(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name left:<Id.Lit_VarLike 'test_description='> name:test_description) op: assign_op.Equal rhs: { (SQ <'object name disambiguation\n'> <'\n'> <'Create blobs, trees, commits and a tag that all share the same\n'> <'prefix, and make sure "git rev-parse" can take advantage of\n'> <'type information to disambiguate short object names that are\n'> <'not necessarily unique.\n'> <'\n'> <'The final history used in the test has five commits, with the bottom\n'> <'one tagged as v1.0.0. They all have one regular file each.\n'> <'\n'> <' +-------------------------------------------+\n'> <' | |\n'> <' | .-------b3wettvi---- ad2uee |\n'> <' | / / |\n'> <' | a2onsxbvj---czy8f73t--ioiley5o |\n'> <' | |\n'> <' +-------------------------------------------+\n'> <'\n'> ) } spids: [4] ) ] redirects: [] ) (C {<.>} {<'./test-lib.sh'>}) (C {<test_expect_success>} {(SQ <'blob and tree'>)} { (SQ <'\n'> <'\ttest_tick &&\n'> <'\t(\n'> <'\t\tfor i in 0 1 2 3 4 5 6 7 8 9\n'> <'\t\tdo\n'> <'\t\t\techo $i\n'> <'\t\tdone\n'> <'\t\techo\n'> <'\t\techo b1rwzyc3\n'> <'\t) >a0blgqsjc &&\n'> <'\n'> <'\t# create one blob 0000000000b36\n'> <'\tgit add a0blgqsjc &&\n'> <'\n'> <'\t# create one tree 0000000000cdc\n'> <'\tgit write-tree\n'> ) } ) (C {<test_expect_success>} {(SQ <'warn ambiguity when no candidate matches type hint'>)} { (SQ <'\n'> <'\ttest_must_fail git rev-parse --verify 000000000^{commit} 2>actual &&\n'> <'\ttest_i18ngrep "short SHA1 000000000 is ambiguous" actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'disambiguate tree-ish'>)} { (SQ <'\n'> <'\t# feed tree-ish in an unambiguous way\n'> <'\tgit rev-parse --verify 0000000000cdc:a0blgqsjc &&\n'> <'\n'> <'\t# ambiguous at the object name level, but there is only one\n'> <'\t# such tree-ish (the other is a blob)\n'> <'\tgit rev-parse --verify 000000000:a0blgqsjc\n'> ) } ) (C {<test_expect_success>} {(SQ <'disambiguate blob'>)} { (SQ <'\n'> <'\tsed -e "s/|$//" >patch <<-EOF &&\n'> <'\tdiff --git a/frotz b/frotz\n'> <'\tindex 000000000..ffffff 100644\n'> <'\t--- a/frotz\n'> <'\t+++ b/frotz\n'> <'\t@@ -10,3 +10,4 @@\n'> <'\t 9\n'> <'\t |\n'> <'\t b1rwzyc3\n'> <'\t+irwry\n'> <'\tEOF\n'> <'\t(\n'> <'\t\tGIT_INDEX_FILE=frotz &&\n'> <'\t\texport GIT_INDEX_FILE &&\n'> <'\t\tgit apply --build-fake-ancestor frotz patch &&\n'> <'\t\tgit cat-file blob :frotz >actual\n'> <'\t) &&\n'> <'\ttest_cmp a0blgqsjc actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'disambiguate tree'>)} { (SQ <'\n'> <'\tcommit=$(echo "d7xm" | git commit-tree 000000000) &&\n'> <'\t# this commit is fffff2e and not ambiguous with the 00000* objects\n'> <'\ttest $(git rev-parse $commit^{tree}) = $(git rev-parse 0000000000cdc)\n'> ) } ) (C {<test_expect_success>} {(SQ <'first commit'>)} {(SQ <'\n'> <'\t# create one commit 0000000000e4f\n'> <'\tgit commit -m a2onsxbvj\n'>)} ) (C {<test_expect_success>} {(SQ <'disambiguate commit-ish'>)} { (SQ <'\n'> <'\t# feed commit-ish in an unambiguous way\n'> <'\tgit rev-parse --verify 0000000000e4f^{commit} &&\n'> <'\n'> <'\t# ambiguous at the object name level, but there is only one\n'> <'\t# such commit (the others are tree and blob)\n'> <'\tgit rev-parse --verify 000000000^{commit} &&\n'> <'\n'> <'\t# likewise\n'> <'\tgit rev-parse --verify 000000000^0\n'> ) } ) (C {<test_expect_success>} {(SQ <'disambiguate commit'>)} { (SQ <'\n'> <'\tcommit=$(echo "hoaxj" | git commit-tree 0000000000cdc -p 000000000) &&\n'> <'\t# this commit is ffffffd8 and not ambiguous with the 00000* objects\n'> <'\ttest $(git rev-parse $commit^) = $(git rev-parse 0000000000e4f)\n'> ) } ) (C {<test_expect_success>} {(SQ <'log name1..name2 takes only commit-ishes on both ends'>)} { (SQ <'\n'> <'\t# These are underspecified from the prefix-length point of view\n'> <'\t# to disambiguate the commit with other objects, but there is only\n'> <'\t# one commit that has 00000* prefix at this point.\n'> <'\tgit log 000000000..000000000 &&\n'> <'\tgit log ..000000000 &&\n'> <'\tgit log 000000000.. &&\n'> <'\tgit log 000000000...000000000 &&\n'> <'\tgit log ...000000000 &&\n'> <'\tgit log 000000000...\n'> ) } ) (C {<test_expect_success>} {(SQ <'rev-parse name1..name2 takes only commit-ishes on both ends'>)} { (SQ <'\n'> <'\t# Likewise.\n'> <'\tgit rev-parse 000000000..000000000 &&\n'> <'\tgit rev-parse ..000000000 &&\n'> <'\tgit rev-parse 000000000..\n'> ) } ) (C {<test_expect_success>} {(SQ <'git log takes only commit-ish'>)} {(SQ <'\n'> <'\t# Likewise.\n'> <'\tgit log 000000000\n'>)} ) (C {<test_expect_success>} {(SQ <'git reset takes only commit-ish'>)} {(SQ <'\n'> <'\t# Likewise.\n'> <'\tgit reset 000000000\n'>)} ) (C {<test_expect_success>} {(SQ <'first tag'>)} {(SQ <'\n'> <'\t# create one tag 0000000000f8f\n'> <'\tgit tag -a -m j7cp83um v1.0.0\n'>)} ) (C {<test_expect_failure>} {(SQ <'two semi-ambiguous commit-ish'>)} { (SQ <'\n'> <'\t# At this point, we have a tag 0000000000f8f that points\n'> <'\t# at a commit 0000000000e4f, and a tree and a blob that\n'> <'\t# share 0000000000 prefix with these tag and commit.\n'> <'\t#\n'> <'\t# Once the parser becomes ultra-smart, it could notice that\n'> <'\t# 0000000000 before ^{commit} name many different objects, but\n'> <'\t# that only two (HEAD and v1.0.0 tag) can be peeled to commit,\n'> <'\t# and that peeling them down to commit yield the same commit\n'> <'\t# without ambiguity.\n'> <'\tgit rev-parse --verify 0000000000^{commit} &&\n'> <'\n'> <'\t# likewise\n'> <'\tgit log 0000000000..0000000000 &&\n'> <'\tgit log ..0000000000 &&\n'> <'\tgit log 0000000000.. &&\n'> <'\tgit log 0000000000...0000000000 &&\n'> <'\tgit log ...0000000000 &&\n'> <'\tgit log 0000000000...\n'> ) } ) (C {<test_expect_failure>} {(SQ <'three semi-ambiguous tree-ish'>)} { (SQ <'\n'> <'\t# Likewise for tree-ish. HEAD, v1.0.0 and HEAD^{tree} share\n'> <'\t# the prefix but peeling them to tree yields the same thing\n'> <'\tgit rev-parse --verify 0000000000^{tree}\n'> ) } ) (C {<test_expect_success>} {(SQ <'parse describe name'>)} { (SQ <'\n'> <'\t# feed an unambiguous describe name\n'> <'\tgit rev-parse --verify v1.0.0-0-g0000000000e4f &&\n'> <'\n'> <'\t# ambiguous at the object name level, but there is only one\n'> <'\t# such commit (others are blob, tree and tag)\n'> <'\tgit rev-parse --verify v1.0.0-0-g000000000\n'> ) } ) (C {<test_expect_success>} {(SQ <'more history'>)} { (SQ <'\n'> <'\t# commit 0000000000043\n'> <'\tgit mv a0blgqsjc d12cr3h8t &&\n'> <'\techo h62xsjeu >>d12cr3h8t &&\n'> <'\tgit add d12cr3h8t &&\n'> <'\n'> <'\ttest_tick &&\n'> <'\tgit commit -m czy8f73t &&\n'> <'\n'> <'\t# commit 00000000008ec\n'> <'\tgit mv d12cr3h8t j000jmpzn &&\n'> <'\techo j08bekfvt >>j000jmpzn &&\n'> <'\tgit add j000jmpzn &&\n'> <'\n'> <'\ttest_tick &&\n'> <'\tgit commit -m ioiley5o &&\n'> <'\n'> <'\t# commit 0000000005b0\n'> <'\tgit checkout v1.0.0^0 &&\n'> <'\tgit mv a0blgqsjc f5518nwu &&\n'> <'\n'> <'\tfor i in h62xsjeu j08bekfvt kg7xflhm\n'> <'\tdo\n'> <'\t\techo $i\n'> <'\tdone >>f5518nwu &&\n'> <'\tgit add f5518nwu &&\n'> <'\n'> <'\ttest_tick &&\n'> <'\tgit commit -m b3wettvi &&\n'> <'\tside=$(git rev-parse HEAD) &&\n'> <'\n'> <'\t# commit 000000000066\n'> <'\tgit checkout master &&\n'> <'\n'> <'\t# If you use recursive, merge will fail and you will need to\n'> <'\t# clean up a0blgqsjc as well. If you use resolve, merge will\n'> <'\t# succeed.\n'> <'\ttest_might_fail git merge --no-commit -s recursive $side &&\n'> <'\tgit rm -f f5518nwu j000jmpzn &&\n'> <'\n'> <'\ttest_might_fail git rm -f a0blgqsjc &&\n'> <'\t(\n'> <'\t\tgit cat-file blob $side:f5518nwu\n'> <'\t\techo j3l0i9s6\n'> <'\t) >ab2gs879 &&\n'> <'\tgit add ab2gs879 &&\n'> <'\n'> <'\ttest_tick &&\n'> <'\tgit commit -m ad2uee\n'> <'\n'> ) } ) (C {<test_expect_failure>} {(SQ <'parse describe name taking advantage of generation'>)} { (SQ <'\n'> <'\t# ambiguous at the object name level, but there is only one\n'> <'\t# such commit at generation 0\n'> <'\tgit rev-parse --verify v1.0.0-0-g000000000 &&\n'> <'\n'> <'\t# likewise for generation 2 and 4\n'> <'\tgit rev-parse --verify v1.0.0-2-g000000000 &&\n'> <'\tgit rev-parse --verify v1.0.0-4-g000000000\n'> ) } ) (C {<test_expect_success>} {(SQ <'parse describe name not ignoring ambiguity'>)} { (SQ <'\n'> <'\t# ambiguous at the object name level, and there are two such\n'> <'\t# commits at generation 1\n'> <'\ttest_must_fail git rev-parse --verify v1.0.0-1-g000000000\n'> ) } ) (C {<test_expect_success>} {(SQ <'ambiguous commit-ish'>)} { (SQ <'\n'> <'\t# Now there are many commits that begin with the\n'> <'\t# common prefix, none of these should pick one at\n'> <'\t# random. They all should result in ambiguity errors.\n'> <'\ttest_must_fail git rev-parse --verify 00000000^{commit} &&\n'> <'\n'> <'\t# likewise\n'> <'\ttest_must_fail git log 000000000..000000000 &&\n'> <'\ttest_must_fail git log ..000000000 &&\n'> <'\ttest_must_fail git log 000000000.. &&\n'> <'\ttest_must_fail git log 000000000...000000000 &&\n'> <'\ttest_must_fail git log ...000000000 &&\n'> <'\ttest_must_fail git log 000000000...\n'> ) } ) (C {<test_expect_success>} {(SQ <'ambiguous tags peel to treeish'>)} {(SQ <'\n'> <'\ttest_must_fail git rev-parse 0000000000f^{tree}\n'>)} ) (C {<test_expect_success>} {(SQ <'rev-parse --disambiguate'>)} { (SQ <'\n'> <'\t# The test creates 16 objects that share the prefix and two\n'> <'\t# commits created by commit-tree in earlier tests share a\n'> <'\t# different prefix.\n'> <'\tgit rev-parse --disambiguate=000000000 >actual &&\n'> <'\ttest $(wc -l <actual) = 16 &&\n'> <'\ttest "$(sed -e "s/^\\(.........\\).*/\\1/" actual | sort -u)" = 000000000\n'> ) } ) (C {<test_expect_success>} {(SQ <'rev-parse --disambiguate drops duplicates'>)} { (SQ <'\n'> <'\tgit rev-parse --disambiguate=000000000 >expect &&\n'> <'\tgit pack-objects .git/objects/pack/pack <expect &&\n'> <'\tgit rev-parse --disambiguate=000000000 >actual &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'ambiguous 40-hex ref'>)} { (SQ <'\n'> <'\tTREE=$(git mktree </dev/null) &&\n'> <'\tREF=$(git rev-parse HEAD) &&\n'> <'\tVAL=$(git commit-tree $TREE </dev/null) &&\n'> <'\tgit update-ref refs/heads/$REF $VAL &&\n'> <'\ttest $(git rev-parse $REF 2>err) = $REF &&\n'> <'\tgrep "refname.*${REF}.*ambiguous" err\n'> ) } ) (C {<test_expect_success>} {(SQ <'ambiguous short sha1 ref'>)} { (SQ <'\n'> <'\tTREE=$(git mktree </dev/null) &&\n'> <'\tREF=$(git rev-parse --short HEAD) &&\n'> <'\tVAL=$(git commit-tree $TREE </dev/null) &&\n'> <'\tgit update-ref refs/heads/$REF $VAL &&\n'> <'\ttest $(git rev-parse $REF 2>err) = $VAL &&\n'> <'\tgrep "refname.*${REF}.*ambiguous" err\n'> ) } ) (C {<test_expect_success>} {<C_LOCALE_OUTPUT>} {(SQ <'ambiguity errors are not repeated (raw)'>)} { (SQ <'\n'> <'\ttest_must_fail git rev-parse 00000 2>stderr &&\n'> <'\tgrep "is ambiguous" stderr >errors &&\n'> <'\ttest_line_count = 1 errors\n'> ) } ) (C {<test_expect_success>} {<C_LOCALE_OUTPUT>} {(SQ <'ambiguity errors are not repeated (treeish)'>)} { (SQ <'\n'> <'\ttest_must_fail git rev-parse 00000:foo 2>stderr &&\n'> <'\tgrep "is ambiguous" stderr >errors &&\n'> <'\ttest_line_count = 1 errors\n'> ) } ) (C {<test_expect_success>} {<C_LOCALE_OUTPUT>} {(SQ <'ambiguity errors are not repeated (peel)'>)} { (SQ <'\n'> <'\ttest_must_fail git rev-parse 00000^{commit} 2>stderr &&\n'> <'\tgrep "is ambiguous" stderr >errors &&\n'> <'\ttest_line_count = 1 errors\n'> ) } ) (C {<test_expect_success>} {<C_LOCALE_OUTPUT>} {(SQ <'ambiguity hints'>)} { (SQ <'\n'> <'\ttest_must_fail git rev-parse 000000000 2>stderr &&\n'> <'\tgrep ^hint: stderr >hints &&\n'> <'\t# 16 candidates, plus one intro line\n'> <'\ttest_line_count = 17 hints\n'> ) } ) (C {<test_expect_success>} {<C_LOCALE_OUTPUT>} {(SQ <'ambiguity hints respect type'>)} { (SQ <'\n'> <'\ttest_must_fail git rev-parse 000000000^{commit} 2>stderr &&\n'> <'\tgrep ^hint: stderr >hints &&\n'> <'\t# 5 commits, 1 tag (which is a commitish), plus intro line\n'> <'\ttest_line_count = 7 hints\n'> ) } ) (C {<test_expect_success>} {<C_LOCALE_OUTPUT>} {(SQ <'failed type-selector still shows hint'>)} { (SQ <'\n'> <'\t# these two blobs share the same prefix "ee3d", but neither\n'> <'\t# will pass for a commit\n'> <'\techo 851 | git hash-object --stdin -w &&\n'> <'\techo 872 | git hash-object --stdin -w &&\n'> <'\ttest_must_fail git rev-parse ee3d^{commit} 2>stderr &&\n'> <'\tgrep ^hint: stderr >hints &&\n'> <'\ttest_line_count = 3 hints\n'> ) } ) (C {<test_expect_success>} {(SQ <'core.disambiguate config can prefer types'>)} { (SQ <'\n'> <'\t# ambiguous between tree and tag\n'> <'\tsha1=0000000000f &&\n'> <'\ttest_must_fail git rev-parse $sha1 &&\n'> <'\tgit rev-parse $sha1^{commit} &&\n'> <'\tgit -c core.disambiguate=committish rev-parse $sha1\n'> ) } ) (C {<test_expect_success>} {(SQ <'core.disambiguate does not override context'>)} { (SQ <'\n'> <'\t# treeish ambiguous between tag and tree\n'> <'\ttest_must_fail \\\n'> <'\t\tgit -c core.disambiguate=committish rev-parse $sha1^{tree}\n'> ) } ) (C {<test_done>}) ] )