[PATCHv2 57/57] merge-recursive: Don't re-sort a list whose order we depend upon

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <newren@xxxxxxxxx>
---
Really this should just be a fixup commit to patch 23 ("merge-recursive:
Fix sorting order and directory change assumptions"), but that has some
(minor) contextual conflicts, which would require me to resubmit the
whole 50+ patch-series again.  I've already flooded everyone's inboxes
enough, so I just created an extra patch.

 merge-recursive.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index 05ba41c..04f3c93 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -402,6 +402,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;
@@ -414,14 +415,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;
@@ -449,6 +456,7 @@ static void record_df_conflict_files(struct merge_options *o,
 			last_file = NULL;
 		}
 	}
+	string_list_clear(&df_sorted_entries, 0);
 }
 
 struct rename {
-- 
1.7.6.100.g7c63c.dirty

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]