diff options
Diffstat (limited to 't')
45 files changed, 1005 insertions, 84 deletions
@@ -334,6 +334,15 @@ that cannot be easily covered by a few specific test cases. These could be enabled by running the test suite with correct GIT_TEST_ environment set. +GIT_TEST_FAIL_PREREQS<non-empty?> fails all prerequisites. This is +useful for discovering issues with the tests where say a later test +implicitly depends on an optional earlier test. + +There's a "FAIL_PREREQS" prerequisite that can be used to test for +whether this mode is active, and e.g. skip some tests that are hard to +refactor to deal with it. The "SYMLINKS" prerequisite is currently +excluded as so much relies on it, but this might change in the future. + GIT_TEST_GETTEXT_POISON=<non-empty?> turns all strings marked for translation into gibberish if non-empty (think "test -n"). Used for spotting those tests that need to be marked with a C_LOCALE_OUTPUT diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index c03054c538..31de7e90f3 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -726,7 +726,7 @@ donthaveit=yes test_expect_success DONTHAVEIT 'unmet prerequisite causes test to be skipped' ' donthaveit=no ' -if test $haveit$donthaveit != yesyes +if test -z "$GIT_TEST_FAIL_PREREQS" -a $haveit$donthaveit != yesyes then say "bug in test framework: prerequisite tags do not work reliably" exit 1 @@ -747,7 +747,7 @@ donthaveiteither=yes test_expect_success DONTHAVEIT,HAVEIT 'unmet prerequisites causes test to be skipped' ' donthaveiteither=no ' -if test $haveit$donthaveit$donthaveiteither != yesyesyes +if test -z "$GIT_TEST_FAIL_PREREQS" -a $haveit$donthaveit$donthaveiteither != yesyesyes then say "bug in test framework: multiple prerequisite tags do not work reliably" exit 1 @@ -763,7 +763,7 @@ test_expect_success !LAZY_TRUE 'missing lazy prereqs skip tests' ' donthavetrue=no ' -if test "$havetrue$donthavetrue" != yesyes +if test -z "$GIT_TEST_FAIL_PREREQS" -a "$havetrue$donthavetrue" != yesyes then say 'bug in test framework: lazy prerequisites do not work' exit 1 @@ -779,7 +779,7 @@ test_expect_success LAZY_FALSE 'missing negative lazy prereqs will skip' ' havefalse=no ' -if test "$nothavefalse$havefalse" != yesyes +if test -z "$GIT_TEST_FAIL_PREREQS" -a "$nothavefalse$havefalse" != yesyes then say 'bug in test framework: negative lazy prerequisites do not work' exit 1 @@ -790,7 +790,7 @@ test_expect_success 'tests clean up after themselves' ' test_when_finished clean=yes ' -if test $clean != yes +if test -z "$GIT_TEST_FAIL_PREREQS" -a $clean != yes then say "bug in test framework: basic cleanup command does not work reliably" exit 1 diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 77a224aafb..0276d14a0b 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -175,7 +175,7 @@ test_expect_success 'reinit' ' test_expect_success 'init with --template' ' mkdir template-source && echo content >template-source/file && - git init --template=../template-source template-custom && + git init --template=template-source template-custom && test_cmp template-source/file template-custom/.git/file ' diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh index dfece751b5..2dc853d1be 100755 --- a/t/t1301-shared-repo.sh +++ b/t/t1301-shared-repo.sh @@ -136,7 +136,7 @@ test_expect_success POSIXPERM 'forced modes' ' ( cd new && umask 002 && - git init --shared=0660 --template=../templates && + git init --shared=0660 --template=templates && >frotz && git add frotz && git commit -a -m initial && @@ -192,7 +192,7 @@ test_expect_success POSIXPERM 're-init respects core.sharedrepository (remote)' umask 0022 && git init --bare --shared=0666 child.git && test_path_is_missing child.git/foo && - git init --bare --template=../templates child.git && + git init --bare --template=templates child.git && echo "-rw-rw-rw-" >expect && test_modebits child.git/foo >actual && test_cmp expect actual @@ -203,7 +203,7 @@ test_expect_success POSIXPERM 'template can set core.sharedrepository' ' umask 0022 && git config core.sharedrepository 0666 && cp .git/config templates/config && - git init --bare --template=../templates child.git && + git init --bare --template=templates child.git && echo "-rw-rw-rw-" >expect && test_modebits child.git/HEAD >actual && test_cmp expect actual diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh index 286bba35d8..e819ba741e 100755 --- a/t/t2400-worktree-add.sh +++ b/t/t2400-worktree-add.sh @@ -570,4 +570,21 @@ test_expect_success '"add" an existing locked but missing worktree' ' git worktree add --force --force --detach gnoo ' +test_expect_success FUNNYNAMES 'sanitize generated worktree name' ' + git worktree add --detach ". weird*..?.lock.lock" && + test -d .git/worktrees/---weird-.- +' + +test_expect_success '"add" should not fail because of another bad worktree' ' + git init add-fail && + ( + cd add-fail && + test_commit first && + mkdir sub && + git worktree add sub/to-be-deleted && + rm -rf sub && + git worktree add second + ) +' + test_done diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index e9d7084d19..411a70b0ce 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -206,18 +206,22 @@ test_expect_success 'git branch -M baz bam should succeed when baz is checked ou git worktree add -f bazdir2 baz && git branch -M baz bam && test $(git -C bazdir rev-parse --abbrev-ref HEAD) = bam && - test $(git -C bazdir2 rev-parse --abbrev-ref HEAD) = bam + test $(git -C bazdir2 rev-parse --abbrev-ref HEAD) = bam && + rm -r bazdir bazdir2 && + git worktree prune ' test_expect_success 'git branch -M baz bam should succeed within a worktree in which baz is checked out' ' git checkout -b baz && - git worktree add -f bazdir3 baz && + git worktree add -f bazdir baz && ( - cd bazdir3 && + cd bazdir && git branch -M baz bam && test $(git rev-parse --abbrev-ref HEAD) = bam ) && - test $(git rev-parse --abbrev-ref HEAD) = bam + test $(git rev-parse --abbrev-ref HEAD) = bam && + rm -r bazdir && + git worktree prune ' test_expect_success 'git branch -M master should work when master is checked out' ' @@ -804,7 +808,9 @@ test_expect_success 'test deleting branch without config' ' test_expect_success 'deleting currently checked out branch fails' ' git worktree add -b my7 my7 && test_must_fail git -C my7 branch -d my7 && - test_must_fail git branch -d my7 + test_must_fail git branch -d my7 && + rm -r my7 && + git worktree prune ' test_expect_success 'test --track without .fetch entries' ' diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index be55148930..71818b90f0 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -136,10 +136,13 @@ test_expect_success 'git branch `--show-current` works properly with worktrees' branch-two EOF git checkout branch-one && - git worktree add worktree branch-two && + test_when_finished " + git worktree remove worktree_dir + " && + git worktree add worktree_dir branch-two && { git branch --show-current && - git -C worktree branch --show-current + git -C worktree_dir branch --show-current } >actual && test_cmp expect actual ' @@ -284,6 +287,24 @@ test_expect_success 'git branch --format option' ' test_i18ncmp expect actual ' +test_expect_success 'worktree colors correct' ' + cat >expect <<-EOF && + * <GREEN>(HEAD detached from fromtag)<RESET> + ambiguous<RESET> + branch-one<RESET> + + <CYAN>branch-two<RESET> + master<RESET> + ref-to-branch<RESET> -> branch-one + ref-to-remote<RESET> -> origin/branch-one + EOF + git worktree add worktree_dir branch-two && + git branch --color >actual.raw && + rm -r worktree_dir && + git worktree prune && + test_decode_color <actual.raw >actual && + test_i18ncmp expect actual +' + test_expect_success "set up color tests" ' echo "<RED>master<RESET>" >expect.color && echo "master" >expect.bare && @@ -308,4 +329,23 @@ test_expect_success '--color overrides auto-color' ' test_cmp expect.color actual ' +test_expect_success 'verbose output lists worktree path' ' + one=$(git rev-parse --short HEAD) && + two=$(git rev-parse --short master) && + cat >expect <<-EOF && + * (HEAD detached from fromtag) $one one + ambiguous $one one + branch-one $two two + + branch-two $one ($(pwd)/worktree_dir) one + master $two two + ref-to-branch $two two + ref-to-remote $two two + EOF + git worktree add worktree_dir branch-two && + git branch -vv >actual && + rm -r worktree_dir && + git worktree prune && + test_i18ncmp expect actual +' + test_done diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 42f147858d..80b23fd326 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -285,7 +285,7 @@ EOF test_cmp From_.msg out ' -test_expect_success 'rebase--am.sh and --show-current-patch' ' +test_expect_success 'rebase --am and --show-current-patch' ' test_create_repo conflict-apply && ( cd conflict-apply && diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index 42ba5b9f09..2315649f43 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -164,6 +164,19 @@ 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 && + ( + set_fake_editor && + FAKE_COMMIT_MESSAGE=edited \ + GIT_SEQUENCE_EDITOR="echo merge -c H G >" \ + git rebase -ir @^ + ) && + echo edited >expected && + git log --pretty=format:%B -1 >actual && + test_cmp expected actual +' + test_expect_success 'with a branch tip that was cherry-picked already' ' git checkout -b already-upstream master && base="$(git rev-parse --verify HEAD)" && diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index b6e2fdbc44..ca7debf1d4 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -36,8 +36,27 @@ test_expect_success setup ' git checkout master && git diff-tree -p C2 | git apply --index && test_tick && - git commit -m "Master accepts moral equivalent of #2" + git commit -m "Master accepts moral equivalent of #2" && + git checkout side && + git checkout -b patchid && + for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >file2 && + for i in 1 2 3 A 4 B C 7 8 9 10 D E F 5 6; do echo "$i"; done >file3 && + for i in 8 9 10; do echo "$i"; done >file && + git add file file2 file3 && + test_tick && + git commit -m "patchid 1" && + for i in 4 A B 7 8 9 10; do echo "$i"; done >file2 && + for i in 8 9 10 5 6; do echo "$i"; done >file3 && + git add file2 file3 && + test_tick && + git commit -m "patchid 2" && + for i in 10 5 6; do echo "$i"; done >file && + git add file && + test_tick && + git commit -m "patchid 3" && + + git checkout master ' test_expect_success "format-patch --ignore-if-in-upstream" ' @@ -738,6 +757,76 @@ test_expect_success 'format-patch --notes --signoff' ' sed "1,/^---$/d" out | grep "test message" ' +test_expect_success 'format-patch notes output control' ' + git notes add -m "notes config message" HEAD && + test_when_finished git notes remove HEAD && + + git format-patch -1 --stdout >out && + ! grep "notes config message" out && + git format-patch -1 --stdout --notes >out && + grep "notes config message" out && + git format-patch -1 --stdout --no-notes >out && + ! grep "notes config message" out && + git format-patch -1 --stdout --notes --no-notes >out && + ! grep "notes config message" out && + git format-patch -1 --stdout --no-notes --notes >out && + grep "notes config message" out && + + test_config format.notes true && + git format-patch -1 --stdout >out && + grep "notes config message" out && + git format-patch -1 --stdout --notes >out && + grep "notes config message" out && + git format-patch -1 --stdout --no-notes >out && + ! grep "notes config message" out && + git format-patch -1 --stdout --notes --no-notes >out && + ! grep "notes config message" out && + git format-patch -1 --stdout --no-notes --notes >out && + grep "notes config message" out +' + +test_expect_success 'format-patch with multiple notes refs' ' + git notes --ref note1 add -m "this is note 1" HEAD && + test_when_finished git notes --ref note1 remove HEAD && + git notes --ref note2 add -m "this is note 2" HEAD && + test_when_finished git notes --ref note2 remove HEAD && + + git format-patch -1 --stdout >out && + ! grep "this is note 1" out && + ! grep "this is note 2" out && + git format-patch -1 --stdout --notes=note1 >out && + grep "this is note 1" out && + ! grep "this is note 2" out && + git format-patch -1 --stdout --notes=note2 >out && + ! grep "this is note 1" out && + grep "this is note 2" out && + git format-patch -1 --stdout --notes=note1 --notes=note2 >out && + grep "this is note 1" out && + grep "this is note 2" out && + + test_config format.notes note1 && + git format-patch -1 --stdout >out && + grep "this is note 1" out && + ! grep "this is note 2" out && + git format-patch -1 --stdout --no-notes >out && + ! grep "this is note 1" out && + ! grep "this is note 2" out && + git format-patch -1 --stdout --notes=note2 >out && + grep "this is note 1" out && + grep "this is note 2" out && + git format-patch -1 --stdout --no-notes --notes=note2 >out && + ! grep "this is note 1" out && + grep "this is note 2" out && + + git config --add format.notes note2 && + git format-patch -1 --stdout >out && + grep "this is note 1" out && + grep "this is note 2" out && + git format-patch -1 --stdout --no-notes >out && + ! grep "this is note 1" out && + ! grep "this is note 2" out +' + echo "fatal: --name-only does not make sense" > expect.name-only echo "fatal: --name-status does not make sense" > expect.name-status echo "fatal: --check does not make sense" > expect.check @@ -1559,7 +1648,7 @@ test_expect_success 'format-patch -o overrides format.outputDirectory' ' ' test_expect_success 'format-patch --base' ' - git checkout side && + git checkout patchid && git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 && git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 && echo >expected && @@ -1568,7 +1657,14 @@ test_expect_success 'format-patch --base' ' echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected && signature >> expected && test_cmp expected actual1 && - test_cmp expected actual2 + test_cmp expected actual2 && + echo >fail && + echo "base-commit: $(git rev-parse HEAD~3)" >>fail && + echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --unstable | awk "{print \$1}")" >>fail && + echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --unstable | awk "{print \$1}")" >>fail && + signature >> fail && + ! test_cmp fail actual1 && + ! test_cmp fail actual2 ' test_expect_success 'format-patch --base errors out when base commit is in revision list' ' diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 22f9f88f0a..9261d6d3a0 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -43,6 +43,7 @@ diffpatterns=" php python ruby + rust tex custom1 custom2 diff --git a/t/t4018/matlab-class-definition b/t/t4018/matlab-class-definition new file mode 100644 index 0000000000..84daedfb4e --- /dev/null +++ b/t/t4018/matlab-class-definition @@ -0,0 +1,5 @@ +classdef RIGHT + properties + ChangeMe + end +end diff --git a/t/t4018/matlab-function b/t/t4018/matlab-function new file mode 100644 index 0000000000..897a9b13ff --- /dev/null +++ b/t/t4018/matlab-function @@ -0,0 +1,4 @@ +function y = RIGHT() +x = 5; +y = ChangeMe + x; +end diff --git a/t/t4018/matlab-octave-section-1 b/t/t4018/matlab-octave-section-1 new file mode 100644 index 0000000000..3bb6c4670e --- /dev/null +++ b/t/t4018/matlab-octave-section-1 @@ -0,0 +1,3 @@ +%%% RIGHT section +# this is octave script +ChangeMe = 1; diff --git a/t/t4018/matlab-octave-section-2 b/t/t4018/matlab-octave-section-2 new file mode 100644 index 0000000000..ab2980f7f2 --- /dev/null +++ b/t/t4018/matlab-octave-section-2 @@ -0,0 +1,3 @@ +## RIGHT section +# this is octave script +ChangeMe = 1; diff --git a/t/t4018/matlab-section b/t/t4018/matlab-section new file mode 100644 index 0000000000..5ea59a5de0 --- /dev/null +++ b/t/t4018/matlab-section @@ -0,0 +1,3 @@ +%% RIGHT section +% this is understood by both matlab and octave +ChangeMe = 1; diff --git a/t/t4018/rust-fn b/t/t4018/rust-fn new file mode 100644 index 0000000000..cbe02155f1 --- /dev/null +++ b/t/t4018/rust-fn @@ -0,0 +1,5 @@ +pub(self) fn RIGHT<T>(x: &[T]) where T: Debug { + let _ = x; + // a comment + let a = ChangeMe; +} diff --git a/t/t4018/rust-impl b/t/t4018/rust-impl new file mode 100644 index 0000000000..09df3cd93b --- /dev/null +++ b/t/t4018/rust-impl @@ -0,0 +1,5 @@ +impl<'a, T: AsRef<[u8]>> std::RIGHT for Git<'a> { + + pub fn ChangeMe(&self) -> () { + } +} diff --git a/t/t4018/rust-struct b/t/t4018/rust-struct new file mode 100644 index 0000000000..76aff1c0d8 --- /dev/null +++ b/t/t4018/rust-struct @@ -0,0 +1,5 @@ +#[derive(Debug)] +pub(super) struct RIGHT<'a> { + name: &'a str, + age: ChangeMe, +} diff --git a/t/t4018/rust-trait b/t/t4018/rust-trait new file mode 100644 index 0000000000..ea397f09ed --- /dev/null +++ b/t/t4018/rust-trait @@ -0,0 +1,5 @@ +unsafe trait RIGHT<T> { + fn len(&self) -> u32; + fn ChangeMe(&self, n: u32) -> T; + fn iter<F>(&self, f: F) where F: Fn(T); +} diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 819c24d10e..c20209324c 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -352,7 +352,7 @@ test_expect_success 'log with grep.patternType configuration and command line' ' test_cmp expect actual ' -test_expect_success 'log with various grep.patternType configurations & command-lines' ' +test_expect_success !FAIL_PREREQS 'log with various grep.patternType configurations & command-lines' ' git init pattern-type && ( cd pattern-type && diff --git a/t/t4257-am-interactive.sh b/t/t4257-am-interactive.sh new file mode 100755 index 0000000000..5344bd248a --- /dev/null +++ b/t/t4257-am-interactive.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +test_description='am --interactive tests' +. ./test-lib.sh + +test_expect_success 'set up patches to apply' ' + test_commit unrelated && + test_commit no-conflict && + test_commit conflict-patch file patch && + git format-patch --stdout -2 >mbox && + + git reset --hard unrelated && + test_commit conflict-master file master base +' + +# Sanity check our setup. +test_expect_success 'applying all patches generates conflict' ' + test_must_fail git am mbox && + echo resolved >file && + git add -u && + git am --resolved +' + +test_expect_success 'interactive am can apply a single patch' ' + git reset --hard base && + # apply the first, but not the second + test_write_lines y n | git am -i mbox && + + echo no-conflict >expect && + git log -1 --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'interactive am can resolve conflict' ' + git reset --hard base && + # apply both; the second one will conflict + test_write_lines y y | test_must_fail git am -i mbox && + echo resolved >file && + git add -u && + # interactive "--resolved" will ask us if we want to apply the result + echo y | git am -i --resolved && + + echo conflict-patch >expect && + git log -1 --format=%s >actual && + test_cmp expect actual && + + echo resolved >expect && + git cat-file blob HEAD:file >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh index fca001eb9b..852dcd913f 100755 --- a/t/t5150-request-pull.sh +++ b/t/t5150-request-pull.sh @@ -246,4 +246,57 @@ test_expect_success 'request-pull ignores OPTIONS_KEEPDASHDASH poison' ' ' +test_expect_success 'request-pull quotes regex metacharacters properly' ' + + rm -fr downstream.git && + git init --bare downstream.git && + ( + cd local && + git checkout initial && + git merge --ff-only master && + git tag -mrelease v2.0 && + git push origin refs/tags/v2.0:refs/tags/v2-0 && + test_must_fail git request-pull initial "$downstream_url" tags/v2.0 \ + 2>../err + ) && + grep "No match for commit .*" err && + grep "Are you sure you pushed" err + +' + +test_expect_success 'pull request with mismatched object' ' + + rm -fr downstream.git && + git init --bare downstream.git && + ( + cd local && + git checkout initial && + git merge --ff-only master && + git push origin HEAD:refs/tags/full && + test_must_fail git request-pull initial "$downstream_url" tags/full \ + 2>../err + ) && + grep "points to a different object" err && + grep "Are you sure you pushed" err + +' + +test_expect_success 'pull request with stale object' ' + + rm -fr downstream.git && + git init --bare downstream.git && + ( + cd local && + git checkout initial && + git merge --ff-only master && + git push origin refs/tags/full && + git tag -f -m"Thirty-one days" full && + test_must_fail git request-pull initial "$downstream_url" tags/full \ + 2>../err + ) && + grep "points to a different object" err && + grep "Are you sure you pushed" err + +' + test_done diff --git a/t/t5200-update-server-info.sh b/t/t5200-update-server-info.sh new file mode 100755 index 0000000000..21a58eecb9 --- /dev/null +++ b/t/t5200-update-server-info.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +test_description='Test git update-server-info' + +. ./test-lib.sh + +test_expect_success 'setup' 'test_commit file' + +test_expect_success 'create info/refs' ' + git update-server-info && + test_path_is_file .git/info/refs +' + +test_expect_success 'modify and store mtime' ' + test-tool chmtime =0 .git/info/refs && + test-tool chmtime --get .git/info/refs >a +' + +test_expect_success 'info/refs is not needlessly overwritten' ' + git update-server-info && + test-tool chmtime --get .git/info/refs >b && + test_cmp a b +' + +test_expect_success 'info/refs can be forced to update' ' + git update-server-info -f && + test-tool chmtime --get .git/info/refs >b && + ! test_cmp a b +' + +test_expect_success 'info/refs updates when changes are made' ' + test-tool chmtime =0 .git/info/refs && + test-tool chmtime --get .git/info/refs >b && + test_cmp a b && + git update-ref refs/heads/foo HEAD && + git update-server-info && + test-tool chmtime --get .git/info/refs >b && + ! test_cmp a b +' + +test_done diff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh index c88df78c0b..75cbfcc392 100755 --- a/t/t5509-fetch-push-namespaces.sh +++ b/t/t5509-fetch-push-namespaces.sh @@ -124,4 +124,32 @@ test_expect_success 'try to update a hidden full ref' ' test_must_fail git -C original push pushee-namespaced master ' +test_expect_success 'set up ambiguous HEAD' ' + git init ambiguous && + ( + cd ambiguous && + git commit --allow-empty -m foo && + git update-ref refs/namespaces/ns/refs/heads/one HEAD && + git update-ref refs/namespaces/ns/refs/heads/two HEAD && + git symbolic-ref refs/namespaces/ns/HEAD \ + refs/namespaces/ns/refs/heads/two + ) +' + +test_expect_success 'clone chooses correct HEAD (v0)' ' + GIT_NAMESPACE=ns git -c protocol.version=0 \ + clone ambiguous ambiguous-v0 && + echo refs/heads/two >expect && + git -C ambiguous-v0 symbolic-ref HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'clone chooses correct HEAD (v2)' ' + GIT_NAMESPACE=ns git -c protocol.version=2 \ + clone ambiguous ambiguous-v2 && + echo refs/heads/two >expect && + git -C ambiguous-v2 symbolic-ref HEAD >actual && + test_cmp expect actual +' + test_done diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index de9d99cf88..37d76808d4 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -630,9 +630,8 @@ test_expect_success CASE_INSENSITIVE_FS 'colliding file detection' ' test_i18ngrep "the following paths have collided" icasefs/warning ' -partial_clone () { +partial_clone_server () { SERVER="$1" && - URL="$2" && rm -rf "$SERVER" client && test_create_repo "$SERVER" && @@ -642,8 +641,14 @@ partial_clone () { test_commit -C "$SERVER" two && HASH2=$(git hash-object "$SERVER/two.t") && test_config -C "$SERVER" uploadpack.allowfilter 1 && - test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 && + test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 +} +partial_clone () { + SERVER="$1" && + URL="$2" && + + partial_clone_server "${SERVER}" && git clone --filter=blob:limit=0 "$URL" client && git -C client fsck && @@ -660,6 +665,11 @@ test_expect_success 'partial clone' ' partial_clone server "file://$(pwd)/server" ' +test_expect_success 'partial clone with -o' ' + partial_clone_server server && + git clone -o blah --filter=blob:limit=0 "file://$(pwd)/server" client +' + test_expect_success 'partial clone: warn if server does not support object filtering' ' rm -rf server client && test_create_repo server && diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh index cf39e9e243..2a0fb15cf1 100755 --- a/t/t5607-clone-bundle.sh +++ b/t/t5607-clone-bundle.sh @@ -14,6 +14,12 @@ test_expect_success 'setup' ' git tag -d third ' +test_expect_success '"verify" needs a worktree' ' + git bundle create tip.bundle -1 master && + test_must_fail nongit git bundle verify ../tip.bundle 2>err && + test_i18ngrep "need a repository" err +' + test_expect_success 'annotated tags can be excluded by rev-list options' ' git bundle create bundle --all --since=7.Apr.2005.15:14:00.-0700 && git ls-remote bundle > output && diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 9a8f9886b3..b91ef548f8 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -244,11 +244,25 @@ test_expect_success 'fetch what is specified on CLI even if already promised' ' . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd -# Converts bytes into a form suitable for inclusion in a sed command. For -# example, "printf 'ab\r\n' | hex_unpack" results in '\x61\x62\x0d\x0a'. -sed_escape () { - perl -e '$/ = undef; $input = <>; print unpack("H2" x length($input), $input)' | - sed 's/\(..\)/\\x\1/g' +# Converts bytes into their hexadecimal representation. For example, +# "printf 'ab\r\n' | hex_unpack" results in '61620d0a'. +hex_unpack () { + perl -e '$/ = undef; $input = <>; print unpack("H2" x length($input), $input)' +} + +# Inserts $1 at the start of the string and every 2 characters thereafter. +intersperse () { + sed 's/\(..\)/'$1'\1/g' +} + +# Create a one-time-sed command to replace the existing packfile with $1. +replace_packfile () { + # The protocol requires that the packfile be sent in sideband 1, hence + # the extra \x01 byte at the beginning. + printf "1,/packfile/!c %04x\\\\x01%s0000" \ + "$(($(wc -c <$1) + 5))" \ + "$(hex_unpack <$1 | intersperse '\\x')" \ + >"$HTTPD_ROOT_PATH/one-time-sed" } test_expect_success 'upon cloning, check that all refs point to objects' ' @@ -270,10 +284,7 @@ test_expect_success 'upon cloning, check that all refs point to objects' ' # Replace the existing packfile with the crafted one. The protocol # requires that the packfile be sent in sideband 1, hence the extra # \x01 byte at the beginning. - printf "1,/packfile/!c %04x\\\\x01%s0000" \ - "$(($(wc -c <incomplete.pack) + 5))" \ - "$(sed_escape <incomplete.pack)" \ - >"$HTTPD_ROOT_PATH/one-time-sed" && + replace_packfile incomplete.pack && # Use protocol v2 because the sed command looks for the "packfile" # section header. @@ -313,10 +324,7 @@ test_expect_success 'when partial cloning, tolerate server not sending target of # Replace the existing packfile with the crafted one. The protocol # requires that the packfile be sent in sideband 1, hence the extra # \x01 byte at the beginning. - printf "1,/packfile/!c %04x\\\\x01%s0000" \ - "$(($(wc -c <incomplete.pack) + 5))" \ - "$(sed_escape <incomplete.pack)" \ - >"$HTTPD_ROOT_PATH/one-time-sed" && + replace_packfile incomplete.pack && # Use protocol v2 because the sed command looks for the "packfile" # section header. @@ -331,4 +339,82 @@ test_expect_success 'when partial cloning, tolerate server not sending target of ! test -e "$HTTPD_ROOT_PATH/one-time-sed" ' +test_expect_success 'tolerate server sending REF_DELTA against missing promisor objects' ' + SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" && + rm -rf "$SERVER" repo && + test_create_repo "$SERVER" && + test_config -C "$SERVER" uploadpack.allowfilter 1 && + test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 && + + # Create a commit with 2 blobs to be used as delta bases. + for i in $(test_seq 10) + do + echo "this is a line" >>"$SERVER/foo.txt" && + echo "this is another line" >>"$SERVER/have.txt" + done && + git -C "$SERVER" add foo.txt have.txt && + git -C "$SERVER" commit -m bar && + git -C "$SERVER" rev-parse HEAD:foo.txt >deltabase_missing && + git -C "$SERVER" rev-parse HEAD:have.txt >deltabase_have && + + # Clone. The client has deltabase_have but not deltabase_missing. + git -c protocol.version=2 clone --no-checkout \ + --filter=blob:none $HTTPD_URL/one_time_sed/server repo && + git -C repo hash-object -w -- "$SERVER/have.txt" && + + # Sanity check to ensure that the client does not have + # deltabase_missing. + git -C repo rev-list --objects --ignore-missing \ + -- $(cat deltabase_missing) >objlist && + test_line_count = 0 objlist && + + # Another commit. This commit will be fetched by the client. + echo "abcdefghijklmnopqrstuvwxyz" >>"$SERVER/foo.txt" && + echo "abcdefghijklmnopqrstuvwxyz" >>"$SERVER/have.txt" && + git -C "$SERVER" add foo.txt have.txt && + git -C "$SERVER" commit -m baz && + + # Pack a thin pack containing, among other things, HEAD:foo.txt + # delta-ed against HEAD^:foo.txt and HEAD:have.txt delta-ed against + # HEAD^:have.txt. + printf "%s\n--not\n%s\n" \ + $(git -C "$SERVER" rev-parse HEAD) \ + $(git -C "$SERVER" rev-parse HEAD^) | + git -C "$SERVER" pack-objects --thin --stdout >thin.pack && + + # Ensure that the pack contains one delta against HEAD^:foo.txt. Since + # the delta contains at least 26 novel characters, the size cannot be + # contained in 4 bits, so the object header will take up 2 bytes. The + # most significant nybble of the first byte is 0b1111 (0b1 to indicate + # that the header continues, and 0b111 to indicate REF_DELTA), followed + # by any 3 nybbles, then the OID of the delta base. + printf "f.,..%s" $(intersperse "," <deltabase_missing) >want && + hex_unpack <thin.pack | intersperse "," >have && + grep $(cat want) have && + + # Ensure that the pack contains one delta against HEAD^:have.txt, + # similar to the above. + printf "f.,..%s" $(intersperse "," <deltabase_have) >want && + hex_unpack <thin.pack | intersperse "," >have && + grep $(cat want) have && + + replace_packfile thin.pack && + + # Use protocol v2 because the sed command looks for the "packfile" + # section header. + test_config -C "$SERVER" protocol.version 2 && + + # Fetch the thin pack and ensure that index-pack is able to handle the + # REF_DELTA object with a missing promisor delta base. + GIT_TRACE_PACKET="$(pwd)/trace" git -C repo -c protocol.version=2 fetch && + + # Ensure that the missing delta base was directly fetched, but not the + # one that the client has. + grep "want $(cat deltabase_missing)" trace && + ! grep "want $(cat deltabase_have)" trace && + + # Ensure that the one-time-sed script was used. + ! test -e "$HTTPD_ROOT_PATH/one-time-sed" +' + test_done diff --git a/t/t5617-clone-submodules-remote.sh b/t/t5617-clone-submodules-remote.sh new file mode 100755 index 0000000000..37fcce9c40 --- /dev/null +++ b/t/t5617-clone-submodules-remote.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +test_description='Test cloning repos with submodules using remote-tracking branches' + +. ./test-lib.sh + +pwd=$(pwd) + +test_expect_success 'setup' ' + git checkout -b master && + test_commit commit1 && + mkdir sub && + ( + cd sub && + git init && + test_commit subcommit1 && + git tag sub_when_added_to_super + ) && + git submodule add "file://$pwd/sub" sub && + git commit -m "add submodule" && + ( + cd sub && + test_commit subcommit2 + ) +' + +test_expect_success 'clone with --no-remote-submodules' ' + test_when_finished "rm -rf super_clone" && + git clone --recurse-submodules --no-remote-submodules "file://$pwd/." super_clone && + ( + cd super_clone/sub && + git diff --exit-code sub_when_added_to_super + ) +' + +test_expect_success 'clone with --remote-submodules' ' + test_when_finished "rm -rf super_clone" && + git clone --recurse-submodules --remote-submodules "file://$pwd/." super_clone && + ( + cd super_clone/sub && + git diff --exit-code remotes/origin/master + ) +' + +test_expect_success 'check the default is --no-remote-submodules' ' + test_when_finished "rm -rf super_clone" && + git clone --recurse-submodules "file://$pwd/." super_clone && + ( + cd super_clone/sub && + git diff --exit-code sub_when_added_to_super + ) +' + +test_done diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index d04f8007e0..2d6c4a281e 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -126,7 +126,7 @@ test_expect_success 'forced push' ' ' test_expect_success 'cloning without refspec' ' - GIT_REMOTE_TESTGIT_REFSPEC="" \ + GIT_REMOTE_TESTGIT_NOREFSPEC=1 \ git clone "testgit::${PWD}/server" local2 2>error && test_i18ngrep "this remote helper should implement refspec capability" error && compare_refs local2 HEAD server HEAD @@ -135,7 +135,7 @@ test_expect_success 'cloning without refspec' ' test_expect_success 'pulling without refspecs' ' (cd local2 && git reset --hard && - GIT_REMOTE_TESTGIT_REFSPEC="" git pull 2>../error) && + GIT_REMOTE_TESTGIT_NOREFSPEC=1 git pull 2>../error) && test_i18ngrep "this remote helper should implement refspec capability" error && compare_refs local2 HEAD server HEAD ' @@ -145,8 +145,8 @@ test_expect_success 'pushing without refspecs' ' (cd local2 && echo content >>file && git commit -a -m ten && - GIT_REMOTE_TESTGIT_REFSPEC="" && - export GIT_REMOTE_TESTGIT_REFSPEC && + GIT_REMOTE_TESTGIT_NOREFSPEC=1 && + export GIT_REMOTE_TESTGIT_NOREFSPEC && test_must_fail git push 2>../error) && test_i18ngrep "remote-helper doesn.t support push; refspec needed" error ' @@ -303,4 +303,14 @@ test_expect_success 'fetch url' ' compare_refs server HEAD local FETCH_HEAD ' +test_expect_success 'fetch tag' ' + (cd server && + git tag v1.0 + ) && + (cd local && + git fetch + ) && + compare_refs local v1.0 server v1.0 +' + test_done diff --git a/t/t5801/git-remote-testgit b/t/t5801/git-remote-testgit index 752c763eb6..6b9f0b5dc7 100755 --- a/t/t5801/git-remote-testgit +++ b/t/t5801/git-remote-testgit @@ -11,13 +11,15 @@ fi url=$2 dir="$GIT_DIR/testgit/$alias" -prefix="refs/testgit/$alias" -default_refspec="refs/heads/*:${prefix}/heads/*" +h_refspec="refs/heads/*:refs/testgit/$alias/heads/*" +t_refspec="refs/tags/*:refs/testgit/$alias/tags/*" -refspec="${GIT_REMOTE_TESTGIT_REFSPEC-$default_refspec}" - -test -z "$refspec" && prefix="refs" +if test -n "$GIT_REMOTE_TESTGIT_NOREFSPEC" +then + h_refspec="" + t_refspec="" +fi GIT_DIR="$url/.git" export GIT_DIR @@ -40,7 +42,8 @@ do capabilities) echo 'import' echo 'export' - test -n "$refspec" && echo "refspec $refspec" + test -n "$h_refspec" && echo "refspec $h_refspec" + test -n "$t_refspec" && echo "refspec $t_refspec" if test -n "$gitmarks" then echo "*import-marks $gitmarks" @@ -52,7 +55,7 @@ do echo ;; list) - git for-each-ref --format='? %(refname)' 'refs/heads/' + git for-each-ref --format='? %(refname)' 'refs/heads/' 'refs/tags/' head=$(git symbolic-ref HEAD) echo "@$head HEAD" echo @@ -81,10 +84,11 @@ do echo "feature done" git fast-export \ + ${h_refspec:+"--refspec=$h_refspec"} \ + ${t_refspec:+"--refspec=$t_refspec"} \ ${testgitmarks:+"--import-marks=$testgitmarks"} \ ${testgitmarks:+"--export-marks=$testgitmarks"} \ - $refs | - sed -e "s#refs/heads/#${prefix}/heads/#g" + $refs echo "done" ;; export) diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh index 09dfa8bd92..c5b57f40c3 100755 --- a/t/t6042-merge-rename-corner-cases.sh +++ b/t/t6042-merge-rename-corner-cases.sh @@ -411,6 +411,122 @@ test_expect_success 'disappearing dir in rename/directory conflict handled' ' ) ' +# Test for basic rename/add-dest conflict, with rename needing content merge: +# Commit O: a +# Commit A: rename a->b, modifying b too +# Commit B: modify a, add different b + +test_expect_success 'setup rename-with-content-merge vs. add' ' + test_create_repo rename-with-content-merge-and-add && + ( + cd rename-with-content-merge-and-add && + + test_seq 1 5 >a && + git add a && + git commit -m O && + git tag O && + + git checkout -b A O && + git mv a b && + test_seq 0 5 >b && + git add b && + git commit -m A && + + git checkout -b B O && + echo 6 >>a && + echo hello world >b && + git add a b && + git commit -m B + ) +' + +test_expect_success 'handle rename-with-content-merge vs. add' ' + ( + cd rename-with-content-merge-and-add && + + git checkout A^0 && + + test_must_fail git merge -s recursive B^0 >out && + test_i18ngrep "CONFLICT (rename/add)" out && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + # Also, make sure both unmerged entries are for "b" + git ls-files -u b >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out && + + test_path_is_missing a && + test_path_is_file b && + + test_seq 0 6 >tmp && + git hash-object tmp >expect && + git rev-parse B:b >>expect && + git rev-parse >actual \ + :2:b :3:b && + test_cmp expect actual && + + # Test that the two-way merge in b is as expected + git cat-file -p :2:b >>ours && + git cat-file -p :3:b >>theirs && + >empty && + test_must_fail git merge-file \ + -L "HEAD" \ + -L "" \ + -L "B^0" \ + ours empty theirs && + test_cmp ours b + ) +' + +test_expect_success 'handle rename-with-content-merge vs. add, merge other way' ' + ( + cd rename-with-content-merge-and-add && + + git reset --hard && + git clean -fdx && + + git checkout B^0 && + + test_must_fail git merge -s recursive A^0 >out && + test_i18ngrep "CONFLICT (rename/add)" out && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + # Also, make sure both unmerged entries are for "b" + git ls-files -u b >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out && + + test_path_is_missing a && + test_path_is_file b && + + test_seq 0 6 >tmp && + git rev-parse B:b >expect && + git hash-object tmp >>expect && + git rev-parse >actual \ + :2:b :3:b && + test_cmp expect actual && + + # Test that the two-way merge in b is as expected + git cat-file -p :2:b >>ours && + git cat-file -p :3:b >>theirs && + >empty && + test_must_fail git merge-file \ + -L "HEAD" \ + -L "" \ + -L "A^0" \ + ours empty theirs && + test_cmp ours b + ) +' + # Test for all kinds of things that can go wrong with rename/rename (2to1): # Commit A: new files: a & b # Commit B: rename a->c, modify b diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index fc067ed672..35408d53fd 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -441,4 +441,17 @@ test_expect_success '--merged is incompatible with --no-merged' ' test_must_fail git for-each-ref --merged HEAD --no-merged HEAD ' +test_expect_success 'validate worktree atom' ' + cat >expect <<-EOF && + master: $(pwd) + master_worktree: $(pwd)/worktree_dir + side: not checked out + EOF + git worktree add -b master_worktree worktree_dir master && + git for-each-ref --format="%(refname:short): %(if)%(worktreepath)%(then)%(worktreepath)%(else)not checked out%(end)" refs/heads/ >actual && + rm -r worktree_dir && + git worktree prune && + test_cmp expect actual +' + test_done diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index 515c6735e9..c0f04dc6b0 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -71,6 +71,8 @@ test_expect_success 'gc --keep-largest-pack' ' git gc --keep-largest-pack && ( cd .git/objects/pack && ls *.pack ) >pack-list && test_line_count = 2 pack-list && + awk "/^P /{print \$2}" <.git/objects/info/packs >pack-info && + test_line_count = 2 pack-info && test_path_is_file $BASE_PACK && git fsck ) diff --git a/t/t7405-submodule-merge.sh b/t/t7405-submodule-merge.sh index 7855bd8648..aa33978ed2 100755 --- a/t/t7405-submodule-merge.sh +++ b/t/t7405-submodule-merge.sh @@ -417,7 +417,7 @@ test_expect_failure 'directory/submodule conflict; keep submodule clean' ' ) ' -test_expect_failure 'directory/submodule conflict; should not treat submodule files as untracked or in the way' ' +test_expect_failure !FAIL_PREREQS 'directory/submodule conflict; should not treat submodule files as untracked or in the way' ' test_when_finished "git -C directory-submodule/path reset --hard" && test_when_finished "git -C directory-submodule reset --hard" && ( diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 7f9c68cbe7..132608879a 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -570,6 +570,12 @@ test_expect_success 'combining --squash and --no-ff is refused' ' test_must_fail git merge --no-ff --squash c1 ' +test_expect_success 'combining --squash and --commit is refused' ' + git reset --hard c0 && + test_must_fail git merge --squash --commit c1 && + test_must_fail git merge --commit --squash c1 +' + test_expect_success 'option --ff-only overwrites --no-ff' ' git merge --no-ff --ff-only c1 && test_must_fail git merge --no-ff --ff-only c2 @@ -867,4 +873,50 @@ test_expect_success EXECKEEPSPID 'killed merge can be completed with --continue' verify_parents $c0 $c1 ' +test_expect_success 'merge --quit' ' + git init merge-quit && + ( + cd merge-quit && + test_commit base && + echo one >>base.t && + git commit -am one && + git branch one && + git checkout base && + echo two >>base.t && + git commit -am two && + test_must_fail git -c rerere.enabled=true merge one && + test_path_is_file .git/MERGE_HEAD && + test_path_is_file .git/MERGE_MODE && + test_path_is_file .git/MERGE_MSG && + git rerere status >rerere.before && + git merge --quit && + test_path_is_missing .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_MODE && + test_path_is_missing .git/MERGE_MSG && + git rerere status >rerere.after && + test_must_be_empty rerere.after && + ! test_cmp rerere.after rerere.before + ) +' + +test_expect_success 'merge suggests matching remote refname' ' + git commit --allow-empty -m not-local && + git update-ref refs/remotes/origin/not-local HEAD && + git reset --hard HEAD^ && + + # This is white-box testing hackery; we happen to know + # that reading packed refs is more picky about the memory + # ownership of strings we pass to for_each_ref() callbacks. + git pack-refs --all --prune && + + test_must_fail git merge not-local 2>stderr && + grep origin/not-local stderr +' + +test_expect_success 'suggested names are not ambiguous' ' + git update-ref refs/heads/origin/not-local HEAD && + test_must_fail git merge not-local 2>stderr && + grep remotes/origin/not-local stderr +' + test_done diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 2e1bb61b41..7d7b396c23 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -412,7 +412,7 @@ do test_cmp expected actual ' - test_expect_success !PCRE "grep $L with grep.patterntype=perl errors without PCRE" ' + test_expect_success !FAIL_PREREQS,!PCRE "grep $L with grep.patterntype=perl errors without PCRE" ' test_must_fail git -c grep.patterntype=perl grep "foo.*bar" ' @@ -1234,7 +1234,7 @@ test_expect_success PCRE 'grep --perl-regexp pattern' ' test_cmp expected actual ' -test_expect_success !PCRE 'grep --perl-regexp pattern errors without PCRE' ' +test_expect_success !FAIL_PREREQS,!PCRE 'grep --perl-regexp pattern errors without PCRE' ' test_must_fail git grep --perl-regexp "foo.*bar" ' @@ -1249,7 +1249,7 @@ test_expect_success LIBPCRE2 "grep -P with (*NO_JIT) doesn't error out" ' ' -test_expect_success !PCRE 'grep -P pattern errors without PCRE' ' +test_expect_success !FAIL_PREREQS,!PCRE 'grep -P pattern errors without PCRE' ' test_must_fail git grep -P "foo.*bar" ' diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 1e3ac3c384..997f90b42b 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1204,7 +1204,7 @@ test_expect_success $PREREQ 'no in-reply-to and no threading' ' --from="Example <nobody@example.com>" \ --to=nobody@example.com \ --no-thread \ - $patches $patches >stdout && + $patches >stdout && ! grep "In-Reply-To: " stdout ' @@ -1224,17 +1224,72 @@ test_expect_success $PREREQ 'sendemail.to works' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ - $patches $patches >stdout && + $patches >stdout && grep "To: Somebody <somebody@ex.com>" stdout ' +test_expect_success $PREREQ 'setup sendemail.identity' ' + git config --replace-all sendemail.to "default@example.com" && + git config --replace-all sendemail.isp.to "isp@example.com" && + git config --replace-all sendemail.cloud.to "cloud@example.com" +' + +test_expect_success $PREREQ 'sendemail.identity: reads the correct identity config' ' + git -c sendemail.identity=cloud send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout +' + +test_expect_success $PREREQ 'sendemail.identity: identity overrides sendemail.identity' ' + git -c sendemail.identity=cloud send-email \ + --identity=isp \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: isp@example.com" stdout +' + +test_expect_success $PREREQ 'sendemail.identity: --no-identity clears previous identity' ' + git -c sendemail.identity=cloud send-email \ + --no-identity \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: default@example.com" stdout +' + +test_expect_success $PREREQ 'sendemail.identity: bool identity variable existance overrides' ' + git -c sendemail.identity=cloud \ + -c sendemail.xmailer=true \ + -c sendemail.cloud.xmailer=false \ + send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout && + ! grep "X-Mailer" stdout +' + +test_expect_success $PREREQ 'sendemail.identity: bool variable fallback' ' + git -c sendemail.identity=cloud \ + -c sendemail.xmailer=false \ + send-email \ + --dry-run \ + --from="nobody@example.com" \ + $patches >stdout && + grep "To: cloud@example.com" stdout && + ! grep "X-Mailer" stdout +' + test_expect_success $PREREQ '--no-to overrides sendemail.to' ' git send-email \ --dry-run \ --from="Example <nobody@example.com>" \ --no-to \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "To: nobody@example.com" stdout && ! grep "To: Somebody <somebody@ex.com>" stdout ' @@ -1245,7 +1300,7 @@ test_expect_success $PREREQ 'sendemail.cc works' ' --dry-run \ --from="Example <nobody@example.com>" \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "Cc: Somebody <somebody@ex.com>" stdout ' @@ -1256,7 +1311,7 @@ test_expect_success $PREREQ '--no-cc overrides sendemail.cc' ' --no-cc \ --cc=bodies@example.com \ --to=nobody@example.com \ - $patches $patches >stdout && + $patches >stdout && grep "Cc: bodies@example.com" stdout && ! grep "Cc: Somebody <somebody@ex.com>" stdout ' @@ -1268,7 +1323,7 @@ test_expect_success $PREREQ 'sendemail.bcc works' ' --from="Example <nobody@example.com>" \ --to=nobody@example.com \ --smtp-server relay.example.com \ - $patches $patches >stdout && + $patches >stdout && grep "RCPT TO:<other@ex.com>" stdout ' @@ -1280,7 +1335,7 @@ test_expect_success $PREREQ '--no-bcc overrides sendemail.bcc' ' --bcc=bodies@example.com \ --to=nobody@example.com \ --smtp-server relay.example.com \ - $patches $patches >stdout && + $patches >stdout && grep "RCPT TO:<bodies@example.com>" stdout && ! grep "RCPT TO:<other@ex.com>" stdout ' @@ -1437,10 +1492,10 @@ test_expect_success $PREREQ 'setup expect' ' EOF ' -test_expect_success $PREREQ 'sendemail.transferencoding=7bit fails on 8bit data' ' +test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' ' clean_fake_sendmail && - git config sendemail.transferEncoding 7bit && - test_must_fail git send-email \ + test_must_fail git -c sendemail.transferEncoding=8bit \ + send-email \ --transfer-encoding=7bit \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ @@ -1449,11 +1504,10 @@ test_expect_success $PREREQ 'sendemail.transferencoding=7bit fails on 8bit data' test -z "$(ls msgtxt*)" ' -test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEncoding' ' +test_expect_success $PREREQ 'sendemail.transferEncoding via config' ' clean_fake_sendmail && - git config sendemail.transferEncoding 8bit && - test_must_fail git send-email \ - --transfer-encoding=7bit \ + test_must_fail git -c sendemail.transferEncoding=7bit \ + send-email \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ 2>errors >out && @@ -1461,16 +1515,15 @@ test_expect_success $PREREQ '--transfer-encoding overrides sendemail.transferEnc test -z "$(ls msgtxt*)" ' -test_expect_success $PREREQ 'sendemail.transferencoding=8bit' ' +test_expect_success $PREREQ 'sendemail.transferEncoding via cli' ' clean_fake_sendmail && - git send-email \ - --transfer-encoding=8bit \ + test_must_fail git send-email \ + --transfer-encoding=7bit \ --smtp-server="$(pwd)/fake.sendmail" \ email-using-8bit \ 2>errors >out && - sed '1,/^$/d' msgtxt1 >actual && - sed '1,/^$/d' email-using-8bit >expected && - test_cmp expected actual + grep "cannot send message as 7bit" errors && + test -z "$(ls msgtxt*)" ' test_expect_success $PREREQ 'setup expect' ' @@ -1787,6 +1840,15 @@ test_expect_success '--dump-aliases must be used alone' ' test_must_fail git send-email --dump-aliases --to=janice@example.com -1 refs/heads/accounting ' +test_expect_success $PREREQ 'aliases and sendemail.identity' ' + test_must_fail git \ + -c sendemail.identity=cloud \ + -c sendemail.aliasesfile=default-aliases \ + -c sendemail.cloud.aliasesfile=cloud-aliases \ + send-email -1 2>stderr && + test_i18ngrep "cloud-aliases" stderr +' + test_sendmail_aliases () { msg="$1" && shift && expect="$@" && diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 3668263c40..141b7fa35e 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -3299,4 +3299,24 @@ test_expect_success !MINGW 'W: get-mark & empty orphan commit with erroneous thi sed -e s/LFs/LLL/ W-input | tr L "\n" | test_must_fail git fast-import ' +### +### series X (other new features) +### + +test_expect_success 'X: handling encoding' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/encoding + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + encoding iso-8859-7 + data <<COMMIT + INPUT_END + + printf "Pi: \360\nCOMMIT\n" >>input && + + git fast-import <input && + git cat-file -p encoding | grep $(printf "\360") && + git log -1 --format=%B encoding | grep $(printf "\317\200") +' + test_done diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 5690fe2810..b4004e05c2 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -94,22 +94,83 @@ test_expect_success 'fast-export --show-original-ids | git fast-import' ' test $MUSS = $(git rev-parse --verify refs/tags/muss) ' -test_expect_success 'iso-8859-1' ' +test_expect_success 'reencoding iso-8859-7' ' - git config i18n.commitencoding ISO8859-1 && - # use author and committer name in ISO-8859-1 to match it. - . "$TEST_DIRECTORY"/t3901/8859-1.txt && + test_when_finished "git reset --hard HEAD~1" && + test_config i18n.commitencoding iso-8859-7 && test_tick && echo rosten >file && - git commit -s -m den file && - git fast-export wer^..wer >iso8859-1.fi && - sed "s/wer/i18n/" iso8859-1.fi | + git commit -s -F "$TEST_DIRECTORY/t9350/simple-iso-8859-7-commit-message.txt" file && + git fast-export --reencode=yes wer^..wer >iso-8859-7.fi && + sed "s/wer/i18n/" iso-8859-7.fi | (cd new && git fast-import && + # The commit object, if not re-encoded, would be 240 bytes. + # Removing the "encoding iso-8859-7\n" header drops 20 bytes. + # Re-encoding the Pi character from \xF0 (\360) in iso-8859-7 + # to \xCF\x80 (\317\200) in UTF-8 adds a byte. Check for + # the expected size. + test 221 -eq "$(git cat-file -s i18n)" && + # ...and for the expected translation of bytes. git cat-file commit i18n >actual && - grep "Áéí óú" actual) + grep $(printf "\317\200") actual && + # Also make sure the commit does not have the "encoding" header + ! grep ^encoding actual) +' + +test_expect_success 'aborting on iso-8859-7' ' + test_when_finished "git reset --hard HEAD~1" && + test_config i18n.commitencoding iso-8859-7 && + echo rosten >file && + git commit -s -F "$TEST_DIRECTORY/t9350/simple-iso-8859-7-commit-message.txt" file && + test_must_fail git fast-export --reencode=abort wer^..wer >iso-8859-7.fi ' + +test_expect_success 'preserving iso-8859-7' ' + + test_when_finished "git reset --hard HEAD~1" && + test_config i18n.commitencoding iso-8859-7 && + echo rosten >file && + git commit -s -F "$TEST_DIRECTORY/t9350/simple-iso-8859-7-commit-message.txt" file && + git fast-export --reencode=no wer^..wer >iso-8859-7.fi && + sed "s/wer/i18n-no-recoding/" iso-8859-7.fi | + (cd new && + git fast-import && + # The commit object, if not re-encoded, is 240 bytes. + # Removing the "encoding iso-8859-7\n" header would drops 20 + # bytes. Re-encoding the Pi character from \xF0 (\360) in + # iso-8859-7 to \xCF\x80 (\317\200) in UTF-8 adds a byte. + # Check for the expected size... + test 240 -eq "$(git cat-file -s i18n-no-recoding)" && + # ...as well as the expected byte. + git cat-file commit i18n-no-recoding >actual && + grep $(printf "\360") actual && + # Also make sure the commit has the "encoding" header + grep ^encoding actual) +' + +test_expect_success 'encoding preserved if reencoding fails' ' + + test_when_finished "git reset --hard HEAD~1" && + test_config i18n.commitencoding iso-8859-7 && + echo rosten >file && + git commit -s -F "$TEST_DIRECTORY/t9350/broken-iso-8859-7-commit-message.txt" file && + git fast-export --reencode=yes wer^..wer >iso-8859-7.fi && + sed "s/wer/i18n-invalid/" iso-8859-7.fi | + (cd new && + git fast-import && + git cat-file commit i18n-invalid >actual && + # Make sure the commit still has the encoding header + grep ^encoding actual && + # Verify that the commit has the expected size; i.e. + # that no bytes were re-encoded to a different encoding. + test 252 -eq "$(git cat-file -s i18n-invalid)" && + # ...and check for the original special bytes + grep $(printf "\360") actual && + grep $(printf "\377") actual) +' + test_expect_success 'import/export-marks' ' git checkout -b marks master && @@ -224,7 +285,6 @@ GIT_COMMITTER_NAME='C O Mitter'; export GIT_COMMITTER_NAME test_expect_success 'setup copies' ' - git config --unset i18n.commitencoding && git checkout -b copy rein && git mv file file3 && git commit -m move1 && diff --git a/t/t9350/broken-iso-8859-7-commit-message.txt b/t/t9350/broken-iso-8859-7-commit-message.txt new file mode 100644 index 0000000000..d06ad75b44 --- /dev/null +++ b/t/t9350/broken-iso-8859-7-commit-message.txt @@ -0,0 +1 @@ +Pi: ; Invalid:
\ No newline at end of file diff --git a/t/t9350/simple-iso-8859-7-commit-message.txt b/t/t9350/simple-iso-8859-7-commit-message.txt new file mode 100644 index 0000000000..8b3f0c3dba --- /dev/null +++ b/t/t9350/simple-iso-8859-7-commit-message.txt @@ -0,0 +1 @@ +Pi:
\ No newline at end of file diff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh index 1286a5b824..e9276c48f4 100755 --- a/t/t9832-unshelve.sh +++ b/t/t9832-unshelve.sh @@ -22,7 +22,10 @@ test_expect_success 'init depot' ' : >file_to_move && p4 add file_to_delete && p4 add file_to_move && - p4 submit -d "add files to delete" + p4 submit -d "add files to delete" && + echo file_to_integrate >file_to_integrate && + p4 add file_to_integrate && + p4 submit -d "add file to integrate" ) ' @@ -40,6 +43,7 @@ test_expect_success 'create shelved changelist' ' p4 delete file_to_delete && p4 edit file_to_move && p4 move file_to_move moved_file && + p4 integrate file_to_integrate integrated_file && p4 opened && p4 shelve -i <<EOF Change: new @@ -53,6 +57,7 @@ Files: //depot/file_to_delete //depot/file_to_move //depot/moved_file + //depot/integrated_file EOF ) && @@ -65,6 +70,7 @@ EOF test_path_is_file file2 && test_cmp file1 "$cli"/file1 && test_cmp file2 "$cli"/file2 && + test_cmp file_to_integrate "$cli"/integrated_file && test_path_is_missing file_to_delete && test_path_is_missing file_to_move && test_path_is_file moved_file diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 8270de74be..0367cec5fd 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -309,6 +309,26 @@ test_unset_prereq () { } test_set_prereq () { + if test -n "$GIT_TEST_FAIL_PREREQS" + then + case "$1" in + # The "!" case is handled below with + # test_unset_prereq() + !*) + ;; + # (Temporary?) whitelist of things we can't easily + # pretend not to support + SYMLINKS) + ;; + # Inspecting whether GIT_TEST_FAIL_PREREQS is on + # should be unaffected. + FAIL_PREREQS) + ;; + *) + return + esac + fi + case "$1" in !*) test_unset_prereq "${1#!}" diff --git a/t/test-lib.sh b/t/test-lib.sh index 599fd70e14..4b346467df 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1607,3 +1607,7 @@ test_lazy_prereq SHA1 ' test_lazy_prereq REBASE_P ' test -z "$GIT_TEST_SKIP_REBASE_P" ' + +test_lazy_prereq FAIL_PREREQS ' + test -n "$GIT_TEST_FAIL_PREREQS" +' |