]>
Commit | Line | Data |
---|---|---|
6269b6b6 JH |
1 | #!/bin/sh |
2 | ||
3 | test_description='object name disambiguation | |
4 | ||
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. | |
9 | ||
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. | |
12 | ||
13 | +-------------------------------------------+ | |
14 | | | | |
15 | | .-------b3wettvi---- ad2uee | | |
16 | | / / | | |
17 | | a2onsxbvj---czy8f73t--ioiley5o | | |
18 | | | | |
19 | +-------------------------------------------+ | |
20 | ||
21 | ' | |
22 | ||
23 | . ./test-lib.sh | |
24 | ||
25 | test_expect_success 'blob and tree' ' | |
26 | test_tick && | |
27 | ( | |
28 | for i in 0 1 2 3 4 5 6 7 8 9 | |
29 | do | |
30 | echo $i | |
31 | done | |
32 | echo | |
33 | echo b1rwzyc3 | |
34 | ) >a0blgqsjc && | |
35 | ||
36 | # create one blob 0000000000b36 | |
37 | git add a0blgqsjc && | |
38 | ||
39 | # create one tree 0000000000cdc | |
40 | git write-tree | |
41 | ' | |
42 | ||
43 | test_expect_success 'warn ambiguity when no candidate matches type hint' ' | |
44 | test_must_fail git rev-parse --verify 000000000^{commit} 2>actual && | |
3bb46443 | 45 | test_i18ngrep "short SHA1 000000000 is ambiguous" actual |
6269b6b6 JH |
46 | ' |
47 | ||
daba53ae | 48 | test_expect_success 'disambiguate tree-ish' ' |
6269b6b6 JH |
49 | # feed tree-ish in an unambiguous way |
50 | git rev-parse --verify 0000000000cdc:a0blgqsjc && | |
51 | ||
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 | |
55 | ' | |
56 | ||
da3ac0c1 | 57 | test_expect_success 'disambiguate blob' ' |
6269b6b6 JH |
58 | sed -e "s/|$//" >patch <<-EOF && |
59 | diff --git a/frotz b/frotz | |
60 | index 000000000..ffffff 100644 | |
61 | --- a/frotz | |
62 | +++ b/frotz | |
63 | @@ -10,3 +10,4 @@ | |
64 | 9 | |
65 | | | |
66 | b1rwzyc3 | |
67 | +irwry | |
68 | EOF | |
69 | ( | |
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 | |
74 | ) && | |
75 | test_cmp a0blgqsjc actual | |
76 | ' | |
77 | ||
75f5ac04 | 78 | test_expect_success 'disambiguate tree' ' |
6269b6b6 | 79 | commit=$(echo "d7xm" | git commit-tree 000000000) && |
2c57f7c9 | 80 | # this commit is fffff2e and not ambiguous with the 00000* objects |
6269b6b6 JH |
81 | test $(git rev-parse $commit^{tree}) = $(git rev-parse 0000000000cdc) |
82 | ' | |
83 | ||
84 | test_expect_success 'first commit' ' | |
85 | # create one commit 0000000000e4f | |
86 | git commit -m a2onsxbvj | |
87 | ' | |
88 | ||
e2643617 | 89 | test_expect_success 'disambiguate commit-ish' ' |
6269b6b6 JH |
90 | # feed commit-ish in an unambiguous way |
91 | git rev-parse --verify 0000000000e4f^{commit} && | |
92 | ||
93 | # ambiguous at the object name level, but there is only one | |
94 | # such commit (the others are tree and blob) | |
95 | git rev-parse --verify 000000000^{commit} && | |
96 | ||
97 | # likewise | |
98 | git rev-parse --verify 000000000^0 | |
99 | ' | |
100 | ||
75f5ac04 | 101 | test_expect_success 'disambiguate commit' ' |
31ffd0c0 | 102 | commit=$(echo "hoaxj" | git commit-tree 0000000000cdc -p 000000000) && |
2c57f7c9 | 103 | # this commit is ffffffd8 and not ambiguous with the 00000* objects |
6269b6b6 JH |
104 | test $(git rev-parse $commit^) = $(git rev-parse 0000000000e4f) |
105 | ' | |
106 | ||
cd74e473 | 107 | test_expect_success 'log name1..name2 takes only commit-ishes on both ends' ' |
2c57f7c9 JH |
108 | # These are underspecified from the prefix-length point of view |
109 | # to disambiguate the commit with other objects, but there is only | |
110 | # one commit that has 00000* prefix at this point. | |
6269b6b6 JH |
111 | git log 000000000..000000000 && |
112 | git log ..000000000 && | |
113 | git log 000000000.. && | |
114 | git log 000000000...000000000 && | |
115 | git log ...000000000 && | |
116 | git log 000000000... | |
117 | ' | |
118 | ||
c036c4c5 | 119 | test_expect_success 'rev-parse name1..name2 takes only commit-ishes on both ends' ' |
2c57f7c9 | 120 | # Likewise. |
6269b6b6 JH |
121 | git rev-parse 000000000..000000000 && |
122 | git rev-parse ..000000000 && | |
123 | git rev-parse 000000000.. | |
124 | ' | |
125 | ||
d5f6b1d7 | 126 | test_expect_success 'git log takes only commit-ish' ' |
2c57f7c9 | 127 | # Likewise. |
6269b6b6 JH |
128 | git log 000000000 |
129 | ' | |
130 | ||
13243c2c | 131 | test_expect_success 'git reset takes only commit-ish' ' |
2c57f7c9 | 132 | # Likewise. |
6269b6b6 JH |
133 | git reset 000000000 |
134 | ' | |
135 | ||
136 | test_expect_success 'first tag' ' | |
137 | # create one tag 0000000000f8f | |
138 | git tag -a -m j7cp83um v1.0.0 | |
139 | ' | |
140 | ||
141 | test_expect_failure 'two semi-ambiguous commit-ish' ' | |
2c57f7c9 JH |
142 | # At this point, we have a tag 0000000000f8f that points |
143 | # at a commit 0000000000e4f, and a tree and a blob that | |
144 | # share 0000000000 prefix with these tag and commit. | |
145 | # | |
6269b6b6 | 146 | # Once the parser becomes ultra-smart, it could notice that |
2c57f7c9 | 147 | # 0000000000 before ^{commit} name many different objects, but |
6269b6b6 JH |
148 | # that only two (HEAD and v1.0.0 tag) can be peeled to commit, |
149 | # and that peeling them down to commit yield the same commit | |
150 | # without ambiguity. | |
2c57f7c9 | 151 | git rev-parse --verify 0000000000^{commit} && |
6269b6b6 JH |
152 | |
153 | # likewise | |
2c57f7c9 JH |
154 | git log 0000000000..0000000000 && |
155 | git log ..0000000000 && | |
156 | git log 0000000000.. && | |
157 | git log 0000000000...0000000000 && | |
158 | git log ...0000000000 && | |
159 | git log 0000000000... | |
6269b6b6 JH |
160 | ' |
161 | ||
162 | test_expect_failure 'three semi-ambiguous tree-ish' ' | |
163 | # Likewise for tree-ish. HEAD, v1.0.0 and HEAD^{tree} share | |
164 | # the prefix but peeling them to tree yields the same thing | |
2c57f7c9 | 165 | git rev-parse --verify 0000000000^{tree} |
6269b6b6 JH |
166 | ' |
167 | ||
168 | test_expect_success 'parse describe name' ' | |
169 | # feed an unambiguous describe name | |
170 | git rev-parse --verify v1.0.0-0-g0000000000e4f && | |
171 | ||
172 | # ambiguous at the object name level, but there is only one | |
173 | # such commit (others are blob, tree and tag) | |
174 | git rev-parse --verify v1.0.0-0-g000000000 | |
175 | ' | |
176 | ||
177 | test_expect_success 'more history' ' | |
178 | # commit 0000000000043 | |
179 | git mv a0blgqsjc d12cr3h8t && | |
180 | echo h62xsjeu >>d12cr3h8t && | |
181 | git add d12cr3h8t && | |
182 | ||
183 | test_tick && | |
184 | git commit -m czy8f73t && | |
185 | ||
186 | # commit 00000000008ec | |
187 | git mv d12cr3h8t j000jmpzn && | |
188 | echo j08bekfvt >>j000jmpzn && | |
189 | git add j000jmpzn && | |
190 | ||
191 | test_tick && | |
192 | git commit -m ioiley5o && | |
193 | ||
194 | # commit 0000000005b0 | |
195 | git checkout v1.0.0^0 && | |
196 | git mv a0blgqsjc f5518nwu && | |
197 | ||
198 | for i in h62xsjeu j08bekfvt kg7xflhm | |
199 | do | |
200 | echo $i | |
201 | done >>f5518nwu && | |
202 | git add f5518nwu && | |
203 | ||
204 | test_tick && | |
205 | git commit -m b3wettvi && | |
206 | side=$(git rev-parse HEAD) && | |
207 | ||
208 | # commit 000000000066 | |
209 | git checkout master && | |
210 | ||
211 | # If you use recursive, merge will fail and you will need to | |
212 | # clean up a0blgqsjc as well. If you use resolve, merge will | |
213 | # succeed. | |
214 | test_might_fail git merge --no-commit -s recursive $side && | |
215 | git rm -f f5518nwu j000jmpzn && | |
216 | ||
217 | test_might_fail git rm -f a0blgqsjc && | |
218 | ( | |
219 | git cat-file blob $side:f5518nwu | |
220 | echo j3l0i9s6 | |
221 | ) >ab2gs879 && | |
222 | git add ab2gs879 && | |
223 | ||
224 | test_tick && | |
225 | git commit -m ad2uee | |
226 | ||
227 | ' | |
228 | ||
229 | test_expect_failure 'parse describe name taking advantage of generation' ' | |
230 | # ambiguous at the object name level, but there is only one | |
231 | # such commit at generation 0 | |
232 | git rev-parse --verify v1.0.0-0-g000000000 && | |
233 | ||
234 | # likewise for generation 2 and 4 | |
235 | git rev-parse --verify v1.0.0-2-g000000000 && | |
236 | git rev-parse --verify v1.0.0-4-g000000000 | |
237 | ' | |
238 | ||
239 | # Note: because rev-parse does not even try to disambiguate based on | |
240 | # the generation number, this test currently succeeds for a wrong | |
241 | # reason. When it learns to use the generation number, the previous | |
242 | # test should succeed, and also this test should fail because the | |
243 | # describe name used in the test with generation number can name two | |
244 | # commits. Make sure that such a future enhancement does not randomly | |
245 | # pick one. | |
246 | test_expect_success 'parse describe name not ignoring ambiguity' ' | |
247 | # ambiguous at the object name level, and there are two such | |
248 | # commits at generation 1 | |
249 | test_must_fail git rev-parse --verify v1.0.0-1-g000000000 | |
250 | ' | |
251 | ||
252 | test_expect_success 'ambiguous commit-ish' ' | |
253 | # Now there are many commits that begin with the | |
254 | # common prefix, none of these should pick one at | |
255 | # random. They all should result in ambiguity errors. | |
2c57f7c9 | 256 | test_must_fail git rev-parse --verify 00000000^{commit} && |
6269b6b6 JH |
257 | |
258 | # likewise | |
259 | test_must_fail git log 000000000..000000000 && | |
260 | test_must_fail git log ..000000000 && | |
261 | test_must_fail git log 000000000.. && | |
262 | test_must_fail git log 000000000...000000000 && | |
263 | test_must_fail git log ...000000000 && | |
264 | test_must_fail git log 000000000... | |
265 | ' | |
266 | ||
5d5def2a JK |
267 | # There are three objects with this prefix: a blob, a tree, and a tag. We know |
268 | # the blob will not pass as a treeish, but the tree and tag should (and thus | |
269 | # cause an error). | |
270 | test_expect_success 'ambiguous tags peel to treeish' ' | |
271 | test_must_fail git rev-parse 0000000000f^{tree} | |
272 | ' | |
273 | ||
957d7406 JH |
274 | test_expect_success 'rev-parse --disambiguate' ' |
275 | # The test creates 16 objects that share the prefix and two | |
31ffd0c0 JH |
276 | # commits created by commit-tree in earlier tests share a |
277 | # different prefix. | |
957d7406 | 278 | git rev-parse --disambiguate=000000000 >actual && |
4c654f5f | 279 | test $(wc -l <actual) = 16 && |
957d7406 JH |
280 | test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000 |
281 | ' | |
282 | ||
fad6b9e5 JK |
283 | test_expect_success 'rev-parse --disambiguate drops duplicates' ' |
284 | git rev-parse --disambiguate=000000000 >expect && | |
285 | git pack-objects .git/objects/pack/pack <expect && | |
286 | git rev-parse --disambiguate=000000000 >actual && | |
287 | test_cmp expect actual | |
288 | ' | |
289 | ||
798c35fc NTND |
290 | test_expect_success 'ambiguous 40-hex ref' ' |
291 | TREE=$(git mktree </dev/null) && | |
dcfbb2aa | 292 | REF=$(git rev-parse HEAD) && |
798c35fc NTND |
293 | VAL=$(git commit-tree $TREE </dev/null) && |
294 | git update-ref refs/heads/$REF $VAL && | |
dcfbb2aa | 295 | test $(git rev-parse $REF 2>err) = $REF && |
798c35fc NTND |
296 | grep "refname.*${REF}.*ambiguous" err |
297 | ' | |
298 | ||
299 | test_expect_success 'ambiguous short sha1 ref' ' | |
300 | TREE=$(git mktree </dev/null) && | |
dcfbb2aa | 301 | REF=$(git rev-parse --short HEAD) && |
798c35fc NTND |
302 | VAL=$(git commit-tree $TREE </dev/null) && |
303 | git update-ref refs/heads/$REF $VAL && | |
dcfbb2aa | 304 | test $(git rev-parse $REF 2>err) = $VAL && |
798c35fc NTND |
305 | grep "refname.*${REF}.*ambiguous" err |
306 | ' | |
307 | ||
8a10fea4 | 308 | test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (raw)' ' |
7243ffdd JK |
309 | test_must_fail git rev-parse 00000 2>stderr && |
310 | grep "is ambiguous" stderr >errors && | |
311 | test_line_count = 1 errors | |
312 | ' | |
313 | ||
8a10fea4 JK |
314 | test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (treeish)' ' |
315 | test_must_fail git rev-parse 00000:foo 2>stderr && | |
316 | grep "is ambiguous" stderr >errors && | |
317 | test_line_count = 1 errors | |
318 | ' | |
319 | ||
320 | test_expect_success C_LOCALE_OUTPUT 'ambiguity errors are not repeated (peel)' ' | |
321 | test_must_fail git rev-parse 00000^{commit} 2>stderr && | |
322 | grep "is ambiguous" stderr >errors && | |
323 | test_line_count = 1 errors | |
324 | ' | |
325 | ||
1ffa26c4 JK |
326 | test_expect_success C_LOCALE_OUTPUT 'ambiguity hints' ' |
327 | test_must_fail git rev-parse 000000000 2>stderr && | |
328 | grep ^hint: stderr >hints && | |
329 | # 16 candidates, plus one intro line | |
330 | test_line_count = 17 hints | |
331 | ' | |
332 | ||
333 | test_expect_success C_LOCALE_OUTPUT 'ambiguity hints respect type' ' | |
334 | test_must_fail git rev-parse 000000000^{commit} 2>stderr && | |
335 | grep ^hint: stderr >hints && | |
336 | # 5 commits, 1 tag (which is a commitish), plus intro line | |
337 | test_line_count = 7 hints | |
338 | ' | |
339 | ||
340 | test_expect_success C_LOCALE_OUTPUT 'failed type-selector still shows hint' ' | |
341 | # these two blobs share the same prefix "ee3d", but neither | |
342 | # will pass for a commit | |
343 | echo 851 | git hash-object --stdin -w && | |
344 | echo 872 | git hash-object --stdin -w && | |
345 | test_must_fail git rev-parse ee3d^{commit} 2>stderr && | |
346 | grep ^hint: stderr >hints && | |
347 | test_line_count = 3 hints | |
348 | ' | |
349 | ||
5b33cb1f JK |
350 | test_expect_success 'core.disambiguate config can prefer types' ' |
351 | # ambiguous between tree and tag | |
352 | sha1=0000000000f && | |
353 | test_must_fail git rev-parse $sha1 && | |
354 | git rev-parse $sha1^{commit} && | |
355 | git -c core.disambiguate=committish rev-parse $sha1 | |
356 | ' | |
357 | ||
358 | test_expect_success 'core.disambiguate does not override context' ' | |
359 | # treeish ambiguous between tag and tree | |
360 | test_must_fail \ | |
361 | git -c core.disambiguate=committish rev-parse $sha1^{tree} | |
362 | ' | |
363 | ||
6269b6b6 | 364 | test_done |