diff options
Diffstat (limited to 't')
37 files changed, 1477 insertions, 289 deletions
diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh index f8ed8573b7..de2a224a36 100755 --- a/t/perf/p5310-pack-bitmaps.sh +++ b/t/perf/p5310-pack-bitmaps.sh @@ -39,14 +39,14 @@ test_expect_success 'create partial bitmap state' ' # now kill off all of the refs and pretend we had # just the one tip - rm -rf .git/logs .git/refs/* .git/packed-refs - git update-ref HEAD $cutoff + rm -rf .git/logs .git/refs/* .git/packed-refs && + git update-ref HEAD $cutoff && # and then repack, which will leave us with a nice # big bitmap pack of the "old" history, and all of # the new history will be loose, as if it had been pushed # up incrementally and exploded via unpack-objects - git repack -Ad + git repack -Ad && # and now restore our original tip, as if the pushes # had happened diff --git a/t/perf/p7300-clean.sh b/t/perf/p7300-clean.sh new file mode 100755 index 0000000000..ec94cdd657 --- /dev/null +++ b/t/perf/p7300-clean.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +test_description="Test git-clean performance" + +. ./perf-lib.sh + +test_perf_default_repo +test_checkout_worktree + +test_expect_success 'setup untracked directory with many sub dirs' ' + rm -rf 500_sub_dirs 100000_sub_dirs clean_test_dir && + mkdir 500_sub_dirs 100000_sub_dirs clean_test_dir && + for i in $(test_seq 1 500) + do + mkdir 500_sub_dirs/dir$i || return $? + done && + for i in $(test_seq 1 200) + do + cp -r 500_sub_dirs 100000_sub_dirs/dir$i || return $? + done +' + +test_perf 'clean many untracked sub dirs, check for nested git' ' + git clean -n -q -f -d 100000_sub_dirs/ +' + +test_perf 'clean many untracked sub dirs, ignore nested git' ' + git clean -n -q -f -f -d 100000_sub_dirs/ +' + +test_done diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index 37e9396e5d..9393322c3e 100755 --- a/t/t0002-gitfile.sh +++ b/t/t0002-gitfile.sh @@ -99,4 +99,21 @@ test_expect_success 'check rev-list' ' test "$SHA" = "$(git rev-list HEAD)" ' +test_expect_success 'setup_git_dir twice in subdir' ' + git init sgd && + ( + cd sgd && + git config alias.lsfi ls-files && + mv .git .realgit && + echo "gitdir: .realgit" >.git && + mkdir subdir && + cd subdir && + >foo && + git add foo && + git lsfi >actual && + echo foo >expected && + test_cmp expected actual + ) +' + test_done diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index b044785175..9be6411104 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -19,6 +19,7 @@ usage: test-parse-options <options> -i, --integer <n> get a integer -j <n> get a integer, too + -m, --magnitude <n> get a magnitude --set23 set integer to 23 -t <time> get timestamp of <time> -L, --length <str> get length of <str> @@ -58,6 +59,7 @@ mv expect expect.err cat >expect.template <<EOF boolean: 0 integer: 0 +magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 @@ -132,9 +134,32 @@ test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown_i18n --no-no-fear test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt' +test_expect_success 'OPT_INT() negative' 'check integer: -2345 -i -2345' + +test_expect_success 'OPT_MAGNITUDE() simple' ' + check magnitude: 2345678 -m 2345678 +' + +test_expect_success 'OPT_MAGNITUDE() kilo' ' + check magnitude: 239616 -m 234k +' + +test_expect_success 'OPT_MAGNITUDE() mega' ' + check magnitude: 104857600 -m 100m +' + +test_expect_success 'OPT_MAGNITUDE() giga' ' + check magnitude: 1073741824 -m 1g +' + +test_expect_success 'OPT_MAGNITUDE() 3giga' ' + check magnitude: 3221225472 -m 3g +' + cat > expect << EOF boolean: 2 integer: 1729 +magnitude: 16384 timestamp: 0 string: 123 abbrev: 7 @@ -145,8 +170,8 @@ file: prefix/my.file EOF test_expect_success 'short options' ' - test-parse-options -s123 -b -i 1729 -b -vv -n -F my.file \ - > output 2> output.err && + test-parse-options -s123 -b -i 1729 -m 16k -b -vv -n -F my.file \ + >output 2>output.err && test_cmp expect output && test_must_be_empty output.err ' @@ -154,6 +179,7 @@ test_expect_success 'short options' ' cat > expect << EOF boolean: 2 integer: 1729 +magnitude: 16384 timestamp: 0 string: 321 abbrev: 10 @@ -164,9 +190,10 @@ file: prefix/fi.le EOF test_expect_success 'long options' ' - test-parse-options --boolean --integer 1729 --boolean --string2=321 \ - --verbose --verbose --no-dry-run --abbrev=10 --file fi.le\ - --obsolete > output 2> output.err && + test-parse-options --boolean --integer 1729 --magnitude 16k \ + --boolean --string2=321 --verbose --verbose --no-dry-run \ + --abbrev=10 --file fi.le --obsolete \ + >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' @@ -180,6 +207,7 @@ test_expect_success 'missing required value' ' cat > expect << EOF boolean: 1 integer: 13 +magnitude: 0 timestamp: 0 string: 123 abbrev: 7 @@ -202,6 +230,7 @@ test_expect_success 'intermingled arguments' ' cat > expect << EOF boolean: 0 integer: 2 +magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 @@ -230,6 +259,7 @@ test_expect_success 'ambiguously abbreviated option' ' cat > expect << EOF boolean: 0 integer: 0 +magnitude: 0 timestamp: 0 string: 123 abbrev: 7 @@ -268,6 +298,7 @@ test_expect_success 'detect possible typos' ' cat > expect <<EOF boolean: 0 integer: 0 +magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 @@ -287,6 +318,7 @@ test_expect_success 'keep some options as arguments' ' cat > expect <<EOF boolean: 0 integer: 0 +magnitude: 0 timestamp: 1 string: (not set) abbrev: 7 @@ -308,6 +340,7 @@ cat > expect <<EOF Callback: "four", 0 boolean: 5 integer: 4 +magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 @@ -336,6 +369,7 @@ test_expect_success 'OPT_CALLBACK() and callback errors work' ' cat > expect <<EOF boolean: 1 integer: 23 +magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 @@ -360,6 +394,7 @@ test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' ' cat > expect <<EOF boolean: 6 integer: 0 +magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 @@ -390,6 +425,7 @@ test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' ' cat > expect <<EOF boolean: 0 integer: 12345 +magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 @@ -408,6 +444,7 @@ test_expect_success 'OPT_NUMBER_CALLBACK() works' ' cat >expect <<EOF boolean: 0 integer: 0 +magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 diff --git a/t/t0302-credential-store.sh b/t/t0302-credential-store.sh index 0979df93a1..1d8d1f210b 100755 --- a/t/t0302-credential-store.sh +++ b/t/t0302-credential-store.sh @@ -75,7 +75,7 @@ test_expect_success 'get: use xdg file if home file has no matches' ' EOF ' -test_expect_success POSIXPERM 'get: use xdg file if home file is unreadable' ' +test_expect_success POSIXPERM,SANITY 'get: use xdg file if home file is unreadable' ' echo "https://home-user:home-pass@example.com" >"$HOME/.git-credentials" && chmod -r "$HOME/.git-credentials" && mkdir -p "$HOME/.config/git" && diff --git a/t/t2019-checkout-ambiguous-ref.sh b/t/t2019-checkout-ambiguous-ref.sh index b99d5192a9..8396320d52 100755 --- a/t/t2019-checkout-ambiguous-ref.sh +++ b/t/t2019-checkout-ambiguous-ref.sh @@ -56,4 +56,30 @@ test_expect_success VAGUENESS_SUCCESS 'checkout reports switch to branch' ' test_i18ngrep ! "^HEAD is now at" stderr ' +test_expect_success 'wildcard ambiguation, paths win' ' + git init ambi && + ( + cd ambi && + echo a >a.c && + git add a.c && + echo b >a.c && + git checkout "*.c" && + echo a >expect && + test_cmp expect a.c + ) +' + +test_expect_success 'wildcard ambiguation, refs lose' ' + git init ambi2 && + ( + cd ambi2 && + echo a >"*.c" && + git add . && + test_must_fail git show :"*.c" && + git show :"*.c" -- >actual && + echo a >expect && + test_cmp expect actual + ) +' + test_done diff --git a/t/t2025-checkout-to.sh b/t/t2025-checkout-to.sh deleted file mode 100755 index f8e4df4818..0000000000 --- a/t/t2025-checkout-to.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/sh - -test_description='test git checkout --to' - -. ./test-lib.sh - -test_expect_success 'setup' ' - test_commit init -' - -test_expect_success 'checkout --to not updating paths' ' - test_must_fail git checkout --to -- init.t -' - -test_expect_success 'checkout --to an existing worktree' ' - mkdir -p existing/subtree && - test_must_fail git checkout --detach --to existing master -' - -test_expect_success 'checkout --to an existing empty worktree' ' - mkdir existing_empty && - git checkout --detach --to existing_empty master -' - -test_expect_success 'checkout --to refuses to checkout locked branch' ' - test_must_fail git checkout --to zere master && - ! test -d zere && - ! test -d .git/worktrees/zere -' - -test_expect_success 'checkout --to a new worktree' ' - git rev-parse HEAD >expect && - git checkout --detach --to here master && - ( - cd here && - test_cmp ../init.t init.t && - test_must_fail git symbolic-ref HEAD && - git rev-parse HEAD >actual && - test_cmp ../expect actual && - git fsck - ) -' - -test_expect_success 'checkout --to a new worktree from a subdir' ' - ( - mkdir sub && - cd sub && - git checkout --detach --to here master && - cd here && - test_cmp ../../init.t init.t - ) -' - -test_expect_success 'checkout --to from a linked checkout' ' - ( - cd here && - git checkout --detach --to nested-here master && - cd nested-here && - git fsck - ) -' - -test_expect_success 'checkout --to a new worktree creating new branch' ' - git checkout --to there -b newmaster master && - ( - cd there && - test_cmp ../init.t init.t && - git symbolic-ref HEAD >actual && - echo refs/heads/newmaster >expect && - test_cmp expect actual && - git fsck - ) -' - -test_expect_success 'die the same branch is already checked out' ' - ( - cd here && - test_must_fail git checkout newmaster - ) -' - -test_expect_success 'not die the same branch is already checked out' ' - ( - cd here && - git checkout --ignore-other-worktrees --to anothernewmaster newmaster - ) -' - -test_expect_success 'not die on re-checking out current branch' ' - ( - cd there && - git checkout newmaster - ) -' - -test_expect_success 'checkout --to from a bare repo' ' - ( - git clone --bare . bare && - cd bare && - git checkout --to ../there2 -b bare-master master - ) -' - -test_expect_success 'checkout from a bare repo without --to' ' - ( - cd bare && - test_must_fail git checkout master - ) -' - -test_expect_success 'checkout with grafts' ' - test_when_finished rm .git/info/grafts && - test_commit abc && - SHA1=`git rev-parse HEAD` && - test_commit def && - test_commit xyz && - echo "`git rev-parse HEAD` $SHA1" >.git/info/grafts && - cat >expected <<-\EOF && - xyz - abc - EOF - git log --format=%s -2 >actual && - test_cmp expected actual && - git checkout --detach --to grafted master && - git --git-dir=grafted/.git log --format=%s -2 >actual && - test_cmp expected actual -' - -test_done diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh new file mode 100755 index 0000000000..ead8aa2a9d --- /dev/null +++ b/t/t2025-worktree-add.sh @@ -0,0 +1,162 @@ +#!/bin/sh + +test_description='test git worktree add' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit init +' + +test_expect_success '"add" an existing worktree' ' + mkdir -p existing/subtree && + test_must_fail git worktree add --detach existing master +' + +test_expect_success '"add" an existing empty worktree' ' + mkdir existing_empty && + git worktree add --detach existing_empty master +' + +test_expect_success '"add" refuses to checkout locked branch' ' + test_must_fail git worktree add zere master && + ! test -d zere && + ! test -d .git/worktrees/zere +' + +test_expect_success 'checking out paths not complaining about linked checkouts' ' + ( + cd existing_empty && + echo dirty >>init.t && + git checkout master -- init.t + ) +' + +test_expect_success '"add" worktree' ' + git rev-parse HEAD >expect && + git worktree add --detach here master && + ( + cd here && + test_cmp ../init.t init.t && + test_must_fail git symbolic-ref HEAD && + git rev-parse HEAD >actual && + test_cmp ../expect actual && + git fsck + ) +' + +test_expect_success '"add" worktree from a subdir' ' + ( + mkdir sub && + cd sub && + git worktree add --detach here master && + cd here && + test_cmp ../../init.t init.t + ) +' + +test_expect_success '"add" from a linked checkout' ' + ( + cd here && + git worktree add --detach nested-here master && + cd nested-here && + git fsck + ) +' + +test_expect_success '"add" worktree creating new branch' ' + git worktree add -b newmaster there master && + ( + cd there && + test_cmp ../init.t init.t && + git symbolic-ref HEAD >actual && + echo refs/heads/newmaster >expect && + test_cmp expect actual && + git fsck + ) +' + +test_expect_success 'die the same branch is already checked out' ' + ( + cd here && + test_must_fail git checkout newmaster + ) +' + +test_expect_success 'not die the same branch is already checked out' ' + ( + cd here && + git worktree add --force anothernewmaster newmaster + ) +' + +test_expect_success 'not die on re-checking out current branch' ' + ( + cd there && + git checkout newmaster + ) +' + +test_expect_success '"add" from a bare repo' ' + ( + git clone --bare . bare && + cd bare && + git worktree add -b bare-master ../there2 master + ) +' + +test_expect_success 'checkout from a bare repo without "add"' ' + ( + cd bare && + test_must_fail git checkout master + ) +' + +test_expect_success 'checkout with grafts' ' + test_when_finished rm .git/info/grafts && + test_commit abc && + SHA1=`git rev-parse HEAD` && + test_commit def && + test_commit xyz && + echo "`git rev-parse HEAD` $SHA1" >.git/info/grafts && + cat >expected <<-\EOF && + xyz + abc + EOF + git log --format=%s -2 >actual && + test_cmp expected actual && + git worktree add --detach grafted master && + git --git-dir=grafted/.git log --format=%s -2 >actual && + test_cmp expected actual +' + +test_expect_success '"add" from relative HEAD' ' + test_commit a && + test_commit b && + test_commit c && + git rev-parse HEAD~1 >expected && + git worktree add relhead HEAD~1 && + git -C relhead rev-parse HEAD >actual && + test_cmp expected actual +' + +test_expect_success '"add -b" with <branch> omitted' ' + git worktree add -b burble flornk && + test_cmp_rev HEAD burble +' + +test_expect_success '"add" with <branch> omitted' ' + git worktree add wiffle/bat && + test_cmp_rev HEAD bat +' + +test_expect_success '"add" auto-vivify does not clobber existing branch' ' + test_commit c1 && + test_commit c2 && + git branch precious HEAD~1 && + test_must_fail git worktree add precious && + test_cmp_rev HEAD~1 precious && + test_path_is_missing precious +' + +test_done diff --git a/t/t2026-prune-linked-checkouts.sh b/t/t2026-prune-linked-checkouts.sh index 1821a480c5..a0f1e3bb80 100755 --- a/t/t2026-prune-linked-checkouts.sh +++ b/t/t2026-prune-linked-checkouts.sh @@ -8,15 +8,15 @@ test_expect_success initialize ' git commit --allow-empty -m init ' -test_expect_success 'prune --worktrees on normal repo' ' - git prune --worktrees && - test_must_fail git prune --worktrees abc +test_expect_success 'worktree prune on normal repo' ' + git worktree prune && + test_must_fail git worktree prune abc ' test_expect_success 'prune files inside $GIT_DIR/worktrees' ' mkdir .git/worktrees && : >.git/worktrees/abc && - git prune --worktrees --verbose >actual && + git worktree prune --verbose >actual && cat >expect <<EOF && Removing worktrees/abc: not a valid directory EOF @@ -31,7 +31,7 @@ test_expect_success 'prune directories without gitdir' ' cat >expect <<EOF && Removing worktrees/def: gitdir file does not exist EOF - git prune --worktrees --verbose >actual && + git worktree prune --verbose >actual && test_i18ncmp expect actual && ! test -d .git/worktrees/def && ! test -d .git/worktrees @@ -42,7 +42,7 @@ test_expect_success SANITY 'prune directories with unreadable gitdir' ' : >.git/worktrees/def/def && : >.git/worktrees/def/gitdir && chmod u-r .git/worktrees/def/gitdir && - git prune --worktrees --verbose >actual && + git worktree prune --verbose >actual && test_i18ngrep "Removing worktrees/def: unable to read gitdir file" actual && ! test -d .git/worktrees/def && ! test -d .git/worktrees @@ -52,7 +52,7 @@ test_expect_success 'prune directories with invalid gitdir' ' mkdir -p .git/worktrees/def/abc && : >.git/worktrees/def/def && : >.git/worktrees/def/gitdir && - git prune --worktrees --verbose >actual && + git worktree prune --verbose >actual && test_i18ngrep "Removing worktrees/def: invalid gitdir file" actual && ! test -d .git/worktrees/def && ! test -d .git/worktrees @@ -62,7 +62,7 @@ test_expect_success 'prune directories with gitdir pointing to nowhere' ' mkdir -p .git/worktrees/def/abc && : >.git/worktrees/def/def && echo "$(pwd)"/nowhere >.git/worktrees/def/gitdir && - git prune --worktrees --verbose >actual && + git worktree prune --verbose >actual && test_i18ngrep "Removing worktrees/def: gitdir file points to non-existent location" actual && ! test -d .git/worktrees/def && ! test -d .git/worktrees @@ -72,7 +72,7 @@ test_expect_success 'not prune locked checkout' ' test_when_finished rm -r .git/worktrees && mkdir -p .git/worktrees/ghi && : >.git/worktrees/ghi/locked && - git prune --worktrees && + git worktree prune && test -d .git/worktrees/ghi ' @@ -82,14 +82,14 @@ test_expect_success 'not prune recent checkouts' ' mkdir -p .git/worktrees/jlm && echo "$(pwd)"/zz >.git/worktrees/jlm/gitdir && rmdir zz && - git prune --worktrees --verbose --expire=2.days.ago && + git worktree prune --verbose --expire=2.days.ago && test -d .git/worktrees/jlm ' test_expect_success 'not prune proper checkouts' ' test_when_finished rm -r .git/worktrees && - git checkout "--to=$PWD/nop" --detach master && - git prune --worktrees && + git worktree add --detach "$PWD/nop" master && + git worktree prune && test -d .git/worktrees/nop ' diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index 7c641bfaf4..2a4a749b4f 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -5,24 +5,10 @@ test_description='Intent to add' . ./test-lib.sh test_expect_success 'intent to add' ' - test_commit 1 && - git rm 1.t && - echo hello >1.t && echo hello >file && echo hello >elif && git add -N file && - git add elif && - git add -N 1.t -' - -test_expect_success 'git status' ' - git status --porcelain | grep -v actual >actual && - cat >expect <<-\EOF && - DA 1.t - A elif - A file - EOF - test_cmp expect actual + git add elif ' test_expect_success 'check result of "add -N"' ' @@ -57,8 +43,7 @@ test_expect_success 'i-t-a entry is simply ignored' ' git add -N nitfol && git commit -m second && test $(git ls-tree HEAD -- nitfol | wc -l) = 0 && - test $(git diff --name-only HEAD -- nitfol | wc -l) = 0 && - test $(git diff --name-only -- nitfol | wc -l) = 1 + test $(git diff --name-only HEAD -- nitfol | wc -l) = 1 ' test_expect_success 'can commit with an unrelated i-t-a entry in index' ' @@ -87,13 +72,13 @@ test_expect_success 'cache-tree invalidates i-t-a paths' ' : >dir/bar && git add -N dir/bar && git diff --cached --name-only >actual && - >expect && + echo dir/bar >expect && test_cmp expect actual && git write-tree >/dev/null && git diff --cached --name-only >actual && - >expect && + echo dir/bar >expect && test_cmp expect actual ' diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index ac429a0bbb..467e6c1ed5 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -1102,4 +1102,25 @@ test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' ' test $(git cat-file commit HEAD | sed -ne \$p) = I ' +test_expect_success 'rebase --continue removes CHERRY_PICK_HEAD' ' + git checkout -b commit-to-skip && + for double in X 3 1 + do + test_seq 5 | sed "s/$double/&&/" >seq && + git add seq && + test_tick && + git commit -m seq-$double + done && + git tag seq-onto && + git reset --hard HEAD~2 && + git cherry-pick seq-onto && + set_fake_editor && + test_must_fail env FAKE_LINES= git rebase -i seq-onto && + test -d .git/rebase-merge && + git rebase --continue && + git diff --exit-code seq-onto && + test ! -d .git/rebase-merge && + test ! -f .git/CHERRY_PICK_HEAD +' + test_done diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index 41370ab998..8f53e54ce4 100755 --- a/t/t3415-rebase-autosquash.sh +++ b/t/t3415-rebase-autosquash.sh @@ -250,4 +250,25 @@ test_expect_success 'squash! fixup!' ' test_auto_fixup_fixup squash fixup ' +test_expect_success 'autosquash with custom inst format' ' + git reset --hard base && + git config --add rebase.instructionFormat "[%an @ %ar] %s" && + echo 2 >file1 && + git add -u && + test_tick && + git commit -m "squash! $(git rev-parse --short HEAD^)" && + echo 1 >file1 && + git add -u && + test_tick && + git commit -m "squash! $(git log -n 1 --format=%s HEAD~2)" && + git tag final-squash-instFmt && + test_tick && + git rebase --autosquash -i HEAD~4 && + git log --oneline >actual && + test_line_count = 3 actual && + git diff --exit-code final-squash-instFmt && + test 1 = "$(git cat-file blob HEAD^:file1)" && + test 2 = $(git cat-file commit HEAD^ | grep squash | wc -l) +' + test_done diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 7396ca9911..f5f18b7d21 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -45,13 +45,6 @@ test_expect_success 'applying bogus stash does nothing' ' test_cmp expect file ' -test_expect_success 'apply requires a clean index' ' - test_when_finished "git reset --hard" && - echo changed >other-file && - git add other-file && - test_must_fail git stash apply -' - test_expect_success 'apply does not need clean working directory' ' echo 4 >other-file && git stash apply && diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index 7452fce0da..13e7f621ab 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -139,13 +139,11 @@ test_expect_success SYMLINKS 'setup symlinks with attributes' ' test_expect_success SYMLINKS 'symlinks do not respect userdiff config by path' ' cat >expect <<-\EOF && diff --git a/file.bin b/file.bin - new file mode 100644 - index 0000000..d95f3ad - Binary files /dev/null and b/file.bin differ + index e69de29..d95f3ad 100644 + Binary files a/file.bin and b/file.bin differ diff --git a/link.bin b/link.bin - new file mode 120000 - index 0000000..dce41ec - --- /dev/null + index e69de29..dce41ec 120000 + --- a/link.bin +++ b/link.bin @@ -0,0 +1 @@ +file.bin diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index c39e50028f..890db1174f 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -57,6 +57,14 @@ test_expect_success "format-patch --ignore-if-in-upstream" ' ' +test_expect_success "format-patch --ignore-if-in-upstream handles tags" ' + git tag -a v1 -m tag side && + git tag -a v2 -m tag master && + git format-patch --stdout --ignore-if-in-upstream v2..v1 >patch1 && + cnt=$(grep "^From " patch1 | wc -l) && + test $cnt = 2 +' + test_expect_success "format-patch doesn't consider merge commits" ' git checkout -b slave master && diff --git a/t/t4136-apply-check.sh b/t/t4136-apply-check.sh index a321f7c245..4b0a374b63 100755 --- a/t/t4136-apply-check.sh +++ b/t/t4136-apply-check.sh @@ -16,4 +16,17 @@ test_expect_success 'apply --check exits non-zero with unrecognized input' ' EOF ' +test_expect_success 'apply exits non-zero with no-op patch' ' + cat >input <<-\EOF && + diff --get a/1 b/1 + index 6696ea4..606eddd 100644 + --- a/1 + +++ b/1 + @@ -1,1 +1,1 @@ + 1 + EOF + test_must_fail git apply --stat input && + test_must_fail git apply --check input +' + test_done diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 306e6f39ac..3320fa6315 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -104,6 +104,38 @@ test_expect_success setup ' echo "X-Fake-Field: Line Three" && git format-patch --stdout first | sed -e "1d" } > patch1-ws.eml && + { + sed -ne "1p" msg && + echo && + echo "From: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" && + echo "Date: $GIT_AUTHOR_DATE" && + echo && + sed -e "1,2d" msg && + echo && + echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" && + echo "---" && + git diff-tree --no-commit-id --stat -p second + } >patch1-stgit.eml && + mkdir stgit-series && + cp patch1-stgit.eml stgit-series/patch && + { + echo "# This series applies on GIT commit $(git rev-parse first)" && + echo "patch" + } >stgit-series/series && + { + echo "# HG changeset patch" && + echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" && + echo "# Date $test_tick 25200" && + echo "# $(git show --pretty="%aD" -s second)" && + echo "# Node ID $_z40" && + echo "# Parent $_z40" && + cat msg && + echo && + echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" && + echo && + git diff-tree --no-commit-id -p second + } >patch1-hg.eml && + sed -n -e "3,\$p" msg >file && git add file && @@ -187,6 +219,56 @@ test_expect_success 'am applies patch e-mail with preceding whitespace' ' test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" ' +test_expect_success 'am applies stgit patch' ' + rm -fr .git/rebase-apply && + git checkout -f first && + git am patch1-stgit.eml && + test_path_is_missing .git/rebase-apply && + git diff --exit-code second && + test_cmp_rev second HEAD && + test_cmp_rev second^ HEAD^ +' + +test_expect_success 'am --patch-format=stgit applies stgit patch' ' + rm -fr .git/rebase-apply && + git checkout -f first && + git am --patch-format=stgit <patch1-stgit.eml && + test_path_is_missing .git/rebase-apply && + git diff --exit-code second && + test_cmp_rev second HEAD && + test_cmp_rev second^ HEAD^ +' + +test_expect_success 'am applies stgit series' ' + rm -fr .git/rebase-apply && + git checkout -f first && + git am stgit-series/series && + test_path_is_missing .git/rebase-apply && + git diff --exit-code second && + test_cmp_rev second HEAD && + test_cmp_rev second^ HEAD^ +' + +test_expect_success 'am applies hg patch' ' + rm -fr .git/rebase-apply && + git checkout -f first && + git am patch1-hg.eml && + test_path_is_missing .git/rebase-apply && + git diff --exit-code second && + test_cmp_rev second HEAD && + test_cmp_rev second^ HEAD^ +' + +test_expect_success 'am --patch-format=hg applies hg patch' ' + rm -fr .git/rebase-apply && + git checkout -f first && + git am --patch-format=hg <patch1-hg.eml && + test_path_is_missing .git/rebase-apply && + git diff --exit-code second && + test_cmp_rev second HEAD && + test_cmp_rev second^ HEAD^ +' + test_expect_success 'setup: new author and committer' ' GIT_AUTHOR_NAME="Another Thor" && GIT_AUTHOR_EMAIL="a.thor@example.com" && @@ -274,15 +356,21 @@ test_expect_success 'am --keep-non-patch really keeps the non-patch part' ' grep "^\[foo\] third" actual ' -test_expect_success 'am -3 falls back to 3-way merge' ' +test_expect_success 'setup am -3' ' rm -fr .git/rebase-apply && git reset --hard && - git checkout -b lorem2 master2 && + git checkout -b base3way master2 && sed -n -e "3,\$p" msg >file && head -n 9 msg >>file && git add file && test_tick && - git commit -m "copied stuff" && + git commit -m "copied stuff" +' + +test_expect_success 'am -3 falls back to 3-way merge' ' + rm -fr .git/rebase-apply && + git reset --hard && + git checkout -b lorem2 base3way && git am -3 lorem-move.patch && test_path_is_missing .git/rebase-apply && git diff --exit-code lorem @@ -291,12 +379,7 @@ test_expect_success 'am -3 falls back to 3-way merge' ' test_expect_success 'am -3 -p0 can read --no-prefix patch' ' rm -fr .git/rebase-apply && git reset --hard && - git checkout -b lorem3 master2 && - sed -n -e "3,\$p" msg >file && - head -n 9 msg >>file && - git add file && - test_tick && - git commit -m "copied stuff" && + git checkout -b lorem3 base3way && git am -3 -p0 lorem-zero.patch && test_path_is_missing .git/rebase-apply && git diff --exit-code lorem @@ -338,12 +421,7 @@ test_expect_success 'am -3 can rename a file after falling back to 3-way merge' test_expect_success 'am -3 -q is quiet' ' rm -fr .git/rebase-apply && git checkout -f lorem2 && - git reset master2 --hard && - sed -n -e "3,\$p" msg >file && - head -n 9 msg >>file && - git add file && - test_tick && - git commit -m "copied stuff" && + git reset base3way --hard && git am -3 -q lorem-move.patch >output.out 2>&1 && ! test -s output.out ' diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh index 8d90634ab8..833e7b2cea 100755 --- a/t/t4151-am-abort.sh +++ b/t/t4151-am-abort.sh @@ -14,6 +14,7 @@ test_expect_success setup ' git add file-1 file-2 && git commit -m initial && git tag initial && + git format-patch --stdout --root initial >initial.patch && for i in 2 3 4 5 6 do echo $i >>file-1 && @@ -63,6 +64,28 @@ do done +test_expect_success 'am -3 --skip removes otherfile-4' ' + git reset --hard initial && + test_must_fail git am -3 0003-*.patch && + test 3 -eq $(git ls-files -u | wc -l) && + test 4 = "$(cat otherfile-4)" && + git am --skip && + test_cmp_rev initial HEAD && + test -z "$(git ls-files -u)" && + test_path_is_missing otherfile-4 +' + +test_expect_success 'am -3 --abort removes otherfile-4' ' + git reset --hard initial && + test_must_fail git am -3 0003-*.patch && + test 3 -eq $(git ls-files -u | wc -l) && + test 4 = "$(cat otherfile-4)" && + git am --abort && + test_cmp_rev initial HEAD && + test -z $(git ls-files -u) && + test_path_is_missing otherfile-4 +' + test_expect_success 'am --abort will keep the local commits intact' ' test_must_fail git am 0004-*.patch && test_commit unrelated && @@ -72,4 +95,62 @@ test_expect_success 'am --abort will keep the local commits intact' ' test_cmp expect actual ' +test_expect_success 'am -3 stops on conflict on unborn branch' ' + git checkout -f --orphan orphan && + git reset && + rm -f otherfile-4 && + test_must_fail git am -3 0003-*.patch && + test 2 -eq $(git ls-files -u | wc -l) && + test 4 = "$(cat otherfile-4)" +' + +test_expect_success 'am -3 --skip clears index on unborn branch' ' + test_path_is_dir .git/rebase-apply && + echo tmpfile >tmpfile && + git add tmpfile && + git am --skip && + test -z "$(git ls-files)" && + test_path_is_missing otherfile-4 && + test_path_is_missing tmpfile +' + +test_expect_success 'am -3 --abort removes otherfile-4 on unborn branch' ' + git checkout -f --orphan orphan && + git reset && + rm -f otherfile-4 file-1 && + test_must_fail git am -3 0003-*.patch && + test 2 -eq $(git ls-files -u | wc -l) && + test 4 = "$(cat otherfile-4)" && + git am --abort && + test -z "$(git ls-files -u)" && + test_path_is_missing otherfile-4 +' + +test_expect_success 'am -3 --abort on unborn branch removes applied commits' ' + git checkout -f --orphan orphan && + git reset && + rm -f otherfile-4 otherfile-2 file-1 file-2 && + test_must_fail git am -3 initial.patch 0003-*.patch && + test 3 -eq $(git ls-files -u | wc -l) && + test 4 = "$(cat otherfile-4)" && + git am --abort && + test -z "$(git ls-files -u)" && + test_path_is_missing otherfile-4 && + test_path_is_missing file-1 && + test_path_is_missing file-2 && + test 0 -eq $(git log --oneline 2>/dev/null | wc -l) && + test refs/heads/orphan = "$(git symbolic-ref HEAD)" +' + +test_expect_success 'am --abort on unborn branch will keep local commits intact' ' + git checkout -f --orphan orphan && + git reset && + test_must_fail git am 0004-*.patch && + test_commit unrelated2 && + git rev-parse HEAD >expect && + git am --abort && + git rev-parse HEAD >actual && + test_cmp expect actual +' + test_done diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index 0794d33dad..023d7c6f7b 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -218,6 +218,7 @@ test_expect_success 'gc: prune old objects after local clone' ' ' test_expect_success 'garbage report in count-objects -v' ' + test_when_finished "rm -f .git/objects/pack/fake*" && : >.git/objects/pack/foo && : >.git/objects/pack/foo.bar && : >.git/objects/pack/foo.keep && diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index 6003490192..d446706e94 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -53,6 +53,12 @@ rev_list_tests() { test_cmp expect actual ' + test_expect_success "counting commits with limiting ($state)" ' + git rev-list --count HEAD -- 1.t >expect && + git rev-list --use-bitmap-index --count HEAD -- 1.t >actual && + test_cmp expect actual + ' + test_expect_success "enumerate --objects ($state)" ' git rev-list --objects --use-bitmap-index HEAD >tmp && cut -d" " -f1 <tmp >tmp2 && diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index af31f04c28..f4a7193677 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -160,6 +160,18 @@ test_expect_success 'fail if no configuration for current branch' ' test "$(cat file)" = file ' +test_expect_success 'pull --all: fail if no configuration for current branch' ' + git remote add test_remote . && + test_when_finished "git remote remove test_remote" && + git checkout -b test copy^ && + test_when_finished "git checkout -f copy && git branch -D test" && + test_config branch.test.remote test_remote && + test "$(cat file)" = file && + test_must_fail git pull --all 2>err && + test_i18ngrep "There is no tracking information" err && + test "$(cat file)" = file +' + test_expect_success 'fail if upstream branch does not exist' ' git checkout -b test copy^ && test_when_finished "git checkout -f copy && git branch -D test" && @@ -365,6 +377,14 @@ test_expect_success '--rebase with rebased upstream' ' ' +test_expect_success '--rebase -f with rebased upstream' ' + test_when_finished "test_might_fail git rebase --abort" && + git reset --hard to-rebase-orig && + git pull --rebase -f me copy && + test "conflicting modification" = "$(cat file)" && + test file = "$(cat file2)" +' + test_expect_success '--rebase with rebased default upstream' ' git update-ref refs/remotes/me/copy copy-orig && diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 56e7377189..18372caa15 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -130,4 +130,18 @@ test_expect_success 'git pull --dry-run' ' ) ' +test_expect_success 'git pull --all --dry-run' ' + test_when_finished "rm -rf cloneddry" && + git init clonedry && + ( + cd clonedry && + git remote add origin ../parent && + git pull --all --dry-run && + test_path_is_missing .git/FETCH_HEAD && + test_path_is_missing .git/refs/remotes/origin/master && + test_path_is_missing .git/index && + test_path_is_missing file + ) +' + test_done diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index bfdaf75966..9b34f3c615 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -496,4 +496,11 @@ test_expect_success 'shallow clone locally' ' ( cd ddsstt && git fsck ) ' +test_expect_success 'GIT_TRACE_PACKFILE produces a usable pack' ' + rm -rf dst.git && + GIT_TRACE_PACKFILE=$PWD/tmp.pack git clone --no-local --bare src dst.git && + git init --bare replay.git && + git -C replay.git index-pack -v --stdin <tmp.pack +' + test_done diff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh index 3c21938a68..04c0509c47 100755 --- a/t/t6026-merge-attr.sh +++ b/t/t6026-merge-attr.sh @@ -85,11 +85,12 @@ test_expect_success 'retry the merge with longer context' ' cat >./custom-merge <<\EOF #!/bin/sh -orig="$1" ours="$2" theirs="$3" exit="$4" +orig="$1" ours="$2" theirs="$3" exit="$4" path=$5 ( echo "orig is $orig" echo "ours is $ours" echo "theirs is $theirs" + echo "path is $path" echo "=== orig ===" cat "$orig" echo "=== ours ===" @@ -110,7 +111,7 @@ test_expect_success 'custom merge backend' ' git reset --hard anchor && git config --replace-all \ - merge.custom.driver "./custom-merge %O %A %B 0" && + merge.custom.driver "./custom-merge %O %A %B 0 %P" && git config --replace-all \ merge.custom.name "custom merge driver for testing" && @@ -121,7 +122,7 @@ test_expect_success 'custom merge backend' ' o=$(git unpack-file master^:text) && a=$(git unpack-file side^:text) && b=$(git unpack-file master:text) && - sh -c "./custom-merge $o $a $b 0" && + sh -c "./custom-merge $o $a $b 0 'text'" && sed -e 1,3d $a >check-2 && cmp check-1 check-2 && rm -f $o $a $b @@ -131,7 +132,7 @@ test_expect_success 'custom merge backend' ' git reset --hard anchor && git config --replace-all \ - merge.custom.driver "./custom-merge %O %A %B 1" && + merge.custom.driver "./custom-merge %O %A %B 1 %P" && git config --replace-all \ merge.custom.name "custom merge driver for testing" && @@ -148,9 +149,12 @@ test_expect_success 'custom merge backend' ' o=$(git unpack-file master^:text) && a=$(git unpack-file anchor:text) && b=$(git unpack-file master:text) && - sh -c "./custom-merge $o $a $b 0" && + sh -c "./custom-merge $o $a $b 0 'text'" && sed -e 1,3d $a >check-2 && cmp check-1 check-2 && + sed -e 1,3d -e 4q $a >check-3 && + echo "path is text" >expect && + cmp expect check-3 && rm -f $o $a $b ' diff --git a/t/t6301-for-each-ref-errors.sh b/t/t6301-for-each-ref-errors.sh new file mode 100755 index 0000000000..cdb67a03b7 --- /dev/null +++ b/t/t6301-for-each-ref-errors.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +test_description='for-each-ref errors for broken refs' + +. ./test-lib.sh + +ZEROS=$_z40 +MISSING=abababababababababababababababababababab + +test_expect_success setup ' + git commit --allow-empty -m "Initial" && + git tag testtag && + git for-each-ref >full-list && + git for-each-ref --format="%(objectname) %(refname)" >brief-list +' + +test_expect_success 'Broken refs are reported correctly' ' + r=refs/heads/bogus && + : >.git/$r && + test_when_finished "rm -f .git/$r" && + echo "warning: ignoring broken ref $r" >broken-err && + git for-each-ref >out 2>err && + test_cmp full-list out && + test_cmp broken-err err +' + +test_expect_success 'NULL_SHA1 refs are reported correctly' ' + r=refs/heads/zeros && + echo $ZEROS >.git/$r && + test_when_finished "rm -f .git/$r" && + echo "warning: ignoring broken ref $r" >zeros-err && + git for-each-ref >out 2>err && + test_cmp full-list out && + test_cmp zeros-err err && + git for-each-ref --format="%(objectname) %(refname)" >brief-out 2>brief-err && + test_cmp brief-list brief-out && + test_cmp zeros-err brief-err +' + +test_expect_success 'Missing objects are reported correctly' ' + r=refs/heads/missing && + echo $MISSING >.git/$r && + test_when_finished "rm -f .git/$r" && + echo "fatal: missing object $MISSING for $r" >missing-err && + test_must_fail git for-each-ref 2>err && + test_cmp missing-err err && + ( + cat brief-list && + echo "$MISSING $r" + ) | sort -k 2 >missing-brief-expected && + git for-each-ref --format="%(objectname) %(refname)" >brief-out 2>brief-err && + test_cmp missing-brief-expected brief-out && + test_must_be_empty brief-err +' + +test_done diff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh new file mode 100755 index 0000000000..4608e71343 --- /dev/null +++ b/t/t7030-verify-tag.sh @@ -0,0 +1,115 @@ +#!/bin/sh + +test_description='signed tag tests' +. ./test-lib.sh +. "$TEST_DIRECTORY/lib-gpg.sh" + +test_expect_success GPG 'create signed tags' ' + echo 1 >file && git add file && + test_tick && git commit -m initial && + git tag -s -m initial initial && + git branch side && + + echo 2 >file && test_tick && git commit -a -m second && + git tag -s -m second second && + + git checkout side && + echo 3 >elif && git add elif && + test_tick && git commit -m "third on side" && + + git checkout master && + test_tick && git merge -S side && + git tag -s -m merge merge && + + echo 4 >file && test_tick && git commit -a -S -m "fourth unsigned" && + git tag -a -m fourth-unsigned fourth-unsigned && + + test_tick && git commit --amend -S -m "fourth signed" && + git tag -s -m fourth fourth-signed && + + echo 5 >file && test_tick && git commit -a -m "fifth" && + git tag fifth-unsigned && + + git config commit.gpgsign true && + echo 6 >file && test_tick && git commit -a -m "sixth" && + git tag -a -m sixth sixth-unsigned && + + test_tick && git rebase -f HEAD^^ && git tag -s -m 6th sixth-signed HEAD^ && + git tag -m seventh -s seventh-signed && + + echo 8 >file && test_tick && git commit -a -m eighth && + git tag -uB7227189 -m eighth eighth-signed-alt +' + +test_expect_success GPG 'verify and show signatures' ' + ( + for tag in initial second merge fourth-signed sixth-signed seventh-signed + do + git verify-tag $tag 2>actual && + grep "Good signature from" actual && + ! grep "BAD signature from" actual && + echo $tag OK || exit 1 + done + ) && + ( + for tag in fourth-unsigned fifth-unsigned sixth-unsigned + do + test_must_fail git verify-tag $tag 2>actual && + ! grep "Good signature from" actual && + ! grep "BAD signature from" actual && + echo $tag OK || exit 1 + done + ) && + ( + for tag in eighth-signed-alt + do + git verify-tag $tag 2>actual && + grep "Good signature from" actual && + ! grep "BAD signature from" actual && + grep "not certified" actual && + echo $tag OK || exit 1 + done + ) +' + +test_expect_success GPG 'detect fudged signature' ' + git cat-file tag seventh-signed >raw && + sed -e "s/seventh/7th forged/" raw >forged1 && + git hash-object -w -t tag forged1 >forged1.tag && + test_must_fail git verify-tag $(cat forged1.tag) 2>actual1 && + grep "BAD signature from" actual1 && + ! grep "Good signature from" actual1 +' + +test_expect_success GPG 'verify signatures with --raw' ' + ( + for tag in initial second merge fourth-signed sixth-signed seventh-signed + do + git verify-tag --raw $tag 2>actual && + grep "GOODSIG" actual && + ! grep "BADSIG" actual && + echo $tag OK || exit 1 + done + ) && + ( + for tag in fourth-unsigned fifth-unsigned sixth-unsigned + do + test_must_fail git verify-tag --raw $tag 2>actual && + ! grep "GOODSIG" actual && + ! grep "BADSIG" actual && + echo $tag OK || exit 1 + done + ) && + ( + for tag in eighth-signed-alt + do + git verify-tag --raw $tag 2>actual && + grep "GOODSIG" actual && + ! grep "BADSIG" actual && + grep "TRUST_UNDEFINED" actual && + echo $tag OK || exit 1 + done + ) +' + +test_done diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 99be5d95d0..32e96da7e3 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -455,6 +455,146 @@ test_expect_success 'nested git work tree' ' ! test -d bar ' +test_expect_success 'should clean things that almost look like git but are not' ' + rm -fr almost_git almost_bare_git almost_submodule && + mkdir -p almost_git/.git/objects && + mkdir -p almost_git/.git/refs && + cat >almost_git/.git/HEAD <<-\EOF && + garbage + EOF + cp -r almost_git/.git/ almost_bare_git && + mkdir almost_submodule/ && + cat >almost_submodule/.git <<-\EOF && + garbage + EOF + test_when_finished "rm -rf almost_*" && + git clean -f -d && + test_path_is_missing almost_git && + test_path_is_missing almost_bare_git && + test_path_is_missing almost_submodule +' + +test_expect_success 'should not clean submodules' ' + rm -fr repo to_clean sub1 sub2 && + mkdir repo to_clean && + ( + cd repo && + git init && + test_commit msg hello.world + ) && + git submodule add ./repo/.git sub1 && + git commit -m "sub1" && + git branch before_sub2 && + git submodule add ./repo/.git sub2 && + git commit -m "sub2" && + git checkout before_sub2 && + >to_clean/should_clean.this && + git clean -f -d && + test_path_is_file repo/.git/index && + test_path_is_file repo/hello.world && + test_path_is_file sub1/.git && + test_path_is_file sub1/hello.world && + test_path_is_file sub2/.git && + test_path_is_file sub2/hello.world && + test_path_is_missing to_clean +' + +test_expect_success 'should avoid cleaning possible submodules' ' + rm -fr to_clean possible_sub1 && + mkdir to_clean possible_sub1 && + test_when_finished "rm -rf possible_sub*" && + echo "gitdir: foo" >possible_sub1/.git && + >possible_sub1/hello.world && + chmod 0 possible_sub1/.git && + >to_clean/should_clean.this && + git clean -f -d && + test_path_is_file possible_sub1/.git && + test_path_is_file possible_sub1/hello.world && + test_path_is_missing to_clean +' + +test_expect_success 'nested (empty) git should be kept' ' + rm -fr empty_repo to_clean && + git init empty_repo && + mkdir to_clean && + >to_clean/should_clean.this && + git clean -f -d && + test_path_is_file empty_repo/.git/HEAD && + test_path_is_missing to_clean +' + +test_expect_success 'nested bare repositories should be cleaned' ' + rm -fr bare1 bare2 subdir && + git init --bare bare1 && + git clone --local --bare . bare2 && + mkdir subdir && + cp -r bare2 subdir/bare3 && + git clean -f -d && + test_path_is_missing bare1 && + test_path_is_missing bare2 && + test_path_is_missing subdir +' + +test_expect_failure 'nested (empty) bare repositories should be cleaned even when in .git' ' + rm -fr strange_bare && + mkdir strange_bare && + git init --bare strange_bare/.git && + git clean -f -d && + test_path_is_missing strange_bare +' + +test_expect_failure 'nested (non-empty) bare repositories should be cleaned even when in .git' ' + rm -fr strange_bare && + mkdir strange_bare && + git clone --local --bare . strange_bare/.git && + git clean -f -d && + test_path_is_missing strange_bare +' + +test_expect_success 'giving path in nested git work tree will remove it' ' + rm -fr repo && + mkdir repo && + ( + cd repo && + git init && + mkdir -p bar/baz && + test_commit msg bar/baz/hello.world + ) && + git clean -f -d repo/bar/baz && + test_path_is_file repo/.git/HEAD && + test_path_is_dir repo/bar/ && + test_path_is_missing repo/bar/baz +' + +test_expect_success 'giving path to nested .git will not remove it' ' + rm -fr repo && + mkdir repo untracked && + ( + cd repo && + git init && + test_commit msg hello.world + ) && + git clean -f -d repo/.git && + test_path_is_file repo/.git/HEAD && + test_path_is_dir repo/.git/refs && + test_path_is_dir repo/.git/objects && + test_path_is_dir untracked/ +' + +test_expect_success 'giving path to nested .git/ will remove contents' ' + rm -fr repo untracked && + mkdir repo untracked && + ( + cd repo && + git init && + test_commit msg hello.world + ) && + git clean -f -d repo/.git/ && + test_path_is_dir repo/.git && + test_dir_is_empty repo/.git && + test_path_is_dir untracked/ +' + test_expect_success 'force removal of nested git work tree' ' rm -fr foo bar baz && mkdir -p foo bar baz/boo && diff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh index 8f30aed6cc..3f609e8909 100755 --- a/t/t7410-submodule-checkout-to.sh +++ b/t/t7410-submodule-checkout-to.sh @@ -33,7 +33,7 @@ rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1 test_expect_success 'checkout main' \ 'mkdir default_checkout && (cd clone/main && - git checkout --to "$base_path/default_checkout/main" "$rev1_hash_main")' + git worktree add "$base_path/default_checkout/main" "$rev1_hash_main")' test_expect_failure 'can see submodule diffs just after checkout' \ '(cd default_checkout/main && git diff --submodule master"^!" | grep "file1 updated")' @@ -41,7 +41,7 @@ test_expect_failure 'can see submodule diffs just after checkout' \ test_expect_success 'checkout main and initialize independed clones' \ 'mkdir fully_cloned_submodule && (cd clone/main && - git checkout --to "$base_path/fully_cloned_submodule/main" "$rev1_hash_main") && + git worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main") && (cd fully_cloned_submodule/main && git submodule update)' test_expect_success 'can see submodule diffs after independed cloning' \ diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index 2e0d557243..b39e313ac2 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -229,14 +229,36 @@ test_expect_success 'cleanup commit messages (scissors option,-F,-e)' ' cat >text <<EOF && # to be kept + + # ------------------------ >8 ------------------------ +# to be kept, too # ------------------------ >8 ------------------------ to be removed +# ------------------------ >8 ------------------------ +to be removed, too +EOF + + cat >expect <<EOF && +# to be kept + + # ------------------------ >8 ------------------------ +# to be kept, too EOF - echo "# to be kept" >expect && git commit --cleanup=scissors -e -F text -a && git cat-file -p HEAD |sed -e "1,/^\$/d">actual && test_cmp expect actual +' +test_expect_success 'cleanup commit messages (scissors option,-F,-e, scissors on first line)' ' + + echo >>negative && + cat >text <<EOF && +# ------------------------ >8 ------------------------ +to be removed +EOF + git commit --cleanup=scissors -e -F text -a --allow-empty-message && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + test_must_be_empty actual ' test_expect_success 'cleanup commit messages (strip option,-F)' ' diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 13331e533b..18e5cf0663 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -81,6 +81,44 @@ test_expect_success GPG 'verify and show signatures' ' ) ' +test_expect_success GPG 'verify-commit exits success on untrusted signature' ' + git verify-commit eighth-signed-alt 2>actual && + grep "Good signature from" actual && + ! grep "BAD signature from" actual && + grep "not certified" actual +' + +test_expect_success GPG 'verify signatures with --raw' ' + ( + for commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed + do + git verify-commit --raw $commit 2>actual && + grep "GOODSIG" actual && + ! grep "BADSIG" actual && + echo $commit OK || exit 1 + done + ) && + ( + for commit in merge^2 fourth-unsigned sixth-unsigned seventh-unsigned + do + test_must_fail git verify-commit --raw $commit 2>actual && + ! grep "GOODSIG" actual && + ! grep "BADSIG" actual && + echo $commit OK || exit 1 + done + ) && + ( + for commit in eighth-signed-alt + do + git verify-commit --raw $commit 2>actual && + grep "GOODSIG" actual && + ! grep "BADSIG" actual && + grep "TRUST_UNDEFINED" actual && + echo $commit OK || exit 1 + done + ) +' + test_expect_success GPG 'show signed commit with signature' ' git show -s initial >commit && git show -s --show-signature initial >show && diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh index 5cdf3f178e..ff09aced68 100755 --- a/t/t8002-blame.sh +++ b/t/t8002-blame.sh @@ -19,4 +19,66 @@ test_expect_success 'blame --show-email' ' "<E at test dot git>" 1 ' +test_expect_success 'setup showEmail tests' ' + echo "bin: test number 1" >one && + git add one && + GIT_AUTHOR_NAME=name1 \ + GIT_AUTHOR_EMAIL=email1@test.git \ + git commit -m First --date="2010-01-01 01:00:00" && + cat >expected_n <<-\EOF && + (name1 2010-01-01 01:00:00 +0000 1) bin: test number 1 + EOF + cat >expected_e <<-\EOF + (<email1@test.git> 2010-01-01 01:00:00 +0000 1) bin: test number 1 + EOF +' + +find_blame () { + sed -e 's/^[^(]*//' +} + +test_expect_success 'blame with no options and no config' ' + git blame one >blame && + find_blame <blame >result && + test_cmp expected_n result +' + +test_expect_success 'blame with showemail options' ' + git blame --show-email one >blame1 && + find_blame <blame1 >result && + test_cmp expected_e result && + git blame -e one >blame2 && + find_blame <blame2 >result && + test_cmp expected_e result && + git blame --no-show-email one >blame3 && + find_blame <blame3 >result && + test_cmp expected_n result +' + +test_expect_success 'blame with showEmail config false' ' + git config blame.showEmail false && + git blame one >blame1 && + find_blame <blame1 >result && + test_cmp expected_n result && + git blame --show-email one >blame2 && + find_blame <blame2 >result && + test_cmp expected_e result && + git blame -e one >blame3 && + find_blame <blame3 >result && + test_cmp expected_e result && + git blame --no-show-email one >blame4 && + find_blame <blame4 >result && + test_cmp expected_n result +' + +test_expect_success 'blame with showEmail config true' ' + git config blame.showEmail true && + git blame one >blame1 && + find_blame <blame1 >result && + test_cmp expected_e result && + git blame --no-show-email one >blame2 && + find_blame <blame2 >result && + test_cmp expected_n result +' + test_done diff --git a/t/t9000-addresses.sh b/t/t9000-addresses.sh new file mode 100755 index 0000000000..a1ebef6de2 --- /dev/null +++ b/t/t9000-addresses.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +test_description='compare address parsing with and without Mail::Address' +. ./test-lib.sh + +if ! test_have_prereq PERL; then + skip_all='skipping perl interface tests, perl not available' + test_done +fi + +perl -MTest::More -e 0 2>/dev/null || { + skip_all="Perl Test::More unavailable, skipping test" + test_done +} + +perl -MMail::Address -e 0 2>/dev/null || { + skip_all="Perl Mail::Address unavailable, skipping test" + test_done +} + +test_external_has_tap=1 + +test_external_without_stderr \ + 'Perl address parsing function' \ + perl "$TEST_DIRECTORY"/t9000/test.pl + +test_done diff --git a/t/t9000/test.pl b/t/t9000/test.pl new file mode 100755 index 0000000000..2d05d3eeab --- /dev/null +++ b/t/t9000/test.pl @@ -0,0 +1,67 @@ +#!/usr/bin/perl +use lib (split(/:/, $ENV{GITPERLLIB})); + +use 5.008; +use warnings; +use strict; + +use Test::More qw(no_plan); +use Mail::Address; + +BEGIN { use_ok('Git') } + +my @success_list = (q[Jane], + q[jdoe@example.com], + q[<jdoe@example.com>], + q[Jane <jdoe@example.com>], + q[Jane Doe <jdoe@example.com>], + q["Jane" <jdoe@example.com>], + q["Doe, Jane" <jdoe@example.com>], + q["Jane@:;\>.,()<Doe" <jdoe@example.com>], + q[Jane!#$%&'*+-/=?^_{|}~Doe' <jdoe@example.com>], + q["<jdoe@example.com>"], + q["Jane jdoe@example.com"], + q[Jane Doe <jdoe @ example.com >], + q[Jane Doe < jdoe@example.com >], + q[Jane @ Doe @ Jane @ Doe], + q["Jane, 'Doe'" <jdoe@example.com>], + q['Doe, "Jane' <jdoe@example.com>], + q["Jane" "Do"e <jdoe@example.com>], + q["Jane' Doe" <jdoe@example.com>], + q["Jane Doe <jdoe@example.com>" <jdoe@example.com>], + q["Jane\" Doe" <jdoe@example.com>], + q[Doe, jane <jdoe@example.com>], + q["Jane Doe <jdoe@example.com>], + q['Jane 'Doe' <jdoe@example.com>]); + +my @known_failure_list = (q[Jane\ Doe <jdoe@example.com>], + q["Doe, Ja"ne <jdoe@example.com>], + q["Doe, Katarina" Jane <jdoe@example.com>], + q[Jane@:;\.,()<>Doe <jdoe@example.com>], + q[Jane jdoe@example.com], + q[<jdoe@example.com> Jane Doe], + q[Jane <jdoe@example.com> Doe], + q["Jane "Kat"a" ri"na" ",Doe" <jdoe@example.com>], + q[Jane Doe], + q[Jane "Doe <jdoe@example.com>"], + q[\"Jane Doe <jdoe@example.com>], + q[Jane\"\" Doe <jdoe@example.com>], + q['Jane "Katarina\" \' Doe' <jdoe@example.com>]); + +foreach my $str (@success_list) { + my @expected = map { $_->format } Mail::Address->parse("$str"); + my @actual = Git::parse_mailboxes("$str"); + is_deeply(\@expected, \@actual, qq[same output : $str]); +} + +TODO: { + local $TODO = "known breakage"; + foreach my $str (@known_failure_list) { + my @expected = map { $_->format } Mail::Address->parse("$str"); + my @actual = Git::parse_mailboxes("$str"); + is_deeply(\@expected, \@actual, qq[same output : $str]); + } +} + +my $is_passing = eval { Test::More->is_passing }; +exit($is_passing ? 0 : 1) unless $@ =~ /Can't locate object method/; diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index a3663da49b..5b4a5ce06b 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -312,13 +312,19 @@ test_expect_success $PREREQ,!AUTOIDENT 'broken implicit ident aborts send-email' ) ' +test_expect_success $PREREQ 'setup tocmd and cccmd scripts' ' + write_script tocmd-sed <<-\EOF && + sed -n -e "s/^tocmd--//p" "$1" + EOF + write_script cccmd-sed <<-\EOF + sed -n -e "s/^cccmd--//p" "$1" + EOF +' + test_expect_success $PREREQ 'tocmd works' ' clean_fake_sendmail && cp $patches tocmd.patch && echo tocmd--tocmd@example.com >>tocmd.patch && - write_script tocmd-sed <<-\EOF && - sed -n -e "s/^tocmd--//p" "$1" - EOF git send-email \ --from="Example <nobody@example.com>" \ --to-cmd=./tocmd-sed \ @@ -332,9 +338,6 @@ test_expect_success $PREREQ 'cccmd works' ' clean_fake_sendmail && cp $patches cccmd.patch && echo "cccmd-- cccmd@example.com" >>cccmd.patch && - write_script cccmd-sed <<-\EOF && - sed -n -e "s/^cccmd--//p" "$1" - EOF git send-email \ --from="Example <nobody@example.com>" \ --to=nobody@example.com \ @@ -519,6 +522,12 @@ Result: OK EOF " +replace_variable_fields () { + sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \ + -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \ + -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" +} + test_suppression () { git send-email \ --dry-run \ @@ -526,10 +535,7 @@ test_suppression () { --from="Example <from@example.com>" \ --to=to@example.com \ --smtp-server relay.example.com \ - $patches | - sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \ - -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \ - -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \ + $patches | replace_variable_fields \ >actual-suppress-$1${2+"-$2"} && test_cmp expected-suppress-$1${2+"-$2"} actual-suppress-$1${2+"-$2"} } @@ -1549,10 +1555,35 @@ test_expect_success $PREREQ 'sendemail.aliasfile=~/.mailrc' ' grep "^!someone@example\.org!$" commandline1 ' -test_expect_success $PREREQ 'sendemail.aliasfiletype=sendmail' ' - clean_fake_sendmail && rm -fr outdir && - git format-patch -1 -o outdir && - cat >>.tmp-email-aliases <<-\EOF && +test_sendmail_aliases () { + msg="$1" && shift && + expect="$@" && + cat >.tmp-email-aliases && + + test_expect_success $PREREQ "$msg" ' + clean_fake_sendmail && rm -fr outdir && + git format-patch -1 -o outdir && + git config --replace-all sendemail.aliasesfile \ + "$(pwd)/.tmp-email-aliases" && + git config sendemail.aliasfiletype sendmail && + git send-email \ + --from="Example <nobody@example.com>" \ + --to=alice --to=bcgrp \ + --smtp-server="$(pwd)/fake.sendmail" \ + outdir/0001-*.patch \ + 2>errors >out && + for i in $expect + do + grep "^!$i!$" commandline1 || return 1 + done + ' +} + +test_sendmail_aliases 'sendemail.aliasfiletype=sendmail' \ + 'awol@example\.com' \ + 'bob@example\.com' \ + 'chloe@example\.com' \ + 'o@example\.com' <<-\EOF alice: Alice W Land <awol@example.com> bob: Robert Bobbyton <bob@example.com> # this is a comment @@ -1561,19 +1592,99 @@ test_expect_success $PREREQ 'sendemail.aliasfiletype=sendmail' ' abgroup: alice, bob bcgrp: bob, chloe, Other <o@example.com> EOF - git config --replace-all sendemail.aliasesfile \ - "$(pwd)/.tmp-email-aliases" && - git config sendemail.aliasfiletype sendmail && + +test_sendmail_aliases 'sendmail aliases line folding' \ + alice1 \ + bob1 bob2 \ + chuck1 chuck2 \ + darla1 darla2 darla3 \ + elton1 elton2 elton3 \ + fred1 fred2 \ + greg1 <<-\EOF + alice: alice1 + bob: bob1,\ + bob2 + chuck: chuck1, + chuck2 + darla: darla1,\ + darla2, + darla3 + elton: elton1, + elton2,\ + elton3 + fred: fred1,\ + fred2 + greg: greg1 + bcgrp: bob, chuck, darla, elton, fred, greg + EOF + +test_sendmail_aliases 'sendmail aliases tolerate bogus line folding' \ + alice1 bob1 <<-\EOF + alice: alice1 + bcgrp: bob1\ + EOF + +test_sendmail_aliases 'sendmail aliases empty' alice bcgrp <<-\EOF + EOF + +test_expect_success $PREREQ 'alias support in To header' ' + clean_fake_sendmail && + echo "alias sbd someone@example.org" >.mailrc && + test_config sendemail.aliasesfile ".mailrc" && + test_config sendemail.aliasfiletype mailrc && + git format-patch --stdout -1 --to=sbd >aliased.patch && git send-email \ --from="Example <nobody@example.com>" \ - --to=alice --to=bcgrp \ --smtp-server="$(pwd)/fake.sendmail" \ - outdir/0001-*.patch \ + aliased.patch \ 2>errors >out && - grep "^!awol@example\.com!$" commandline1 && - grep "^!bob@example\.com!$" commandline1 && - grep "^!chloe@example\.com!$" commandline1 && - grep "^!o@example\.com!$" commandline1 + grep "^!someone@example\.org!$" commandline1 +' + +test_expect_success $PREREQ 'alias support in Cc header' ' + clean_fake_sendmail && + echo "alias sbd someone@example.org" >.mailrc && + test_config sendemail.aliasesfile ".mailrc" && + test_config sendemail.aliasfiletype mailrc && + git format-patch --stdout -1 --cc=sbd >aliased.patch && + git send-email \ + --from="Example <nobody@example.com>" \ + --smtp-server="$(pwd)/fake.sendmail" \ + aliased.patch \ + 2>errors >out && + grep "^!someone@example\.org!$" commandline1 +' + +test_expect_success $PREREQ 'tocmd works with aliases' ' + clean_fake_sendmail && + echo "alias sbd someone@example.org" >.mailrc && + test_config sendemail.aliasesfile ".mailrc" && + test_config sendemail.aliasfiletype mailrc && + git format-patch --stdout -1 >tocmd.patch && + echo tocmd--sbd >>tocmd.patch && + git send-email \ + --from="Example <nobody@example.com>" \ + --to-cmd=./tocmd-sed \ + --smtp-server="$(pwd)/fake.sendmail" \ + tocmd.patch \ + 2>errors >out && + grep "^!someone@example\.org!$" commandline1 +' + +test_expect_success $PREREQ 'cccmd works with aliases' ' + clean_fake_sendmail && + echo "alias sbd someone@example.org" >.mailrc && + test_config sendemail.aliasesfile ".mailrc" && + test_config sendemail.aliasfiletype mailrc && + git format-patch --stdout -1 >cccmd.patch && + echo cccmd--sbd >>cccmd.patch && + git send-email \ + --from="Example <nobody@example.com>" \ + --cc-cmd=./cccmd-sed \ + --smtp-server="$(pwd)/fake.sendmail" \ + cccmd.patch \ + 2>errors >out && + grep "^!someone@example\.org!$" commandline1 ' do_xmailer_test () { @@ -1609,4 +1720,72 @@ test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=false' ' do_xmailer_test 1 "--xmailer" ' +test_expect_success $PREREQ 'setup expected-list' ' + git send-email \ + --dry-run \ + --from="Example <from@example.com>" \ + --to="To 1 <to1@example.com>" \ + --to="to2@example.com" \ + --to="to3@example.com" \ + --cc="Cc 1 <cc1@example.com>" \ + --cc="Cc2 <cc2@example.com>" \ + --bcc="bcc1@example.com" \ + --bcc="bcc2@example.com" \ + 0001-add-master.patch | replace_variable_fields \ + >expected-list +' + +test_expect_success $PREREQ 'use email list in --cc --to and --bcc' ' + git send-email \ + --dry-run \ + --from="Example <from@example.com>" \ + --to="To 1 <to1@example.com>, to2@example.com" \ + --to="to3@example.com" \ + --cc="Cc 1 <cc1@example.com>, Cc2 <cc2@example.com>" \ + --bcc="bcc1@example.com, bcc2@example.com" \ + 0001-add-master.patch | replace_variable_fields \ + >actual-list && + test_cmp expected-list actual-list +' + +test_expect_success $PREREQ 'aliases work with email list' ' + echo "alias to2 to2@example.com" >.mutt && + echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt && + test_config sendemail.aliasesfile ".mutt" && + test_config sendemail.aliasfiletype mutt && + git send-email \ + --dry-run \ + --from="Example <from@example.com>" \ + --to="To 1 <to1@example.com>, to2, to3@example.com" \ + --cc="cc1, Cc2 <cc2@example.com>" \ + --bcc="bcc1@example.com, bcc2@example.com" \ + 0001-add-master.patch | replace_variable_fields \ + >actual-list && + test_cmp expected-list actual-list +' + +test_expect_success $PREREQ 'leading and trailing whitespaces are removed' ' + echo "alias to2 to2@example.com" >.mutt && + echo "alias cc1 Cc 1 <cc1@example.com>" >>.mutt && + test_config sendemail.aliasesfile ".mutt" && + test_config sendemail.aliasfiletype mutt && + TO1=$(echo "QTo 1 <to1@example.com>" | q_to_tab) && + TO2=$(echo "QZto2" | qz_to_tab_space) && + CC1=$(echo "cc1" | append_cr) && + BCC1=$(echo "Q bcc1@example.com Q" | q_to_nul) && + git send-email \ + --dry-run \ + --from=" Example <from@example.com>" \ + --to="$TO1" \ + --to="$TO2" \ + --to=" to3@example.com " \ + --cc="$CC1" \ + --cc="Cc2 <cc2@example.com>" \ + --bcc="$BCC1" \ + --bcc="bcc2@example.com" \ + 0001-add-master.patch | replace_variable_fields \ + >actual-list && + test_cmp expected-list actual-list +' + test_done diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh index 5b562122a1..90d41ed954 100755 --- a/t/t9800-git-p4-basic.sh +++ b/t/t9800-git-p4-basic.sh @@ -131,6 +131,44 @@ test_expect_success 'clone two dirs, @all, conflicting files' ' ) ' +revision_ranges="2000/01/01,#head \ + 1,2080/01/01 \ + 2000/01/01,2080/01/01 \ + 2000/01/01,1000 \ + 1,1000" + +test_expect_success 'clone using non-numeric revision ranges' ' + test_when_finished cleanup_git && + for r in $revision_ranges + do + rm -fr "$git" && + test ! -d "$git" && + git p4 clone --dest="$git" //depot@$r && + ( + cd "$git" && + git ls-files >lines && + test_line_count = 6 lines + ) + done +' + +test_expect_success 'clone with date range, excluding some changes' ' + test_when_finished cleanup_git && + before=$(date +%Y/%m/%d:%H:%M:%S) && + sleep 2 && + ( + cd "$cli" && + :>date_range_test && + p4 add date_range_test && + p4 submit -d "Adding file" + ) && + git p4 clone --dest="$git" //depot@1,$before && + ( + cd "$git" && + test_path_is_missing date_range_test + ) +' + test_expect_success 'exit when p4 fails to produce marshaled output' ' mkdir badp4dir && test_when_finished "rm badp4dir/p4 && rmdir badp4dir" && diff --git a/t/t9818-git-p4-block.sh b/t/t9818-git-p4-block.sh index 153b20afbd..3b3ae1f59a 100755 --- a/t/t9818-git-p4-block.sh +++ b/t/t9818-git-p4-block.sh @@ -8,18 +8,34 @@ test_expect_success 'start p4d' ' start_p4d ' -test_expect_success 'Create a repo with ~100 changes' ' +create_restricted_group() { + p4 group -i <<-EOF + Group: restricted + MaxResults: 7 + MaxScanRows: 40 + Users: author + EOF +} + +test_expect_success 'Create group with limited maxrows' ' + create_restricted_group +' + +test_expect_success 'Create a repo with many changes' ' ( - cd "$cli" && + client_view "//depot/included/... //client/included/..." \ + "//depot/excluded/... //client/excluded/..." && + mkdir -p "$cli/included" "$cli/excluded" && + cd "$cli/included" && >file.txt && p4 add file.txt && p4 submit -d "Add file.txt" && - for i in $(test_seq 0 9) + for i in $(test_seq 0 5) do >outer$i.txt && p4 add outer$i.txt && p4 submit -d "Adding outer$i.txt" && - for j in $(test_seq 0 9) + for j in $(test_seq 0 5) do p4 edit file.txt && echo $i$j >file.txt && @@ -29,34 +45,73 @@ test_expect_success 'Create a repo with ~100 changes' ' ) ' +test_expect_success 'Default user cannot fetch changes' ' + ! p4 changes -m 1 //depot/... +' + test_expect_success 'Clone the repo' ' - git p4 clone --dest="$git" --changes-block-size=10 --verbose //depot@all + git p4 clone --dest="$git" --changes-block-size=7 --verbose //depot/included@all ' test_expect_success 'All files are present' ' echo file.txt >expected && test_write_lines outer0.txt outer1.txt outer2.txt outer3.txt outer4.txt >>expected && - test_write_lines outer5.txt outer6.txt outer7.txt outer8.txt outer9.txt >>expected && + test_write_lines outer5.txt >>expected && ls "$git" >current && test_cmp expected current ' test_expect_success 'file.txt is correct' ' - echo 99 >expected && + echo 55 >expected && test_cmp expected "$git/file.txt" ' test_expect_success 'Correct number of commits' ' (cd "$git" && git log --oneline) >log && - test_line_count = 111 log + wc -l log && + test_line_count = 43 log ' test_expect_success 'Previous version of file.txt is correct' ' (cd "$git" && git checkout HEAD^^) && - echo 97 >expected && + echo 53 >expected && test_cmp expected "$git/file.txt" ' +# Test git-p4 sync, with some files outside the client specification. + +p4_add_file() { + (cd "$cli" && + >$1 && + p4 add $1 && + p4 submit -d "Added a file" $1 + ) +} + +test_expect_success 'Add some more files' ' + for i in $(test_seq 0 10) + do + p4_add_file "included/x$i" && + p4_add_file "excluded/x$i" + done && + for i in $(test_seq 0 10) + do + p4_add_file "excluded/y$i" + done +' + +# This should pick up the 10 new files in "included", but not be confused +# by the additional files in "excluded" +test_expect_success 'Syncing files' ' + ( + cd "$git" && + git p4 sync --changes-block-size=7 && + git checkout p4/master && + ls -l x* > log && + test_line_count = 11 log + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/test-lib.sh b/t/test-lib.sh index 39da9c2d99..cea6cda604 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -15,9 +15,6 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/ . -# Keep the original TERM for say_color -ORIGINAL_TERM=$TERM - # Test the binaries we have just built. The tests are kept in # t/ subdirectory and are run in 'trash directory' subdirectory. if test -z "$TEST_DIRECTORY" @@ -68,12 +65,12 @@ done,*) esac # For repeatability, reset the environment to known value. +# TERM is sanitized below, after saving color control sequences. LANG=C LC_ALL=C PAGER=cat TZ=UTC -TERM=dumb -export LANG LC_ALL PAGER TERM TZ +export LANG LC_ALL PAGER TZ EDITOR=: # A call to "unset" with no arguments causes at least Solaris 10 # /usr/xpg4/bin/sh and /bin/ksh to bail out. So keep the unsets @@ -181,8 +178,14 @@ export _x05 _x40 _z40 LF u200c # This test checks if command xyzzy does the right thing... # ' # . ./test-lib.sh +test "x$TERM" != "xdumb" && ( + test -t 1 && + tput bold >/dev/null 2>&1 && + tput setaf 1 >/dev/null 2>&1 && + tput sgr0 >/dev/null 2>&1 + ) && + color=t -unset color while test "$#" -ne 0 do case "$1" in @@ -253,6 +256,44 @@ then verbose=t fi +if test -n "$color" +then + # Save the color control sequences now rather than run tput + # each time say_color() is called. This is done for two + # reasons: + # * TERM will be changed to dumb + # * HOME will be changed to a temporary directory and tput + # might need to read ~/.terminfo from the original HOME + # directory to get the control sequences + # Note: This approach assumes the control sequences don't end + # in a newline for any terminal of interest (command + # substitutions strip trailing newlines). Given that most + # (all?) terminals in common use are related to ECMA-48, this + # shouldn't be a problem. + say_color_error=$(tput bold; tput setaf 1) # bold red + say_color_skip=$(tput setaf 4) # blue + say_color_warn=$(tput setaf 3) # brown/yellow + say_color_pass=$(tput setaf 2) # green + say_color_info=$(tput setaf 6) # cyan + say_color_reset=$(tput sgr0) + say_color_="" # no formatting for normal text + say_color () { + test -z "$1" && test -n "$quiet" && return + eval "say_color_color=\$say_color_$1" + shift + printf "%s\\n" "$say_color_color$*$say_color_reset" + } +else + say_color() { + test -z "$1" && test -n "$quiet" && return + shift + printf "%s\n" "$*" + } +fi + +TERM=dumb +export TERM + error () { say_color error "error: $*" GIT_EXIT_OK=t @@ -829,52 +870,6 @@ HOME="$TRASH_DIRECTORY" GNUPGHOME="$HOME/gnupg-home-not-used" export HOME GNUPGHOME -# run the tput tests *after* changing HOME (in case ncurses needs -# ~/.terminfo for $TERM) -test -n "${color+set}" || test "x$ORIGINAL_TERM" != "xdumb" && ( - TERM=$ORIGINAL_TERM && - export TERM && - test -t 1 && - tput bold >/dev/null 2>&1 && - tput setaf 1 >/dev/null 2>&1 && - tput sgr0 >/dev/null 2>&1 - ) && - color=t - -if test -n "$color" -then - say_color () { - ( - TERM=$ORIGINAL_TERM - export TERM - case "$1" in - error) - tput bold; tput setaf 1;; # bold red - skip) - tput setaf 4;; # blue - warn) - tput setaf 3;; # brown/yellow - pass) - tput setaf 2;; # green - info) - tput setaf 6;; # cyan - *) - test -n "$quiet" && return;; - esac - shift - printf "%s" "$*" - tput sgr0 - echo - ) - } -else - say_color() { - test -z "$1" && test -n "$quiet" && return - shift - printf "%s\n" "$*" - } -fi - if test -z "$TEST_NO_CREATE_REPO" then test_create_repo "$TRASH_DIRECTORY" |