mirror of
https://github.com/git/git.git
synced 2024-11-28 12:34:08 +08:00
730f72840c
This makes the traversal of index be in sync with the tree traversal. When unpack_callback() is fed a set of tree entries from trees, it inspects the name of the entry and checks if the an index entry with the same name could be hiding behind the current index entry, and (1) if the name appears in the index as a leaf node, it is also fed to the n_way_merge() callback function; (2) if the name is a directory in the index, i.e. there are entries in that are underneath it, then nothing is fed to the n_way_merge() callback function; (3) otherwise, if the name comes before the first eligible entry in the index, the index entry is first unpacked alone. When traverse_trees_recursive() descends into a subdirectory, the cache_bottom pointer is moved to walk index entries within that directory. All of these are omitted for diff-index, which does not even want to be fed an index entry and a tree entry with D/F conflicts. This fixes 3-way read-tree and exposes a bug in other parts of the system in t6035, test #5. The test prepares these three trees: O = HEAD^ 100644 blobe69de29bb2
a/b-2/c/d 100644 blobe69de29bb2
a/b/c/d 100644 blobe69de29bb2
a/x A = HEAD 100644 blobe69de29bb2
a/b-2/c/d 100644 blobe69de29bb2
a/b/c/d 100644 blob 587be6b4c3f93f93c489c0111bba5596147a26cb a/x B = master 120000 blob a36b77384451ea1de7bd340ffca868249626bc52 a/b 100644 blobe69de29bb2
a/b-2/c/d 100644 blobe69de29bb2
a/x With a clean index that matches HEAD, running git read-tree -m -u --aggressive $O $A $B now yields 120000 a36b77384451ea1de7bd340ffca868249626bc52 3 a/b 100644e69de29bb2
0 a/b-2/c/d 100644e69de29bb2
1 a/b/c/d 100644e69de29bb2
2 a/b/c/d 100644 587be6b4c3f93f93c489c0111bba5596147a26cb 0 a/x which is correct. "master" created "a/b" symlink that did not exist, and removed "a/b/c/d" while HEAD did not do touch either path. Before this series, read-tree did not notice the situation and resolved addition of "a/b" and removal of "a/b/c/d" independently. If A = HEAD had another path "a/b/c/e" added, this merge should conflict but instead it silently resolved "a/b" and then immediately overwrote it to add "a/b/c/e", which was quite bogus. Tests in t1012 start to work with this. Signed-off-by: Junio C Hamano <gitster@pobox.com>
103 lines
1.8 KiB
Bash
Executable File
103 lines
1.8 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='read-tree D/F conflict corner cases'
|
|
|
|
. ./test-lib.sh
|
|
|
|
maketree () {
|
|
(
|
|
rm -f .git/index .git/index.lock &&
|
|
git clean -d -f -f -q -x &&
|
|
name="$1" &&
|
|
shift &&
|
|
for it
|
|
do
|
|
path=$(expr "$it" : '\([^:]*\)') &&
|
|
mkdir -p $(dirname "$path") &&
|
|
echo "$it" >"$path" &&
|
|
git update-index --add "$path" || exit
|
|
done &&
|
|
git tag "$name" $(git write-tree)
|
|
)
|
|
}
|
|
|
|
settree () {
|
|
rm -f .git/index .git/index.lock &&
|
|
git clean -d -f -f -q -x &&
|
|
git read-tree "$1" &&
|
|
git checkout-index -f -q -u -a &&
|
|
git update-index --refresh
|
|
}
|
|
|
|
checkindex () {
|
|
git ls-files -s |
|
|
sed "s|^[0-7][0-7]* $_x40 \([0-3]\) |\1 |" >current &&
|
|
cat >expect &&
|
|
test_cmp expect current
|
|
}
|
|
|
|
test_expect_success setup '
|
|
maketree O-000 a/b-2/c/d a/b/c/d a/x &&
|
|
maketree A-000 a/b-2/c/d a/b/c/d a/x &&
|
|
maketree A-001 a/b-2/c/d a/b/c/d a/b/c/e a/x &&
|
|
maketree B-000 a/b-2/c/d a/b a/x &&
|
|
|
|
maketree O-010 t-0 t/1 t/2 t=3 &&
|
|
maketree A-010 t-0 t t=3 &&
|
|
maketree B-010 t/1: t=3: &&
|
|
|
|
maketree O-020 ds/dma/ioat.c ds/dma/ioat_dca.c &&
|
|
maketree A-020 ds/dma/ioat/Makefile ds/dma/ioat/registers.h &&
|
|
:
|
|
'
|
|
|
|
test_expect_success '3-way (1)' '
|
|
settree A-000 &&
|
|
git read-tree -m -u O-000 A-000 B-000 &&
|
|
checkindex <<-EOF
|
|
3 a/b
|
|
0 a/b-2/c/d
|
|
1 a/b/c/d
|
|
2 a/b/c/d
|
|
0 a/x
|
|
EOF
|
|
'
|
|
|
|
test_expect_success '3-way (2)' '
|
|
settree A-001 &&
|
|
git read-tree -m -u O-000 A-001 B-000 &&
|
|
checkindex <<-EOF
|
|
3 a/b
|
|
0 a/b-2/c/d
|
|
1 a/b/c/d
|
|
2 a/b/c/d
|
|
2 a/b/c/e
|
|
0 a/x
|
|
EOF
|
|
'
|
|
|
|
test_expect_success '3-way (3)' '
|
|
settree A-010 &&
|
|
git read-tree -m -u O-010 A-010 B-010 &&
|
|
checkindex <<-EOF
|
|
2 t
|
|
1 t-0
|
|
2 t-0
|
|
1 t/1
|
|
3 t/1
|
|
1 t/2
|
|
0 t=3
|
|
EOF
|
|
'
|
|
|
|
test_expect_success '2-way (1)' '
|
|
settree O-020 &&
|
|
git read-tree -m -u O-020 A-020 &&
|
|
checkindex <<-EOF
|
|
0 ds/dma/ioat/Makefile
|
|
0 ds/dma/ioat/registers.h
|
|
EOF
|
|
'
|
|
|
|
test_done
|