merge-recursive: Save D/F conflict filenames instead of unlinking them

Rename make_room_for_directories_of_df_conflicts() to record_df_conflict_files() to reflect the change in functionality. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Aug 11, 2011 at 23:19 UTC 70cc3d36eba58f8bf177c91d82781fb727a9a4fa
2 files changed +25 -16
merge-recursive.c
+24 -16
@@ -360,20 +360,24 @@ static int string_list_df_name_compare(const void *a, const void *b)
360 return onelen - twolen;
361 }
362
363 -
364 -
365 -static void make_room_for_directories_of_df_conflicts(struct merge_options *o,
366 - struct string_list *entries)
363 +static void record_df_conflict_files(struct merge_options *o,
364 + struct string_list *entries)
365 {
368 - /* If there are D/F conflicts, and the paths currently exist
369 - * in the working copy as a file, we want to remove them to
370 - * make room for the corresponding directory. Such paths will
371 - * later be processed in process_df_entry() at the end. If
372 - * the corresponding directory ends up being removed by the
373 - * merge, then the file will be reinstated at that time;
374 - * otherwise, if the file is not supposed to be removed by the
375 - * merge, the contents of the file will be placed in another
376 - * unique filename.
366 + /* If there is a D/F conflict and the file for such a conflict
367 + * currently exist in the working copy, we want to allow it to
368 + * be removed to make room for the corresponding directory if
369 + * needed. The files underneath the directories of such D/F
370 + * conflicts will be handled in process_entry(), while the
371 + * files of such D/F conflicts will be processed later in
372 + * process_df_entry(). If the corresponding directory ends up
373 + * being removed by the merge, then no additional work needs
374 + * to be done by process_df_entry() for the conflicting file.
375 + * If the directory needs to be written to the working copy,
376 + * then the conflicting file will simply be removed (e.g. in
377 + * make_room_for_path). If the directory is written to the
378 + * working copy but the file also has a conflict that needs to
379 + * be resolved, then process_df_entry() will reinstate the
380 + * file with a new unique name.
381 */
382 const char *last_file = NULL;
383 int last_len = 0;
@@ -390,6 +394,7 @@ static void make_room_for_directories_of_df_conflicts(struct merge_options *o,
394 qsort(entries->items, entries->nr, sizeof(*entries->items),
395 string_list_df_name_compare);
396
397 + string_list_clear(&o->df_conflict_file_set, 1);
398 for (i = 0; i < entries->nr; i++) {
399 const char *path = entries->items[i].string;
400 int len = strlen(path);
@@ -398,14 +403,15 @@ static void make_room_for_directories_of_df_conflicts(struct merge_options *o,
403 /*
404 * Check if last_file & path correspond to a D/F conflict;
405 * i.e. whether path is last_file+'/'+<something>.
401 - * If so, remove last_file to make room for path and friends.
406 + * If so, record that it's okay to remove last_file to make
407 + * room for path and friends if needed.
408 */
409 if (last_file &&
410 len > last_len &&
411 memcmp(path, last_file, last_len) == 0 &&
412 path[last_len] == '/') {
413 output(o, 3, "Removing %s to make room for subdirectory; may re-add later.", last_file);
408 - unlink(last_file);
414 + string_list_insert(&o->df_conflict_file_set, last_file);
415 }
416
417 /*
@@ -1569,7 +1575,7 @@ int merge_trees(struct merge_options *o,
1575 get_files_dirs(o, merge);
1576
1577 entries = get_unmerged();
1572 - make_room_for_directories_of_df_conflicts(o, entries);
1578 + record_df_conflict_files(o, entries);
1579 re_head = get_renames(o, head, common, head, merge, entries);
1580 re_merge = get_renames(o, merge, common, head, merge, entries);
1581 clean = process_renames(o, re_head, re_merge);
@@ -1795,6 +1801,8 @@ void init_merge_options(struct merge_options *o)
1801 o->current_file_set.strdup_strings = 1;
1802 memset(&o->current_directory_set, 0, sizeof(struct string_list));
1803 o->current_directory_set.strdup_strings = 1;
1804 + memset(&o->df_conflict_file_set, 0, sizeof(struct string_list));
1805 + o->df_conflict_file_set.strdup_strings = 1;
1806 }
1807
1808 int parse_merge_opt(struct merge_options *o, const char *s)
merge-recursive.h
+1
@@ -26,6 +26,7 @@ struct merge_options {
26 struct strbuf obuf;
27 struct string_list current_file_set;
28 struct string_list current_directory_set;
29 + struct string_list df_conflict_file_set;
30 };
31
32 /* merge_trees() but with recursive ancestor consolidation */