diff options
Diffstat (limited to 't')
40 files changed, 908 insertions, 141 deletions
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index dc75b83451..ec6b9b107d 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -151,3 +151,59 @@ test_editor_unchanged () { EOF test_cmp expect actual } + +# Set up an editor for testing reword commands +# Checks that there are no uncommitted changes when rewording and that the +# todo-list is reread after each +set_reword_editor () { + >reword-actual && + >reword-oid && + + # Check rewording keeps the original authorship + GIT_AUTHOR_NAME="Reword Author" + GIT_AUTHOR_EMAIL="reword.author@example.com" + GIT_AUTHOR_DATE=@123456 + + write_script reword-sequence-editor.sh <<-\EOF && + todo="$(cat "$1")" && + echo "exec git log -1 --pretty=format:'%an <%ae> %at%n%B%n' \ + >>reword-actual" >"$1" && + printf "%s\n" "$todo" >>"$1" + EOF + + write_script reword-editor.sh <<-EOF && + # Save the oid of the first reworded commit so we can check rebase + # fast-forwards to it. Also check that we do not write .git/MERGE_MSG + # when fast-forwarding + if ! test -s reword-oid + then + git rev-parse HEAD >reword-oid && + if test -f .git/MERGE_MSG + then + echo 1>&2 "error: .git/MERGE_MSG exists" + exit 1 + fi + fi && + # There should be no uncommited changes + git diff --exit-code HEAD && + # The todo-list should be re-read after a reword + GIT_SEQUENCE_EDITOR="\"$PWD/reword-sequence-editor.sh\"" \ + git rebase --edit-todo && + echo edited >>"\$1" + EOF + + test_set_editor "$PWD/reword-editor.sh" +} + +# Check the results of a rebase after calling set_reword_editor +# Pass the commits that were reworded in the order that they were picked +# Expects the first pick to be a fast-forward +check_reworded_commits () { + test_cmp_rev "$(cat reword-oid)" "$1^{commit}" && + git log --format="%an <%ae> %at%n%B%nedited%n" --no-walk=unsorted "$@" \ + >reword-expected && + test_cmp reword-expected reword-actual && + git log --format="%an <%ae> %at%n%B" -n $# --first-parent --reverse \ + >reword-log && + test_cmp reword-expected reword-log +} diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index b5749f327d..33dfc9cd56 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -6,6 +6,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-terminal.sh TEST_ROOT="$PWD" PATH=$TEST_ROOT:$PATH @@ -1061,4 +1062,74 @@ test_expect_success PERL,SYMLINKS,CASE_INSENSITIVE_FS \ ) ' +test_expect_success PERL 'setup for progress tests' ' + git init progress && + ( + cd progress && + git config filter.delay.process "rot13-filter.pl delay-progress.log clean smudge delay" && + git config filter.delay.required true && + + echo "*.a filter=delay" >.gitattributes && + touch test-delay10.a && + git add . && + git commit -m files + ) +' + +test_delayed_checkout_progress () { + if test "$1" = "!" + then + local expect_progress=N && + shift + else + local expect_progress= + fi && + + if test $# -lt 1 + then + BUG "no command given to test_delayed_checkout_progress" + fi && + + ( + cd progress && + GIT_PROGRESS_DELAY=0 && + export GIT_PROGRESS_DELAY && + rm -f *.a delay-progress.log && + + "$@" 2>err && + grep "IN: smudge test-delay10.a .* \\[DELAYED\\]" delay-progress.log && + if test "$expect_progress" = N + then + ! grep "Filtering content" err + else + grep "Filtering content" err + fi + ) +} + +for mode in pathspec branch +do + case "$mode" in + pathspec) opt='.' ;; + branch) opt='-f HEAD' ;; + esac + + test_expect_success PERL,TTY "delayed checkout shows progress by default on tty ($mode checkout)" ' + test_delayed_checkout_progress test_terminal git checkout $opt + ' + + test_expect_success PERL "delayed checkout ommits progress on non-tty ($mode checkout)" ' + test_delayed_checkout_progress ! git checkout $opt + ' + + test_expect_success PERL,TTY "delayed checkout ommits progress with --quiet ($mode checkout)" ' + test_delayed_checkout_progress ! test_terminal git checkout --quiet $opt + ' + + test_expect_success PERL,TTY "delayed checkout honors --[no]-progress ($mode checkout)" ' + test_delayed_checkout_progress ! test_terminal git checkout --no-progress $opt && + test_delayed_checkout_progress test_terminal git checkout --quiet --progress $opt + ' +done + test_done diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index cc4b10236e..e575ffb4ff 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -1272,6 +1272,19 @@ test_expect_success 'attempt to delete a branch merged to its base' ' test_must_fail git branch -d my10 ' +test_expect_success 'branch --delete --force removes dangling branch' ' + git checkout main && + test_commit unstable && + hash=$(git rev-parse HEAD) && + objpath=$(echo $hash | sed -e "s|^..|.git/objects/&/|") && + git branch --no-track dangling && + mv $objpath $objpath.x && + test_when_finished "mv $objpath.x $objpath" && + git branch --delete --force dangling && + git for-each-ref refs/heads/dangling >actual && + test_must_be_empty actual +' + test_expect_success 'use --edit-description' ' write_script editor <<-\EOF && echo "New contents" >"$1" diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index e26762d0b2..f6e4864497 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -20,6 +20,7 @@ test_expect_success setup ' git add hello && git commit -m "hello" && git branch skip-reference && + git tag hello && echo world >> hello && git commit -a -m "hello world" && @@ -36,7 +37,8 @@ test_expect_success setup ' test_tick && GIT_AUTHOR_NAME="Another Author" \ GIT_AUTHOR_EMAIL="another.author@example.com" \ - git commit --amend --no-edit -m amended-goodbye && + git commit --amend --no-edit -m amended-goodbye \ + --reset-author && test_tick && git tag amended-goodbye && @@ -51,7 +53,7 @@ test_expect_success setup ' ' test_expect_success 'rebase with git am -3 (default)' ' - test_must_fail git rebase main + test_must_fail git rebase --apply main ' test_expect_success 'rebase --skip can not be used with other options' ' @@ -95,6 +97,13 @@ test_expect_success 'moved back to branch correctly' ' test_debug 'gitk --all & sleep 1' +test_expect_success 'skipping final pick removes .git/MERGE_MSG' ' + test_must_fail git rebase --onto hello reverted-goodbye^ \ + reverted-goodbye && + git rebase --skip && + test_path_is_missing .git/MERGE_MSG +' + test_expect_success 'correct advice upon picking empty commit' ' test_when_finished "git rebase --abort" && test_must_fail git rebase -i --onto goodbye \ diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 66bcbbf952..d877872e8f 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -839,6 +839,19 @@ test_expect_success 'reword' ' git show HEAD~2 | grep "C changed" ' +test_expect_success 'no uncommited changes when rewording the todo list is reloaded' ' + git checkout E && + test_when_finished "git checkout @{-1}" && + ( + set_fake_editor && + GIT_SEQUENCE_EDITOR="\"$PWD/fake-editor.sh\"" && + export GIT_SEQUENCE_EDITOR && + set_reword_editor && + FAKE_LINES="reword 1 reword 2" git rebase -i C + ) && + check_reworded_commits D E +' + test_expect_success 'rebase -i can copy notes' ' git config notes.rewrite.rebase true && git config notes.rewriteRef "refs/notes/*" && diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index f4c2ee02bc..738fbae9b2 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -21,7 +21,7 @@ test_expect_success 'setup' ' git checkout main ' -test_expect_success 'interactive rebase --continue works with touched file' ' +test_expect_success 'merge based rebase --continue with works with touched file' ' rm -fr .git/rebase-* && git reset --hard && git checkout main && @@ -31,12 +31,22 @@ test_expect_success 'interactive rebase --continue works with touched file' ' git rebase --continue ' -test_expect_success 'non-interactive rebase --continue works with touched file' ' +test_expect_success 'merge based rebase --continue removes .git/MERGE_MSG' ' + git checkout -f --detach topic && + + test_must_fail git rebase --onto main HEAD^ && + git read-tree --reset -u HEAD && + test_path_is_file .git/MERGE_MSG && + git rebase --continue && + test_path_is_missing .git/MERGE_MSG +' + +test_expect_success 'apply based rebase --continue works with touched file' ' rm -fr .git/rebase-* && git reset --hard && git checkout main && - test_must_fail git rebase --onto main main topic && + test_must_fail git rebase --apply --onto main main topic && echo "Resolved" >F2 && git add F2 && test-tool chmtime =-60 F1 && @@ -254,7 +264,7 @@ test_rerere_autoupdate () { ' } -test_rerere_autoupdate +test_rerere_autoupdate --apply test_rerere_autoupdate -m GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR test_rerere_autoupdate -i diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index 6748070df5..43c82d9a33 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -172,19 +172,39 @@ test_expect_success 'failed `merge <branch>` does not crash' ' grep "^Merge branch ${SQ}G${SQ}$" .git/rebase-merge/message ' -test_expect_success 'fast-forward merge -c still rewords' ' - git checkout -b fast-forward-merge-c H && +test_expect_success 'merge -c commits before rewording and reloads todo-list' ' + cat >script-from-scratch <<-\EOF && + merge -c E B + merge -c H G + EOF + + git checkout -b merge-c H && ( - set_fake_editor && - FAKE_COMMIT_MESSAGE=edited \ - GIT_SEQUENCE_EDITOR="echo merge -c H G >" \ - git rebase -ir @^ + set_reword_editor && + GIT_SEQUENCE_EDITOR="\"$PWD/replace-editor.sh\"" \ + git rebase -i -r D ) && - echo edited >expected && - git log --pretty=format:%B -1 >actual && - test_cmp expected actual + check_reworded_commits E H ' +test_expect_success 'merge -c rewords when a strategy is given' ' + git checkout -b merge-c-with-strategy H && + write_script git-merge-override <<-\EOF && + echo overridden$1 >G.t + git add G.t + EOF + + PATH="$PWD:$PATH" \ + GIT_SEQUENCE_EDITOR="echo merge -c H G >" \ + GIT_EDITOR="echo edited >>" \ + git rebase --no-ff -ir -s override -Xxopt E && + test_write_lines overridden--xopt >expect && + test_cmp expect G.t && + test_write_lines H "" edited "" >expect && + git log --format=%B -1 >actual && + test_cmp expect actual + +' test_expect_success 'with a branch tip that was cherry-picked already' ' git checkout -b already-upstream main && base="$(git rev-parse --verify HEAD)" && diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index 9d100cd188..4b5b607673 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -158,4 +158,20 @@ test_expect_success 'cherry-pick works with dirty renamed file' ' grep -q "^modified$" renamed ' +test_expect_success 'advice from failed revert' ' + test_commit --no-tag "add dream" dream dream && + dream_oid=$(git rev-parse --short HEAD) && + cat <<-EOF >expected && + error: could not revert $dream_oid... add dream + hint: After resolving the conflicts, mark them with + hint: "git add/rm <pathspec>", then run + hint: "git revert --continue". + hint: You can instead skip this commit with "git revert --skip". + hint: To abort and get back to the state before "git revert", + hint: run "git revert --abort". + EOF + test_commit --append --no-tag "double-add dream" dream dream && + test_must_fail git revert HEAD^ 2>actual && + test_cmp expected actual +' test_done diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 014001b8f3..979e843c65 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -47,20 +47,23 @@ test_expect_success 'failed cherry-pick does not advance HEAD' ' test "$head" = "$newhead" ' -test_expect_success 'advice from failed cherry-pick' " +test_expect_success 'advice from failed cherry-pick' ' pristine_detach initial && - picked=\$(git rev-parse --short picked) && + picked=$(git rev-parse --short picked) && cat <<-EOF >expected && - error: could not apply \$picked... picked - hint: after resolving the conflicts, mark the corrected paths - hint: with 'git add <paths>' or 'git rm <paths>' - hint: and commit the result with 'git commit' + error: could not apply $picked... picked + hint: After resolving the conflicts, mark them with + hint: "git add/rm <pathspec>", then run + hint: "git cherry-pick --continue". + hint: You can instead skip this commit with "git cherry-pick --skip". + hint: To abort and get back to the state before "git cherry-pick", + hint: run "git cherry-pick --abort". EOF test_must_fail git cherry-pick picked 2>actual && test_cmp expected actual -" +' test_expect_success 'advice from failed cherry-pick --no-commit' " pristine_detach initial && diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index e561a8e485..28683d059d 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -65,7 +65,7 @@ test_expect_success setup ' export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && git checkout master && - git pull -s ours . side && + git pull -s ours --no-rebase . side && GIT_AUTHOR_DATE="2006-06-26 00:05:00 +0000" && GIT_COMMITTER_DATE="2006-06-26 00:05:00 +0000" && diff --git a/t/t4018/java-class-member-function b/t/t4018/java-class-member-function index 298bc7a71b..3b95f68b3b 100644 --- a/t/t4018/java-class-member-function +++ b/t/t4018/java-class-member-function @@ -3,6 +3,10 @@ public class Beer int special; public static void main(String RIGHT[]) { + someMethodCall(); + someOtherMethod("17") + .doThat(); + // Whatever System.out.print("ChangeMe"); } } diff --git a/t/t4018/java-enum-constant b/t/t4018/java-enum-constant new file mode 100644 index 0000000000..a1931c8379 --- /dev/null +++ b/t/t4018/java-enum-constant @@ -0,0 +1,6 @@ +private enum RIGHT { + ONE, + TWO, + THREE, + ChangeMe +} diff --git a/t/t4018/java-method-return-generic-bounded b/t/t4018/java-method-return-generic-bounded new file mode 100644 index 0000000000..66dd78c379 --- /dev/null +++ b/t/t4018/java-method-return-generic-bounded @@ -0,0 +1,9 @@ +class MyExample { + public <T extends Bar & Foo<T>, R> Map<T, R[]> foo(String[] RIGHT) { + someMethodCall(); + someOtherMethod() + .doThat(); + // Whatever... + return (List<T>) Arrays.asList("ChangeMe"); + } +} diff --git a/t/t4018/java-method-return-generic-wildcard b/t/t4018/java-method-return-generic-wildcard new file mode 100644 index 0000000000..96e9e5f2c1 --- /dev/null +++ b/t/t4018/java-method-return-generic-wildcard @@ -0,0 +1,9 @@ +class MyExample { + public List<? extends Comparable> foo(String[] RIGHT) { + someMethodCall(); + someOtherMethod() + .doThat(); + // Whatever... + return Arrays.asList("ChangeMe"); + } +} diff --git a/t/t4018/java-nested-field b/t/t4018/java-nested-field new file mode 100644 index 0000000000..d92d3ec688 --- /dev/null +++ b/t/t4018/java-nested-field @@ -0,0 +1,6 @@ +class MyExample { + private static class RIGHT { + // change an inner class field + String inner = "ChangeMe"; + } +} diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh index 61ba5f707f..fab351b48a 100755 --- a/t/t4045-diff-relative.sh +++ b/t/t4045-diff-relative.sh @@ -162,4 +162,57 @@ check_diff_relative_option subdir file2 true --no-relative --relative check_diff_relative_option . file2 false --no-relative --relative=subdir check_diff_relative_option . file2 true --no-relative --relative=subdir +test_expect_success 'setup diff --relative unmerged' ' + test_commit zero file0 && + test_commit base subdir/file0 && + git switch -c br1 && + test_commit one file0 && + test_commit sub1 subdir/file0 && + git switch -c br2 base && + test_commit two file0 && + git switch -c br3 && + test_commit sub3 subdir/file0 +' + +test_expect_success 'diff --relative without change in subdir' ' + git switch br2 && + test_when_finished "git merge --abort" && + test_must_fail git merge one && + git -C subdir diff --relative >out && + test_must_be_empty out && + git -C subdir diff --relative --name-only >out && + test_must_be_empty out +' + +test_expect_success 'diff --relative --name-only with change in subdir' ' + git switch br3 && + test_when_finished "git merge --abort" && + test_must_fail git merge sub1 && + test_write_lines file0 file0 >expected && + git -C subdir diff --relative --name-only >out && + test_cmp expected out +' + +test_expect_failure 'diff --relative with change in subdir' ' + git switch br3 && + br1_blob=$(git rev-parse --short --verify br1:subdir/file0) && + br3_blob=$(git rev-parse --short --verify br3:subdir/file0) && + test_when_finished "git merge --abort" && + test_must_fail git merge br1 && + cat >expected <<-EOF && + diff --cc file0 + index $br3_blob,$br1_blob..0000000 + --- a/file0 + +++ b/file0 + @@@ -1,1 -1,1 +1,5 @@@ + ++<<<<<<< HEAD + +sub3 + ++======= + + sub1 + ++>>>>>>> br1 + EOF + git -C subdir diff --relative >out && + test_cmp expected out +' + test_done diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index fad6d3f542..d370ecfe0d 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -158,4 +158,27 @@ test_expect_success 'apply binary -p0 diff' ' test -z "$(git diff --name-status binary -- file3)" ' +test_expect_success 'reject truncated binary diff' ' + do_reset && + + # this length is calculated to get us very close to + # the 8192-byte strbuf we will use to read in the patch. + test-tool genrandom foo 6205 >file1 && + git diff --binary >patch && + + # truncate the patch at the second "literal" line, + # but exclude the trailing newline. We must use perl + # for this, since tools like "sed" cannot reliably + # produce output without the trailing newline. + perl -pe " + if (/^literal/ && \$count++ >= 1) { + chomp; + print; + exit 0; + } + " <patch >patch.trunc && + + do_reset && + test_must_fail git apply patch.trunc +' test_done diff --git a/t/t5323-pack-redundant.sh b/t/t5323-pack-redundant.sh index 8b01793845..8dbbcc5e51 100755 --- a/t/t5323-pack-redundant.sh +++ b/t/t5323-pack-redundant.sh @@ -114,9 +114,9 @@ test_expect_success 'setup main repo' ' create_commits_in "$main_repo" A B C D E F G H I J K L M N O P Q R ' -test_expect_success 'master: pack-redundant works with no packfile' ' +test_expect_success 'main: pack-redundant works with no packfile' ' ( - cd "$master_repo" && + cd "$main_repo" && cat >expect <<-EOF && fatal: Zero packs found! EOF diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index e2c0c51022..672001a18b 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -136,12 +136,12 @@ test_expect_success 'the default remote . should not break explicit pull' ' git reset --hard HEAD^ && echo file >expect && test_cmp expect file && - git pull . second && + git pull --no-rebase . second && echo modified >expect && test_cmp expect file && git reflog -1 >reflog.actual && sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && - echo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected && + echo "OBJID HEAD@{0}: pull --no-rebase . second: Fast-forward" >reflog.expected && test_cmp reflog.expected reflog.fuzzy ' @@ -226,7 +226,7 @@ test_expect_success 'fail if the index has unresolved entries' ' test_commit modified2 file && git ls-files -u >unmerged && test_must_be_empty unmerged && - test_must_fail git pull . second && + test_must_fail git pull --no-rebase . second && git ls-files -u >unmerged && test_file_not_empty unmerged && cp file expected && @@ -409,37 +409,37 @@ test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' ' test_expect_success 'pull succeeds with dirty working directory and merge.autostash set' ' test_config merge.autostash true && - test_pull_autostash 2 + test_pull_autostash 2 --no-rebase ' test_expect_success 'pull --autostash & merge.autostash=true' ' test_config merge.autostash true && - test_pull_autostash 2 --autostash + test_pull_autostash 2 --autostash --no-rebase ' test_expect_success 'pull --autostash & merge.autostash=false' ' test_config merge.autostash false && - test_pull_autostash 2 --autostash + test_pull_autostash 2 --autostash --no-rebase ' test_expect_success 'pull --autostash & merge.autostash unset' ' test_unconfig merge.autostash && - test_pull_autostash 2 --autostash + test_pull_autostash 2 --autostash --no-rebase ' test_expect_success 'pull --no-autostash & merge.autostash=true' ' test_config merge.autostash true && - test_pull_autostash_fail --no-autostash + test_pull_autostash_fail --no-autostash --no-rebase ' test_expect_success 'pull --no-autostash & merge.autostash=false' ' test_config merge.autostash false && - test_pull_autostash_fail --no-autostash + test_pull_autostash_fail --no-autostash --no-rebase ' test_expect_success 'pull --no-autostash & merge.autostash unset' ' test_unconfig merge.autostash && - test_pull_autostash_fail --no-autostash + test_pull_autostash_fail --no-autostash --no-rebase ' test_expect_success 'pull.rebase' ' diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 63a688bdbf..7601c919fd 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -113,7 +113,7 @@ test_expect_success 'git pull --force' ' git pull two && test_commit A && git branch -f origin && - git pull --all --force + git pull --no-rebase --all --force ) ' @@ -179,7 +179,7 @@ test_expect_success 'git pull --allow-unrelated-histories' ' ( cd dst && test_must_fail git pull ../src side && - git pull --allow-unrelated-histories ../src side + git pull --no-rebase --allow-unrelated-histories ../src side ) ' diff --git a/t/t5524-pull-msg.sh b/t/t5524-pull-msg.sh index c278adaa5a..b2be3605f5 100755 --- a/t/t5524-pull-msg.sh +++ b/t/t5524-pull-msg.sh @@ -28,7 +28,7 @@ test_expect_success setup ' test_expect_success pull ' ( cd cloned && - git pull --log && + git pull --no-rebase --log && git log -2 && git cat-file commit HEAD >result && grep Dollar result @@ -41,7 +41,7 @@ test_expect_success '--log=1 limits shortlog length' ' git reset --hard HEAD^ && test "$(cat afile)" = original && test "$(cat bfile)" = added && - git pull --log=1 && + git pull --no-rebase --log=1 && git log -3 && git cat-file commit HEAD >result && grep Dollar result && diff --git a/t/t5553-set-upstream.sh b/t/t5553-set-upstream.sh index b1d614ce18..9c12c0f8c3 100755 --- a/t/t5553-set-upstream.sh +++ b/t/t5553-set-upstream.sh @@ -108,27 +108,27 @@ test_expect_success 'setup commit on main and other pull' ' test_expect_success 'pull --set-upstream upstream main sets branch main but not other' ' clear_config main other && - git pull --set-upstream upstream main && + git pull --no-rebase --set-upstream upstream main && check_config main upstream refs/heads/main && check_config_missing other ' test_expect_success 'pull --set-upstream main:other2 does not set the branch other2' ' clear_config other2 && - git pull --set-upstream upstream main:other2 && + git pull --no-rebase --set-upstream upstream main:other2 && check_config_missing other2 ' test_expect_success 'pull --set-upstream upstream other sets branch main' ' clear_config main other && - git pull --set-upstream upstream other && + git pull --no-rebase --set-upstream upstream other && check_config main upstream refs/heads/other && check_config_missing other ' test_expect_success 'pull --set-upstream upstream tag does not set the tag' ' clear_config three && - git pull --tags --set-upstream upstream three && + git pull --no-rebase --tags --set-upstream upstream three && check_config_missing three ' @@ -144,16 +144,16 @@ test_expect_success 'pull --set-upstream http://nosuchdomain.example.com fails w test_expect_success 'pull --set-upstream upstream HEAD sets branch HEAD' ' clear_config main other && - git pull --set-upstream upstream HEAD && + git pull --no-rebase --set-upstream upstream HEAD && check_config main upstream HEAD && git checkout other && - git pull --set-upstream upstream HEAD && + git pull --no-rebase --set-upstream upstream HEAD && check_config other upstream HEAD ' test_expect_success 'pull --set-upstream upstream with more than one branch does nothing' ' clear_config main three && - git pull --set-upstream upstream main three && + git pull --no-rebase --set-upstream upstream main three && check_config_missing main && check_config_missing three ' diff --git a/t/t5582-fetch-negative-refspec.sh b/t/t5582-fetch-negative-refspec.sh index e5d2e79ad3..7a80e47c2b 100755 --- a/t/t5582-fetch-negative-refspec.sh +++ b/t/t5582-fetch-negative-refspec.sh @@ -105,7 +105,6 @@ test_expect_success "fetch with negative pattern refspec does not expand prefix" ' test_expect_success "fetch with negative refspec avoids duplicate conflict" ' - cd "$D" && ( cd one && git branch dups/a && diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index e845d621f6..24340e6d56 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -87,7 +87,7 @@ test_expect_success 'updating origin' ' ' test_expect_success 'pulling changes from origin' ' - git -C C pull origin + git -C C pull --no-rebase origin ' # the 2 local objects are commit and tree from the merge @@ -96,7 +96,7 @@ test_expect_success 'that alternate to origin gets used' ' ' test_expect_success 'pulling changes from origin' ' - git -C D pull origin + git -C D pull --no-rebase origin ' # the 5 local objects are expected; file3 blob, commit in A to add it diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh index ed0d911e95..51705aa86a 100755 --- a/t/t5607-clone-bundle.sh +++ b/t/t5607-clone-bundle.sh @@ -91,7 +91,8 @@ test_expect_success 'ridiculously long subject in boundary' ' git fetch long-subject-bundle.bdl && - if ! test_have_prereq SHA1 + algo=$(test_oid algo) && + if test "$algo" != sha1 then echo "@object-format=sha256" fi >expect && @@ -100,7 +101,7 @@ test_expect_success 'ridiculously long subject in boundary' ' $(git rev-parse HEAD) HEAD EOF - if test_have_prereq SHA1 + if test "$algo" = sha1 then head -n 3 long-subject-bundle.bdl else diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 78de1ff2ad..d3687b1a2e 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -27,9 +27,9 @@ test_expect_success 'list refs with git:// using protocol v2' ' ls-remote --symref "$GIT_DAEMON_URL/parent" >actual && # Client requested to use protocol v2 - grep "git> .*\\\0\\\0version=2\\\0$" log && + grep "ls-remote> .*\\\0\\\0version=2\\\0$" log && # Server responded using protocol v2 - grep "git< version 2" log && + grep "ls-remote< version 2" log && git ls-remote --symref "$GIT_DAEMON_URL/parent" >expect && test_cmp expect actual @@ -151,7 +151,7 @@ test_expect_success 'list refs with file:// using protocol v2' ' ls-remote --symref "file://$(pwd)/file_parent" >actual && # Server responded using protocol v2 - grep "git< version 2" log && + grep "ls-remote< version 2" log && git ls-remote --symref "file://$(pwd)/file_parent" >expect && test_cmp expect actual diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index e9e471621d..220098523a 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -40,6 +40,30 @@ write_command () { fi } +# Write a complete fetch command to stdout, suitable for use with `test-tool +# pkt-line`. "want-ref", "want", and "have" lines are read from stdin. +# +# Examples: +# +# write_fetch_command <<-EOF +# want-ref refs/heads/main +# have $(git rev-parse a) +# EOF +# +# write_fetch_command <<-EOF +# want $(git rev-parse b) +# have $(git rev-parse a) +# EOF +# +write_fetch_command () { + write_command fetch && + echo "0001" && + echo "no-progress" && + cat && + echo "done" && + echo "0000" +} + # c(o/foo) d(o/bar) # \ / # b e(baz) f(main) @@ -77,15 +101,11 @@ test_expect_success 'config controls ref-in-want advertisement' ' ' test_expect_success 'invalid want-ref line' ' - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/non-existent - done - 0000 EOF + test-tool pkt-line pack <pkt >in && test_must_fail test-tool serve-v2 --stateless-rpc 2>out <in && grep "unknown ref" out ' @@ -97,16 +117,11 @@ test_expect_success 'basic want-ref' ' EOF git rev-parse f >expected_commits && - oid=$(git rev-parse a) && - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/main - have $oid - done - 0000 + have $(git rev-parse a) EOF + test-tool pkt-line pack <pkt >in && test-tool serve-v2 --stateless-rpc >out <in && check_output @@ -121,17 +136,12 @@ test_expect_success 'multiple want-ref lines' ' EOF git rev-parse c d >expected_commits && - oid=$(git rev-parse b) && - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/o/foo want-ref refs/heads/o/bar - have $oid - done - 0000 + have $(git rev-parse b) EOF + test-tool pkt-line pack <pkt >in && test-tool serve-v2 --stateless-rpc >out <in && check_output @@ -144,16 +154,12 @@ test_expect_success 'mix want and want-ref' ' EOF git rev-parse e f >expected_commits && - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/main want $(git rev-parse e) have $(git rev-parse a) - done - 0000 EOF + test-tool pkt-line pack <pkt >in && test-tool serve-v2 --stateless-rpc >out <in && check_output @@ -166,16 +172,11 @@ test_expect_success 'want-ref with ref we already have commit for' ' EOF >expected_commits && - oid=$(git rev-parse c) && - test-tool pkt-line pack >in <<-EOF && - $(write_command fetch) - 0001 - no-progress + write_fetch_command >pkt <<-EOF && want-ref refs/heads/o/foo - have $oid - done - 0000 + have $(git rev-parse c) EOF + test-tool pkt-line pack <pkt >in && test-tool serve-v2 --stateless-rpc >out <in && check_output @@ -298,6 +299,141 @@ test_expect_success 'fetching with wildcard that matches multiple refs' ' grep "want-ref refs/heads/o/bar" log ' +REPO="$(pwd)/repo-ns" + +test_expect_success 'setup namespaced repo' ' + ( + git init -b main "$REPO" && + cd "$REPO" && + test_commit a && + test_commit b && + git checkout a && + test_commit c && + git checkout a && + test_commit d && + git update-ref refs/heads/ns-no b && + git update-ref refs/namespaces/ns/refs/heads/ns-yes c && + git update-ref refs/namespaces/ns/refs/heads/hidden d + ) && + git -C "$REPO" config uploadpack.allowRefInWant true +' + +test_expect_success 'with namespace: want-ref is considered relative to namespace' ' + wanted_ref=refs/heads/ns-yes && + + oid=$(git -C "$REPO" rev-parse "refs/namespaces/ns/$wanted_ref") && + cat >expected_refs <<-EOF && + $oid $wanted_ref + EOF + cat >expected_commits <<-EOF && + $oid + $(git -C "$REPO" rev-parse a) + EOF + + write_fetch_command >pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack <pkt >in && + + GIT_NAMESPACE=ns test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in && + check_output +' + +test_expect_success 'with namespace: want-ref outside namespace is unknown' ' + wanted_ref=refs/heads/ns-no && + + write_fetch_command >pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack <pkt >in && + + test_must_fail env GIT_NAMESPACE=ns \ + test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in && + grep "unknown ref" out +' + +# Cross-check refs/heads/ns-no indeed exists +test_expect_success 'without namespace: want-ref outside namespace succeeds' ' + wanted_ref=refs/heads/ns-no && + + oid=$(git -C "$REPO" rev-parse $wanted_ref) && + cat >expected_refs <<-EOF && + $oid $wanted_ref + EOF + cat >expected_commits <<-EOF && + $oid + $(git -C "$REPO" rev-parse a) + EOF + + write_fetch_command >pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack <pkt >in && + + test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in && + check_output +' + +test_expect_success 'with namespace: hideRefs is matched, relative to namespace' ' + wanted_ref=refs/heads/hidden && + git -C "$REPO" config transfer.hideRefs $wanted_ref && + + write_fetch_command >pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack <pkt >in && + + test_must_fail env GIT_NAMESPACE=ns \ + test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in && + grep "unknown ref" out +' + +# Cross-check refs/heads/hidden indeed exists +test_expect_success 'with namespace: want-ref succeeds if hideRefs is removed' ' + wanted_ref=refs/heads/hidden && + git -C "$REPO" config --unset transfer.hideRefs $wanted_ref && + + oid=$(git -C "$REPO" rev-parse "refs/namespaces/ns/$wanted_ref") && + cat >expected_refs <<-EOF && + $oid $wanted_ref + EOF + cat >expected_commits <<-EOF && + $oid + $(git -C "$REPO" rev-parse a) + EOF + + write_fetch_command >pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack <pkt >in && + + GIT_NAMESPACE=ns test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in && + check_output +' + +test_expect_success 'without namespace: relative hideRefs does not match' ' + wanted_ref=refs/namespaces/ns/refs/heads/hidden && + git -C "$REPO" config transfer.hideRefs refs/heads/hidden && + + oid=$(git -C "$REPO" rev-parse $wanted_ref) && + cat >expected_refs <<-EOF && + $oid $wanted_ref + EOF + cat >expected_commits <<-EOF && + $oid + $(git -C "$REPO" rev-parse a) + EOF + + write_fetch_command >pkt <<-EOF && + want-ref $wanted_ref + EOF + test-tool pkt-line pack <pkt >in && + + test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in && + check_output +' + + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh index f1d189d5bc..eb8c79aafd 100755 --- a/t/t5705-session-id-in-capabilities.sh +++ b/t/t5705-session-id-in-capabilities.sh @@ -73,6 +73,17 @@ do grep \"key\":\"server-sid\" tr2-client-events && grep \"key\":\"client-sid\" tr2-server-events ' + + test_expect_success "client & server log negotiated version (v${PROTO})" ' + test_when_finished "rm -rf local tr2-client-events tr2-server-events" && + cp -r "$LOCAL_PRISTINE" local && + GIT_TRACE2_EVENT="$(pwd)/tr2-client-events" \ + git -c protocol.version=$PROTO -C local fetch \ + --upload-pack "GIT_TRACE2_EVENT=\"$(pwd)/tr2-server-events\" git-upload-pack" \ + origin && + grep \"key\":\"negotiated-version\",\"value\":\"$PROTO\" tr2-client-events && + grep \"key\":\"negotiated-version\",\"value\":\"$PROTO\" tr2-server-events + ' done test_done diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index 12def7bcbf..ef849e5bc8 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -169,4 +169,35 @@ test_expect_success 'rev-list --count --objects' ' test_line_count = $count actual ' +test_expect_success 'rev-list --unsorted-input results in different sorting' ' + git rev-list --unsorted-input HEAD HEAD~ >first && + git rev-list --unsorted-input HEAD~ HEAD >second && + ! test_cmp first second && + sort first >first.sorted && + sort second >second.sorted && + test_cmp first.sorted second.sorted +' + +test_expect_success 'rev-list --unsorted-input incompatible with --no-walk' ' + cat >expect <<-EOF && + fatal: --no-walk is incompatible with --unsorted-input + EOF + test_must_fail git rev-list --unsorted-input --no-walk HEAD 2>error && + test_cmp expect error && + test_must_fail git rev-list --unsorted-input --no-walk=sorted HEAD 2>error && + test_cmp expect error && + test_must_fail git rev-list --unsorted-input --no-walk=unsorted HEAD 2>error && + test_cmp expect error && + + cat >expect <<-EOF && + fatal: --unsorted-input is incompatible with --no-walk + EOF + test_must_fail git rev-list --no-walk --unsorted-input HEAD 2>error && + test_cmp expect error && + test_must_fail git rev-list --no-walk=sorted --unsorted-input HEAD 2>error && + test_cmp expect error && + test_must_fail git rev-list --no-walk=unsorted --unsorted-input HEAD 2>error && + test_cmp expect error +' + test_done diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 0d2e062f79..80679d5e12 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -59,18 +59,25 @@ test_atom() { # Automatically test "contents:size" atom after testing "contents" if test "$2" = "contents" then - case $(git cat-file -t "$ref") in - tag) - # We cannot use $3 as it expects sanitize_pgp to run - expect=$(git cat-file tag $ref | tail -n +6 | wc -c) ;; - tree | blob) - expect='' ;; - commit) - expect=$(printf '%s' "$3" | wc -c) ;; - esac - # Leave $expect unquoted to lose possible leading whitespaces - echo $expect >expected + # for commit leg, $3 is changed there + expect=$(printf '%s' "$3" | wc -c) test_expect_${4:-success} $PREREQ "basic atom: $1 contents:size" ' + type=$(git cat-file -t "$ref") && + case $type in + tag) + # We cannot use $3 as it expects sanitize_pgp to run + git cat-file tag $ref >out && + expect=$(tail -n +6 out | wc -c) && + rm -f out ;; + tree | blob) + expect="" ;; + commit) + : "use the calculated expect" ;; + *) + BUG "unknown object type" ;; + esac && + # Leave $expect unquoted to lose possible leading whitespaces + echo $expect >expected && git for-each-ref --format="%(contents:size)" "$ref" >actual && test_cmp expected actual ' diff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh index 3da2896e3b..3a32b1a45c 100755 --- a/t/t6402-merge-rename.sh +++ b/t/t6402-merge-rename.sh @@ -103,7 +103,7 @@ test_expect_success 'setup' ' test_expect_success 'pull renaming branch into unrenaming one' \ ' git show-branch && - test_expect_code 1 git pull . white && + test_expect_code 1 git pull --no-rebase . white && git ls-files -s && test_stdout_line_count = 3 git ls-files -u B && test_stdout_line_count = 1 git ls-files -s N && @@ -119,7 +119,7 @@ test_expect_success 'pull renaming branch into another renaming one' \ rm -f B && git reset --hard && git checkout red && - test_expect_code 1 git pull . white && + test_expect_code 1 git pull --no-rebase . white && test_stdout_line_count = 3 git ls-files -u B && test_stdout_line_count = 1 git ls-files -s N && sed -ne "/^g/{ @@ -133,7 +133,7 @@ test_expect_success 'pull unrenaming branch into renaming one' \ ' git reset --hard && git show-branch && - test_expect_code 1 git pull . main && + test_expect_code 1 git pull --no-rebase . main && test_stdout_line_count = 3 git ls-files -u B && test_stdout_line_count = 1 git ls-files -s N && sed -ne "/^g/{ @@ -147,7 +147,7 @@ test_expect_success 'pull conflicting renames' \ ' git reset --hard && git show-branch && - test_expect_code 1 git pull . blue && + test_expect_code 1 git pull --no-rebase . blue && test_stdout_line_count = 1 git ls-files -u A && test_stdout_line_count = 1 git ls-files -u B && test_stdout_line_count = 1 git ls-files -u C && @@ -163,7 +163,7 @@ test_expect_success 'interference with untracked working tree file' ' git reset --hard && git show-branch && echo >A this file should not matter && - test_expect_code 1 git pull . white && + test_expect_code 1 git pull --no-rebase . white && test_path_is_file A ' @@ -173,7 +173,7 @@ test_expect_success 'interference with untracked working tree file' ' git show-branch && rm -f A && echo >A this file should not matter && - test_expect_code 1 git pull . red && + test_expect_code 1 git pull --no-rebase . red && test_path_is_file A ' @@ -183,7 +183,7 @@ test_expect_success 'interference with untracked working tree file' ' git checkout -f main && git tag -f anchor && git show-branch && - git pull . yellow && + git pull --no-rebase . yellow && test_path_is_missing M && git reset --hard anchor ' @@ -210,7 +210,7 @@ test_expect_success 'updated working tree file should prevent the merge' ' echo >>M one line addition && cat M >M.saved && git update-index M && - test_expect_code 128 git pull . yellow && + test_expect_code 128 git pull --no-rebase . yellow && test_cmp M M.saved && rm -f M.saved ' @@ -222,7 +222,7 @@ test_expect_success 'interference with untracked working tree file' ' git tag -f anchor && git show-branch && echo >M this file should not matter && - git pull . main && + git pull --no-rebase . main && test_path_is_file M && ! { git ls-files -s | diff --git a/t/t6409-merge-subtree.sh b/t/t6409-merge-subtree.sh index d406b2343c..ba7890ec52 100755 --- a/t/t6409-merge-subtree.sh +++ b/t/t6409-merge-subtree.sh @@ -100,7 +100,7 @@ test_expect_success 'merge update' ' git checkout -b topic_2 && git commit -m "update git-gui" && cd ../git && - git pull -s subtree gui topic_2 && + git pull --no-rebase -s subtree gui topic_2 && git ls-files -s >actual && ( echo "100644 $o3 0 git-gui/git-gui.sh" && @@ -129,7 +129,7 @@ test_expect_success 'initial ambiguous subtree' ' test_expect_success 'merge using explicit' ' cd ../git && git reset --hard topic_2 && - git pull -Xsubtree=git-gui gui topic_2 && + git pull --no-rebase -Xsubtree=git-gui gui topic_2 && git ls-files -s >actual && ( echo "100644 $o3 0 git-gui/git-gui.sh" && @@ -142,7 +142,7 @@ test_expect_success 'merge using explicit' ' test_expect_success 'merge2 using explicit' ' cd ../git && git reset --hard topic_2 && - git pull -Xsubtree=git-gui2 gui topic_2 && + git pull --no-rebase -Xsubtree=git-gui2 gui topic_2 && git ls-files -s >actual && ( echo "100644 $o1 0 git-gui/git-gui.sh" && diff --git a/t/t6417-merge-ours-theirs.sh b/t/t6417-merge-ours-theirs.sh index ac9aee9a66..ec065d6a65 100755 --- a/t/t6417-merge-ours-theirs.sh +++ b/t/t6417-merge-ours-theirs.sh @@ -69,11 +69,11 @@ test_expect_success 'binary file with -Xours/-Xtheirs' ' ' test_expect_success 'pull passes -X to underlying merge' ' - git reset --hard main && git pull -s recursive -Xours . side && - git reset --hard main && git pull -s recursive -X ours . side && - git reset --hard main && git pull -s recursive -Xtheirs . side && - git reset --hard main && git pull -s recursive -X theirs . side && - git reset --hard main && test_must_fail git pull -s recursive -X bork . side + git reset --hard main && git pull --no-rebase -s recursive -Xours . side && + git reset --hard main && git pull --no-rebase -s recursive -X ours . side && + git reset --hard main && git pull --no-rebase -s recursive -Xtheirs . side && + git reset --hard main && git pull --no-rebase -s recursive -X theirs . side && + git reset --hard main && test_must_fail git pull --no-rebase -s recursive -X bork . side ' test_expect_success SYMLINKS 'symlink with -Xours/-Xtheirs' ' diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh index 54c2082acb..8dd0f98812 100755 --- a/t/t7500-commit-template-squash-signoff.sh +++ b/t/t7500-commit-template-squash-signoff.sh @@ -270,7 +270,7 @@ EOF test_expect_success 'commit --fixup provides correct one-line commit message' ' commit_for_rebase_autosquash_setup && - git commit --fixup HEAD~1 && + EDITOR="echo ignored >>" git commit --fixup HEAD~1 && commit_msg_is "fixup! target message subject line" ' @@ -281,6 +281,13 @@ test_expect_success 'commit --fixup -m"something" -m"extra"' ' extra" ' +test_expect_success 'commit --fixup --edit' ' + commit_for_rebase_autosquash_setup && + EDITOR="printf \"something\nextra\" >>" git commit --fixup HEAD~1 --edit && + commit_msg_is "fixup! target message subject linesomething +extra" +' + get_commit_msg () { rev="$1" && git log -1 --pretty=format:"%B" "$rev" diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 52e8ccc933..1f652f433e 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -27,120 +27,324 @@ test_expect_success 'setup' ' git tag c3 ' -test_expect_success 'pull.rebase not set' ' +test_expect_success 'pull.rebase not set, ff possible' ' git reset --hard c0 && git pull . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and pull.ff=true' ' git reset --hard c0 && test_config pull.ff true && git pull . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and pull.ff=false' ' git reset --hard c0 && test_config pull.ff false && git pull . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and pull.ff=only' ' git reset --hard c0 && test_config pull.ff only && git pull . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --rebase given' ' git reset --hard c0 && git pull --rebase . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --no-rebase given' ' git reset --hard c0 && git pull --no-rebase . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --ff given' ' git reset --hard c0 && git pull --ff . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --no-ff given' ' git reset --hard c0 && git pull --no-ff . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --ff-only given' ' git reset --hard c0 && git pull --ff-only . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set (not-fast-forward)' ' git reset --hard c2 && - git -c color.advice=always pull . c1 2>err && + test_must_fail git -c color.advice=always pull . c1 2>err && test_decode_color <err >decoded && test_i18ngrep "<YELLOW>hint: " decoded && - test_i18ngrep "Pulling without specifying how to reconcile" decoded + test_i18ngrep "You have divergent branches" decoded ' test_expect_success 'pull.rebase not set and pull.ff=true (not-fast-forward)' ' git reset --hard c2 && test_config pull.ff true && git pull . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and pull.ff=false (not-fast-forward)' ' git reset --hard c2 && test_config pull.ff false && git pull . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and pull.ff=only (not-fast-forward)' ' git reset --hard c2 && test_config pull.ff only && test_must_fail git pull . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --rebase given (not-fast-forward)' ' git reset --hard c2 && git pull --rebase . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --no-rebase given (not-fast-forward)' ' git reset --hard c2 && git pull --no-rebase . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --ff given (not-fast-forward)' ' git reset --hard c2 && git pull --ff . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --no-ff given (not-fast-forward)' ' git reset --hard c2 && git pull --no-ff . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err ' test_expect_success 'pull.rebase not set and --ff-only given (not-fast-forward)' ' git reset --hard c2 && test_must_fail git pull --ff-only . c1 2>err && - test_i18ngrep ! "Pulling without specifying how to reconcile" err + test_i18ngrep ! "You have divergent branches" err +' + +test_does_rebase () { + git reset --hard c2 && + git "$@" . c1 && + # Check that we actually did a rebase + git rev-list --count HEAD >actual && + git rev-list --merges --count HEAD >>actual && + test_write_lines 3 0 >expect && + test_cmp expect actual && + rm actual expect +} + +# Prefers merge over fast-forward +test_does_merge_when_ff_possible () { + git reset --hard c0 && + git "$@" . c1 && + # Check that we actually did a merge + git rev-list --count HEAD >actual && + git rev-list --merges --count HEAD >>actual && + test_write_lines 3 1 >expect && + test_cmp expect actual && + rm actual expect +} + +# Prefers fast-forward over merge or rebase +test_does_fast_forward () { + git reset --hard c0 && + git "$@" . c1 && + + # Check that we did not get any merges + git rev-list --count HEAD >actual && + git rev-list --merges --count HEAD >>actual && + test_write_lines 2 0 >expect && + test_cmp expect actual && + + # Check that we ended up at c1 + git rev-parse HEAD >actual && + git rev-parse c1^{commit} >expect && + test_cmp actual expect && + + # Remove temporary files + rm actual expect +} + +# Doesn't fail when fast-forward not possible; does a merge +test_falls_back_to_full_merge () { + git reset --hard c2 && + git "$@" . c1 && + # Check that we actually did a merge + git rev-list --count HEAD >actual && + git rev-list --merges --count HEAD >>actual && + test_write_lines 4 1 >expect && + test_cmp expect actual && + rm actual expect +} + +# Attempts fast forward, which is impossible, and bails +test_attempts_fast_forward () { + git reset --hard c2 && + test_must_fail git "$@" . c1 2>err && + test_i18ngrep "Not possible to fast-forward, aborting" err +} + +# +# Group 1: Interaction of --ff-only with --[no-]rebase +# (And related interaction of pull.ff=only with pull.rebase) +# +test_expect_success '--ff-only overrides --rebase' ' + test_attempts_fast_forward pull --rebase --ff-only +' + +test_expect_success '--ff-only overrides --rebase even if first' ' + test_attempts_fast_forward pull --ff-only --rebase +' + +test_expect_success '--ff-only overrides --no-rebase' ' + test_attempts_fast_forward pull --ff-only --no-rebase +' + +test_expect_success 'pull.ff=only overrides pull.rebase=true' ' + test_attempts_fast_forward -c pull.ff=only -c pull.rebase=true pull +' + +test_expect_success 'pull.ff=only overrides pull.rebase=false' ' + test_attempts_fast_forward -c pull.ff=only -c pull.rebase=false pull +' + +# Group 2: --rebase=[!false] overrides --no-ff and --ff +# (And related interaction of pull.rebase=!false and pull.ff=!only) +test_expect_success '--rebase overrides --no-ff' ' + test_does_rebase pull --rebase --no-ff +' + +test_expect_success '--rebase overrides --ff' ' + test_does_rebase pull --rebase --ff +' + +test_expect_success '--rebase fast-forwards when possible' ' + test_does_fast_forward pull --rebase --ff +' + +test_expect_success 'pull.rebase=true overrides pull.ff=false' ' + test_does_rebase -c pull.rebase=true -c pull.ff=false pull +' + +test_expect_success 'pull.rebase=true overrides pull.ff=true' ' + test_does_rebase -c pull.rebase=true -c pull.ff=true pull +' + +# Group 3: command line flags take precedence over config +test_expect_success '--ff-only takes precedence over pull.rebase=true' ' + test_attempts_fast_forward -c pull.rebase=true pull --ff-only +' + +test_expect_success '--ff-only takes precedence over pull.rebase=false' ' + test_attempts_fast_forward -c pull.rebase=false pull --ff-only +' + +test_expect_success '--no-rebase takes precedence over pull.ff=only' ' + test_falls_back_to_full_merge -c pull.ff=only pull --no-rebase +' + +test_expect_success '--rebase takes precedence over pull.ff=only' ' + test_does_rebase -c pull.ff=only pull --rebase +' + +test_expect_success '--rebase overrides pull.ff=true' ' + test_does_rebase -c pull.ff=true pull --rebase +' + +test_expect_success '--rebase overrides pull.ff=false' ' + test_does_rebase -c pull.ff=false pull --rebase +' + +test_expect_success '--rebase overrides pull.ff unset' ' + test_does_rebase pull --rebase +' + +# Group 4: --no-rebase heeds pull.ff=!only or explict --ff or --no-ff + +test_expect_success '--no-rebase works with --no-ff' ' + test_does_merge_when_ff_possible pull --no-rebase --no-ff +' + +test_expect_success '--no-rebase works with --ff' ' + test_does_fast_forward pull --no-rebase --ff +' + +test_expect_success '--no-rebase does ff if pull.ff unset' ' + test_does_fast_forward pull --no-rebase +' + +test_expect_success '--no-rebase heeds pull.ff=true' ' + test_does_fast_forward -c pull.ff=true pull --no-rebase +' + +test_expect_success '--no-rebase heeds pull.ff=false' ' + test_does_merge_when_ff_possible -c pull.ff=false pull --no-rebase +' + +# Group 5: pull.rebase=!false in combination with --no-ff or --ff +test_expect_success 'pull.rebase=true and --no-ff' ' + test_does_rebase -c pull.rebase=true pull --no-ff +' + +test_expect_success 'pull.rebase=true and --ff' ' + test_does_rebase -c pull.rebase=true pull --ff +' + +test_expect_success 'pull.rebase=false and --no-ff' ' + test_does_merge_when_ff_possible -c pull.rebase=false pull --no-ff +' + +test_expect_success 'pull.rebase=false and --ff, ff possible' ' + test_does_fast_forward -c pull.rebase=false pull --ff +' + +test_expect_success 'pull.rebase=false and --ff, ff not possible' ' + test_falls_back_to_full_merge -c pull.rebase=false pull --ff +' + +# End of groupings for conflicting merge vs. rebase flags/options + +test_expect_success 'Multiple heads warns about inability to fast forward' ' + git reset --hard c1 && + test_must_fail git pull . c2 c3 2>err && + test_i18ngrep "You have divergent branches" err +' + +test_expect_success 'Multiple can never be fast forwarded' ' + git reset --hard c0 && + test_must_fail git -c pull.ff=only pull . c1 c2 c3 2>err && + test_i18ngrep ! "You have divergent branches" err && + # In addition to calling out "cannot fast-forward", we very much + # want the "multiple branches" piece to be called out to users. + test_i18ngrep "Cannot fast-forward to multiple branches" err +' + +test_expect_success 'Cannot rebase with multiple heads' ' + git reset --hard c0 && + test_must_fail git -c pull.rebase=true pull . c1 c2 c3 2>err && + test_i18ngrep ! "You have divergent branches" err && + test_i18ngrep "Cannot rebase onto multiple branches." err ' test_expect_success 'merge c1 with c2' ' diff --git a/t/t7603-merge-reduce-heads.sh b/t/t7603-merge-reduce-heads.sh index 98948955ae..27cd94ad6f 100755 --- a/t/t7603-merge-reduce-heads.sh +++ b/t/t7603-merge-reduce-heads.sh @@ -68,7 +68,7 @@ test_expect_success 'merge c1 with c2, c3, c4, c5' ' test_expect_success 'pull c2, c3, c4, c5 into c1' ' git reset --hard c1 && - git pull . c2 c3 c4 c5 && + git pull --no-rebase . c2 c3 c4 c5 && test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && test "$(git rev-parse c1)" = "$(git rev-parse HEAD^1)" && test "$(git rev-parse c2)" = "$(git rev-parse HEAD^2)" && diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 58f46c77e6..fc16ac2258 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -582,6 +582,23 @@ test_expect_success 'start and stop macOS maintenance' ' test_line_count = 0 actual ' +test_expect_success 'use launchctl list to prevent extra work' ' + # ensure we are registered + GIT_TEST_MAINT_SCHEDULER=launchctl:./print-args git maintenance start && + + # do it again on a fresh args file + rm -f args && + GIT_TEST_MAINT_SCHEDULER=launchctl:./print-args git maintenance start && + + ls "$HOME/Library/LaunchAgents" >actual && + cat >expect <<-\EOF && + list org.git-scm.git.hourly + list org.git-scm.git.daily + list org.git-scm.git.weekly + EOF + test_cmp expect args +' + test_expect_success 'start and stop Windows maintenance' ' write_script print-args <<-\EOF && echo $* >>args diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 57fc10e7f8..595cbad372 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -2198,7 +2198,7 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' ' test_expect_success $PREREQ 'test using command name with --sendmail-cmd' ' clean_fake_sendmail && - PATH="$(pwd):$PATH" \ + PATH="$PWD:$PATH" \ git send-email \ --from="Example <nobody@example.com>" \ --to=nobody@example.com \ diff --git a/t/t9002-column.sh b/t/t9002-column.sh index 89983527b6..6d3dbde3fe 100755 --- a/t/t9002-column.sh +++ b/t/t9002-column.sh @@ -42,6 +42,24 @@ EOF test_cmp expected actual ' +test_expect_success '--nl' ' + cat >expected <<\EOF && +oneZ +twoZ +threeZ +fourZ +fiveZ +sixZ +sevenZ +eightZ +nineZ +tenZ +elevenZ +EOF + git column --nl="Z$LF" --mode=plain <lista >actual && + test_cmp expected actual +' + test_expect_success '80 columns' ' cat >expected <<\EOF && one two three four five six seven eight nine ten eleven diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 11573936d5..5decc3b269 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -540,6 +540,15 @@ test_expect_success '__gitcomp - expand/narrow all negative options' ' EOF ' +test_expect_success '__gitcomp - equal skip' ' + test_gitcomp "--option=" "--option=" <<-\EOF && + + EOF + test_gitcomp "option=" "option=" <<-\EOF + + EOF +' + test_expect_success '__gitcomp - doesnt fail because of invalid variable name' ' __gitcomp "$invalid_variable_name" ' @@ -2380,6 +2389,12 @@ test_expect_success 'git clone --config= - value' ' EOF ' +test_expect_success 'options with value' ' + test_completion "git merge -X diff-algorithm=" <<-\EOF + + EOF +' + test_expect_success 'sourcing the completion script clears cached commands' ' __git_compute_all_commands && verbose test -n "$__git_all_commands" && |