t / t1512-rev-parse-disambiguation.shon commit Merge branch 'gp/avoid-explicit-mention-of-dot-git-refs' (9adf272)
   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_done