(command.CommandList children: [ (command.ShAssignment pairs: [ (assign_pair lhs: (sh_lhs_expr.Name name:test_description) op: assign_op.Equal rhs: {(SQ <'pulling into void'>)} spids: [4] ) ] ) (C {<.>} {<'./test-lib.sh'>}) (command.ShFunction name: modify body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp] children: [ (command.Simple words: [{<sed>} {<-e>} {(DQ ($ Id.VSub_Number '$1'))}] redirects: [ (redir op: <Id.Redir_Less '<'> loc: (redir_loc.Fd fd:0) arg: {(DQ ($ Id.VSub_Number '$2'))} ) (redir op: <Id.Redir_Great '>'> loc: (redir_loc.Fd fd:1) arg: {(DQ ($ Id.VSub_Number '$2') <.x>)} ) ] do_fork: T ) (C {<mv>} {(DQ ($ Id.VSub_Number '$2') <.x>)} {(DQ ($ Id.VSub_Number '$2'))}) ] ) ] ) ) (command.ShFunction name: test_pull_autostash body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (C {<git>} {<reset>} {<--hard>} {<before-rebase>}) (command.Simple words: [{<echo>} {<dirty>}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<new_file>})] do_fork: T ) (C {<git>} {<add>} {<new_file>}) (C {<git>} {<pull>} {(DQ ($ Id.VSub_At '$@'))} {<.>} {<copy>}) (C {<test_cmp_rev>} {<HEAD> <Id.Lit_Other '^'>} {<copy>}) (C {<test>} { (DQ (command_sub left_token: <Id.Left_DollarParen '$('> child: (C {<cat>} {<new_file>}) ) ) } {<Id.Lit_Equals '='>} {<dirty>} ) (C {<test>} {(DQ (command_sub left_token:<Id.Left_DollarParen '$('> child:(C {<cat>} {<file>})))} {<Id.Lit_Equals '='>} {(DQ <'modified again'>)} ) ] ) ] ) ) (command.ShFunction name: test_pull_autostash_fail body: (BraceGroup children: [ (command.AndOr ops: [Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp Id.Op_DAmp] children: [ (C {<git>} {<reset>} {<--hard>} {<before-rebase>}) (command.Simple words: [{<echo>} {<dirty>}] redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<new_file>})] do_fork: T ) (C {<git>} {<add>} {<new_file>}) (command.Simple words: [{<test_must_fail>} {<git>} {<pull>} {(DQ ($ Id.VSub_At '$@'))} {<.>} {<copy>}] redirects: [(redir op:<Id.Redir_Great '2>'> loc:(redir_loc.Fd fd:2) arg:{<err>})] do_fork: T ) (C {<test_i18ngrep>} {(DQ <'uncommitted changes.'>)} {<err>}) ] ) ] ) ) (C {<test_expect_success>} {<setup>} { (SQ <'\n'> <'\techo file >file &&\n'> <'\tgit add file &&\n'> <'\tgit commit -a -m original\n'>) } ) (C {<test_expect_success>} {(SQ <'pulling into void'>)} { (SQ <'\n'> <'\tgit init cloned &&\n'> <'\t(\n'> <'\t\tcd cloned &&\n'> <'\t\tgit pull ..\n'> <'\t) &&\n'> <'\ttest -f file &&\n'> <'\ttest -f cloned/file &&\n'> <'\ttest_cmp file cloned/file\n'> ) } ) (C {<test_expect_success>} {(SQ <'pulling into void using master:master'>)} { (SQ <'\n'> <'\tgit init cloned-uho &&\n'> <'\t(\n'> <'\t\tcd cloned-uho &&\n'> <'\t\tgit pull .. master:master\n'> <'\t) &&\n'> <'\ttest -f file &&\n'> <'\ttest -f cloned-uho/file &&\n'> <'\ttest_cmp file cloned-uho/file\n'> ) } ) (C {<test_expect_success>} {(SQ <'pulling into void does not overwrite untracked files'>)} { (SQ <'\n'> <'\tgit init cloned-untracked &&\n'> <'\t(\n'> <'\t\tcd cloned-untracked &&\n'> <'\t\techo untracked >file &&\n'> <'\t\ttest_must_fail git pull .. master &&\n'> <'\t\techo untracked >expect &&\n'> <'\t\ttest_cmp expect file\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'pulling into void does not overwrite staged files'>)} { (SQ <'\n'> <'\tgit init cloned-staged-colliding &&\n'> <'\t(\n'> <'\t\tcd cloned-staged-colliding &&\n'> <'\t\techo "alternate content" >file &&\n'> <'\t\tgit add file &&\n'> <'\t\ttest_must_fail git pull .. master &&\n'> <'\t\techo "alternate content" >expect &&\n'> <'\t\ttest_cmp expect file &&\n'> <'\t\tgit cat-file blob :file >file.index &&\n'> <'\t\ttest_cmp expect file.index\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'pulling into void does not remove new staged files'>)} { (SQ <'\n'> <'\tgit init cloned-staged-new &&\n'> <'\t(\n'> <'\t\tcd cloned-staged-new &&\n'> <'\t\techo "new tracked file" >newfile &&\n'> <'\t\tgit add newfile &&\n'> <'\t\tgit pull .. master &&\n'> <'\t\techo "new tracked file" >expect &&\n'> <'\t\ttest_cmp expect newfile &&\n'> <'\t\tgit cat-file blob :newfile >newfile.index &&\n'> <'\t\ttest_cmp expect newfile.index\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'pulling into void must not create an octopus'>)} { (SQ <'\n'> <'\tgit init cloned-octopus &&\n'> <'\t(\n'> <'\t\tcd cloned-octopus &&\n'> <'\t\ttest_must_fail git pull .. master master &&\n'> <'\t\t! test -f file\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'test . as a remote'>)} { (SQ <'\n'> <'\tgit branch copy master &&\n'> <'\tgit config branch.copy.remote . &&\n'> <'\tgit config branch.copy.merge refs/heads/master &&\n'> <'\techo updated >file &&\n'> <'\tgit commit -a -m updated &&\n'> <'\tgit checkout copy &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\tgit pull &&\n'> <'\ttest "$(cat file)" = updated &&\n'> <'\tgit reflog -1 >reflog.actual &&\n'> <'\tsed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&\n'> <'\techo "OBJID HEAD@{0}: pull: Fast-forward" >reflog.expected &&\n'> <'\ttest_cmp reflog.expected reflog.fuzzy\n'> ) } ) (C {<test_expect_success>} {(SQ <'the default remote . should not break explicit pull'>)} { (SQ <'\n'> <'\tgit checkout -b second master^ &&\n'> <'\techo modified >file &&\n'> <'\tgit commit -a -m modified &&\n'> <'\tgit checkout copy &&\n'> <'\tgit reset --hard HEAD^ &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\tgit pull . second &&\n'> <'\ttest "$(cat file)" = modified &&\n'> <'\tgit reflog -1 >reflog.actual &&\n'> <'\tsed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy &&\n'> <'\techo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected &&\n'> <'\ttest_cmp reflog.expected reflog.fuzzy\n'> ) } ) (C {<test_expect_success>} {(SQ <'fail if wildcard spec does not match any refs'>)} { (SQ <'\n'> <'\tgit checkout -b test copy^ &&\n'> <'\ttest_when_finished "git checkout -f copy && git branch -D test" &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\ttest_must_fail git pull . "refs/nonexisting1/*:refs/nonexisting2/*" 2>err &&\n'> <'\ttest_i18ngrep "no candidates for merging" err &&\n'> <'\ttest "$(cat file)" = file\n'> ) } ) (C {<test_expect_success>} {(SQ <'fail if no branches specified with non-default remote'>)} { (SQ <'\n'> <'\tgit remote add test_remote . &&\n'> <'\ttest_when_finished "git remote remove test_remote" &&\n'> <'\tgit checkout -b test copy^ &&\n'> <'\ttest_when_finished "git checkout -f copy && git branch -D test" &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\ttest_config branch.test.remote origin &&\n'> <'\ttest_must_fail git pull test_remote 2>err &&\n'> <'\ttest_i18ngrep "specify a branch on the command line" err &&\n'> <'\ttest "$(cat file)" = file\n'> ) } ) (C {<test_expect_success>} {(SQ <'fail if not on a branch'>)} { (SQ <'\n'> <'\tgit remote add origin . &&\n'> <'\ttest_when_finished "git remote remove origin" &&\n'> <'\tgit checkout HEAD^ &&\n'> <'\ttest_when_finished "git checkout -f copy" &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\ttest_must_fail git pull 2>err &&\n'> <'\ttest_i18ngrep "not currently on a branch" err &&\n'> <'\ttest "$(cat file)" = file\n'> ) } ) (C {<test_expect_success>} {(SQ <'fail if no configuration for current branch'>)} { (SQ <'\n'> <'\tgit remote add test_remote . &&\n'> <'\ttest_when_finished "git remote remove test_remote" &&\n'> <'\tgit checkout -b test copy^ &&\n'> <'\ttest_when_finished "git checkout -f copy && git branch -D test" &&\n'> <'\ttest_config branch.test.remote test_remote &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\ttest_must_fail git pull 2>err &&\n'> <'\ttest_i18ngrep "no tracking information" err &&\n'> <'\ttest "$(cat file)" = file\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --all: fail if no configuration for current branch'>)} { (SQ <'\n'> <'\tgit remote add test_remote . &&\n'> <'\ttest_when_finished "git remote remove test_remote" &&\n'> <'\tgit checkout -b test copy^ &&\n'> <'\ttest_when_finished "git checkout -f copy && git branch -D test" &&\n'> <'\ttest_config branch.test.remote test_remote &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\ttest_must_fail git pull --all 2>err &&\n'> <'\ttest_i18ngrep "There is no tracking information" err &&\n'> <'\ttest "$(cat file)" = file\n'> ) } ) (C {<test_expect_success>} {(SQ <'fail if upstream branch does not exist'>)} { (SQ <'\n'> <'\tgit checkout -b test copy^ &&\n'> <'\ttest_when_finished "git checkout -f copy && git branch -D test" &&\n'> <'\ttest_config branch.test.remote . &&\n'> <'\ttest_config branch.test.merge refs/heads/nonexisting &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\ttest_must_fail git pull 2>err &&\n'> <'\ttest_i18ngrep "no such ref was fetched" err &&\n'> <'\ttest "$(cat file)" = file\n'> ) } ) (C {<test_expect_success>} {(SQ <'fail if the index has unresolved entries'>)} { (SQ <'\n'> <'\tgit checkout -b third second^ &&\n'> <'\ttest_when_finished "git checkout -f copy && git branch -D third" &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\ttest_commit modified2 file &&\n'> <'\ttest -z "$(git ls-files -u)" &&\n'> <'\ttest_must_fail git pull . second &&\n'> <'\ttest -n "$(git ls-files -u)" &&\n'> <'\tcp file expected &&\n'> <'\ttest_must_fail git pull . second 2>err &&\n'> <'\ttest_i18ngrep "Pulling is not possible because you have unmerged files." err &&\n'> <'\ttest_cmp expected file &&\n'> <'\tgit add file &&\n'> <'\ttest -z "$(git ls-files -u)" &&\n'> <'\ttest_must_fail git pull . second 2>err &&\n'> <'\ttest_i18ngrep "You have not concluded your merge" err &&\n'> <'\ttest_cmp expected file\n'> ) } ) (C {<test_expect_success>} {(SQ <'fast-forwards working tree if branch head is updated'>)} { (SQ <'\n'> <'\tgit checkout -b third second^ &&\n'> <'\ttest_when_finished "git checkout -f copy && git branch -D third" &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\tgit pull . second:third 2>err &&\n'> <'\ttest_i18ngrep "fetch updated the current branch head" err &&\n'> <'\ttest "$(cat file)" = modified &&\n'> <'\ttest "$(git rev-parse third)" = "$(git rev-parse second)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'fast-forward fails with conflicting work tree'>)} { (SQ <'\n'> <'\tgit checkout -b third second^ &&\n'> <'\ttest_when_finished "git checkout -f copy && git branch -D third" &&\n'> <'\ttest "$(cat file)" = file &&\n'> <'\techo conflict >file &&\n'> <'\ttest_must_fail git pull . second:third 2>err &&\n'> <'\ttest_i18ngrep "Cannot fast-forward your working tree" err &&\n'> <'\ttest "$(cat file)" = conflict &&\n'> <'\ttest "$(git rev-parse third)" = "$(git rev-parse second)"\n'> ) } ) (C {<test_expect_success>} {(SQ <--rebase>)} { (SQ <'\n'> <'\tgit branch to-rebase &&\n'> <'\techo modified again > file &&\n'> <'\tgit commit -m file file &&\n'> <'\tgit checkout to-rebase &&\n'> <'\techo new > file2 &&\n'> <'\tgit add file2 &&\n'> <'\tgit commit -m "new file" &&\n'> <'\tgit tag before-rebase &&\n'> <'\tgit pull --rebase . copy &&\n'> <'\ttest "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&\n'> <'\ttest new = "$(git show HEAD:file2)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase with conflicts shows advice'>)} { (SQ <'\n'> <'\ttest_when_finished "git rebase --abort; git checkout -f to-rebase" &&\n'> <'\tgit checkout -b seq &&\n'> <'\ttest_seq 5 >seq.txt &&\n'> <'\tgit add seq.txt &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m "Add seq.txt" &&\n'> <'\techo 6 >>seq.txt &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m "Append to seq.txt" seq.txt &&\n'> <'\tgit checkout -b with-conflicts HEAD^ &&\n'> <'\techo conflicting >>seq.txt &&\n'> <'\ttest_tick &&\n'> <'\tgit commit -m "Create conflict" seq.txt &&\n'> <'\ttest_must_fail git pull --rebase . seq 2>err >out &&\n'> <'\ttest_i18ngrep "When you have resolved this problem" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'failed --rebase shows advice'>)} { (SQ <'\n'> <'\ttest_when_finished "git rebase --abort; git checkout -f to-rebase" &&\n'> <'\tgit checkout -b diverging &&\n'> <'\ttest_commit attributes .gitattributes "* text=auto" attrs &&\n'> <'\tsha1="$(printf "1\\\\r\\\\n" | git hash-object -w --stdin)" &&\n'> <'\tgit update-index --cacheinfo 0644 $sha1 file &&\n'> <'\tgit commit -m v1-with-cr &&\n'> <'\t# force checkout because `git reset --hard` will not leave clean `file`\n'> <'\tgit checkout -f -b fails-to-rebase HEAD^ &&\n'> <'\ttest_commit v2-without-cr file "2" file2-lf &&\n'> <'\ttest_must_fail git pull --rebase . diverging 2>err >out &&\n'> <'\ttest_i18ngrep "When you have resolved this problem" out\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase fails with multiple branches'>)} { (SQ <'\n'> <'\tgit reset --hard before-rebase &&\n'> <'\ttest_must_fail git pull --rebase . copy master 2>err &&\n'> <'\ttest "$(git rev-parse HEAD)" = "$(git rev-parse before-rebase)" &&\n'> <'\ttest_i18ngrep "Cannot rebase onto multiple branches" err &&\n'> <'\ttest modified = "$(git show HEAD:file)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase succeeds with dirty working directory and rebase.autostash set'>)} {(SQ <'\n'> <'\ttest_config rebase.autostash true &&\n'> <'\ttest_pull_autostash --rebase\n'>)} ) (C {<test_expect_success>} {(SQ <'pull --rebase --autostash & rebase.autostash=true'>)} { (SQ <'\n'> <'\ttest_config rebase.autostash true &&\n'> <'\ttest_pull_autostash --rebase --autostash\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase --autostash & rebase.autostash=false'>)} { (SQ <'\n'> <'\ttest_config rebase.autostash false &&\n'> <'\ttest_pull_autostash --rebase --autostash\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase --autostash & rebase.autostash unset'>)} { (SQ <'\n'> <'\ttest_unconfig rebase.autostash &&\n'> <'\ttest_pull_autostash --rebase --autostash\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase --no-autostash & rebase.autostash=true'>)} { (SQ <'\n'> <'\ttest_config rebase.autostash true &&\n'> <'\ttest_pull_autostash_fail --rebase --no-autostash\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase --no-autostash & rebase.autostash=false'>)} { (SQ <'\n'> <'\ttest_config rebase.autostash false &&\n'> <'\ttest_pull_autostash_fail --rebase --no-autostash\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase --no-autostash & rebase.autostash unset'>)} { (SQ <'\n'> <'\ttest_unconfig rebase.autostash &&\n'> <'\ttest_pull_autostash_fail --rebase --no-autostash\n'> ) } ) (command.ForEach iter_name: i iter_words: [{<--autostash>} {<--no-autostash>}] do_arg_iter: F body: (command.DoGroup children: [ (C {<test_expect_success>} {(DQ <'pull '> ($ Id.VSub_DollarName '$i') <' (without --rebase) is illegal'>)} { (SQ <'\n'> <'\t\ttest_must_fail git pull $i . copy 2>err &&\n'> <'\t\ttest_i18ngrep "only valid with --rebase" err\n'> <'\t'> ) } ) ] ) ) (C {<test_expect_success>} {(SQ <pull.rebase>)} { (SQ <'\n'> <'\tgit reset --hard before-rebase &&\n'> <'\ttest_config pull.rebase true &&\n'> <'\tgit pull . copy &&\n'> <'\ttest "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&\n'> <'\ttest new = "$(git show HEAD:file2)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --autostash & pull.rebase=true'>)} {(SQ <'\n'> <'\ttest_config pull.rebase true &&\n'> <'\ttest_pull_autostash --autostash\n'>)} ) (C {<test_expect_success>} {(SQ <'pull --no-autostash & pull.rebase=true'>)} { (SQ <'\n'> <'\ttest_config pull.rebase true &&\n'> <'\ttest_pull_autostash_fail --no-autostash\n'> ) } ) (C {<test_expect_success>} {(SQ <branch.to-rebase.rebase>)} { (SQ <'\n'> <'\tgit reset --hard before-rebase &&\n'> <'\ttest_config branch.to-rebase.rebase true &&\n'> <'\tgit pull . copy &&\n'> <'\ttest "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&\n'> <'\ttest new = "$(git show HEAD:file2)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'branch.to-rebase.rebase should override pull.rebase'>)} { (SQ <'\n'> <'\tgit reset --hard before-rebase &&\n'> <'\ttest_config pull.rebase true &&\n'> <'\ttest_config branch.to-rebase.rebase false &&\n'> <'\tgit pull . copy &&\n'> <'\ttest "$(git rev-parse HEAD^)" != "$(git rev-parse copy)" &&\n'> <'\ttest new = "$(git show HEAD:file2)"\n'> ) } ) (C {<test_expect_success>} {(DQ <'pull --rebase warns on --verify-signatures'>)} { (SQ <'\n'> <'\tgit reset --hard before-rebase &&\n'> <'\tgit pull --rebase --verify-signatures . copy 2>err &&\n'> <'\ttest "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&\n'> <'\ttest new = "$(git show HEAD:file2)" &&\n'> <'\ttest_i18ngrep "ignoring --verify-signatures for rebase" err\n'> ) } ) (C {<test_expect_success>} {(DQ <'pull --rebase does not warn on --no-verify-signatures'>)} { (SQ <'\n'> <'\tgit reset --hard before-rebase &&\n'> <'\tgit pull --rebase --no-verify-signatures . copy 2>err &&\n'> <'\ttest "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" &&\n'> <'\ttest new = "$(git show HEAD:file2)" &&\n'> <'\ttest_i18ngrep ! "verify-signatures" err\n'> ) } ) (C {<test_expect_success>} {(SQ <'preserve merge setup'>)} { (SQ <'\n'> <'\tgit reset --hard before-rebase &&\n'> <'\tgit checkout -b keep-merge second^ &&\n'> <'\ttest_commit file3 &&\n'> <'\tgit checkout to-rebase &&\n'> <'\tgit merge keep-merge &&\n'> <'\tgit tag before-preserve-rebase\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull.rebase=false create a new merge commit'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase false &&\n'> <'\tgit pull . copy &&\n'> <'\ttest "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&\n'> <'\ttest "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&\n'> <'\ttest file3 = "$(git show HEAD:file3.t)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull.rebase=true flattens keep-merge'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase true &&\n'> <'\tgit pull . copy &&\n'> <'\ttest "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&\n'> <'\ttest file3 = "$(git show HEAD:file3.t)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull.rebase=1 is treated as true and flattens keep-merge'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase 1 &&\n'> <'\tgit pull . copy &&\n'> <'\ttest "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&\n'> <'\ttest file3 = "$(git show HEAD:file3.t)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull.rebase=preserve rebases and merges keep-merge'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase preserve &&\n'> <'\tgit pull . copy &&\n'> <'\ttest "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&\n'> <'\ttest "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull.rebase=interactive'>)} { (SQ <'\n'> <'\twrite_script "$TRASH_DIRECTORY/fake-editor" <<-\\EOF &&\n'> <'\techo I was here >fake.out &&\n'> <'\tfalse\n'> <'\tEOF\n'> <'\ttest_set_editor "$TRASH_DIRECTORY/fake-editor" &&\n'> <'\ttest_must_fail git pull --rebase=interactive . copy &&\n'> <'\ttest "I was here" = "$(cat fake.out)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull.rebase=invalid fails'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase invalid &&\n'> <'\t! git pull . copy\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase=false create a new merge commit'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase true &&\n'> <'\tgit pull --rebase=false . copy &&\n'> <'\ttest "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" &&\n'> <'\ttest "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" &&\n'> <'\ttest file3 = "$(git show HEAD:file3.t)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase=true rebases and flattens keep-merge'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase preserve &&\n'> <'\tgit pull --rebase=true . copy &&\n'> <'\ttest "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&\n'> <'\ttest file3 = "$(git show HEAD:file3.t)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase=preserve rebases and merges keep-merge'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase true &&\n'> <'\tgit pull --rebase=preserve . copy &&\n'> <'\ttest "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&\n'> <'\ttest "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase=invalid fails'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\t! git pull --rebase=invalid . copy\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase overrides pull.rebase=preserve and flattens keep-merge'>)} { (SQ <'\n'> <'\tgit reset --hard before-preserve-rebase &&\n'> <'\ttest_config pull.rebase preserve &&\n'> <'\tgit pull --rebase . copy &&\n'> <'\ttest "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" &&\n'> <'\ttest file3 = "$(git show HEAD:file3.t)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase with rebased upstream'>)} { (SQ <'\n'> <'\n'> <'\tgit remote add -f me . &&\n'> <'\tgit checkout copy &&\n'> <'\tgit tag copy-orig &&\n'> <'\tgit reset --hard HEAD^ &&\n'> <'\techo conflicting modification > file &&\n'> <'\tgit commit -m conflict file &&\n'> <'\tgit checkout to-rebase &&\n'> <'\techo file > file2 &&\n'> <'\tgit commit -m to-rebase file2 &&\n'> <'\tgit tag to-rebase-orig &&\n'> <'\tgit pull --rebase me copy &&\n'> <'\ttest "conflicting modification" = "$(cat file)" &&\n'> <'\ttest file = "$(cat file2)"\n'> <'\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase -f with rebased upstream'>)} { (SQ <'\n'> <'\ttest_when_finished "test_might_fail git rebase --abort" &&\n'> <'\tgit reset --hard to-rebase-orig &&\n'> <'\tgit pull --rebase -f me copy &&\n'> <'\ttest "conflicting modification" = "$(cat file)" &&\n'> <'\ttest file = "$(cat file2)"\n'> ) } ) (C {<test_expect_success>} {(SQ <'--rebase with rebased default upstream'>)} { (SQ <'\n'> <'\n'> <'\tgit update-ref refs/remotes/me/copy copy-orig &&\n'> <'\tgit checkout --track -b to-rebase2 me/copy &&\n'> <'\tgit reset --hard to-rebase-orig &&\n'> <'\tgit pull --rebase &&\n'> <'\ttest "conflicting modification" = "$(cat file)" &&\n'> <'\ttest file = "$(cat file2)"\n'> <'\n'> ) } ) (C {<test_expect_success>} {(SQ <'rebased upstream + fetch + pull --rebase'>)} { (SQ <'\n'> <'\n'> <'\tgit update-ref refs/remotes/me/copy copy-orig &&\n'> <'\tgit reset --hard to-rebase-orig &&\n'> <'\tgit checkout --track -b to-rebase3 me/copy &&\n'> <'\tgit reset --hard to-rebase-orig &&\n'> <'\tgit fetch &&\n'> <'\tgit pull --rebase &&\n'> <'\ttest "conflicting modification" = "$(cat file)" &&\n'> <'\ttest file = "$(cat file2)"\n'> <'\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase dies early with dirty working directory'>)} { (SQ <'\n'> <'\n'> <'\tgit checkout to-rebase &&\n'> <'\tgit update-ref refs/remotes/me/copy copy^ &&\n'> <'\tCOPY="$(git rev-parse --verify me/copy)" &&\n'> <'\tgit rebase --onto $COPY copy &&\n'> <'\ttest_config branch.to-rebase.remote me &&\n'> <'\ttest_config branch.to-rebase.merge refs/heads/copy &&\n'> <'\ttest_config branch.to-rebase.rebase true &&\n'> <'\techo dirty >> file &&\n'> <'\tgit add file &&\n'> <'\ttest_must_fail git pull &&\n'> <'\ttest "$COPY" = "$(git rev-parse --verify me/copy)" &&\n'> <'\tgit checkout HEAD -- file &&\n'> <'\tgit pull &&\n'> <'\ttest "$COPY" != "$(git rev-parse --verify me/copy)"\n'> <'\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase works on branch yet to be born'>)} { (SQ <'\n'> <'\tgit rev-parse master >expect &&\n'> <'\tmkdir empty_repo &&\n'> <'\t(cd empty_repo &&\n'> <'\t git init &&\n'> <'\t git pull --rebase .. master &&\n'> <'\t git rev-parse HEAD >../actual\n'> <'\t) &&\n'> <'\ttest_cmp expect actual\n'> ) } ) (C {<test_expect_success>} {(SQ <'pull --rebase fails on unborn branch with staged changes'>)} { (SQ <'\n'> <'\ttest_when_finished "rm -rf empty_repo2" &&\n'> <'\tgit init empty_repo2 &&\n'> <'\t(\n'> <'\t\tcd empty_repo2 &&\n'> <'\t\techo staged-file >staged-file &&\n'> <'\t\tgit add staged-file &&\n'> <'\t\ttest "$(git ls-files)" = staged-file &&\n'> <'\t\ttest_must_fail git pull --rebase .. master 2>err &&\n'> <'\t\ttest "$(git ls-files)" = staged-file &&\n'> <'\t\ttest "$(git show :staged-file)" = staged-file &&\n'> <'\t\ttest_i18ngrep "unborn branch with changes added to the index" err\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'setup for detecting upstreamed changes'>)} { (SQ <'\n'> <'\tmkdir src &&\n'> <'\t(cd src &&\n'> <'\t git init &&\n'> <'\t printf "1\\n2\\n3\\n4\\n5\\n6\\n7\\n8\\n9\\n10\\n" > stuff &&\n'> <'\t git add stuff &&\n'> <'\t git commit -m "Initial revision"\n'> <'\t) &&\n'> <'\tgit clone src dst &&\n'> <'\t(cd src &&\n'> <'\t modify s/5/43/ stuff &&\n'> <'\t git commit -a -m "5->43" &&\n'> <'\t modify s/6/42/ stuff &&\n'> <'\t git commit -a -m "Make it bigger"\n'> <'\t) &&\n'> <'\t(cd dst &&\n'> <'\t modify s/5/43/ stuff &&\n'> <'\t git commit -a -m "Independent discovery of 5->43"\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'git pull --rebase detects upstreamed changes'>)} { (SQ <'\n'> <'\t(cd dst &&\n'> <'\t git pull --rebase &&\n'> <'\t test -z "$(git ls-files -u)"\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'setup for avoiding reapplying old patches'>)} { (SQ <'\n'> <'\t(cd dst &&\n'> <'\t test_might_fail git rebase --abort &&\n'> <'\t git reset --hard origin/master\n'> <'\t) &&\n'> <'\tgit clone --bare src src-replace.git &&\n'> <'\trm -rf src &&\n'> <'\tmv src-replace.git src &&\n'> <'\t(cd dst &&\n'> <'\t modify s/2/22/ stuff &&\n'> <'\t git commit -a -m "Change 2" &&\n'> <'\t modify s/3/33/ stuff &&\n'> <'\t git commit -a -m "Change 3" &&\n'> <'\t modify s/4/44/ stuff &&\n'> <'\t git commit -a -m "Change 4" &&\n'> <'\t git push &&\n'> <'\n'> <'\t modify s/44/55/ stuff &&\n'> <'\t git commit --amend -a -m "Modified Change 4"\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'git pull --rebase does not reapply old patches'>)} { (SQ <'\n'> <'\t(cd dst &&\n'> <'\t test_must_fail git pull --rebase &&\n'> <'\t test 1 = $(find .git/rebase-apply -name "000*" | wc -l)\n'> <'\t)\n'> ) } ) (C {<test_expect_success>} {(SQ <'git pull --rebase against local branch'>)} { (SQ <'\n'> <'\tgit checkout -b copy2 to-rebase-orig &&\n'> <'\tgit pull --rebase . to-rebase &&\n'> <'\ttest "conflicting modification" = "$(cat file)" &&\n'> <'\ttest file = "$(cat file2)"\n'> ) } ) (C {<test_done>}) ] )