Merge branch 'js/format-2047'
[git] / t / t1512-rev-parse-disambiguation.sh
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 &&
45         grep "short SHA1 000000000 is ambiguous" actual
46 '
47
48 test_expect_success 'disambiguate tree-ish' '
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
57 test_expect_success 'disambiguate blob' '
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
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)
81 '
82
83 test_expect_success 'first commit' '
84         # create one commit 0000000000e4f
85         git commit -m a2onsxbvj
86 '
87
88 test_expect_success 'disambiguate commit-ish' '
89         # feed commit-ish in an unambiguous way
90         git rev-parse --verify 0000000000e4f^{commit} &&
91
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} &&
95
96         # likewise
97         git rev-parse --verify 000000000^0
98 '
99
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)
103 '
104
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 &&
111         git log 000000000...
112 '
113
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..
118 '
119
120 test_expect_success 'git log takes only commit-ish' '
121         git log 000000000
122 '
123
124 test_expect_success 'git reset takes only commit-ish' '
125         git reset 000000000
126 '
127
128 test_expect_success 'first tag' '
129         # create one tag 0000000000f8f
130         git tag -a -m j7cp83um v1.0.0
131 '
132
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
138         # without ambiguity.
139         git rev-parse --verify 110282^{commit} &&
140
141         # likewise
142         git log 000000000..000000000 &&
143         git log ..000000000 &&
144         git log 000000000.. &&
145         git log 000000000...000000000 &&
146         git log ...000000000 &&
147         git log 000000000...
148 '
149
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}
154 '
155
156 test_expect_success 'parse describe name' '
157         # feed an unambiguous describe name
158         git rev-parse --verify v1.0.0-0-g0000000000e4f &&
159
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
163 '
164
165 test_expect_success 'more history' '
166         # commit 0000000000043
167         git mv a0blgqsjc d12cr3h8t &&
168         echo h62xsjeu >>d12cr3h8t &&
169         git add d12cr3h8t &&
170
171         test_tick &&
172         git commit -m czy8f73t &&
173
174         # commit 00000000008ec
175         git mv d12cr3h8t j000jmpzn &&
176         echo j08bekfvt >>j000jmpzn &&
177         git add j000jmpzn &&
178
179         test_tick &&
180         git commit -m ioiley5o &&
181
182         # commit 0000000005b0
183         git checkout v1.0.0^0 &&
184         git mv a0blgqsjc f5518nwu &&
185
186         for i in h62xsjeu j08bekfvt kg7xflhm
187         do
188                 echo $i
189         done >>f5518nwu &&
190         git add f5518nwu &&
191
192         test_tick &&
193         git commit -m b3wettvi &&
194         side=$(git rev-parse HEAD) &&
195
196         # commit 000000000066
197         git checkout master &&
198
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
201         # succeed.
202         test_might_fail git merge --no-commit -s recursive $side &&
203         git rm -f f5518nwu j000jmpzn &&
204
205         test_might_fail git rm -f a0blgqsjc &&
206         (
207                 git cat-file blob $side:f5518nwu
208                 echo j3l0i9s6
209         ) >ab2gs879 &&
210         git add ab2gs879 &&
211
212         test_tick &&
213         git commit -m ad2uee
214
215 '
216
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 &&
221
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
225 '
226
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
233 # pick one.
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
238 '
239
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} &&
245
246         # likewise
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...
253 '
254
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
258         # different prefix.
259         git rev-parse --disambiguate=000000000 >actual &&
260         test $(wc -l <actual) = 16 &&
261         test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000
262 '
263
264 test_done