Skip to content

Commit

Permalink
merge-tree: handle directory/empty conflict correctly
Browse files Browse the repository at this point in the history
git-merge-tree causes a null pointer dereference when a directory
entry exists in only one or two of the three trees being compared with
no corresponding entry in the other tree(s).

When this happens, we want to handle the entry as a directory and not
attempt to mark it as a file merge.  Do this by setting the entries bit
in the directory mask when the entry is missing or when it is a
directory, only performing the file comparison when we know that a file
entry exists.

Reported-by: Andreas Jacobsen <[email protected]>
Signed-off-by: John Keeping <[email protected]>
Tested-by: Andreas Jacobsen <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
johnkeeping authored and gitster committed May 7, 2013
1 parent ab5f424 commit 94883b4
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 1 deletion.
6 changes: 5 additions & 1 deletion builtin/merge-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,11 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3])

for (i = 0; i < 3; i++) {
mask |= (1 << i);
if (n[i].mode && S_ISDIR(n[i].mode))
/*
* Treat missing entries as directories so that we return
* after unresolved_directory has handled this.
*/
if (!n[i].mode || S_ISDIR(n[i].mode))
dirmask |= (1 << i);
}

Expand Down
51 changes: 51 additions & 0 deletions t/t4300-merge-tree.sh
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,57 @@ EXPECTED
test_cmp expected actual
'

test_expect_success 'tree add A, B (same)' '
cat >expect <<-\EOF &&
EOF
git reset --hard initial &&
mkdir sub &&
test_commit "add sub/file" "sub/file" "file" add-tree-A &&
git merge-tree initial add-tree-A add-tree-A >actual &&
test_cmp expect actual
'

test_expect_success 'tree add A, B (different)' '
cat >expect <<-\EOF &&
added in both
our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file
their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 sub/file
@@ -1 +1,5 @@
+<<<<<<< .our
AAA
+=======
+BBB
+>>>>>>> .their
EOF
git reset --hard initial &&
mkdir sub &&
test_commit "add sub/file" "sub/file" "AAA" add-tree-a-b-A &&
git reset --hard initial &&
mkdir sub &&
test_commit "add sub/file" "sub/file" "BBB" add-tree-a-b-B &&
git merge-tree initial add-tree-a-b-A add-tree-a-b-B >actual &&
test_cmp expect actual
'

test_expect_success 'tree unchanged A, removed B' '
cat >expect <<-\EOF &&
removed in remote
base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file
our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file
@@ -1 +0,0 @@
-AAA
EOF
git reset --hard initial &&
mkdir sub &&
test_commit "add sub/file" "sub/file" "AAA" tree-remove-b-initial &&
git rm sub/file &&
test_tick &&
git commit -m "remove sub/file" &&
git tag tree-remove-b-B &&
git merge-tree tree-remove-b-initial tree-remove-b-initial tree-remove-b-B >actual &&
test_cmp expect actual
'

test_expect_success 'turn file to tree' '
git reset --hard initial &&
rm initial-file &&
Expand Down

0 comments on commit 94883b4

Please sign in to comment.