Skip to content

Commit 4109c28

Browse files
committed
Merge branch 'jk/diff-tree-t-fix'
Fix (rarely used) "git diff-tree -t" regression in 2.0. * jk/diff-tree-t-fix: intersect_paths: respect mode in git's tree-sort
2 parents a3d54f9 + e09867f commit 4109c28

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

combine-diff.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@
1212
#include "sha1-array.h"
1313
#include "revision.h"
1414

15+
static int compare_paths(const struct combine_diff_path *one,
16+
const struct diff_filespec *two)
17+
{
18+
if (!S_ISDIR(one->mode) && !S_ISDIR(two->mode))
19+
return strcmp(one->path, two->path);
20+
21+
return base_name_compare(one->path, strlen(one->path), one->mode,
22+
two->path, strlen(two->path), two->mode);
23+
}
24+
1525
static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
1626
{
1727
struct diff_queue_struct *q = &diff_queued_diff;
@@ -52,7 +62,7 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr,
5262
i = 0;
5363
while ((p = *tail) != NULL) {
5464
cmp = ((i >= q->nr)
55-
? -1 : strcmp(p->path, q->queue[i]->two->path));
65+
? -1 : compare_paths(p, q->queue[i]->two));
5666

5767
if (cmp < 0) {
5868
/* p->path not in q->queue[]; drop it */

t/t4038-diff-combined.sh

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,4 +401,38 @@ test_expect_success 'combine diff missing delete bug' '
401401
compare_diff_patch expected actual
402402
'
403403

404+
test_expect_success 'combine diff gets tree sorting right' '
405+
# create a directory and a file that sort differently in trees
406+
# versus byte-wise (implied "/" sorts after ".")
407+
git checkout -f master &&
408+
mkdir foo &&
409+
echo base >foo/one &&
410+
echo base >foo/two &&
411+
echo base >foo.ext &&
412+
git add foo foo.ext &&
413+
git commit -m base &&
414+
415+
# one side modifies a file in the directory, along with the root
416+
# file...
417+
echo master >foo/one &&
418+
echo master >foo.ext &&
419+
git commit -a -m master &&
420+
421+
# the other side modifies the other file in the directory
422+
git checkout -b other HEAD^ &&
423+
echo other >foo/two &&
424+
git commit -a -m other &&
425+
426+
# And now we merge. The files in the subdirectory will resolve cleanly,
427+
# meaning that a combined diff will not find them interesting. But it
428+
# will find the tree itself interesting, because it had to be merged.
429+
git checkout master &&
430+
git merge other &&
431+
432+
printf "MM\tfoo\n" >expect &&
433+
git diff-tree -c --name-status -t HEAD >actual.tmp &&
434+
sed 1d <actual.tmp >actual &&
435+
test_cmp expect actual
436+
'
437+
404438
test_done

0 commit comments

Comments
 (0)