1#!/bin/sh 2 3test_description='object name disambiguation 4 5Create blobs, trees, commits and a tag that all share the same 6prefix, and make sure "git rev-parse" can take advantage of 7type information to disambiguate short object names that are 8not necessarily unique. 9 10The final history used in the test has five commits, with the bottom 11one 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 25test_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 43test_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 48test_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 57test_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 78test_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 83test_expect_success 'first commit'' 84 # create one commit 0000000000e4f 85 git commit -m a2onsxbvj 86' 87 88test_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 100test_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 105test_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 114test_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 120test_expect_success 'git log takes only commit-ish'' 121 git log 000000000 122' 123 124test_expect_success 'git reset takes only commit-ish'' 125 git reset 000000000 126' 127 128test_expect_success 'first tag'' 129 # create one tag 0000000000f8f 130 git tag -a -m j7cp83um v1.0.0 131' 132 133test_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 150test_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 156test_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 165test_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 217test_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. 234test_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 240test_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 255test_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 264test_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$REF2>err` =$REF&& 270 grep "refname.*${REF}.*ambiguous" err 271' 272 273test_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$REF2>err` =$VAL&& 279 grep "refname.*${REF}.*ambiguous" err 280' 281 282test_done