summaryrefslogtreecommitdiff
path: root/builtin/fast-export.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2010-08-31 23:23:58 (GMT)
committerJunio C Hamano <gitster@pobox.com>2010-08-31 23:23:58 (GMT)
commit3f29dd6c2344c56aad263a82a773ead0d9fded30 (patch)
tree3c9747da395c4e478f84e8118f28f78e9e8c8ee0 /builtin/fast-export.c
parentaca35505db3706c87d391dd213e856f73edfd42c (diff)
parent96ecac677aa84639a0b8e0aa0d781b197a2d16fe (diff)
downloadgit-3f29dd6c2344c56aad263a82a773ead0d9fded30.zip
git-3f29dd6c2344c56aad263a82a773ead0d9fded30.tar.gz
git-3f29dd6c2344c56aad263a82a773ead0d9fded30.tar.bz2
Merge branch 'en/d-f-conflict-fix'
* en/d-f-conflict-fix: merge-recursive: Avoid excessive output for and reprocessing of renames merge-recursive: Fix multiple file rename across D/F conflict t6031: Add a testcase covering multiple renames across a D/F conflict merge-recursive: Fix typo Mark tests that use symlinks as needing SYMLINKS prerequisite t/t6035-merge-dir-to-symlink.sh: Remove TODO on passing test fast-import: Improve robustness when D->F changes provided in wrong order fast-export: Fix output order of D/F changes merge_recursive: Fix renames across paths below D/F conflicts merge-recursive: Fix D/F conflicts Add a rename + D/F conflict testcase Add additional testcases for D/F conflicts Conflicts: merge-recursive.c
Diffstat (limited to 'builtin/fast-export.c')
-rw-r--r--builtin/fast-export.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 66cafe6..a9bbf86 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -148,10 +148,39 @@ static void handle_object(const unsigned char *sha1)
free(buf);
}
+static int depth_first(const void *a_, const void *b_)
+{
+ const struct diff_filepair *a = *((const struct diff_filepair **)a_);
+ const struct diff_filepair *b = *((const struct diff_filepair **)b_);
+ const char *name_a, *name_b;
+ int len_a, len_b, len;
+ int cmp;
+
+ name_a = a->one ? a->one->path : a->two->path;
+ name_b = b->one ? b->one->path : b->two->path;
+
+ len_a = strlen(name_a);
+ len_b = strlen(name_b);
+ len = (len_a < len_b) ? len_a : len_b;
+
+ /* strcmp will sort 'd' before 'd/e', we want 'd/e' before 'd' */
+ cmp = memcmp(name_a, name_b, len);
+ if (cmp)
+ return cmp;
+ return (len_b - len_a);
+}
+
static void show_filemodify(struct diff_queue_struct *q,
struct diff_options *options, void *data)
{
int i;
+
+ /*
+ * Handle files below a directory first, in case they are all deleted
+ * and the directory changes to a file or symlink.
+ */
+ qsort(q->queue, q->nr, sizeof(q->queue[0]), depth_first);
+
for (i = 0; i < q->nr; i++) {
struct diff_filespec *ospec = q->queue[i]->one;
struct diff_filespec *spec = q->queue[i]->two;