(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: {(SQ <'Tests replace refs functionality'>)} spids: [12] ) ] ) (command.Simple words: [{<exec>}] redirects: [(redir op:<Id.Redir_Less '<'> loc:(redir_loc.Fd fd:0) arg:{<'/dev/null'>})] do_fork: T ) (C {<.>} {<'./test-lib.sh'>}) (C {<.>} {(DQ ($ Id.VSub_DollarName '$TEST_DIRECTORY') <'/lib-gpg.sh'>)}) (command.ShFunction name: add_and_commit_file body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_file) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_Number '$1'))} spids: [44] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_msg) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_Number '$2'))} spids: [50] ) ] ) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<git>} {<add>} {($ Id.VSub_DollarName '$_file')}) (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {($ Id.VSub_QMark '$?')} ) ] ) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<test_tick>}) (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {($ Id.VSub_QMark '$?')} ) ] ) (C {<git>} {<commit>} {<--quiet>} {<-m>} {(DQ ($ Id.VSub_DollarName '$_file') <': '> ($ Id.VSub_DollarName '$_msg'))} ) ] ) ) (command.ShFunction name: commit_buffer_contains_parents body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (command.Simple words: [{<git>} {<cat-file>} {<commit>} {(DQ ($ Id.VSub_Number '$1'))}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<payload>})] do_fork: T ) (command.Simple words: [{<sed>} {<-n>} {<-e>} {(SQ <'/^$/q'>)} {<-e>} {(SQ <'/^parent /p'>)}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: {<payload>} ) (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {<actual>} ) ] do_fork: T ) (C {<shift>}) (command.ForEach iter_names: [_parent] iterable: (for_iter.Args) body: (command.DoGroup children: [(C {<echo>} {(DQ <'parent '> ($ Id.VSub_DollarName '$_parent'))})] ) redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<expected>})] ) (C {<test_cmp>} {<expected>} {<actual>}) ] ) ] ) ) (command.ShFunction name: commit_peeling_shows_parents body: (BraceGroup children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_parent_number) op: assign_op.Equal rhs: {<1>} spids: [191] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_commit) op: assign_op.Equal rhs: {(DQ ($ Id.VSub_Number '$1'))} spids: [195] ) ] ) (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp] children: [ (C {<shift>}) (command.ForEach iter_names: [_parent] iterable: (for_iter.Args) body: (command.DoGroup children: [ (command.AndOr ops: [Id.Op_DPipe] children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_found) op: assign_op.Equal rhs: { (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<git>} {<rev-parse>} {<--verify>} {($ Id.VSub_DollarName '$_commit') <Id.Lit_Other '^'> ($ Id.VSub_DollarName '$_parent_number') } ) ) } spids: [214] ) ] ) (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<1>} ) ] ) (command.AndOr ops: [Id.Op_DPipe] children: [ (C {<test>} {(DQ ($ Id.VSub_DollarName '$_found'))} {<Id.Lit_Equals '='>} {(DQ ($ Id.VSub_DollarName '$_parent'))} ) (command.ControlFlow token: <Id.ControlFlow_Return return> arg_word: {<1>} ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:_parent_number) op: assign_op.Equal rhs: { (word_part.ArithSub anode: (arith_expr.Binary op_id: Id.Arith_Plus left: {($ Id.VSub_DollarName '$_parent_number')} right: {<Id.Lit_Digits 1>} ) ) } spids: [253] ) ] ) ] ) ) (C {<test_must_fail>} {<git>} {<rev-parse>} {<--verify>} {($ Id.VSub_DollarName '$_commit') <Id.Lit_Other '^'> ($ Id.VSub_DollarName '$_parent_number') } ) ] ) ] ) ) (command.ShFunction name: commit_has_parents body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (C {<commit_buffer_contains_parents>} {(DQ ($ Id.VSub_At '$@'))}) (C {<commit_peeling_shows_parents>} {(DQ ($ Id.VSub_At '$@'))}) ] ) ] ) ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HASH1) op: assign_op.Equal rhs: (word.Empty) spids: [312] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HASH2) op: assign_op.Equal rhs: (word.Empty) spids: [314] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HASH3) op: assign_op.Equal rhs: (word.Empty) spids: [316] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HASH4) op: assign_op.Equal rhs: (word.Empty) spids: [318] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HASH5) op: assign_op.Equal rhs: (word.Empty) spids: [320] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HASH6) op: assign_op.Equal rhs: (word.Empty) spids: [322] ) ] ) (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:HASH7) op: assign_op.Equal rhs: (word.Empty) spids: [324] ) ] ) (C {<test_expect_success>} {(SQ <'set up buggy branch'>)} { (SQ <'\n'> <' echo "line 1" >>hello &&\n'> <' echo "line 2" >>hello &&\n'> <' echo "line 3" >>hello &&\n'> <' echo "line 4" >>hello &&\n'> <' add_and_commit_file hello "4 lines" &&\n'> <' HASH1=$(git rev-parse --verify HEAD) &&\n'> <' echo "line BUG" >>hello &&\n'> <' echo "line 6" >>hello &&\n'> <' echo "line 7" >>hello &&\n'> <' echo "line 8" >>hello &&\n'> <' add_and_commit_file hello "4 more lines with a BUG" &&\n'> <' HASH2=$(git rev-parse --verify HEAD) &&\n'> <' echo "line 9" >>hello &&\n'> <' echo "line 10" >>hello &&\n'> <' add_and_commit_file hello "2 more lines" &&\n'> <' HASH3=$(git rev-parse --verify HEAD) &&\n'> <' echo "line 11" >>hello &&\n'> <' add_and_commit_file hello "1 more line" &&\n'> <' HASH4=$(git rev-parse --verify HEAD) &&\n'> <' sed -e "s/BUG/5/" hello >hello.new &&\n'> <' mv hello.new hello &&\n'> <' add_and_commit_file hello "BUG fixed" &&\n'> <' HASH5=$(git rev-parse --verify HEAD) &&\n'> <' echo "line 12" >>hello &&\n'> <' echo "line 13" >>hello &&\n'> <' add_and_commit_file hello "2 more lines" &&\n'> <' HASH6=$(git rev-parse --verify HEAD) &&\n'> <' echo "line 14" >>hello &&\n'> <' echo "line 15" >>hello &&\n'> <' echo "line 16" >>hello &&\n'> <' add_and_commit_file hello "again 3 more lines" &&\n'> <' HASH7=$(git rev-parse --verify HEAD)\n'> ) } ) (C {<test_expect_success>} {(SQ <'replace the author'>)} { (SQ <'\n'> <' git cat-file commit $HASH2 | grep "author A U Thor" &&\n'> < ' R=$(git cat-file commit $HASH2 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) &&\n' > <' git cat-file commit $R | grep "author O Thor" &&\n'> <' git update-ref refs/replace/$HASH2 $R &&\n'> <' git show HEAD~5 | grep "O Thor" &&\n'> <' git show $HASH2 | grep "O Thor"\n'> ) } ) (C {<test_expect_success>} {(SQ <'test --no-replace-objects option'>)} { (SQ <'\n'> <' git cat-file commit $HASH2 | grep "author O Thor" &&\n'> <' git --no-replace-objects cat-file commit $HASH2 | grep "author A U Thor" &&\n'> <' git show $HASH2 | grep "O Thor" &&\n'> <' git --no-replace-objects show $HASH2 | grep "A U Thor"\n'> ) } ) (C {<test_expect_success>} {(SQ <'test GIT_NO_REPLACE_OBJECTS env variable'>)} { (SQ <'\n'> <' GIT_NO_REPLACE_OBJECTS=1 git cat-file commit $HASH2 | grep "author A U Thor" &&\n'> <' GIT_NO_REPLACE_OBJECTS=1 git show $HASH2 | grep "A U Thor"\n'> ) } ) (command.Simple words: [{<cat>}] redirects: [ (redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<tag.sig>}) (redir op: <Id.Redir_DLess '<<'> loc: (redir_loc.Fd fd:0) arg: (redir_param.HereDoc here_begin: {<EOF>} here_end_span_id: 431 stdin_parts: [ <'object '> ($ Id.VSub_DollarName '$HASH2') <'\n'> <'type commit\n'> <'tag mytag\n'> <'tagger T A Gger <> 0 +0000\n'> <'\n'> ] ) ) ] do_fork: T ) (C {<test_expect_success>} {(SQ <'tag replaced commit'>)} {(SQ <'\n'> <' git mktag <tag.sig >.git/refs/tags/mytag 2>message\n'>)} ) (C {<test_expect_success>} {(SQ <'"git fsck" works'>)} { (SQ <'\n'> <' git fsck master >fsck_master.out &&\n'> <' grep "dangling commit $R" fsck_master.out &&\n'> <' grep "dangling tag $(cat .git/refs/tags/mytag)" fsck_master.out &&\n'> <' test -z "$(git fsck)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'repack, clone and fetch work'>)} { (SQ <'\n'> <' git repack -a -d &&\n'> <' git clone --no-hardlinks . clone_dir &&\n'> <' (\n'> <'\t cd clone_dir &&\n'> <'\t git show HEAD~5 | grep "A U Thor" &&\n'> <'\t git show $HASH2 | grep "A U Thor" &&\n'> <'\t git cat-file commit $R &&\n'> <'\t git repack -a -d &&\n'> <'\t test_must_fail git cat-file commit $R &&\n'> <'\t git fetch ../ "refs/replace/*:refs/replace/*" &&\n'> <'\t git show HEAD~5 | grep "O Thor" &&\n'> <'\t git show $HASH2 | grep "O Thor" &&\n'> <'\t git cat-file commit $R\n'> <' )\n'> ) } ) (C {<test_expect_success>} {(SQ <'"git replace" listing and deleting'>)} { (SQ <'\n'> <' test "$HASH2" = "$(git replace -l)" &&\n'> <' test "$HASH2" = "$(git replace)" &&\n'> <' aa=${HASH2%??????????????????????????????????????} &&\n'> <' test "$HASH2" = "$(git replace --list "$aa*")" &&\n'> <' test_must_fail git replace -d $R &&\n'> <' test_must_fail git replace --delete &&\n'> <' test_must_fail git replace -l -d $HASH2 &&\n'> <' git replace -d $HASH2 &&\n'> <' git show $HASH2 | grep "A U Thor" &&\n'> <' test -z "$(git replace -l)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'"git replace" replacing'>)} { (SQ <'\n'> <' git replace $HASH2 $R &&\n'> <' git show $HASH2 | grep "O Thor" &&\n'> <' test_must_fail git replace $HASH2 $R &&\n'> <' git replace -f $HASH2 $R &&\n'> <' test_must_fail git replace -f &&\n'> <' test "$HASH2" = "$(git replace)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'"git replace" resolves sha1'>)} { (SQ <'\n'> <' SHORTHASH2=$(git rev-parse --short=8 $HASH2) &&\n'> <' git replace -d $SHORTHASH2 &&\n'> <' git replace $SHORTHASH2 $R &&\n'> <' git show $HASH2 | grep "O Thor" &&\n'> <' test_must_fail git replace $HASH2 $R &&\n'> <' git replace -f $HASH2 $R &&\n'> <' test_must_fail git replace --force &&\n'> <' test "$HASH2" = "$(git replace)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'create parallel branch without the bug'>)} { (SQ <'\n'> <' git replace -d $HASH2 &&\n'> <' git show $HASH2 | grep "A U Thor" &&\n'> <' git checkout $HASH1 &&\n'> <' git cherry-pick $HASH2 &&\n'> <' git show $HASH5 | git apply &&\n'> <' git commit --amend -m "hello: 4 more lines WITHOUT the bug" hello &&\n'> <' PARA2=$(git rev-parse --verify HEAD) &&\n'> <' git cherry-pick $HASH3 &&\n'> <' PARA3=$(git rev-parse --verify HEAD) &&\n'> <' git cherry-pick $HASH4 &&\n'> <' PARA4=$(git rev-parse --verify HEAD) &&\n'> <' git cherry-pick $HASH6 &&\n'> <' PARA6=$(git rev-parse --verify HEAD) &&\n'> <' git replace $HASH6 $PARA6 &&\n'> <' git checkout master &&\n'> <' cur=$(git rev-parse --verify HEAD) &&\n'> <' test "$cur" = "$HASH7" &&\n'> <' git log --pretty=oneline | grep $PARA2 &&\n'> <' git remote add cloned ./clone_dir\n'> ) } ) (C {<test_expect_success>} {(SQ <'push to cloned repo'>)} { (SQ <'\n'> <' git push cloned $HASH6^:refs/heads/parallel &&\n'> <' (\n'> <'\t cd clone_dir &&\n'> <'\t git checkout parallel &&\n'> <'\t git log --pretty=oneline | grep $PARA2\n'> <' )\n'> ) } ) (C {<test_expect_success>} {(SQ <'push branch with replacement'>)} { (SQ <'\n'> <' git cat-file commit $PARA3 | grep "author A U Thor" &&\n'> < ' S=$(git cat-file commit $PARA3 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) &&\n' > <' git cat-file commit $S | grep "author O Thor" &&\n'> <' git replace $PARA3 $S &&\n'> <' git show $HASH6~2 | grep "O Thor" &&\n'> <' git show $PARA3 | grep "O Thor" &&\n'> <' git push cloned $HASH6^:refs/heads/parallel2 &&\n'> <' (\n'> <'\t cd clone_dir &&\n'> <'\t git checkout parallel2 &&\n'> <'\t git log --pretty=oneline | grep $PARA3 &&\n'> <'\t git show $PARA3 | grep "A U Thor"\n'> <' )\n'> ) } ) (C {<test_expect_success>} {(SQ <'fetch branch with replacement'>)} { (SQ <'\n'> <' git branch tofetch $HASH6 &&\n'> <' (\n'> <'\t cd clone_dir &&\n'> <'\t git fetch origin refs/heads/tofetch:refs/heads/parallel3 &&\n'> <'\t git log --pretty=oneline parallel3 >output.txt &&\n'> <'\t ! grep $PARA3 output.txt &&\n'> <'\t git show $PARA3 >para3.txt &&\n'> <'\t grep "A U Thor" para3.txt &&\n'> <'\t git fetch origin "refs/replace/*:refs/replace/*" &&\n'> <'\t git log --pretty=oneline parallel3 >output.txt &&\n'> <'\t grep $PARA3 output.txt &&\n'> <'\t git show $PARA3 >para3.txt &&\n'> <'\t grep "O Thor" para3.txt\n'> <' )\n'> ) } ) (C {<test_expect_success>} {(SQ <'bisect and replacements'>)} { (SQ <'\n'> <' git bisect start $HASH7 $HASH1 &&\n'> <' test "$PARA3" = "$(git rev-parse --verify HEAD)" &&\n'> <' git bisect reset &&\n'> <' GIT_NO_REPLACE_OBJECTS=1 git bisect start $HASH7 $HASH1 &&\n'> <' test "$HASH4" = "$(git rev-parse --verify HEAD)" &&\n'> <' git bisect reset &&\n'> <' git --no-replace-objects bisect start $HASH7 $HASH1 &&\n'> <' test "$HASH4" = "$(git rev-parse --verify HEAD)" &&\n'> <' git bisect reset\n'> ) } ) (C {<test_expect_success>} {(SQ <'index-pack and replacements'>)} { (SQ <'\n'> <'\tgit --no-replace-objects rev-list --objects HEAD |\n'> <'\tgit --no-replace-objects pack-objects test- &&\n'> <'\tgit index-pack test-*.pack\n'> ) } ) (C {<test_expect_success>} {(SQ <'not just commits'>)} { (SQ <'\n'> <'\techo replaced >file &&\n'> <'\tgit add file &&\n'> <'\tREPLACED=$(git rev-parse :file) &&\n'> <'\tmv file file.replaced &&\n'> <'\n'> <'\techo original >file &&\n'> <'\tgit add file &&\n'> <'\tORIGINAL=$(git rev-parse :file) &&\n'> <'\tgit update-ref refs/replace/$ORIGINAL $REPLACED &&\n'> <'\tmv file file.original &&\n'> <'\n'> <'\tgit checkout file &&\n'> <'\ttest_cmp file.replaced file\n'> ) } ) (C {<test_expect_success>} {(SQ <'replaced and replacement objects must be of the same type'>)} { (SQ <'\n'> <'\ttest_must_fail git replace mytag $HASH1 &&\n'> <'\ttest_must_fail git replace HEAD^{tree} HEAD~1 &&\n'> <'\tBLOB=$(git rev-parse :file) &&\n'> <'\ttest_must_fail git replace HEAD^ $BLOB\n'> ) } ) (C {<test_expect_success>} {(SQ <'-f option bypasses the type check'>)} { (SQ <'\n'> <'\tgit replace -f mytag $HASH1 &&\n'> <'\tgit replace --force HEAD^{tree} HEAD~1 &&\n'> <'\tgit replace -f HEAD^ $BLOB\n'> ) } ) (C {<test_expect_success>} {(SQ <'git cat-file --batch works on replace objects'>)} {(SQ <'\n'> <'\tgit replace | grep $PARA3 &&\n'> <'\techo $PARA3 | git cat-file --batch\n'>)} ) (C {<test_expect_success>} {(SQ <'test --format bogus'>)} {(SQ <'\n'> <'\ttest_must_fail git replace --format bogus >/dev/null 2>&1\n'>)} ) (C {<test_expect_success>} {(SQ <'test --format short'>)} { (SQ <'\n'> <'\tgit replace --format=short >actual &&\n'> <'\tgit replace >expected &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'test --format medium'>)} { (SQ <'\n'> <'\tH1=$(git --no-replace-objects rev-parse HEAD~1) &&\n'> <'\tHT=$(git --no-replace-objects rev-parse HEAD^{tree}) &&\n'> <'\tMYTAG=$(git --no-replace-objects rev-parse mytag) &&\n'> <'\t{\n'> <'\t\techo "$H1 -> $BLOB" &&\n'> <'\t\techo "$BLOB -> $REPLACED" &&\n'> <'\t\techo "$HT -> $H1" &&\n'> <'\t\techo "$PARA3 -> $S" &&\n'> <'\t\techo "$MYTAG -> $HASH1"\n'> <'\t} | sort >expected &&\n'> <'\tgit replace -l --format medium | sort >actual &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'test --format long'>)} { (SQ <'\n'> <'\t{\n'> <'\t\techo "$H1 (commit) -> $BLOB (blob)" &&\n'> <'\t\techo "$BLOB (blob) -> $REPLACED (blob)" &&\n'> <'\t\techo "$HT (tree) -> $H1 (commit)" &&\n'> <'\t\techo "$PARA3 (commit) -> $S (commit)" &&\n'> <'\t\techo "$MYTAG (tag) -> $HASH1 (commit)"\n'> <'\t} | sort >expected &&\n'> <'\tgit replace --format=long | sort >actual &&\n'> <'\ttest_cmp expected actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'setup fake editors'>)} { (SQ <'\n'> <'\twrite_script fakeeditor <<-\\EOF &&\n'> <'\t\tsed -e "s/A U Thor/A fake Thor/" "$1" >"$1.new"\n'> <'\t\tmv "$1.new" "$1"\n'> <'\tEOF\n'> <'\twrite_script failingfakeeditor <<-\\EOF\n'> <'\t\t./fakeeditor "$@"\n'> <'\t\tfalse\n'> <'\tEOF\n'> ) } ) (C {<test_expect_success>} {(SQ <'--edit with and without already replaced object'>)} { (SQ <'\n'> <'\ttest_must_fail env GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" &&\n'> <'\tGIT_EDITOR=./fakeeditor git replace --force --edit "$PARA3" &&\n'> <'\tgit replace -l | grep "$PARA3" &&\n'> <'\tgit cat-file commit "$PARA3" | grep "A fake Thor" &&\n'> <'\tgit replace -d "$PARA3" &&\n'> <'\tGIT_EDITOR=./fakeeditor git replace --edit "$PARA3" &&\n'> <'\tgit replace -l | grep "$PARA3" &&\n'> <'\tgit cat-file commit "$PARA3" | grep "A fake Thor"\n'> ) } ) (C {<test_expect_success>} {(SQ <'--edit and change nothing or command failed'>)} { (SQ <'\n'> <'\tgit replace -d "$PARA3" &&\n'> <'\ttest_must_fail env GIT_EDITOR=true git replace --edit "$PARA3" &&\n'> <'\ttest_must_fail env GIT_EDITOR="./failingfakeeditor" git replace --edit "$PARA3" &&\n'> <'\tGIT_EDITOR=./fakeeditor git replace --edit "$PARA3" &&\n'> <'\tgit replace -l | grep "$PARA3" &&\n'> <'\tgit cat-file commit "$PARA3" | grep "A fake Thor"\n'> ) } ) (C {<test_expect_success>} {(SQ <'replace ref cleanup'>)} { (SQ <'\n'> <'\ttest -n "$(git replace)" &&\n'> <'\tgit replace -d $(git replace) &&\n'> <'\ttest -z "$(git replace)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'--graft with and without already replaced object'>)} { (SQ <'\n'> <'\ttest $(git log --oneline | wc -l) = 7 &&\n'> <'\tgit replace --graft $HASH5 &&\n'> <'\ttest $(git log --oneline | wc -l) = 3 &&\n'> <'\tcommit_has_parents $HASH5 &&\n'> <'\ttest_must_fail git replace --graft $HASH5 $HASH4 $HASH3 &&\n'> <'\tgit replace --force -g $HASH5 $HASH4 $HASH3 &&\n'> <'\tcommit_has_parents $HASH5 $HASH4 $HASH3 &&\n'> <'\tgit replace -d $HASH5\n'> ) } ) (C {<test_expect_success>} {<GPG>} {(SQ <'set up a signed commit'>)} { (SQ <'\n'> <'\techo "line 17" >>hello &&\n'> <'\techo "line 18" >>hello &&\n'> <'\tgit add hello &&\n'> <'\ttest_tick &&\n'> <'\tgit commit --quiet -S -m "hello: 2 more lines in a signed commit" &&\n'> <'\tHASH8=$(git rev-parse --verify HEAD) &&\n'> <'\tgit verify-commit $HASH8\n'> ) } ) (C {<test_expect_success>} {<GPG>} {(SQ <'--graft with a signed commit'>)} { (SQ <'\n'> <'\tgit cat-file commit $HASH8 >orig &&\n'> <'\tgit replace --graft $HASH8 &&\n'> <'\tgit cat-file commit $HASH8 >repl &&\n'> <'\tcommit_has_parents $HASH8 &&\n'> <'\ttest_must_fail git verify-commit $HASH8 &&\n'> <'\tsed -n -e "/^tree /p" -e "/^author /p" -e "/^committer /p" orig >expected &&\n'> <'\techo >>expected &&\n'> <'\tsed -e "/^$/q" repl >actual &&\n'> <'\ttest_cmp expected actual &&\n'> <'\tgit replace -d $HASH8\n'> ) } ) (C {<test_expect_success>} {<GPG>} {(SQ <'set up a merge commit with a mergetag'>)} { (SQ <'\n'> <'\tgit reset --hard HEAD &&\n'> <'\tgit checkout -b test_branch HEAD~2 &&\n'> <'\techo "line 1 from test branch" >>hello &&\n'> <'\techo "line 2 from test branch" >>hello &&\n'> <'\tgit add hello &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m "hello: 2 more lines from a test branch" &&\n'> <'\tHASH9=$(git rev-parse --verify HEAD) &&\n'> <'\tgit tag -s -m "tag for testing with a mergetag" test_tag HEAD &&\n'> <'\tgit checkout master &&\n'> <'\tgit merge -s ours test_tag &&\n'> <'\tHASH10=$(git rev-parse --verify HEAD) &&\n'> <'\tgit cat-file commit $HASH10 | grep "^mergetag object"\n'> ) } ) (C {<test_expect_success>} {<GPG>} {(SQ <'--graft on a commit with a mergetag'>)} { (SQ <'\n'> <'\ttest_must_fail git replace --graft $HASH10 $HASH8^1 &&\n'> <'\tgit replace --graft $HASH10 $HASH8^1 $HASH9 &&\n'> <'\tgit replace -d $HASH10\n'> ) } ) (C {<test_done>}) ] )