@@ -337,32 +337,37 @@ static void init_tree_desc_from_tree(struct tree_desc *desc, struct tree *tree)
337
337
init_tree_desc (desc , tree -> buffer , tree -> size );
338
338
}
339
339
340
- static int git_merge_trees (int index_only ,
340
+ static int git_merge_trees (struct merge_options * o ,
341
341
struct tree * common ,
342
342
struct tree * head ,
343
343
struct tree * merge )
344
344
{
345
345
int rc ;
346
346
struct tree_desc t [3 ];
347
- struct unpack_trees_options opts ;
348
347
349
- memset (& opts , 0 , sizeof (opts ));
350
- if (index_only )
351
- opts .index_only = 1 ;
348
+ memset (& o -> unpack_opts , 0 , sizeof (o -> unpack_opts ));
349
+ if (o -> call_depth )
350
+ o -> unpack_opts .index_only = 1 ;
352
351
else
353
- opts .update = 1 ;
354
- opts .merge = 1 ;
355
- opts .head_idx = 2 ;
356
- opts .fn = threeway_merge ;
357
- opts .src_index = & the_index ;
358
- opts .dst_index = & the_index ;
359
- setup_unpack_trees_porcelain (& opts , "merge" );
352
+ o -> unpack_opts .update = 1 ;
353
+ o -> unpack_opts .merge = 1 ;
354
+ o -> unpack_opts .head_idx = 2 ;
355
+ o -> unpack_opts .fn = threeway_merge ;
356
+ o -> unpack_opts .src_index = & the_index ;
357
+ o -> unpack_opts .dst_index = & the_index ;
358
+ setup_unpack_trees_porcelain (& o -> unpack_opts , "merge" );
360
359
361
360
init_tree_desc_from_tree (t + 0 , common );
362
361
init_tree_desc_from_tree (t + 1 , head );
363
362
init_tree_desc_from_tree (t + 2 , merge );
364
363
365
- rc = unpack_trees (3 , t , & opts );
364
+ rc = unpack_trees (3 , t , & o -> unpack_opts );
365
+ /*
366
+ * unpack_trees NULLifies src_index, but it's used in verify_uptodate,
367
+ * so set to the new index which will usually have modification
368
+ * timestamp info copied over.
369
+ */
370
+ o -> unpack_opts .src_index = & the_index ;
366
371
cache_tree_free (& active_cache_tree );
367
372
return rc ;
368
373
}
@@ -795,6 +800,20 @@ static int would_lose_untracked(const char *path)
795
800
return !was_tracked (path ) && file_exists (path );
796
801
}
797
802
803
+ static int was_dirty (struct merge_options * o , const char * path )
804
+ {
805
+ struct cache_entry * ce ;
806
+ int dirty = 1 ;
807
+
808
+ if (o -> call_depth || !was_tracked (path ))
809
+ return !dirty ;
810
+
811
+ ce = cache_file_exists (path , strlen (path ), ignore_case );
812
+ dirty = (ce -> ce_stat_data .sd_mtime .sec > 0 &&
813
+ verify_uptodate (ce , & o -> unpack_opts ) != 0 );
814
+ return dirty ;
815
+ }
816
+
798
817
static int make_room_for_path (struct merge_options * o , const char * path )
799
818
{
800
819
int status , i ;
@@ -2687,6 +2706,7 @@ static int handle_modify_delete(struct merge_options *o,
2687
2706
2688
2707
static int merge_content (struct merge_options * o ,
2689
2708
const char * path ,
2709
+ int file_in_way ,
2690
2710
struct object_id * o_oid , int o_mode ,
2691
2711
struct object_id * a_oid , int a_mode ,
2692
2712
struct object_id * b_oid , int b_mode ,
@@ -2761,7 +2781,7 @@ static int merge_content(struct merge_options *o,
2761
2781
return -1 ;
2762
2782
}
2763
2783
2764
- if (df_conflict_remains ) {
2784
+ if (df_conflict_remains || file_in_way ) {
2765
2785
char * new_path ;
2766
2786
if (o -> call_depth ) {
2767
2787
remove_file_from_cache (path );
@@ -2795,6 +2815,30 @@ static int merge_content(struct merge_options *o,
2795
2815
return mfi .clean ;
2796
2816
}
2797
2817
2818
+ static int conflict_rename_normal (struct merge_options * o ,
2819
+ const char * path ,
2820
+ struct object_id * o_oid , unsigned int o_mode ,
2821
+ struct object_id * a_oid , unsigned int a_mode ,
2822
+ struct object_id * b_oid , unsigned int b_mode ,
2823
+ struct rename_conflict_info * ci )
2824
+ {
2825
+ int clean_merge ;
2826
+ int file_in_the_way = 0 ;
2827
+
2828
+ if (was_dirty (o , path )) {
2829
+ file_in_the_way = 1 ;
2830
+ output (o , 1 , _ ("Refusing to lose dirty file at %s" ), path );
2831
+ }
2832
+
2833
+ /* Merge the content and write it out */
2834
+ clean_merge = merge_content (o , path , file_in_the_way ,
2835
+ o_oid , o_mode , a_oid , a_mode , b_oid , b_mode ,
2836
+ ci );
2837
+ if (clean_merge > 0 && file_in_the_way )
2838
+ clean_merge = 0 ;
2839
+ return clean_merge ;
2840
+ }
2841
+
2798
2842
/* Per entry merge function */
2799
2843
static int process_entry (struct merge_options * o ,
2800
2844
const char * path , struct stage_data * entry )
@@ -2814,9 +2858,12 @@ static int process_entry(struct merge_options *o,
2814
2858
switch (conflict_info -> rename_type ) {
2815
2859
case RENAME_NORMAL :
2816
2860
case RENAME_ONE_FILE_TO_ONE :
2817
- clean_merge = merge_content (o , path ,
2818
- o_oid , o_mode , a_oid , a_mode , b_oid , b_mode ,
2819
- conflict_info );
2861
+ clean_merge = conflict_rename_normal (o ,
2862
+ path ,
2863
+ o_oid , o_mode ,
2864
+ a_oid , a_mode ,
2865
+ b_oid , b_mode ,
2866
+ conflict_info );
2820
2867
break ;
2821
2868
case RENAME_DIR :
2822
2869
clean_merge = 1 ;
@@ -2912,7 +2959,7 @@ static int process_entry(struct merge_options *o,
2912
2959
} else if (a_oid && b_oid ) {
2913
2960
/* Case C: Added in both (check for same permissions) and */
2914
2961
/* case D: Modified in both, but differently. */
2915
- clean_merge = merge_content (o , path ,
2962
+ clean_merge = merge_content (o , path , 0 /* file_in_way */ ,
2916
2963
o_oid , o_mode , a_oid , a_mode , b_oid , b_mode ,
2917
2964
NULL );
2918
2965
} else if (!o_oid && !a_oid && !b_oid ) {
@@ -2953,7 +3000,7 @@ int merge_trees(struct merge_options *o,
2953
3000
return 1 ;
2954
3001
}
2955
3002
2956
- code = git_merge_trees (o -> call_depth , common , head , merge );
3003
+ code = git_merge_trees (o , common , head , merge );
2957
3004
2958
3005
if (code != 0 ) {
2959
3006
if (show (o , 4 ) || o -> call_depth )
0 commit comments