Re: [PATCH 22/48] merge-recursive: Fix sorting order and directory change assumptions
Am 7/12/2011 9:27, schrieb Johannes Sixt:
Show 11 quoted lines
> Am 7/11/2011 9:04, schrieb Johannes Sixt:
>> A heads-up: This test case fails here on Windows. The messages produced are:
>
>> As you can see, "Removing letters..." is missing on Windows, and the file
>> 'letters' is indeed left in the working tree. Any quick ideas where to
>> begin debugging this?
>
> And the reason for this is that the qsort call in record_df_conflict_files
> assumes that qsort is a stable sort; but this is not guaranteed. In
> particular, the entry "letters" can be moved after "letters/file", which
> is not expected by the loop that follows the qsort.
Perhaps something like below. It passes the tests that previously failed.
--- >8 ---
From: Johannes Sixt <j6t@kdbg.org>
Subject: [PATCH] fixup! Do not assume that qsort is stable
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
merge-recursive.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/merge-recursive.c b/merge-recursive.c
index 88167c3..81fac5f 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -361,6 +361,8 @@ static int string_list_df_name_compare(const void *a, const void *b)
{
const struct string_list_item *one = a;
const struct string_list_item *two = b;
+ int onelen = strlen(one->string);
+ int twolen = strlen(two->string);
/*
* Here we only care that entries for D/F conflicts are
* adjacent, in particular with the file of the D/F conflict
@@ -373,8 +375,15 @@ static int string_list_df_name_compare(const void *a, const void *b)
* since in other cases any changes in their order due to
* sorting cause no problems for us.
*/
- return df_name_compare(one->string, strlen(one->string), S_IFDIR,
- two->string, strlen(two->string), S_IFDIR);
+ int cmp = df_name_compare(one->string, onelen, S_IFDIR,
+ two->string, twolen, S_IFDIR);
+ /*
+ * Now that 'foo' and 'foo/bar' compare equal, we have to make sure
+ * that 'foo' comes before 'foo/bar'.
+ */
+ if (cmp)
+ return cmp;
+ return onelen - twolen;
}
static void record_df_conflict_files(struct merge_options *o,
--
1.7.6.1317.gd8c5a.dirty