@@ -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 ;
@@ -2677,6 +2696,7 @@ static int handle_modify_delete(struct merge_options *o,
2677
2696
2678
2697
static int merge_content (struct merge_options * o ,
2679
2698
const char * path ,
2699
+ int file_in_way ,
2680
2700
struct object_id * o_oid , int o_mode ,
2681
2701
struct object_id * a_oid , int a_mode ,
2682
2702
struct object_id * b_oid , int b_mode ,
@@ -2751,7 +2771,7 @@ static int merge_content(struct merge_options *o,
2751
2771
return -1 ;
2752
2772
}
2753
2773
2754
- if (df_conflict_remains ) {
2774
+ if (df_conflict_remains || file_in_way ) {
2755
2775
char * new_path ;
2756
2776
if (o -> call_depth ) {
2757
2777
remove_file_from_cache (path );
@@ -2785,6 +2805,30 @@ static int merge_content(struct merge_options *o,
2785
2805
return mfi .clean ;
2786
2806
}
2787
2807
2808
+ static int conflict_rename_normal (struct merge_options * o ,
2809
+ const char * path ,
2810
+ struct object_id * o_oid , unsigned int o_mode ,
2811
+ struct object_id * a_oid , unsigned int a_mode ,
2812
+ struct object_id * b_oid , unsigned int b_mode ,
2813
+ struct rename_conflict_info * ci )
2814
+ {
2815
+ int clean_merge ;
2816
+ int file_in_the_way = 0 ;
2817
+
2818
+ if (was_dirty (o , path )) {
2819
+ file_in_the_way = 1 ;
2820
+ output (o , 1 , _ ("Refusing to lose dirty file at %s" ), path );
2821
+ }
2822
+
2823
+ /* Merge the content and write it out */
2824
+ clean_merge = merge_content (o , path , file_in_the_way ,
2825
+ o_oid , o_mode , a_oid , a_mode , b_oid , b_mode ,
2826
+ ci );
2827
+ if (clean_merge > 0 && file_in_the_way )
2828
+ clean_merge = 0 ;
2829
+ return clean_merge ;
2830
+ }
2831
+
2788
2832
/* Per entry merge function */
2789
2833
static int process_entry (struct merge_options * o ,
2790
2834
const char * path , struct stage_data * entry )
@@ -2804,9 +2848,12 @@ static int process_entry(struct merge_options *o,
2804
2848
switch (conflict_info -> rename_type ) {
2805
2849
case RENAME_NORMAL :
2806
2850
case RENAME_ONE_FILE_TO_ONE :
2807
- clean_merge = merge_content (o , path ,
2808
- o_oid , o_mode , a_oid , a_mode , b_oid , b_mode ,
2809
- conflict_info );
2851
+ clean_merge = conflict_rename_normal (o ,
2852
+ path ,
2853
+ o_oid , o_mode ,
2854
+ a_oid , a_mode ,
2855
+ b_oid , b_mode ,
2856
+ conflict_info );
2810
2857
break ;
2811
2858
case RENAME_DIR :
2812
2859
clean_merge = 1 ;
@@ -2902,7 +2949,7 @@ static int process_entry(struct merge_options *o,
2902
2949
} else if (a_oid && b_oid ) {
2903
2950
/* Case C: Added in both (check for same permissions) and */
2904
2951
/* case D: Modified in both, but differently. */
2905
- clean_merge = merge_content (o , path ,
2952
+ clean_merge = merge_content (o , path , 0 /* file_in_way */ ,
2906
2953
o_oid , o_mode , a_oid , a_mode , b_oid , b_mode ,
2907
2954
NULL );
2908
2955
} else if (!o_oid && !a_oid && !b_oid ) {
@@ -2943,7 +2990,7 @@ int merge_trees(struct merge_options *o,
2943
2990
return 1 ;
2944
2991
}
2945
2992
2946
- code = git_merge_trees (o -> call_depth , common , head , merge );
2993
+ code = git_merge_trees (o , common , head , merge );
2947
2994
2948
2995
if (code != 0 ) {
2949
2996
if (show (o , 4 ) || o -> call_depth )
0 commit comments