From: Elijah Newren Date: Sat, 13 Aug 2011 02:23:51 +0000 (-0600) Subject: merge-recursive: Don't re-sort a list whose order we depend upon X-Git-Tag: v1.7.7-rc1~28^2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=f701aae0774f4517b46dd866812c269c78f1e198;p=git.git merge-recursive: Don't re-sort a list whose order we depend upon In record_df_conflict_files() we would resort the entries list using df_name_compare to get a convenient ordering. Unfortunately, this broke assumptions of the get_renames() code (via string_list_lookup() calls) which needed the list to be in the standard ordering. When those lookups would fail, duplicate stage_data entries could be inserted, causing the process_renames and process_entry code to fail (in particular, a path that that process_renames had marked as processed would still be processed anyway in process_entry due to the duplicate entry). Signed-off-by: Elijah Newren Signed-off-by: Junio C Hamano --- diff --git a/merge-recursive.c b/merge-recursive.c index 78555b6a3..d60fd7a0c 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -400,6 +400,7 @@ static void record_df_conflict_files(struct merge_options *o, * and the file need to be present, then the D/F file will be * reinstated with a new unique name at the time it is processed. */ + struct string_list df_sorted_entries; const char *last_file = NULL; int last_len = 0; int i; @@ -412,14 +413,20 @@ static void record_df_conflict_files(struct merge_options *o, return; /* Ensure D/F conflicts are adjacent in the entries list. */ - qsort(entries->items, entries->nr, sizeof(*entries->items), + memset(&df_sorted_entries, 0, sizeof(struct string_list)); + for (i = 0; i < entries->nr; i++) { + struct string_list_item *next = &entries->items[i]; + string_list_append(&df_sorted_entries, next->string)->util = + next->util; + } + qsort(df_sorted_entries.items, entries->nr, sizeof(*entries->items), string_list_df_name_compare); string_list_clear(&o->df_conflict_file_set, 1); - for (i = 0; i < entries->nr; i++) { - const char *path = entries->items[i].string; + for (i = 0; i < df_sorted_entries.nr; i++) { + const char *path = df_sorted_entries.items[i].string; int len = strlen(path); - struct stage_data *e = entries->items[i].util; + struct stage_data *e = df_sorted_entries.items[i].util; /* * Check if last_file & path correspond to a D/F conflict; @@ -447,6 +454,7 @@ static void record_df_conflict_files(struct merge_options *o, last_file = NULL; } } + string_list_clear(&df_sorted_entries, 0); } struct rename {