diff options
Diffstat (limited to 't')
35 files changed, 1763 insertions, 81 deletions
diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 6bd252212a..9a96e1566d 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -14,7 +14,7 @@ # specified line. # # "<cmd> <lineno>" -- add a line with the specified command -# ("squash", "fixup", "edit", or "reword") and the SHA1 taken +# ("squash", "fixup", "edit", "reword" or "drop") and the SHA1 taken # from the specified line. # # "exec_cmd_with_args" -- add an "exec cmd with args" line. @@ -46,7 +46,7 @@ set_fake_editor () { action=pick for line in $FAKE_LINES; do case $line in - squash|fixup|edit|reword) + squash|fixup|edit|reword|drop) action="$line";; exec*) echo "$line" | sed 's/_/ /g' >> "$1";; @@ -54,6 +54,11 @@ set_fake_editor () { echo '# comment' >> "$1";; ">") echo >> "$1";; + bad) + action="badcmd";; + fakesha) + echo "$action XXXXXXX False commit" >> "$1" + action=pick;; *) sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1" action=pick;; 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/t1006-cat-file.sh b/t/t1006-cat-file.sh index 93a4794930..4f38078ff3 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -547,4 +547,30 @@ test_expect_success 'git cat-file --batch --follow-symlink returns correct sha a test_cmp expect actual ' +test_expect_success 'cat-file --batch-all-objects shows all objects' ' + # make new repos so we know the full set of objects; we will + # also make sure that there are some packed and some loose + # objects, some referenced and some not, and that there are + # some available only via alternates. + git init all-one && + ( + cd all-one && + echo content >file && + git add file && + git commit -qm base && + git rev-parse HEAD HEAD^{tree} HEAD:file && + git repack -ad && + echo not-cloned | git hash-object -w --stdin + ) >expect.unsorted && + git clone -s all-one all-two && + ( + cd all-two && + echo local-unref | git hash-object -w --stdin + ) >>expect.unsorted && + sort <expect.unsorted >expect && + git -C all-two cat-file --batch-all-objects \ + --batch-check="%(objectname)" >actual && + test_cmp expect actual +' + test_done diff --git a/t/t1090-sparse-checkout-scope.sh b/t/t1090-sparse-checkout-scope.sh new file mode 100755 index 0000000000..1f61eb3e88 --- /dev/null +++ b/t/t1090-sparse-checkout-scope.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +test_description='sparse checkout scope tests' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo "initial" >a && + echo "initial" >b && + echo "initial" >c && + git add a b c && + git commit -m "initial commit" +' + +test_expect_success 'create feature branch' ' + git checkout -b feature && + echo "modified" >b && + echo "modified" >c && + git add b c && + git commit -m "modification" +' + +test_expect_success 'perform sparse checkout of master' ' + git config --local --bool core.sparsecheckout true && + echo "!/*" >.git/info/sparse-checkout && + echo "/a" >>.git/info/sparse-checkout && + echo "/c" >>.git/info/sparse-checkout && + git checkout master && + test_path_is_file a && + test_path_is_missing b && + test_path_is_file c +' + +test_expect_success 'merge feature branch into sparse checkout of master' ' + git merge feature && + test_path_is_file a && + test_path_is_missing b && + test_path_is_file c && + test "$(cat c)" = "modified" +' + +test_expect_success 'return to full checkout of master' ' + git checkout feature && + echo "/*" >.git/info/sparse-checkout && + git checkout master && + test_path_is_file a && + test_path_is_file b && + test_path_is_file c && + test "$(cat b)" = "modified" +' + +test_done diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index d787bf50f8..9d21c1927e 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -23,6 +23,7 @@ test_expect_success setup ' m=refs/heads/master n_dir=refs/heads/gu n=$n_dir/fixes +outside=foo test_expect_success \ "create $m" \ @@ -74,6 +75,24 @@ test_expect_success "delete $m (by HEAD)" ' ' rm -f .git/$m +test_expect_success 'update-ref does not create reflogs by default' ' + test_when_finished "git update-ref -d $outside" && + git update-ref $outside $A && + git rev-parse $A >expect && + git rev-parse $outside >actual && + test_cmp expect actual && + test_must_fail git reflog exists $outside +' + +test_expect_success 'update-ref creates reflogs with --create-reflog' ' + test_when_finished "git update-ref -d $outside" && + git update-ref --create-reflog $outside $A && + git rev-parse $A >expect && + git rev-parse $outside >actual && + test_cmp expect actual && + git reflog exists $outside +' + test_expect_success \ "create $m (by HEAD)" \ "git update-ref HEAD $A && @@ -472,6 +491,25 @@ test_expect_success 'stdin create ref works' ' test_cmp expect actual ' +test_expect_success 'stdin does not create reflogs by default' ' + test_when_finished "git update-ref -d $outside" && + echo "create $outside $m" >stdin && + git update-ref --stdin <stdin && + git rev-parse $m >expect && + git rev-parse $outside >actual && + test_cmp expect actual && + test_must_fail git reflog exists $outside +' + +test_expect_success 'stdin creates reflogs with --create-reflog' ' + echo "create $outside $m" >stdin && + git update-ref --create-reflog --stdin <stdin && + git rev-parse $m >expect && + git rev-parse $outside >actual && + test_cmp expect actual && + git reflog exists $outside +' + test_expect_success 'stdin succeeds with quoted argument' ' git update-ref -d $a && echo "create $a \"$m\"" >stdin && diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh index e5dc62e9ef..0790edf60d 100755 --- a/t/t1402-check-ref-format.sh +++ b/t/t1402-check-ref-format.sh @@ -62,9 +62,11 @@ invalid_ref 'heads/foo\bar' invalid_ref "$(printf 'heads/foo\t')" invalid_ref "$(printf 'heads/foo\177')" valid_ref "$(printf 'heads/fu\303\237')" -invalid_ref 'heads/*foo/bar' --refspec-pattern -invalid_ref 'heads/foo*/bar' --refspec-pattern -invalid_ref 'heads/f*o/bar' --refspec-pattern +valid_ref 'heads/*foo/bar' --refspec-pattern +valid_ref 'heads/foo*/bar' --refspec-pattern +valid_ref 'heads/f*o/bar' --refspec-pattern +invalid_ref 'heads/f*o*/bar' --refspec-pattern +invalid_ref 'heads/foo*/bar*' --refspec-pattern ref='foo' invalid_ref "$ref" diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh index 6f47c0dd0e..3eb4f102e5 100755 --- a/t/t1411-reflog-show.sh +++ b/t/t1411-reflog-show.sh @@ -166,4 +166,9 @@ test_expect_success 'git log -g -p shows diffs vs. parents' ' test_cmp expect actual ' +test_expect_success 'reflog exists works' ' + git reflog exists refs/heads/master && + ! git reflog exists refs/heads/nonexistent +' + test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index cfb32b6242..956673b8a1 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -231,8 +231,8 @@ test_expect_success 'tag with incorrect tag name & missing tagger' ' git fsck --tags 2>out && cat >expect <<-EOF && - warning in tag $tag: invalid '\''tag'\'' name: wrong name format - warning in tag $tag: invalid format - expected '\''tagger'\'' line + warning in tag $tag: badTagName: invalid '\''tag'\'' name: wrong name format + warning in tag $tag: missingTaggerEntry: invalid format - expected '\''tagger'\'' line EOF test_cmp expect out ' @@ -287,6 +287,17 @@ test_expect_success 'rev-list --verify-objects with bad sha1' ' grep -q "error: sha1 mismatch 63ffffffffffffffffffffffffffffffffffffff" out ' +test_expect_success 'force fsck to ignore double author' ' + git cat-file commit HEAD >basis && + sed "s/^author .*/&,&/" <basis | tr , \\n >multiple-authors && + new=$(git hash-object -t commit -w --stdin <multiple-authors) && + test_when_finished "remove_object $new" && + git update-ref refs/heads/bogus "$new" && + test_when_finished "git update-ref -d refs/heads/bogus" && + test_must_fail git fsck && + git -c fsck.multipleAuthors=ignore fsck +' + _bz='\0' _bz5="$_bz$_bz$_bz$_bz$_bz" _bz20="$_bz5$_bz5$_bz5$_bz5" @@ -420,4 +431,26 @@ test_expect_success 'fsck notices ref pointing to missing tag' ' test_must_fail git -C missing fsck ' +test_expect_success 'fsck --connectivity-only' ' + rm -rf connectivity-only && + git init connectivity-only && + ( + cd connectivity-only && + touch empty && + git add empty && + test_commit empty && + empty=.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 && + rm -f $empty && + echo invalid >$empty && + test_must_fail git fsck --strict && + git fsck --strict --connectivity-only && + tree=$(git rev-parse HEAD:) && + suffix=${tree#??} && + tree=.git/objects/${tree%$suffix}/$suffix && + rm -f $tree && + echo invalid >$tree && + test_must_fail git fsck --strict --connectivity-only + ) +' + test_done diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index ebe7c3b87c..310f93fd30 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -3,7 +3,40 @@ test_description='test git rev-parse --parseopt' . ./test-lib.sh -sed -e 's/^|//' >expect <<\END_EXPECT +test_expect_success 'setup optionspec' ' + sed -e "s/^|//" >optionspec <<\EOF +|some-command [options] <args>... +| +|some-command does foo and bar! +|-- +|h,help show the help +| +|foo some nifty option --foo +|bar= some cool option --bar with an argument +|b,baz a short and long option +| +| An option group Header +|C? option C with an optional argument +|d,data? short and long option with an optional argument +| +| Argument hints +|B=arg short option required argument +|bar2=arg long option required argument +|e,fuz=with-space short and long option required argument +|s?some short option optional argument +|long?data long option optional argument +|g,fluf?path short and long option optional argument +|longest=very-long-argument-hint a very long argument hint +|pair=key=value with an equals sign in the hint +|short-hint=a with a one symbol hint +| +|Extras +|extra1 line above used to cause a segfault but no longer does +EOF +' + +test_expect_success 'test --parseopt help output' ' + sed -e "s/^|//" >expect <<\END_EXPECT && |cat <<\EOF |usage: some-command [options] <args>... | @@ -28,49 +61,23 @@ sed -e 's/^|//' >expect <<\END_EXPECT | -g, --fluf[=<path>] short and long option optional argument | --longest <very-long-argument-hint> | a very long argument hint +| --pair <key=value> with an equals sign in the hint +| --short-hint <a> with a one symbol hint | |Extras | --extra1 line above used to cause a segfault but no longer does | |EOF END_EXPECT - -sed -e 's/^|//' >optionspec <<\EOF -|some-command [options] <args>... -| -|some-command does foo and bar! -|-- -|h,help show the help -| -|foo some nifty option --foo -|bar= some cool option --bar with an argument -|b,baz a short and long option -| -| An option group Header -|C? option C with an optional argument -|d,data? short and long option with an optional argument -| -| Argument hints -|B=arg short option required argument -|bar2=arg long option required argument -|e,fuz=with-space short and long option required argument -|s?some short option optional argument -|long?data long option optional argument -|g,fluf?path short and long option optional argument -|longest=very-long-argument-hint a very long argument hint -| -|Extras -|extra1 line above used to cause a segfault but no longer does -EOF - -test_expect_success 'test --parseopt help output' ' test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec && test_i18ncmp expect output ' -cat > expect <<EOF +test_expect_success 'setup expect.1' " + cat > expect <<EOF set -- --foo --bar 'ham' -b -- 'arg' EOF +" test_expect_success 'test --parseopt' ' git rev-parse --parseopt -- --foo --bar=ham --baz arg < optionspec > output && @@ -82,9 +89,11 @@ test_expect_success 'test --parseopt with mixed options and arguments' ' test_cmp expect output ' -cat > expect <<EOF +test_expect_success 'setup expect.2' " + cat > expect <<EOF set -- --foo -- 'arg' '--bar=ham' EOF +" test_expect_success 'test --parseopt with --' ' git rev-parse --parseopt -- --foo -- arg --bar=ham < optionspec > output && @@ -96,54 +105,66 @@ test_expect_success 'test --parseopt --stop-at-non-option' ' test_cmp expect output ' -cat > expect <<EOF +test_expect_success 'setup expect.3' " + cat > expect <<EOF set -- --foo -- '--' 'arg' '--bar=ham' EOF +" test_expect_success 'test --parseopt --keep-dashdash' ' git rev-parse --parseopt --keep-dashdash -- --foo -- arg --bar=ham < optionspec > output && test_cmp expect output ' -cat >expect <<EOF +test_expect_success 'setup expect.4' " + cat >expect <<EOF set -- --foo -- '--' 'arg' '--spam=ham' EOF +" test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option with --' ' git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo -- arg --spam=ham <optionspec >output && test_cmp expect output ' -cat > expect <<EOF +test_expect_success 'setup expect.5' " + cat > expect <<EOF set -- --foo -- 'arg' '--spam=ham' EOF +" test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option without --' ' git rev-parse --parseopt --keep-dashdash --stop-at-non-option -- --foo arg --spam=ham <optionspec >output && test_cmp expect output ' -cat > expect <<EOF +test_expect_success 'setup expect.6' " + cat > expect <<EOF set -- --foo --bar='z' --baz -C'Z' --data='A' -- 'arg' EOF +" test_expect_success 'test --parseopt --stuck-long' ' git rev-parse --parseopt --stuck-long -- --foo --bar=z -b arg -CZ -dA <optionspec >output && test_cmp expect output ' -cat > expect <<EOF +test_expect_success 'setup expect.7' " + cat > expect <<EOF set -- --data='' -C --baz -- 'arg' EOF +" test_expect_success 'test --parseopt --stuck-long and empty optional argument' ' git rev-parse --parseopt --stuck-long -- --data= arg -C -b <optionspec >output && test_cmp expect output ' -cat > expect <<EOF +test_expect_success 'setup expect.8' " + cat > expect <<EOF set -- --data --baz -- 'arg' EOF +" test_expect_success 'test --parseopt --stuck-long and long option with unset optional argument' ' git rev-parse --parseopt --stuck-long -- --data arg -b <optionspec >output && diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 467e6c1ed5..9d26064aba 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -1123,4 +1123,127 @@ test_expect_success 'rebase --continue removes CHERRY_PICK_HEAD' ' test ! -f .git/CHERRY_PICK_HEAD ' +rebase_setup_and_clean () { + test_when_finished " + git checkout master && + test_might_fail git branch -D $1 && + test_might_fail git rebase --abort + " && + git checkout -b $1 master +} + +test_expect_success 'drop' ' + rebase_setup_and_clean drop-test && + set_fake_editor && + FAKE_LINES="1 drop 2 3 drop 4 5" git rebase -i --root && + test E = $(git cat-file commit HEAD | sed -ne \$p) && + test C = $(git cat-file commit HEAD^ | sed -ne \$p) && + test A = $(git cat-file commit HEAD^^ | sed -ne \$p) +' + +cat >expect <<EOF +Successfully rebased and updated refs/heads/missing-commit. +EOF + +test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' ' + test_config rebase.missingCommitsCheck ignore && + rebase_setup_and_clean missing-commit && + set_fake_editor && + FAKE_LINES="1 2 3 4" \ + git rebase -i --root 2>actual && + test D = $(git cat-file commit HEAD | sed -ne \$p) && + test_cmp expect actual +' + +cat >expect <<EOF +Warning: some commits may have been dropped accidentally. +Dropped commits (newer to older): + - $(git rev-list --pretty=oneline --abbrev-commit -1 master) +To avoid this message, use "drop" to explicitly remove a commit. + +Use 'git config rebase.missingCommitsCheck' to change the level of warnings. +The possible behaviours are: ignore, warn, error. + +Successfully rebased and updated refs/heads/missing-commit. +EOF + +test_expect_success 'rebase -i respects rebase.missingCommitsCheck = warn' ' + test_config rebase.missingCommitsCheck warn && + rebase_setup_and_clean missing-commit && + set_fake_editor && + FAKE_LINES="1 2 3 4" \ + git rebase -i --root 2>actual && + test_cmp expect actual && + test D = $(git cat-file commit HEAD | sed -ne \$p) +' + +cat >expect <<EOF +Warning: some commits may have been dropped accidentally. +Dropped commits (newer to older): + - $(git rev-list --pretty=oneline --abbrev-commit -1 master) + - $(git rev-list --pretty=oneline --abbrev-commit -1 master~2) +To avoid this message, use "drop" to explicitly remove a commit. + +Use 'git config rebase.missingCommitsCheck' to change the level of warnings. +The possible behaviours are: ignore, warn, error. + +You can fix this with 'git rebase --edit-todo'. +Or you can abort the rebase with 'git rebase --abort'. +EOF + +test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' ' + test_config rebase.missingCommitsCheck error && + rebase_setup_and_clean missing-commit && + set_fake_editor && + test_must_fail env FAKE_LINES="1 2 4" \ + git rebase -i --root 2>actual && + test_cmp expect actual && + cp .git/rebase-merge/git-rebase-todo.backup \ + .git/rebase-merge/git-rebase-todo && + FAKE_LINES="1 2 drop 3 4 drop 5" \ + git rebase --edit-todo && + git rebase --continue && + test D = $(git cat-file commit HEAD | sed -ne \$p) && + test B = $(git cat-file commit HEAD^ | sed -ne \$p) +' + +cat >expect <<EOF +Warning: the command isn't recognized in the following line: + - badcmd $(git rev-list --oneline -1 master~1) + +You can fix this with 'git rebase --edit-todo'. +Or you can abort the rebase with 'git rebase --abort'. +EOF + +test_expect_success 'static check of bad command' ' + rebase_setup_and_clean bad-cmd && + set_fake_editor && + test_must_fail env FAKE_LINES="1 2 3 bad 4 5" \ + git rebase -i --root 2>actual && + test_cmp expect actual && + FAKE_LINES="1 2 3 drop 4 5" git rebase --edit-todo && + git rebase --continue && + test E = $(git cat-file commit HEAD | sed -ne \$p) && + test C = $(git cat-file commit HEAD^ | sed -ne \$p) +' + +cat >expect <<EOF +Warning: the SHA-1 is missing or isn't a commit in the following line: + - edit XXXXXXX False commit + +You can fix this with 'git rebase --edit-todo'. +Or you can abort the rebase with 'git rebase --abort'. +EOF + +test_expect_success 'static check of bad SHA-1' ' + rebase_setup_and_clean bad-sha && + set_fake_editor && + test_must_fail env FAKE_LINES="1 2 edit fakesha 3 4 5 #" \ + git rebase -i --root 2>actual && + test_cmp expect actual && + FAKE_LINES="1 2 4 5 6" git rebase --edit-todo && + git rebase --continue && + test E = $(git cat-file commit HEAD | sed -ne \$p) +' + 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/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index 2680375628..4428b9086e 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -40,6 +40,25 @@ test_expect_success 'non-interactive rebase --continue works with touched file' git rebase --continue ' +test_expect_success 'non-interactive rebase --continue with rerere enabled' ' + test_config rerere.enabled true && + test_when_finished "test_might_fail git rebase --abort" && + git reset --hard commit-new-file-F2-on-topic-branch && + git checkout master && + rm -fr .git/rebase-* && + + test_must_fail git rebase --onto master master topic && + echo "Resolved" >F2 && + git add F2 && + cp F2 F2.expected && + git rebase --continue && + + git reset --hard commit-new-file-F2-on-topic-branch && + git checkout master && + test_must_fail git rebase --onto master master topic && + test_cmp F2.expected F2 +' + test_expect_success 'rebase --continue can not be used with other options' ' test_must_fail git rebase -v --continue && test_must_fail git rebase --continue -v diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh index 75cf3ff9bd..509084e1a7 100755 --- a/t/t3901-i18n-patch.sh +++ b/t/t3901-i18n-patch.sh @@ -251,4 +251,66 @@ test_expect_success 'rebase --merge (L/U)' ' check_encoding 2 8859 ' +test_expect_success 'am (U/U)' ' + # Apply UTF-8 patches with UTF-8 commitencoding + git config i18n.commitencoding UTF-8 && + . "$TEST_DIRECTORY"/t3901-utf8.txt && + + git reset --hard master && + git am out-u1 out-u2 && + + check_encoding 2 +' + +test_expect_success !MINGW 'am (L/L)' ' + # Apply ISO-8859-1 patches with ISO-8859-1 commitencoding + git config i18n.commitencoding ISO8859-1 && + . "$TEST_DIRECTORY"/t3901-8859-1.txt && + + git reset --hard master && + git am out-l1 out-l2 && + + check_encoding 2 8859 +' + +test_expect_success 'am (U/L)' ' + # Apply ISO-8859-1 patches with UTF-8 commitencoding + git config i18n.commitencoding UTF-8 && + . "$TEST_DIRECTORY"/t3901-utf8.txt && + git reset --hard master && + + # am specifies --utf8 by default. + git am out-l1 out-l2 && + + check_encoding 2 +' + +test_expect_success 'am --no-utf8 (U/L)' ' + # Apply ISO-8859-1 patches with UTF-8 commitencoding + git config i18n.commitencoding UTF-8 && + . "$TEST_DIRECTORY"/t3901-utf8.txt && + + git reset --hard master && + git am --no-utf8 out-l1 out-l2 2>err && + + # commit-tree will warn that the commit message does not contain valid UTF-8 + # as mailinfo did not convert it + grep "did not conform" err && + + check_encoding 2 +' + +test_expect_success !MINGW 'am (L/U)' ' + # Apply UTF-8 patches with ISO-8859-1 commitencoding + git config i18n.commitencoding ISO8859-1 && + . "$TEST_DIRECTORY"/t3901-8859-1.txt && + + git reset --hard master && + # mailinfo will re-code the commit message to the charset specified by + # i18n.commitencoding + git am out-u1 out-u2 && + + check_encoding 2 8859 +' + test_done diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 1dbaa3864a..67373dc44e 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -31,6 +31,7 @@ diffpatterns=" cpp csharp fortran + fountain html java matlab diff --git a/t/t4018/fountain-scene b/t/t4018/fountain-scene new file mode 100644 index 0000000000..6b3257d680 --- /dev/null +++ b/t/t4018/fountain-scene @@ -0,0 +1,4 @@ +EXT. STREET RIGHT OUTSIDE - DAY + +CHARACTER +You didn't say the magic phrase, "ChangeMe". diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 6ced98cfb4..e9b6f8158a 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -67,6 +67,19 @@ test_expect_success 'setup: messages' ' EOF + cat >scissors-msg <<-\EOF && + Test git-am with scissors line + + This line should be included in the commit message. + EOF + + cat - scissors-msg >no-scissors-msg <<-\EOF && + This line should not be included in the commit message with --scissors enabled. + + - - >8 - - remove everything above this line - - >8 - - + + EOF + signoff="Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" ' @@ -104,6 +117,52 @@ 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 && + + + echo scissors-file >scissors-file && + git add scissors-file && + git commit -F scissors-msg && + git tag scissors && + git format-patch --stdout scissors^ >scissors-patch.eml && + git reset --hard HEAD^ && + + echo no-scissors-file >no-scissors-file && + git add no-scissors-file && + git commit -F no-scissors-msg && + git tag no-scissors && + git format-patch --stdout no-scissors^ >no-scissors-patch.eml && + git reset --hard HEAD^ && sed -n -e "3,\$p" msg >file && git add file && @@ -154,6 +213,18 @@ test_expect_success 'am applies patch correctly' ' test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" ' +test_expect_success 'am fails if index is dirty' ' + test_when_finished "rm -f dirtyfile" && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout first && + echo dirtyfile >dirtyfile && + git add dirtyfile && + test_must_fail git am patch1 && + test_path_is_dir .git/rebase-apply && + test_cmp_rev first HEAD +' + test_expect_success 'am applies patch e-mail not in a mbox' ' rm -fr .git/rebase-apply && git reset --hard && @@ -187,6 +258,183 @@ 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 'am with applypatch-msg hook' ' + test_when_finished "rm -f .git/hooks/applypatch-msg" && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout first && + mkdir -p .git/hooks && + write_script .git/hooks/applypatch-msg <<-\EOF && + cat "$1" >actual-msg && + echo hook-message >"$1" + EOF + git am patch1 && + test_path_is_missing .git/rebase-apply && + git diff --exit-code second && + echo hook-message >expected && + git log -1 --format=format:%B >actual && + test_cmp expected actual && + git log -1 --format=format:%B second >expected && + test_cmp expected actual-msg +' + +test_expect_success 'am with failing applypatch-msg hook' ' + test_when_finished "rm -f .git/hooks/applypatch-msg" && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout first && + mkdir -p .git/hooks && + write_script .git/hooks/applypatch-msg <<-\EOF && + exit 1 + EOF + test_must_fail git am patch1 && + test_path_is_dir .git/rebase-apply && + git diff --exit-code first && + test_cmp_rev first HEAD +' + +test_expect_success 'am with pre-applypatch hook' ' + test_when_finished "rm -f .git/hooks/pre-applypatch" && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout first && + mkdir -p .git/hooks && + write_script .git/hooks/pre-applypatch <<-\EOF && + git diff first >diff.actual + exit 0 + EOF + git am patch1 && + test_path_is_missing .git/rebase-apply && + git diff --exit-code second && + test_cmp_rev second HEAD && + git diff first..second >diff.expected && + test_cmp diff.expected diff.actual +' + +test_expect_success 'am with failing pre-applypatch hook' ' + test_when_finished "rm -f .git/hooks/pre-applypatch" && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout first && + mkdir -p .git/hooks && + write_script .git/hooks/pre-applypatch <<-\EOF && + exit 1 + EOF + test_must_fail git am patch1 && + test_path_is_dir .git/rebase-apply && + git diff --exit-code second && + test_cmp_rev first HEAD +' + +test_expect_success 'am with post-applypatch hook' ' + test_when_finished "rm -f .git/hooks/post-applypatch" && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout first && + mkdir -p .git/hooks && + write_script .git/hooks/post-applypatch <<-\EOF && + git rev-parse HEAD >head.actual + git diff second >diff.actual + exit 0 + EOF + git am patch1 && + test_path_is_missing .git/rebase-apply && + test_cmp_rev second HEAD && + git rev-parse second >head.expected && + test_cmp head.expected head.actual && + git diff second >diff.expected && + test_cmp diff.expected diff.actual +' + +test_expect_success 'am with failing post-applypatch hook' ' + test_when_finished "rm -f .git/hooks/post-applypatch" && + rm -fr .git/rebase-apply && + git reset --hard && + git checkout first && + mkdir -p .git/hooks && + write_script .git/hooks/post-applypatch <<-\EOF && + git rev-parse HEAD >head.actual + exit 1 + EOF + git am patch1 && + test_path_is_missing .git/rebase-apply && + git diff --exit-code second && + test_cmp_rev second HEAD && + git rev-parse second >head.expected && + test_cmp head.expected head.actual +' + +test_expect_success 'am --scissors cuts the message at the scissors line' ' + rm -fr .git/rebase-apply && + git reset --hard && + git checkout second && + git am --scissors scissors-patch.eml && + test_path_is_missing .git/rebase-apply && + git diff --exit-code scissors && + test_cmp_rev scissors HEAD +' + +test_expect_success 'am --no-scissors overrides mailinfo.scissors' ' + rm -fr .git/rebase-apply && + git reset --hard && + git checkout second && + test_config mailinfo.scissors true && + git am --no-scissors no-scissors-patch.eml && + test_path_is_missing .git/rebase-apply && + git diff --exit-code no-scissors && + test_cmp_rev no-scissors HEAD +' + test_expect_success 'setup: new author and committer' ' GIT_AUTHOR_NAME="Another Thor" && GIT_AUTHOR_EMAIL="a.thor@example.com" && @@ -366,6 +614,20 @@ test_expect_success 'am --abort removes a stray directory' ' test_path_is_missing .git/rebase-apply ' +test_expect_success 'am refuses patches when paused' ' + rm -fr .git/rebase-apply && + git reset --hard && + git checkout lorem2^^ && + + test_must_fail git am lorem-move.patch && + test_path_is_dir .git/rebase-apply && + test_cmp_rev lorem2^^ HEAD && + + test_must_fail git am <lorem-move.patch && + test_path_is_dir .git/rebase-apply && + test_cmp_rev lorem2^^ HEAD +' + test_expect_success 'am --resolved works' ' echo goodbye >expected && rm -fr .git/rebase-apply && @@ -380,6 +642,31 @@ test_expect_success 'am --resolved works' ' test_cmp expected another ' +test_expect_success 'am --resolved fails if index has no changes' ' + rm -fr .git/rebase-apply && + git reset --hard && + git checkout lorem2^^ && + test_must_fail git am lorem-move.patch && + test_path_is_dir .git/rebase-apply && + test_cmp_rev lorem2^^ HEAD && + test_must_fail git am --resolved && + test_path_is_dir .git/rebase-apply && + test_cmp_rev lorem2^^ HEAD +' + +test_expect_success 'am --resolved fails if index has unmerged entries' ' + rm -fr .git/rebase-apply && + git reset --hard && + git checkout second && + test_must_fail git am -3 lorem-move.patch && + test_path_is_dir .git/rebase-apply && + test_cmp_rev second HEAD && + test_must_fail git am --resolved >err && + test_path_is_dir .git/rebase-apply && + test_cmp_rev second HEAD && + test_i18ngrep "still have unmerged paths" err +' + test_expect_success 'am takes patches from a Pine mailbox' ' rm -fr .git/rebase-apply && git reset --hard && @@ -544,6 +831,18 @@ test_expect_success 'am --message-id really adds the message id' ' test_cmp expected actual ' +test_expect_success 'am.messageid really adds the message id' ' + rm -fr .git/rebase-apply && + git reset --hard && + git checkout HEAD^ && + test_config am.messageid true && + git am patch1.eml && + test_path_is_missing .git/rebase-apply && + git cat-file commit HEAD | tail -n1 >actual && + grep Message-Id patch1.eml >expected && + test_cmp expected actual +' + test_expect_success 'am --message-id -s signs off after the message id' ' rm -fr .git/rebase-apply && git reset --hard && diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh index 833e7b2cea..05bdc3ee49 100755 --- a/t/t4151-am-abort.sh +++ b/t/t4151-am-abort.sh @@ -95,6 +95,21 @@ test_expect_success 'am --abort will keep the local commits intact' ' test_cmp expect actual ' +test_expect_success 'am --abort will keep dirty index intact' ' + git reset --hard initial && + echo dirtyfile >dirtyfile && + cp dirtyfile dirtyfile.expected && + git add dirtyfile && + test_must_fail git am 0001-*.patch && + test_cmp_rev initial HEAD && + test_path_is_file dirtyfile && + test_cmp dirtyfile.expected dirtyfile && + git am --abort && + test_cmp_rev initial HEAD && + test_path_is_file dirtyfile && + test_cmp dirtyfile.expected dirtyfile +' + test_expect_success 'am -3 stops on conflict on unborn branch' ' git checkout -f --orphan orphan && git reset && diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 1b2e981a00..35d2d7c221 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -146,7 +146,30 @@ test_expect_success 'git log --follow' ' actual=$(git log --follow --pretty="format:%s" ichi) && expect=$(echo third ; echo second ; echo initial) && verbose test "$actual" = "$expect" +' + +test_expect_success 'git config log.follow works like --follow' ' + test_config log.follow true && + actual=$(git log --pretty="format:%s" ichi) && + expect=$(echo third ; echo second ; echo initial) && + verbose test "$actual" = "$expect" +' +test_expect_success 'git config log.follow does not die with multiple paths' ' + test_config log.follow true && + git log --pretty="format:%s" ichi ein +' + +test_expect_success 'git config log.follow does not die with no paths' ' + test_config log.follow true && + git log -- +' + +test_expect_success 'git config log.follow is overridden by --no-follow' ' + test_config log.follow true && + actual=$(git log --no-follow --pretty="format:%s" ichi) && + expect="third" && + verbose test "$actual" = "$expect" ' cat > expect << EOF diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index 61bc8da560..3dc5ec4dd3 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -259,7 +259,7 @@ EOF thirtyeight=${tag#??} && rm -f .git/objects/${tag%$thirtyeight}/$thirtyeight && git index-pack --strict tag-test-${pack1}.pack 2>err && - grep "^error:.* expected .tagger. line" err + grep "^warning:.* expected .tagger. line" err ' test_done diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index 69ee13c8be..44f3d5fb28 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -115,4 +115,55 @@ test_expect_success 'push with transfer.fsckobjects' ' test_cmp exp act ' +cat >bogus-commit <<\EOF +tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 +author Bugs Bunny 1234567890 +0000 +committer Bugs Bunny <bugs@bun.ni> 1234567890 +0000 + +This commit object intentionally broken +EOF + +test_expect_success 'push with receive.fsck.skipList' ' + commit="$(git hash-object -t commit -w --stdin <bogus-commit)" && + git push . $commit:refs/heads/bogus && + rm -rf dst && + git init dst && + git --git-dir=dst/.git config receive.fsckObjects true && + test_must_fail git push --porcelain dst bogus && + git --git-dir=dst/.git config receive.fsck.skipList SKIP && + echo $commit >dst/.git/SKIP && + git push --porcelain dst bogus +' + +test_expect_success 'push with receive.fsck.missingEmail=warn' ' + commit="$(git hash-object -t commit -w --stdin <bogus-commit)" && + git push . $commit:refs/heads/bogus && + rm -rf dst && + git init dst && + git --git-dir=dst/.git config receive.fsckobjects true && + test_must_fail git push --porcelain dst bogus && + git --git-dir=dst/.git config \ + receive.fsck.missingEmail warn && + git push --porcelain dst bogus >act 2>&1 && + grep "missingEmail" act && + git --git-dir=dst/.git branch -D bogus && + git --git-dir=dst/.git config --add \ + receive.fsck.missingEmail ignore && + git --git-dir=dst/.git config --add \ + receive.fsck.badDate warn && + git push --porcelain dst bogus >act 2>&1 && + test_must_fail grep "missingEmail" act +' + +test_expect_success \ + 'receive.fsck.unterminatedHeader=warn triggers error' ' + rm -rf dst && + git init dst && + git --git-dir=dst/.git config receive.fsckobjects true && + git --git-dir=dst/.git config \ + receive.fsck.unterminatedheader warn && + test_must_fail git push --porcelain dst HEAD >act 2>&1 && + grep "Cannot demote unterminatedheader" act +' + test_done diff --git a/t/t5511-refspec.sh b/t/t5511-refspec.sh index de6db86ccf..f541f30bc2 100755 --- a/t/t5511-refspec.sh +++ b/t/t5511-refspec.sh @@ -71,15 +71,18 @@ test_refspec fetch ':refs/remotes/frotz/HEAD-to-me' test_refspec push ':refs/remotes/frotz/delete me' invalid test_refspec fetch ':refs/remotes/frotz/HEAD to me' invalid -test_refspec fetch 'refs/heads/*/for-linus:refs/remotes/mine/*-blah' invalid -test_refspec push 'refs/heads/*/for-linus:refs/remotes/mine/*-blah' invalid +test_refspec fetch 'refs/heads/*/for-linus:refs/remotes/mine/*-blah' +test_refspec push 'refs/heads/*/for-linus:refs/remotes/mine/*-blah' -test_refspec fetch 'refs/heads*/for-linus:refs/remotes/mine/*' invalid -test_refspec push 'refs/heads*/for-linus:refs/remotes/mine/*' invalid +test_refspec fetch 'refs/heads*/for-linus:refs/remotes/mine/*' +test_refspec push 'refs/heads*/for-linus:refs/remotes/mine/*' test_refspec fetch 'refs/heads/*/*/for-linus:refs/remotes/mine/*' invalid test_refspec push 'refs/heads/*/*/for-linus:refs/remotes/mine/*' invalid +test_refspec fetch 'refs/heads/*g*/for-linus:refs/remotes/mine/*' invalid +test_refspec push 'refs/heads/*g*/for-linus:refs/remotes/mine/*' invalid + test_refspec fetch 'refs/heads/*/for-linus:refs/remotes/mine/*' test_refspec push 'refs/heads/*/for-linus:refs/remotes/mine/*' 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/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 24fc2ba55d..7c9bec7630 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -227,6 +227,24 @@ test_expect_success 'Check format "rfc2822" date fields output' ' test_cmp expected actual ' +test_expect_success 'Check format of strftime date fields' ' + echo "my date is 2006-07-03" >expected && + git for-each-ref \ + --format="%(authordate:format:my date is %Y-%m-%d)" \ + refs/heads >actual && + test_cmp expected actual +' + +test_expect_success 'exercise strftime with odd fields' ' + echo >expected && + git for-each-ref --format="%(authordate:format:)" refs/heads >actual && + test_cmp expected actual && + long="long format -- $_z40$_z40$_z40$_z40$_z40$_z40$_z40" && + echo $long >expected && + git for-each-ref --format="%(authordate:format:$long)" refs/heads >actual && + test_cmp expected actual +' + cat >expected <<\EOF refs/heads/master refs/remotes/origin/master diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index d1ff5c94f2..d31788cc6c 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -51,7 +51,19 @@ test_expect_success 'creating a tag using default HEAD should succeed' ' echo foo >foo && git add foo && git commit -m Foo && - git tag mytag + git tag mytag && + test_must_fail git reflog exists refs/tags/mytag +' + +test_expect_success 'creating a tag with --create-reflog should create reflog' ' + test_when_finished "git tag -d tag_with_reflog" && + git tag --create-reflog tag_with_reflog && + git reflog exists refs/tags/tag_with_reflog +' + +test_expect_success '--create-reflog does not create reflog on failure' ' + test_must_fail git tag --create-reflog mytag && + test_must_fail git reflog exists refs/tags/mytag ' test_expect_success 'listing all tags if one exists should succeed' ' 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/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/t7512-status-help.sh b/t/t7512-status-help.sh index 68ad2d7454..49d19a3b36 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -134,9 +134,13 @@ test_expect_success 'prepare for rebase_i_conflicts' ' test_expect_success 'status during rebase -i when conflicts unresolved' ' test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short rebase_i_conflicts) && + LAST_COMMIT=$(git rev-parse --short rebase_i_conflicts_second) && test_must_fail git rebase -i rebase_i_conflicts && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last command done (1 command done): + pick $LAST_COMMIT one_second +No commands remaining. You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''. (fix conflicts and then run "git rebase --continue") (use "git rebase --skip" to skip this patch) @@ -159,10 +163,14 @@ test_expect_success 'status during rebase -i after resolving conflicts' ' git reset --hard rebase_i_conflicts_second && test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short rebase_i_conflicts) && + LAST_COMMIT=$(git rev-parse --short rebase_i_conflicts_second) && test_must_fail git rebase -i rebase_i_conflicts && git add main.txt && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last command done (1 command done): + pick $LAST_COMMIT one_second +No commands remaining. You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''. (all conflicts fixed: run "git rebase --continue") @@ -183,14 +191,20 @@ test_expect_success 'status when rebasing -i in edit mode' ' git checkout -b rebase_i_edit && test_commit one_rebase_i main.txt one && test_commit two_rebase_i main.txt two && + COMMIT2=$(git rev-parse --short rebase_i_edit) && test_commit three_rebase_i main.txt three && + COMMIT3=$(git rev-parse --short rebase_i_edit) && FAKE_LINES="1 edit 2" && export FAKE_LINES && test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short HEAD~2) && git rebase -i HEAD~2 && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + pick $COMMIT2 two_rebase_i + edit $COMMIT3 three_rebase_i +No commands remaining. You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' on '\''$ONTO'\''. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) @@ -207,8 +221,11 @@ test_expect_success 'status when splitting a commit' ' git checkout -b split_commit && test_commit one_split main.txt one && test_commit two_split main.txt two && + COMMIT2=$(git rev-parse --short split_commit) && test_commit three_split main.txt three && + COMMIT3=$(git rev-parse --short split_commit) && test_commit four_split main.txt four && + COMMIT4=$(git rev-parse --short split_commit) && FAKE_LINES="1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && @@ -216,7 +233,13 @@ test_expect_success 'status when splitting a commit' ' git rebase -i HEAD~3 && git reset HEAD^ && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + pick $COMMIT2 two_split + edit $COMMIT3 three_split +Next command to do (1 remaining command): + pick $COMMIT4 four_split + (use "git rebase --edit-todo" to view and edit) You are currently splitting a commit while rebasing branch '\''split_commit'\'' on '\''$ONTO'\''. (Once your working directory is clean, run "git rebase --continue") @@ -239,7 +262,9 @@ test_expect_success 'status after editing the last commit with --amend during a test_commit one_amend main.txt one && test_commit two_amend main.txt two && test_commit three_amend main.txt three && + COMMIT3=$(git rev-parse --short amend_last) && test_commit four_amend main.txt four && + COMMIT4=$(git rev-parse --short amend_last) && FAKE_LINES="1 2 edit 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && @@ -247,7 +272,12 @@ test_expect_success 'status after editing the last commit with --amend during a git rebase -i HEAD~3 && git commit --amend -m "foo" && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (3 commands done): + pick $COMMIT3 three_amend + edit $COMMIT4 four_amend + (see more in file .git/rebase-merge/done) +No commands remaining. You are currently editing a commit while rebasing branch '\''amend_last'\'' on '\''$ONTO'\''. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) @@ -273,11 +303,20 @@ test_expect_success 'status: (continue first edit) second edit' ' FAKE_LINES="edit 1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git rebase --continue && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) @@ -294,12 +333,21 @@ test_expect_success 'status: (continue first edit) second edit and split' ' FAKE_LINES="edit 1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git rebase --continue && git reset HEAD^ && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (Once your working directory is clean, run "git rebase --continue") @@ -321,12 +369,21 @@ test_expect_success 'status: (continue first edit) second edit and amend' ' FAKE_LINES="edit 1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git rebase --continue && git commit --amend -m "foo" && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) @@ -343,12 +400,21 @@ test_expect_success 'status: (amend first edit) second edit' ' FAKE_LINES="edit 1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git commit --amend -m "a" && git rebase --continue && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) @@ -366,12 +432,21 @@ test_expect_success 'status: (amend first edit) second edit and split' ' export FAKE_LINES && test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short HEAD~3) && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && git rebase -i HEAD~3 && git commit --amend -m "b" && git rebase --continue && git reset HEAD^ && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (Once your working directory is clean, run "git rebase --continue") @@ -393,13 +468,22 @@ test_expect_success 'status: (amend first edit) second edit and amend' ' FAKE_LINES="edit 1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git commit --amend -m "c" && git rebase --continue && git commit --amend -m "d" && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) @@ -416,6 +500,9 @@ test_expect_success 'status: (split first edit) second edit' ' FAKE_LINES="edit 1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git reset HEAD^ && @@ -423,7 +510,13 @@ test_expect_success 'status: (split first edit) second edit' ' git commit -m "e" && git rebase --continue && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) @@ -440,6 +533,9 @@ test_expect_success 'status: (split first edit) second edit and split' ' FAKE_LINES="edit 1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git reset HEAD^ && @@ -448,7 +544,13 @@ test_expect_success 'status: (split first edit) second edit and split' ' git rebase --continue && git reset HEAD^ && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (Once your working directory is clean, run "git rebase --continue") @@ -470,6 +572,9 @@ test_expect_success 'status: (split first edit) second edit and amend' ' FAKE_LINES="edit 1 edit 2 3" && export FAKE_LINES && test_when_finished "git rebase --abort" && + COMMIT2=$(git rev-parse --short several_edits^^) && + COMMIT3=$(git rev-parse --short several_edits^) && + COMMIT4=$(git rev-parse --short several_edits) && ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git reset HEAD^ && @@ -478,7 +583,13 @@ test_expect_success 'status: (split first edit) second edit and amend' ' git rebase --continue && git commit --amend -m "h" && cat >expected <<EOF && -rebase in progress; onto $ONTO +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + edit $COMMIT2 two_edits + edit $COMMIT3 three_edits +Next command to do (1 remaining command): + pick $COMMIT4 four_edits + (use "git rebase --edit-todo" to view and edit) You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. (use "git commit --amend" to amend the current commit) (use "git rebase --continue" once you are satisfied with your changes) @@ -745,4 +856,91 @@ EOF test_i18ncmp expected actual ' +test_expect_success 'prepare for different number of commits rebased' ' + git reset --hard master && + git checkout -b several_commits && + test_commit one_commit main.txt one && + test_commit two_commit main.txt two && + test_commit three_commit main.txt three && + test_commit four_commit main.txt four +' + +test_expect_success 'status: one command done nothing remaining' ' + FAKE_LINES="exec_exit_15" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + ONTO=$(git rev-parse --short HEAD~3) && + test_must_fail git rebase -i HEAD~3 && + cat >expected <<EOF && +interactive rebase in progress; onto $ONTO +Last command done (1 command done): + exec exit 15 +No commands remaining. +You are currently editing a commit while rebasing branch '\''several_commits'\'' on '\''$ONTO'\''. + (use "git commit --amend" to amend the current commit) + (use "git rebase --continue" once you are satisfied with your changes) + +nothing to commit (use -u to show untracked files) +EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + +test_expect_success 'status: two commands done with some white lines in done file' ' + FAKE_LINES="1 > exec_exit_15 2 3" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + ONTO=$(git rev-parse --short HEAD~3) && + COMMIT4=$(git rev-parse --short HEAD) && + COMMIT3=$(git rev-parse --short HEAD^) && + COMMIT2=$(git rev-parse --short HEAD^^) && + test_must_fail git rebase -i HEAD~3 && + cat >expected <<EOF && +interactive rebase in progress; onto $ONTO +Last commands done (2 commands done): + pick $COMMIT2 two_commit + exec exit 15 +Next commands to do (2 remaining commands): + pick $COMMIT3 three_commit + pick $COMMIT4 four_commit + (use "git rebase --edit-todo" to view and edit) +You are currently editing a commit while rebasing branch '\''several_commits'\'' on '\''$ONTO'\''. + (use "git commit --amend" to amend the current commit) + (use "git rebase --continue" once you are satisfied with your changes) + +nothing to commit (use -u to show untracked files) +EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + +test_expect_success 'status: two remaining commands with some white lines in todo file' ' + FAKE_LINES="1 2 exec_exit_15 3 > 4" && + export FAKE_LINES && + test_when_finished "git rebase --abort" && + ONTO=$(git rev-parse --short HEAD~4) && + COMMIT4=$(git rev-parse --short HEAD) && + COMMIT3=$(git rev-parse --short HEAD^) && + COMMIT2=$(git rev-parse --short HEAD^^) && + test_must_fail git rebase -i HEAD~4 && + cat >expected <<EOF && +interactive rebase in progress; onto $ONTO +Last commands done (3 commands done): + pick $COMMIT2 two_commit + exec exit 15 + (see more in file .git/rebase-merge/done) +Next commands to do (2 remaining commands): + pick $COMMIT3 three_commit + pick $COMMIT4 four_commit + (use "git rebase --edit-todo" to view and edit) +You are currently editing a commit while rebasing branch '\''several_commits'\'' on '\''$ONTO'\''. + (use "git commit --amend" to amend the current commit) + (use "git rebase --continue" once you are satisfied with your changes) + +nothing to commit (use -u to show untracked files) +EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + 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 db2f45e83b..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"} } @@ -1621,6 +1627,66 @@ test_sendmail_aliases 'sendmail aliases tolerate bogus line folding' \ 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>" \ + --smtp-server="$(pwd)/fake.sendmail" \ + aliased.patch \ + 2>errors >out && + 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 () { expected=$1 params=$2 && git format-patch -1 && @@ -1654,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/t9300-fast-import.sh b/t/t9300-fast-import.sh index aac126fd57..9984c48b5a 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -2339,6 +2339,19 @@ test_expect_success !MINGW 'R: in-stream cat-blob-fd not respected' ' test_cmp expect actual.1 ' +test_expect_success !MINGW 'R: print mark for new blob' ' + echo "effluentish" | git hash-object --stdin >expect && + git fast-import --cat-blob-fd=6 6>actual <<-\EOF && + blob + mark :1 + data <<BLOB_END + effluentish + BLOB_END + get-mark :1 + EOF + test_cmp expect actual +' + test_expect_success !MINGW 'R: print new blob' ' blob=$(echo "yep yep yep" | git hash-object --stdin) && cat >expect <<-EOF && diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index 49d58e6726..6b68777b98 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -397,6 +397,31 @@ test_expect_success 'prompt - untracked files status indicator - untracked files test_cmp expected "$actual" ' +test_expect_success 'prompt - untracked files status indicator - empty untracked dir' ' + printf " (master)" >expected && + mkdir otherrepo/untracked-dir && + test_when_finished "rm -rf otherrepo/untracked-dir" && + ( + GIT_PS1_SHOWUNTRACKEDFILES=y && + cd otherrepo && + __git_ps1 >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - untracked files status indicator - non-empty untracked dir' ' + printf " (master %%)" >expected && + mkdir otherrepo/untracked-dir && + test_when_finished "rm -rf otherrepo/untracked-dir" && + >otherrepo/untracked-dir/untracked-file && + ( + GIT_PS1_SHOWUNTRACKEDFILES=y && + cd otherrepo && + __git_ps1 >"$actual" + ) && + test_cmp expected "$actual" +' + test_expect_success 'prompt - untracked files status indicator - untracked files outside cwd' ' printf " (master %%)" >expected && ( |