3 test_description='object name disambiguation
5 Create blobs, trees, commits and a tag that all share the same
6 prefix, and make sure "git rev-parse" can take advantage of
7 type information to disambiguate short object names that are
8 not necessarily unique.
10 The final history used in the test has five commits, with the bottom
11 one tagged as v1.0.0. They all have one regular file each.
13 +-------------------------------------------+
15 | .-------b3wettvi---- ad2uee |
17 | a2onsxbvj---czy8f73t--ioiley5o |
19 +-------------------------------------------+
25 test_expect_success 'blob and tree' '
28 for i in 0 1 2 3 4 5 6 7 8 9
36 # create one blob 0000000000b36
39 # create one tree 0000000000cdc
43 test_expect_success 'warn ambiguity when no candidate matches type hint' '
44 test_must_fail git rev-parse --verify 000000000^{commit} 2>actual &&
45 grep "short SHA1 000000000 is ambiguous" actual
48 test_expect_success 'disambiguate tree-ish' '
49 # feed tree-ish in an unambiguous way
50 git rev-parse --verify 0000000000cdc:a0blgqsjc &&
52 # ambiguous at the object name level, but there is only one
53 # such tree-ish (the other is a blob)
54 git rev-parse --verify 000000000:a0blgqsjc
57 test_expect_success 'disambiguate blob' '
58 sed -e "s/|$//" >patch <<-EOF &&
59 diff --git a/frotz b/frotz
60 index 000000000..ffffff 100644
70 GIT_INDEX_FILE=frotz &&
71 export GIT_INDEX_FILE &&
72 git apply --build-fake-ancestor frotz patch &&
73 git cat-file blob :frotz >actual
75 test_cmp a0blgqsjc actual
78 test_expect_success 'disambiguate tree' '
79 commit=$(echo "d7xm" | git commit-tree 000000000) &&
80 test $(git rev-parse $commit^{tree}) = $(git rev-parse 0000000000cdc)
83 test_expect_success 'first commit' '
84 # create one commit 0000000000e4f
85 git commit -m a2onsxbvj
88 test_expect_success 'disambiguate commit-ish' '
89 # feed commit-ish in an unambiguous way
90 git rev-parse --verify 0000000000e4f^{commit} &&
92 # ambiguous at the object name level, but there is only one
93 # such commit (the others are tree and blob)
94 git rev-parse --verify 000000000^{commit} &&
97 git rev-parse --verify 000000000^0
100 test_expect_success 'disambiguate commit' '
101 commit=$(echo "hoaxj" | git commit-tree 0000000000cdc -p 000000000) &&
102 test $(git rev-parse $commit^) = $(git rev-parse 0000000000e4f)
105 test_expect_success 'log name1..name2 takes only commit-ishes on both ends' '
106 git log 000000000..000000000 &&
107 git log ..000000000 &&
108 git log 000000000.. &&
109 git log 000000000...000000000 &&
110 git log ...000000000 &&
114 test_expect_success 'rev-parse name1..name2 takes only commit-ishes on both ends' '
115 git rev-parse 000000000..000000000 &&
116 git rev-parse ..000000000 &&
117 git rev-parse 000000000..
120 test_expect_success 'git log takes only commit-ish' '
124 test_expect_success 'git reset takes only commit-ish' '
128 test_expect_success 'first tag' '
129 # create one tag 0000000000f8f
130 git tag -a -m j7cp83um v1.0.0
133 test_expect_failure 'two semi-ambiguous commit-ish' '
134 # Once the parser becomes ultra-smart, it could notice that
135 # 110282 before ^{commit} name many different objects, but
136 # that only two (HEAD and v1.0.0 tag) can be peeled to commit,
137 # and that peeling them down to commit yield the same commit
139 git rev-parse --verify 110282^{commit} &&
142 git log 000000000..000000000 &&
143 git log ..000000000 &&
144 git log 000000000.. &&
145 git log 000000000...000000000 &&
146 git log ...000000000 &&
150 test_expect_failure 'three semi-ambiguous tree-ish' '
151 # Likewise for tree-ish. HEAD, v1.0.0 and HEAD^{tree} share
152 # the prefix but peeling them to tree yields the same thing
153 git rev-parse --verify 000000000^{tree}
156 test_expect_success 'parse describe name' '
157 # feed an unambiguous describe name
158 git rev-parse --verify v1.0.0-0-g0000000000e4f &&
160 # ambiguous at the object name level, but there is only one
161 # such commit (others are blob, tree and tag)
162 git rev-parse --verify v1.0.0-0-g000000000
165 test_expect_success 'more history' '
166 # commit 0000000000043
167 git mv a0blgqsjc d12cr3h8t &&
168 echo h62xsjeu >>d12cr3h8t &&
172 git commit -m czy8f73t &&
174 # commit 00000000008ec
175 git mv d12cr3h8t j000jmpzn &&
176 echo j08bekfvt >>j000jmpzn &&
180 git commit -m ioiley5o &&
182 # commit 0000000005b0
183 git checkout v1.0.0^0 &&
184 git mv a0blgqsjc f5518nwu &&
186 for i in h62xsjeu j08bekfvt kg7xflhm
193 git commit -m b3wettvi &&
194 side=$(git rev-parse HEAD) &&
196 # commit 000000000066
197 git checkout master &&
199 # If you use recursive, merge will fail and you will need to
200 # clean up a0blgqsjc as well. If you use resolve, merge will
202 test_might_fail git merge --no-commit -s recursive $side &&
203 git rm -f f5518nwu j000jmpzn &&
205 test_might_fail git rm -f a0blgqsjc &&
207 git cat-file blob $side:f5518nwu
217 test_expect_failure 'parse describe name taking advantage of generation' '
218 # ambiguous at the object name level, but there is only one
219 # such commit at generation 0
220 git rev-parse --verify v1.0.0-0-g000000000 &&
222 # likewise for generation 2 and 4
223 git rev-parse --verify v1.0.0-2-g000000000 &&
224 git rev-parse --verify v1.0.0-4-g000000000
227 # Note: because rev-parse does not even try to disambiguate based on
228 # the generation number, this test currently succeeds for a wrong
229 # reason. When it learns to use the generation number, the previous
230 # test should succeed, and also this test should fail because the
231 # describe name used in the test with generation number can name two
232 # commits. Make sure that such a future enhancement does not randomly
234 test_expect_success 'parse describe name not ignoring ambiguity' '
235 # ambiguous at the object name level, and there are two such
236 # commits at generation 1
237 test_must_fail git rev-parse --verify v1.0.0-1-g000000000
240 test_expect_success 'ambiguous commit-ish' '
241 # Now there are many commits that begin with the
242 # common prefix, none of these should pick one at
243 # random. They all should result in ambiguity errors.
244 test_must_fail git rev-parse --verify 110282^{commit} &&
247 test_must_fail git log 000000000..000000000 &&
248 test_must_fail git log ..000000000 &&
249 test_must_fail git log 000000000.. &&
250 test_must_fail git log 000000000...000000000 &&
251 test_must_fail git log ...000000000 &&
252 test_must_fail git log 000000000...
255 test_expect_success 'rev-parse --disambiguate' '
256 # The test creates 16 objects that share the prefix and two
257 # commits created by commit-tree in earlier tests share a
259 git rev-parse --disambiguate=000000000 >actual &&
260 test $(wc -l <actual) = 16 &&
261 test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000
264 test_expect_success 'ambiguous 40-hex ref' '
265 TREE=$(git mktree </dev/null) &&
266 REF=`git rev-parse HEAD` &&
267 VAL=$(git commit-tree $TREE </dev/null) &&
268 git update-ref refs/heads/$REF $VAL &&
269 test `git rev-parse $REF 2>err` = $REF &&
270 grep "refname.*${REF}.*ambiguous" err
273 test_expect_success 'ambiguous short sha1 ref' '
274 TREE=$(git mktree </dev/null) &&
275 REF=`git rev-parse --short HEAD` &&
276 VAL=$(git commit-tree $TREE </dev/null) &&
277 git update-ref refs/heads/$REF $VAL &&
278 test `git rev-parse $REF 2>err` = $VAL &&
279 grep "refname.*${REF}.*ambiguous" err