diff options
Diffstat (limited to 't')
35 files changed, 901 insertions, 232 deletions
diff --git a/t/helper/test-date.c b/t/helper/test-date.c index 63f373557e..d9ab360909 100644 --- a/t/helper/test-date.c +++ b/t/helper/test-date.c @@ -1,11 +1,12 @@ #include "cache.h" static const char *usage_msg = "\n" -" test-date show [time_t]...\n" +" test-date relative [time_t]...\n" +" test-date show:<format> [time_t]...\n" " test-date parse [date]...\n" " test-date approxidate [date]...\n"; -static void show_dates(char **argv, struct timeval *now) +static void show_relative_dates(char **argv, struct timeval *now) { struct strbuf buf = STRBUF_INIT; @@ -17,6 +18,29 @@ static void show_dates(char **argv, struct timeval *now) strbuf_release(&buf); } +static void show_dates(char **argv, const char *format) +{ + struct date_mode mode; + + parse_date_format(format, &mode); + for (; *argv; argv++) { + char *arg = *argv; + time_t t; + int tz; + + /* + * Do not use our normal timestamp parsing here, as the point + * is to test the formatting code in isolation. + */ + t = strtol(arg, &arg, 10); + while (*arg == ' ') + arg++; + tz = atoi(arg); + + printf("%s -> %s\n", *argv, show_date(t, tz, &mode)); + } +} + static void parse_dates(char **argv, struct timeval *now) { struct strbuf result = STRBUF_INIT; @@ -61,8 +85,10 @@ int main(int argc, char **argv) argv++; if (!*argv) usage(usage_msg); - if (!strcmp(*argv, "show")) - show_dates(argv+1, &now); + if (!strcmp(*argv, "relative")) + show_relative_dates(argv+1, &now); + else if (skip_prefix(*argv, "show:", &x)) + show_dates(argv+1, x); else if (!strcmp(*argv, "parse")) parse_dates(argv+1, &now); else if (!strcmp(*argv, "approxidate")) diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh index 340534c064..f9cbd47931 100644 --- a/t/lib-git-daemon.sh +++ b/t/lib-git-daemon.sh @@ -82,8 +82,7 @@ stop_git_daemon() { kill "$GIT_DAEMON_PID" wait "$GIT_DAEMON_PID" >&3 2>&4 ret=$? - # expect exit with status 143 = 128+15 for signal TERM=15 - if test $ret -ne 143 + if test_match_signal 15 $? then error "git daemon exited with status: $ret" fi diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index 5ef17440c0..773f955d4a 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -84,6 +84,7 @@ test_perf_create_repo_from () { objects_dir="$(git -C "$source" rev-parse --git-path objects)" mkdir -p "$repo/.git" ( + cd "$source" && { cp -Rl "$objects_dir" "$repo/.git/" 2>/dev/null || cp -R "$objects_dir" "$repo/.git/"; } && for stuff in "$source_git"/*; do @@ -94,7 +95,9 @@ test_perf_create_repo_from () { cp -R "$stuff" "$repo/.git/" || exit 1 ;; esac - done && + done + ) && + ( cd "$repo" && git init -q && { test_have_prereq SYMLINKS || @@ -124,11 +127,15 @@ test_checkout_worktree () { # Performance tests should never fail. If they do, stop immediately immediate=t +# Perf tests require GNU time +case "$(uname -s)" in Darwin) GTIME="${GTIME:-gtime}";; esac +GTIME="${GTIME:-/usr/bin/time}" + test_run_perf_ () { test_cleanup=: test_export_="test_cleanup" export test_cleanup test_export_ - /usr/bin/time -f "%E %U %S" -o test_time.$i "$SHELL" -c ' + "$GTIME" -f "%E %U %S" -o test_time.$i "$SHELL" -c ' . '"$TEST_DIRECTORY"/test-lib-functions.sh' test_export () { [ $# != 0 ] || return 0 diff --git a/t/t0005-signals.sh b/t/t0005-signals.sh index e7f27ebbc1..46042f1f13 100755 --- a/t/t0005-signals.sh +++ b/t/t0005-signals.sh @@ -11,12 +11,13 @@ EOF test_expect_success 'sigchain works' ' { test-sigchain >actual; ret=$?; } && - case "$ret" in - 143) true ;; # POSIX w/ SIGTERM=15 - 271) true ;; # ksh w/ SIGTERM=15 - 3) true ;; # Windows - *) false ;; - esac && + { + # Signal death by raise() on Windows acts like exit(3), + # regardless of the signal number. So we must allow that + # as well as the normal signal check. + test_match_signal 15 "$ret" || + test "$ret" = 3 + } && test_cmp expect actual ' @@ -41,12 +42,12 @@ test_expect_success 'create blob' ' test_expect_success !MINGW 'a constipated git dies with SIGPIPE' ' OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) && - test "$OUT" -eq 141 + test_match_signal 13 "$OUT" ' test_expect_success !MINGW 'a constipated git dies with SIGPIPE even if parent ignores it' ' OUT=$( ((trap "" PIPE; large_git; echo $? 1>&3) | :) 3>&1 ) && - test "$OUT" -eq 141 + test_match_signal 13 "$OUT" ' test_done diff --git a/t/t0006-date.sh b/t/t0006-date.sh index fac0986134..4c8cf58512 100755 --- a/t/t0006-date.sh +++ b/t/t0006-date.sh @@ -6,26 +6,52 @@ test_description='test date parsing and printing' # arbitrary reference time: 2009-08-30 19:20:00 TEST_DATE_NOW=1251660000; export TEST_DATE_NOW -check_show() { +check_relative() { t=$(($TEST_DATE_NOW - $1)) echo "$t -> $2" >expect test_expect_${3:-success} "relative date ($2)" " - test-date show $t >actual && + test-date relative $t >actual && test_i18ncmp expect actual " } -check_show 5 '5 seconds ago' -check_show 300 '5 minutes ago' -check_show 18000 '5 hours ago' -check_show 432000 '5 days ago' -check_show 1728000 '3 weeks ago' -check_show 13000000 '5 months ago' -check_show 37500000 '1 year, 2 months ago' -check_show 55188000 '1 year, 9 months ago' -check_show 630000000 '20 years ago' -check_show 31449600 '12 months ago' -check_show 62985600 '2 years ago' +check_relative 5 '5 seconds ago' +check_relative 300 '5 minutes ago' +check_relative 18000 '5 hours ago' +check_relative 432000 '5 days ago' +check_relative 1728000 '3 weeks ago' +check_relative 13000000 '5 months ago' +check_relative 37500000 '1 year, 2 months ago' +check_relative 55188000 '1 year, 9 months ago' +check_relative 630000000 '20 years ago' +check_relative 31449600 '12 months ago' +check_relative 62985600 '2 years ago' + +check_show () { + format=$1 + time=$2 + expect=$3 + test_expect_success $4 "show date ($format:$time)" ' + echo "$time -> $expect" >expect && + test-date show:$format "$time" >actual && + test_cmp expect actual + ' +} + +# arbitrary but sensible time for examples +TIME='1466000000 +0200' +check_show iso8601 "$TIME" '2016-06-15 16:13:20 +0200' +check_show iso8601-strict "$TIME" '2016-06-15T16:13:20+02:00' +check_show rfc2822 "$TIME" 'Wed, 15 Jun 2016 16:13:20 +0200' +check_show short "$TIME" '2016-06-15' +check_show default "$TIME" 'Wed Jun 15 16:13:20 2016 +0200' +check_show raw "$TIME" '1466000000 +0200' +check_show iso-local "$TIME" '2016-06-15 14:13:20 +0000' + +# arbitrary time absurdly far in the future +FUTURE="5758122296 -0400" +check_show iso "$FUTURE" "2152-06-19 18:24:56 -0400" LONG_IS_64BIT +check_show iso-local "$FUTURE" "2152-06-19 22:24:56 +0000" LONG_IS_64BIT check_parse() { echo "$1 -> $2" >expect diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index 89544dd833..b425f3a0d2 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -605,7 +605,7 @@ cat <<-EOF >expected-verbose a/b/.gitignore:8:!on* a/b/one a/b/.gitignore:8:!on* a/b/one one a/b/.gitignore:8:!on* a/b/one two - a/b/.gitignore:8:!on* "a/b/one\"three" + a/b/.gitignore:8:!on* "a/b/one\\"three" a/b/.gitignore:9:!two a/b/two a/.gitignore:1:two* a/b/twooo $global_excludes:2:!globaltwo globaltwo @@ -686,7 +686,7 @@ cat <<-EOF >expected-all a/b/.gitignore:8:!on* b/one a/b/.gitignore:8:!on* b/one one a/b/.gitignore:8:!on* b/one two - a/b/.gitignore:8:!on* "b/one\"three" + a/b/.gitignore:8:!on* "b/one\\"three" a/b/.gitignore:9:!two b/two :: b/not-ignored a/.gitignore:1:two* b/twooo diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 417eecc3af..ca3fa406c3 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -110,7 +110,7 @@ test_expect_success 'symbolic-ref writes reflog entry' ' update create EOF - git log --format=%gs -g >actual && + git log --format=%gs -g -2 >actual && test_cmp expect actual ' diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 9cf91dc6d2..dd2be049ec 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -348,4 +348,26 @@ test_expect_success 'reflog expire operates on symref not referrent' ' git reflog expire --expire=all the_symref ' +test_expect_success 'continue walking past root commits' ' + git init orphanage && + ( + cd orphanage && + cat >expect <<-\EOF && + HEAD@{0} commit (initial): orphan2-1 + HEAD@{1} commit: orphan1-2 + HEAD@{2} commit (initial): orphan1-1 + HEAD@{3} commit (initial): initial + EOF + test_commit initial && + git reflog && + git checkout --orphan orphan1 && + test_commit orphan1-1 && + test_commit orphan1-2 && + git checkout --orphan orphan2 && + test_commit orphan2-1 && + git log -g --format="%gd %gs" >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 48ee07779d..038e24c401 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -3,85 +3,88 @@ test_description='test git rev-parse' . ./test-lib.sh -test_rev_parse() { - name=$1 - shift - - test_expect_success "$name: is-bare-repository" \ - "test '$1' = \"\$(git rev-parse --is-bare-repository)\"" - shift - [ $# -eq 0 ] && return - - test_expect_success "$name: is-inside-git-dir" \ - "test '$1' = \"\$(git rev-parse --is-inside-git-dir)\"" - shift - [ $# -eq 0 ] && return +# usage: [options] label is-bare is-inside-git is-inside-work prefix git-dir +test_rev_parse () { + d= + bare= + gitdir= + while : + do + case "$1" in + -C) d="$2"; shift; shift ;; + -b) case "$2" in + [tfu]*) bare="$2"; shift; shift ;; + *) error "test_rev_parse: bogus core.bare value '$2'" ;; + esac ;; + -g) gitdir="$2"; shift; shift ;; + -*) error "test_rev_parse: unrecognized option '$1'" ;; + *) break ;; + esac + done - test_expect_success "$name: is-inside-work-tree" \ - "test '$1' = \"\$(git rev-parse --is-inside-work-tree)\"" - shift - [ $# -eq 0 ] && return - - test_expect_success "$name: prefix" \ - "test '$1' = \"\$(git rev-parse --show-prefix)\"" + name=$1 shift - [ $# -eq 0 ] && return - test_expect_success "$name: git-dir" \ - "test '$1' = \"\$(git rev-parse --git-dir)\"" - shift - [ $# -eq 0 ] && return + for o in --is-bare-repository \ + --is-inside-git-dir \ + --is-inside-work-tree \ + --show-prefix \ + --git-dir + do + test $# -eq 0 && break + expect="$1" + test_expect_success "$name: $o" ' + if test -n "$gitdir" + then + test_when_finished "unset GIT_DIR" && + GIT_DIR="$gitdir" && + export GIT_DIR + fi && + + case "$bare" in + t*) test_config ${d:+-C} ${d:+"$d"} core.bare true ;; + f*) test_config ${d:+-C} ${d:+"$d"} core.bare false ;; + u*) test_unconfig ${d:+-C} ${d:+"$d"} core.bare ;; + esac && + + echo "$expect" >expect && + git ${d:+-C} ${d:+"$d"} rev-parse $o >actual && + test_cmp expect actual + ' + shift + done } -# label is-bare is-inside-git is-inside-work prefix git-dir - ROOT=$(pwd) +test_expect_success 'setup' ' + mkdir -p sub/dir work && + cp -R .git repo.git +' + test_rev_parse toplevel false false true '' .git -cd .git || exit 1 -test_rev_parse .git/ false true false '' . -cd objects || exit 1 -test_rev_parse .git/objects/ false true false '' "$ROOT/.git" -cd ../.. || exit 1 +test_rev_parse -C .git .git/ false true false '' . +test_rev_parse -C .git/objects .git/objects/ false true false '' "$ROOT/.git" -mkdir -p sub/dir || exit 1 -cd sub/dir || exit 1 -test_rev_parse subdirectory false false true sub/dir/ "$ROOT/.git" -cd ../.. || exit 1 +test_rev_parse -C sub/dir subdirectory false false true sub/dir/ "$ROOT/.git" -git config core.bare true -test_rev_parse 'core.bare = true' true false false +test_rev_parse -b t 'core.bare = true' true false false -git config --unset core.bare -test_rev_parse 'core.bare undefined' false false true +test_rev_parse -b u 'core.bare undefined' false false true -mkdir work || exit 1 -cd work || exit 1 -GIT_DIR=../.git -GIT_CONFIG="$(pwd)"/../.git/config -export GIT_DIR GIT_CONFIG -git config core.bare false -test_rev_parse 'GIT_DIR=../.git, core.bare = false' false false true '' +test_rev_parse -C work -g ../.git -b f 'GIT_DIR=../.git, core.bare = false' false false true '' -git config core.bare true -test_rev_parse 'GIT_DIR=../.git, core.bare = true' true false false '' +test_rev_parse -C work -g ../.git -b t 'GIT_DIR=../.git, core.bare = true' true false false '' -git config --unset core.bare -test_rev_parse 'GIT_DIR=../.git, core.bare undefined' false false true '' +test_rev_parse -C work -g ../.git -b u 'GIT_DIR=../.git, core.bare undefined' false false true '' -mv ../.git ../repo.git || exit 1 -GIT_DIR=../repo.git -GIT_CONFIG="$(pwd)"/../repo.git/config -git config core.bare false -test_rev_parse 'GIT_DIR=../repo.git, core.bare = false' false false true '' +test_rev_parse -C work -g ../repo.git -b f 'GIT_DIR=../repo.git, core.bare = false' false false true '' -git config core.bare true -test_rev_parse 'GIT_DIR=../repo.git, core.bare = true' true false false '' +test_rev_parse -C work -g ../repo.git -b t 'GIT_DIR=../repo.git, core.bare = true' true false false '' -git config --unset core.bare -test_rev_parse 'GIT_DIR=../repo.git, core.bare undefined' false false true '' +test_rev_parse -C work -g ../repo.git -b u 'GIT_DIR=../repo.git, core.bare undefined' false false true '' test_done diff --git a/t/t2300-cd-to-toplevel.sh b/t/t2300-cd-to-toplevel.sh index 9965bc5c92..c8de6d8a19 100755 --- a/t/t2300-cd-to-toplevel.sh +++ b/t/t2300-cd-to-toplevel.sh @@ -4,11 +4,20 @@ test_description='cd_to_toplevel' . ./test-lib.sh +EXEC_PATH="$(git --exec-path)" +test_have_prereq !MINGW || +case "$EXEC_PATH" in +[A-Za-z]:/*) + EXEC_PATH="/${EXEC_PATH%%:*}${EXEC_PATH#?:}" + ;; +esac + test_cd_to_toplevel () { test_expect_success $3 "$2" ' ( cd '"'$1'"' && - . "$(git --exec-path)"/git-sh-setup && + PATH="$EXEC_PATH:$PATH" && + . git-sh-setup && cd_to_toplevel && [ "$(pwd -P)" = "$TOPLEVEL" ] ) diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 66348f11d1..c7ea8bacf4 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -60,7 +60,7 @@ test_expect_success 'setup' ' test_commit P fileP ' -# "exec" commands are ran with the user shell by default, but this may +# "exec" commands are run with the user shell by default, but this may # be non-POSIX. For example, if SHELL=zsh then ">file" doesn't work # to create a file. Unsetting SHELL avoids such non-portable behavior # in tests. It must be exported for it to take effect where needed. diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh index 944154b2e0..532ff5cbd1 100755 --- a/t/t3420-rebase-autostash.sh +++ b/t/t3420-rebase-autostash.sh @@ -192,4 +192,35 @@ test_expect_success 'abort rebase -i with --autostash' ' test_cmp expected file0 ' +test_expect_success 'restore autostash on editor failure' ' + test_when_finished "git reset --hard" && + echo uncommitted-content >file0 && + ( + test_set_editor "false" && + test_must_fail git rebase -i --autostash HEAD^ + ) && + echo uncommitted-content >expected && + test_cmp expected file0 +' + +test_expect_success 'autostash is saved on editor failure with conflict' ' + test_when_finished "git reset --hard" && + echo uncommitted-content >file0 && + ( + write_script abort-editor.sh <<-\EOF && + echo conflicting-content >file0 + exit 1 + EOF + test_set_editor "$(pwd)/abort-editor.sh" && + test_must_fail git rebase -i --autostash HEAD^ && + rm -f abort-editor.sh + ) && + echo conflicting-content >expected && + test_cmp expected file0 && + git checkout file0 && + git stash pop && + echo uncommitted-content >expected && + test_cmp expected file0 +' + test_done diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh new file mode 100755 index 0000000000..3780877e4e --- /dev/null +++ b/t/t3427-rebase-subtree.sh @@ -0,0 +1,119 @@ +#!/bin/sh + +test_description='git rebase tests for -Xsubtree + +This test runs git rebase and tests the subtree strategy. +' +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + +commit_message() { + git log --pretty=format:%s -1 "$1" +} + +test_expect_success 'setup' ' + test_commit README && + mkdir files && + ( + cd files && + git init && + test_commit master1 && + test_commit master2 && + test_commit master3 + ) && + git fetch files master && + git branch files-master FETCH_HEAD && + git read-tree --prefix=files_subtree files-master && + git checkout -- files_subtree && + tree=$(git write-tree) && + head=$(git rev-parse HEAD) && + rev=$(git rev-parse --verify files-master^0) && + commit=$(git commit-tree -p $head -p $rev -m "Add subproject master" $tree) && + git update-ref HEAD $commit && + ( + cd files_subtree && + test_commit master4 + ) && + test_commit files_subtree/master5 +' + +# FAILURE: Does not preserve master4. +test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 4' ' + reset_rebase && + git checkout -b rebase-preserve-merges-4 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD~)" = "files_subtree/master4" +' + +# FAILURE: Does not preserve master5. +test_expect_failure 'Rebase -Xsubtree --preserve-merges --onto commit 5' ' + reset_rebase && + git checkout -b rebase-preserve-merges-5 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD)" = "files_subtree/master5" +' + +# FAILURE: Does not preserve master4. +test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 4' ' + reset_rebase && + git checkout -b rebase-keep-empty-4 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD~2)" = "files_subtree/master4" +' + +# FAILURE: Does not preserve master5. +test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit 5' ' + reset_rebase && + git checkout -b rebase-keep-empty-5 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD~)" = "files_subtree/master5" +' + +# FAILURE: Does not preserve Empty. +test_expect_failure 'Rebase -Xsubtree --keep-empty --preserve-merges --onto empty commit' ' + reset_rebase && + git checkout -b rebase-keep-empty-empty master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master && + verbose test "$(commit_message HEAD)" = "Empty commit" +' + +# FAILURE: fatal: Could not parse object +test_expect_failure 'Rebase -Xsubtree --onto commit 4' ' + reset_rebase && + git checkout -b rebase-onto-4 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --onto files-master master && + verbose test "$(commit_message HEAD~2)" = "files_subtree/master4" +' + +# FAILURE: fatal: Could not parse object +test_expect_failure 'Rebase -Xsubtree --onto commit 5' ' + reset_rebase && + git checkout -b rebase-onto-5 master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --onto files-master master && + verbose test "$(commit_message HEAD~)" = "files_subtree/master5" +' +# FAILURE: fatal: Could not parse object +test_expect_failure 'Rebase -Xsubtree --onto empty commit' ' + reset_rebase && + git checkout -b rebase-onto-empty master && + git filter-branch --prune-empty -f --subdirectory-filter files_subtree && + git commit -m "Empty commit" --allow-empty && + git rebase -Xsubtree=files_subtree --onto files-master master && + verbose test "$(commit_message HEAD)" = "Empty commit" +' + +test_done diff --git a/t/t3700-add.sh b/t/t3700-add.sh index f14a665356..4865304ebb 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -332,4 +332,34 @@ test_expect_success 'git add --dry-run --ignore-missing of non-existing file out test_i18ncmp expect.err actual.err ' +test_expect_success 'git add --chmod=+x stages a non-executable file with +x' ' + echo foo >foo1 && + git add --chmod=+x foo1 && + case "$(git ls-files --stage foo1)" in + 100755" "*foo1) echo pass;; + *) echo fail; git ls-files --stage foo1; (exit 1);; + esac +' + +test_expect_success 'git add --chmod=-x stages an executable file with -x' ' + echo foo >xfoo1 && + chmod 755 xfoo1 && + git add --chmod=-x xfoo1 && + case "$(git ls-files --stage xfoo1)" in + 100644" "*xfoo1) echo pass;; + *) echo fail; git ls-files --stage xfoo1; (exit 1);; + esac +' + +test_expect_success POSIXPERM,SYMLINKS 'git add --chmod=+x with symlinks' ' + git config core.filemode 1 && + git config core.symlinks 1 && + echo foo >foo2 && + git add --chmod=+x foo2 && + case "$(git ls-files --stage foo2)" in + 100755" "*foo2) echo pass;; + *) echo fail; git ls-files --stage foo2; (exit 1);; + esac +' + test_done diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 8049cad374..805dc9012d 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1072,7 +1072,7 @@ test_expect_success '--from omits redundant in-body header' ' ' test_expect_success 'in-body headers trigger content encoding' ' - GIT_AUTHOR_NAME="éxötìc" test_commit exotic && + test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic && test_when_finished "git reset --hard HEAD^" && git format-patch -1 --stdout --from >patch && cat >expect <<-\EOF && diff --git a/t/t4051-diff-function-context.sh b/t/t4051-diff-function-context.sh index 001d678e09..b79b87790b 100755 --- a/t/t4051-diff-function-context.sh +++ b/t/t4051-diff-function-context.sh @@ -3,90 +3,180 @@ test_description='diff function context' . ./test-lib.sh -. "$TEST_DIRECTORY"/diff-lib.sh +dir="$TEST_DIRECTORY/t4051" -cat <<\EOF >hello.c -#include <stdio.h> - -static int a(void) -{ - /* - * Dummy. - */ +commit_and_tag () { + tag=$1 && + shift && + git add "$@" && + test_tick && + git commit -m "$tag" && + git tag "$tag" } -static int hello_world(void) -{ - /* Classic. */ - printf("Hello world.\n"); - - /* Success! */ - return 0; +first_context_line () { + awk ' + found {print; exit} + /^@@/ {found = 1} + ' } -static int b(void) -{ - /* - * Dummy, too. - */ + +last_context_line () { + sed -ne \$p } -int main(int argc, char **argv) -{ - a(); - b(); - return hello_world(); +check_diff () { + name=$1 + desc=$2 + options="-W $3" + + test_expect_success "$desc" ' + git diff $options "$name^" "$name" >"$name.diff" + ' + + test_expect_success ' diff applies' ' + test_when_finished "git reset --hard" && + git checkout --detach "$name^" && + git apply --index "$name.diff" && + git diff --exit-code "$name" + ' } -EOF test_expect_success 'setup' ' - git add hello.c && - test_tick && - git commit -m initial && - - grep -v Classic <hello.c >hello.c.new && - mv hello.c.new hello.c -' - -cat <<\EOF >expected -diff --git a/hello.c b/hello.c ---- a/hello.c -+++ b/hello.c -@@ -10,8 +10,7 @@ static int a(void) - static int hello_world(void) - { -- /* Classic. */ - printf("Hello world.\n"); - - /* Success! */ - return 0; - } -EOF - -test_expect_success 'diff -U0 -W' ' - git diff -U0 -W >actual && - compare_diff_patch actual expected -' - -cat <<\EOF >expected -diff --git a/hello.c b/hello.c ---- a/hello.c -+++ b/hello.c -@@ -9,9 +9,8 @@ static int a(void) - - static int hello_world(void) - { -- /* Classic. */ - printf("Hello world.\n"); - - /* Success! */ - return 0; - } -EOF - -test_expect_success 'diff -W' ' - git diff -W >actual && - compare_diff_patch actual expected + cat "$dir/includes.c" "$dir/dummy.c" "$dir/dummy.c" "$dir/hello.c" \ + "$dir/dummy.c" "$dir/dummy.c" >file.c && + commit_and_tag initial file.c && + + grep -v "delete me from hello" <file.c >file.c.new && + mv file.c.new file.c && + commit_and_tag changed_hello file.c && + + grep -v "delete me from includes" <file.c >file.c.new && + mv file.c.new file.c && + commit_and_tag changed_includes file.c && + + cat "$dir/appended1.c" >>file.c && + commit_and_tag appended file.c && + + cat "$dir/appended2.c" >>file.c && + commit_and_tag extended file.c && + + grep -v "Begin of second part" <file.c >file.c.new && + mv file.c.new file.c && + commit_and_tag long_common_tail file.c && + + git checkout initial && + grep -v "delete me from hello" <file.c >file.c.new && + mv file.c.new file.c && + cat "$dir/appended1.c" >>file.c && + commit_and_tag changed_hello_appended file.c +' + +check_diff changed_hello 'changed function' + +test_expect_success ' context includes begin' ' + grep "^ .*Begin of hello" changed_hello.diff +' + +test_expect_success ' context includes end' ' + grep "^ .*End of hello" changed_hello.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" changed_hello.diff) -le 1 +' + +test_expect_success ' context does not include preceding empty lines' ' + test "$(first_context_line <changed_hello.diff)" != " " +' + +test_expect_success ' context does not include trailing empty lines' ' + test "$(last_context_line <changed_hello.diff)" != " " +' + +check_diff changed_includes 'changed includes' + +test_expect_success ' context includes begin' ' + grep "^ .*Begin.h" changed_includes.diff +' + +test_expect_success ' context includes end' ' + grep "^ .*End.h" changed_includes.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" changed_includes.diff) -le 1 +' + +test_expect_success ' context does not include trailing empty lines' ' + test "$(last_context_line <changed_includes.diff)" != " " +' + +check_diff appended 'appended function' + +test_expect_success ' context includes begin' ' + grep "^[+].*Begin of first part" appended.diff +' + +test_expect_success ' context includes end' ' + grep "^[+].*End of first part" appended.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" appended.diff) -le 1 +' + +check_diff extended 'appended function part' + +test_expect_success ' context includes begin' ' + grep "^ .*Begin of first part" extended.diff +' + +test_expect_success ' context includes end' ' + grep "^[+].*End of second part" extended.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" extended.diff) -le 2 +' + +test_expect_success ' context does not include preceding empty lines' ' + test "$(first_context_line <extended.diff)" != " " +' + +check_diff long_common_tail 'change with long common tail and no context' -U0 + +test_expect_success ' context includes begin' ' + grep "^ .*Begin of first part" long_common_tail.diff +' + +test_expect_success ' context includes end' ' + grep "^ .*End of second part" long_common_tail.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" long_common_tail.diff) -le 2 +' + +test_expect_success ' context does not include preceding empty lines' ' + test "$(first_context_line <long_common_tail.diff.diff)" != " " +' + +check_diff changed_hello_appended 'changed function plus appended function' + +test_expect_success ' context includes begin' ' + grep "^ .*Begin of hello" changed_hello_appended.diff && + grep "^[+].*Begin of first part" changed_hello_appended.diff +' + +test_expect_success ' context includes end' ' + grep "^ .*End of hello" changed_hello_appended.diff && + grep "^[+].*End of first part" changed_hello_appended.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" changed_hello_appended.diff) -le 2 ' test_done diff --git a/t/t4051/appended1.c b/t/t4051/appended1.c new file mode 100644 index 0000000000..a9f56f11db --- /dev/null +++ b/t/t4051/appended1.c @@ -0,0 +1,15 @@ + +int appended(void) // Begin of first part +{ + int i; + char *s = "a string"; + + printf("%s\n", s); + + for (i = 99; + i >= 0; + i--) { + printf("%d bottles of beer on the wall\n", i); + } + + printf("End of first part\n"); diff --git a/t/t4051/appended2.c b/t/t4051/appended2.c new file mode 100644 index 0000000000..e651f7147b --- /dev/null +++ b/t/t4051/appended2.c @@ -0,0 +1,35 @@ + printf("Begin of second part\n"); + + /* + * Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, + * sed diam nonumy eirmod tempor invidunt ut labore et dolore + * magna aliquyam erat, sed diam voluptua. At vero eos et + * accusam et justo duo dolores et ea rebum. Stet clita kasd + * gubergren, no sea takimata sanctus est Lorem ipsum dolor + * sit amet. + * + * Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, + * sed diam nonumy eirmod tempor invidunt ut labore et dolore + * magna aliquyam erat, sed diam voluptua. At vero eos et + * accusam et justo duo dolores et ea rebum. Stet clita kasd + * gubergren, no sea takimata sanctus est Lorem ipsum dolor + * sit amet. + * + * Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, + * sed diam nonumy eirmod tempor invidunt ut labore et dolore + * magna aliquyam erat, sed diam voluptua. At vero eos et + * accusam et justo duo dolores et ea rebum. Stet clita kasd + * gubergren, no sea takimata sanctus est Lorem ipsum dolor + * sit amet. + * + * Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, + * sed diam nonumy eirmod tempor invidunt ut labore et dolore + * magna aliquyam erat, sed diam voluptua. At vero eos et + * accusam et justo duo dolores et ea rebum. Stet clita kasd + * gubergren, no sea takimata sanctus est Lorem ipsum dolor + * sit amet. + * + */ + + return 0; +} // End of second part diff --git a/t/t4051/dummy.c b/t/t4051/dummy.c new file mode 100644 index 0000000000..a43016e870 --- /dev/null +++ b/t/t4051/dummy.c @@ -0,0 +1,7 @@ + +static int dummy(void) // Begin of dummy +{ + int rc = 0; + + return rc; +} // End of dummy diff --git a/t/t4051/hello.c b/t/t4051/hello.c new file mode 100644 index 0000000000..63b1a1e4ef --- /dev/null +++ b/t/t4051/hello.c @@ -0,0 +1,21 @@ + +static void hello(void) // Begin of hello +{ + /* + * Classic. + */ + putchar('H'); + putchar('e'); + putchar('l'); + putchar('l'); + putchar('o'); + putchar(' '); + /* delete me from hello */ + putchar('w'); + putchar('o'); + putchar('r'); + putchar('l'); + putchar('d'); + putchar('.'); + putchar('\n'); +} // End of hello diff --git a/t/t4051/includes.c b/t/t4051/includes.c new file mode 100644 index 0000000000..efc68f8bf6 --- /dev/null +++ b/t/t4051/includes.c @@ -0,0 +1,20 @@ +#include <Begin.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdarg.h> +/* delete me from includes */ +#include <string.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/time.h> +#include <time.h> +#include <signal.h> +#include <assert.h> +#include <regex.h> +#include <utime.h> +#include <syslog.h> +#include <End.h> diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh index baa9d3c82e..84a809690e 100755 --- a/t/t4204-patch-id.sh +++ b/t/t4204-patch-id.sh @@ -30,11 +30,11 @@ test_expect_success 'patch-id output is well-formed' ' #calculate patch id. Make sure output is not empty. calc_patch_id () { - name="$1" + patch_name="$1" shift git patch-id "$@" | - sed "s/ .*//" >patch-id_"$name" && - test_line_count -gt 0 patch-id_"$name" + sed "s/ .*//" >patch-id_"$patch_name" && + test_line_count -gt 0 patch-id_"$patch_name" } get_top_diff () { diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index 7398605e7b..d9f62425b0 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -176,6 +176,17 @@ EOF test_cmp expected actual ' +test_expect_success 'left alignment formatting at the nth column' ' + COLUMNS=50 git log --pretty="tformat:%h %<|(-10)%s" >actual && + qz_to_tab_space <<EOF >expected && +$head1 message two Z +$head2 message one Z +$head3 add bar Z +$head4 $(commit_msg) Z +EOF + test_cmp expected actual +' + test_expect_success 'left alignment formatting at the nth column. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %<|(40)%s" >actual && qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected && @@ -308,6 +319,17 @@ EOF test_cmp expected actual ' +test_expect_success 'right alignment formatting at the nth column' ' + COLUMNS=50 git log --pretty="tformat:%h %>|(-10)%s" >actual && + qz_to_tab_space <<EOF >expected && +$head1 message two +$head2 message one +$head3 add bar +$head4 $(commit_msg) +EOF + test_cmp expected actual +' + test_expect_success 'right alignment formatting at the nth column. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %>|(40)%s" >actual && qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected && @@ -319,6 +341,19 @@ EOF test_cmp expected actual ' +# Note: Space between 'message' and 'two' should be in the same column +# as in previous test. +test_expect_success 'right alignment formatting at the nth column with --graph. i18n.logOutputEncoding' ' + git -c i18n.logOutputEncoding=$test_encoding log --graph --pretty="tformat:%h %>|(40)%s" >actual && + iconv -f utf-8 -t $test_encoding >expected <<EOF&& +* $head1 message two +* $head2 message one +* $head3 add bar +* $head4 $(commit_msg) +EOF + test_cmp expected actual +' + test_expect_success 'right alignment formatting with no padding' ' git log --pretty="tformat:%>(1)%s" >actual && cat <<EOF >expected && @@ -330,6 +365,17 @@ EOF test_cmp expected actual ' +test_expect_success 'right alignment formatting with no padding and with --graph' ' + git log --graph --pretty="tformat:%>(1)%s" >actual && + cat <<EOF >expected && +* message two +* message one +* add bar +* $(commit_msg) +EOF + test_cmp expected actual +' + test_expect_success 'right alignment formatting with no padding. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%>(1)%s" >actual && cat <<EOF | iconv -f utf-8 -t $test_encoding >expected && @@ -373,6 +419,17 @@ EOF test_cmp expected actual ' +test_expect_success 'center alignment formatting at the nth column' ' + COLUMNS=70 git log --pretty="tformat:%h %><|(-30)%s" >actual && + qz_to_tab_space <<EOF >expected && +$head1 message two Z +$head2 message one Z +$head3 add bar Z +$head4 $(commit_msg) Z +EOF + test_cmp expected actual +' + test_expect_success 'center alignment formatting at the nth column. i18n.logOutputEncoding' ' git -c i18n.logOutputEncoding=$test_encoding log --pretty="tformat:%h %><|(40)%s" >actual && qz_to_tab_space <<EOF | iconv -f utf-8 -t $test_encoding >expected && diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index d446706e94..3893afd687 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -47,6 +47,12 @@ rev_list_tests() { test_cmp expect actual ' + test_expect_success "counting commits with limit ($state)" ' + git rev-list --count -n 1 HEAD >expect && + git rev-list --use-bitmap-index --count -n 1 HEAD >actual && + test_cmp expect actual + ' + test_expect_success "counting non-linear history ($state)" ' git rev-list --count other...master >expect && git rev-list --use-bitmap-index --count other...master >actual && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 91a69fc33a..82d913a6a8 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -558,7 +558,6 @@ check_prot_path () { } check_prot_host_port_path () { - local diagport case "$2" in *ssh*) pp=ssh diff --git a/t/t5614-clone-submodules.sh b/t/t5614-clone-submodules.sh index 62044c5a02..da2a67f656 100755 --- a/t/t5614-clone-submodules.sh +++ b/t/t5614-clone-submodules.sh @@ -25,61 +25,46 @@ test_expect_success 'setup' ' test_expect_success 'nonshallow clone implies nonshallow submodule' ' test_when_finished "rm -rf super_clone" && git clone --recurse-submodules "file://$pwd/." super_clone && - ( - cd super_clone && - git log --oneline >lines && - test_line_count = 3 lines - ) && - ( - cd super_clone/sub && - git log --oneline >lines && - test_line_count = 3 lines - ) + git -C super_clone log --oneline >lines && + test_line_count = 3 lines && + git -C super_clone/sub log --oneline >lines && + test_line_count = 3 lines +' + +test_expect_success 'shallow clone with shallow submodule' ' + test_when_finished "rm -rf super_clone" && + git clone --recurse-submodules --depth 2 --shallow-submodules "file://$pwd/." super_clone && + git -C super_clone log --oneline >lines && + test_line_count = 2 lines && + git -C super_clone/sub log --oneline >lines && + test_line_count = 1 lines ' -test_expect_success 'shallow clone implies shallow submodule' ' +test_expect_success 'shallow clone does not imply shallow submodule' ' test_when_finished "rm -rf super_clone" && git clone --recurse-submodules --depth 2 "file://$pwd/." super_clone && - ( - cd super_clone && - git log --oneline >lines && - test_line_count = 2 lines - ) && - ( - cd super_clone/sub && - git log --oneline >lines && - test_line_count = 1 lines - ) + git -C super_clone log --oneline >lines && + test_line_count = 2 lines && + git -C super_clone/sub log --oneline >lines && + test_line_count = 3 lines ' test_expect_success 'shallow clone with non shallow submodule' ' test_when_finished "rm -rf super_clone" && git clone --recurse-submodules --depth 2 --no-shallow-submodules "file://$pwd/." super_clone && - ( - cd super_clone && - git log --oneline >lines && - test_line_count = 2 lines - ) && - ( - cd super_clone/sub && - git log --oneline >lines && - test_line_count = 3 lines - ) + git -C super_clone log --oneline >lines && + test_line_count = 2 lines && + git -C super_clone/sub log --oneline >lines && + test_line_count = 3 lines ' test_expect_success 'non shallow clone with shallow submodule' ' test_when_finished "rm -rf super_clone" && git clone --recurse-submodules --no-local --shallow-submodules "file://$pwd/." super_clone && - ( - cd super_clone && - git log --oneline >lines && - test_line_count = 3 lines - ) && - ( - cd super_clone/sub && - git log --oneline >lines && - test_line_count = 1 lines - ) + git -C super_clone log --oneline >lines && + test_line_count = 3 lines && + git -C super_clone/sub log --oneline >lines && + test_line_count = 1 lines ' test_done diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index b77d4c97c1..a1dcdb81d7 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -184,38 +184,38 @@ commit $head1 [1;31;43mfoo[m EOF -test_expect_success '%C(auto) does not enable color by default' ' +test_expect_success '%C(auto,...) does not enable color by default' ' git log --format=$AUTO_COLOR -1 >actual && has_no_color actual ' -test_expect_success '%C(auto) enables colors for color.diff' ' +test_expect_success '%C(auto,...) enables colors for color.diff' ' git -c color.diff=always log --format=$AUTO_COLOR -1 >actual && has_color actual ' -test_expect_success '%C(auto) enables colors for color.ui' ' +test_expect_success '%C(auto,...) enables colors for color.ui' ' git -c color.ui=always log --format=$AUTO_COLOR -1 >actual && has_color actual ' -test_expect_success '%C(auto) respects --color' ' +test_expect_success '%C(auto,...) respects --color' ' git log --format=$AUTO_COLOR -1 --color >actual && has_color actual ' -test_expect_success '%C(auto) respects --no-color' ' +test_expect_success '%C(auto,...) respects --no-color' ' git -c color.ui=always log --format=$AUTO_COLOR -1 --no-color >actual && has_no_color actual ' -test_expect_success TTY '%C(auto) respects --color=auto (stdout is tty)' ' +test_expect_success TTY '%C(auto,...) respects --color=auto (stdout is tty)' ' test_terminal env TERM=vt100 \ git log --format=$AUTO_COLOR -1 --color=auto >actual && has_color actual ' -test_expect_success '%C(auto) respects --color=auto (stdout not tty)' ' +test_expect_success '%C(auto,...) respects --color=auto (stdout not tty)' ' ( TERM=vt100 && export TERM && git log --format=$AUTO_COLOR -1 --color=auto >actual && @@ -223,6 +223,18 @@ test_expect_success '%C(auto) respects --color=auto (stdout not tty)' ' ) ' +test_expect_success '%C(auto) respects --color' ' + git log --color --format="%C(auto)%H" -1 >actual && + printf "\\033[33m%s\\033[m\\n" $(git rev-parse HEAD) >expect && + test_cmp expect actual +' + +test_expect_success '%C(auto) respects --no-color' ' + git log --no-color --format="%C(auto)%H" -1 >actual && + git rev-parse HEAD >expect && + test_cmp expect actual +' + iconv -f utf-8 -t $test_encoding > commit-msg <<EOF Test printing of complex bodies diff --git a/t/t6044-merge-unrelated-index-changes.sh b/t/t6044-merge-unrelated-index-changes.sh index 20a3ffed69..01023486c5 100755 --- a/t/t6044-merge-unrelated-index-changes.sh +++ b/t/t6044-merge-unrelated-index-changes.sh @@ -20,7 +20,7 @@ test_description="merges with unrelated index changes" # Commit E: renames a->subdir/a, adds subdir/e test_expect_success 'setup trivial merges' ' - seq 1 10 >a && + test_seq 1 10 >a && git add a && test_tick && git commit -m A && @@ -42,7 +42,7 @@ test_expect_success 'setup trivial merges' ' test_tick && git commit -m C && git checkout D && - seq 2 10 >a && + test_seq 2 10 >a && echo d >d && git add a d && test_tick && git commit -m D && diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh index 79bc135bf6..5503ec067f 100755 --- a/t/t7403-submodule-sync.sh +++ b/t/t7403-submodule-sync.sh @@ -62,13 +62,13 @@ test_expect_success 'change submodule' ' ' reset_submodule_urls () { - local root - root=$(pwd) && ( + root=$(pwd) && cd super-clone/submodule && git config remote.origin.url "$root/submodule" ) && ( + root=$(pwd) && cd super-clone/submodule/sub-submodule && git config remote.origin.url "$root/submodule" ) diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 7ce4cd753e..42a2929835 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -446,7 +446,7 @@ write_script .git/CHECK_SYMLINKS <<\EOF for f in file file2 sub/sub do echo "$f" - readlink "$2/$f" + ls -ld "$2/$f" | sed -e 's/.* -> //' done >actual EOF diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 1e72971a16..cf3f9ec631 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -9,7 +9,9 @@ test_description='git grep various. . ./test-lib.sh cat >hello.c <<EOF +#include <assert.h> #include <stdio.h> + int main(int argc, const char **argv) { printf("Hello world.\n"); @@ -175,7 +177,7 @@ do test_expect_success "grep -c $L (no /dev/null)" ' ! git grep -c test $H | grep /dev/null - ' + ' test_expect_success "grep --max-depth -1 $L" ' { @@ -353,7 +355,7 @@ test_expect_success 'grep -l -C' ' cat >expected <<EOF file:5 EOF -test_expect_success 'grep -l -C' ' +test_expect_success 'grep -c -C' ' git grep -c -C1 foo >actual && test_cmp expected actual ' @@ -715,6 +717,7 @@ test_expect_success 'grep -p' ' cat >expected <<EOF hello.c-#include <stdio.h> +hello.c- hello.c=int main(int argc, const char **argv) hello.c-{ hello.c- printf("Hello world.\n"); @@ -741,6 +744,16 @@ test_expect_success 'grep -W' ' ' cat >expected <<EOF +hello.c-#include <assert.h> +hello.c:#include <stdio.h> +EOF + +test_expect_success 'grep -W shows no trailing empty lines' ' + git grep -W stdio >actual && + test_cmp expected actual +' + +cat >expected <<EOF hello.c= printf("Hello world.\n"); hello.c: return 0; hello.c- /* char ?? */ @@ -1232,8 +1245,8 @@ test_expect_success 'grep --heading' ' cat >expected <<EOF <BOLD;GREEN>hello.c<RESET> -2:int main(int argc, const <BLACK;BYELLOW>char<RESET> **argv) -6: /* <BLACK;BYELLOW>char<RESET> ?? */ +4:int main(int argc, const <BLACK;BYELLOW>char<RESET> **argv) +8: /* <BLACK;BYELLOW>char<RESET> ?? */ <BOLD;GREEN>hello_world<RESET> 3:Hel<BLACK;BYELLOW>lo_w<RESET>orld @@ -1340,7 +1353,7 @@ test_expect_success 'grep --color -e A --and --not -e B with context' ' ' cat >expected <<EOF -hello.c-#include <stdio.h> +hello.c- hello.c=int main(int argc, const char **argv) hello.c-{ hello.c: pr<RED>int<RESET>f("<RED>Hello<RESET> world.\n"); @@ -1364,4 +1377,62 @@ test_expect_success 'grep --color -e A --and -e B -p with context' ' test_cmp expected actual ' +test_expect_success 'grep can find things only in the work tree' ' + : >work-tree-only && + git add work-tree-only && + test_when_finished "git rm -f work-tree-only" && + echo "find in work tree" >work-tree-only && + git grep --quiet "find in work tree" && + test_must_fail git grep --quiet --cached "find in work tree" && + test_must_fail git grep --quiet "find in work tree" HEAD +' + +test_expect_success 'grep can find things only in the work tree (i-t-a)' ' + echo "intend to add this" >intend-to-add && + git add -N intend-to-add && + test_when_finished "git rm -f intend-to-add" && + git grep --quiet "intend to add this" && + test_must_fail git grep --quiet --cached "intend to add this" && + test_must_fail git grep --quiet "intend to add this" HEAD +' + +test_expect_success 'grep does not search work tree with assume unchanged' ' + echo "intend to add this" >intend-to-add && + git add -N intend-to-add && + git update-index --assume-unchanged intend-to-add && + test_when_finished "git rm -f intend-to-add" && + test_must_fail git grep --quiet "intend to add this" && + test_must_fail git grep --quiet --cached "intend to add this" && + test_must_fail git grep --quiet "intend to add this" HEAD +' + +test_expect_success 'grep can find things only in the index' ' + echo "only in the index" >cache-this && + git add cache-this && + rm cache-this && + test_when_finished "git rm --cached cache-this" && + test_must_fail git grep --quiet "only in the index" && + git grep --quiet --cached "only in the index" && + test_must_fail git grep --quiet "only in the index" HEAD +' + +test_expect_success 'grep does not report i-t-a with -L --cached' ' + echo "intend to add this" >intend-to-add && + git add -N intend-to-add && + test_when_finished "git rm -f intend-to-add" && + git ls-files | grep -v "^intend-to-add\$" >expected && + git grep -L --cached "nonexistent_string" >actual && + test_cmp expected actual +' + +test_expect_success 'grep does not report i-t-a and assume unchanged with -L' ' + echo "intend to add this" >intend-to-add-assume-unchanged && + git add -N intend-to-add-assume-unchanged && + test_when_finished "git rm -f intend-to-add-assume-unchanged" && + git update-index --assume-unchanged intend-to-add-assume-unchanged && + git ls-files | grep -v "^intend-to-add-assume-unchanged\$" >expected && + git grep -L "nonexistent_string" >actual && + test_cmp expected actual +' + test_done diff --git a/t/t8008-blame-formats.sh b/t/t8008-blame-formats.sh index 29f84a6dd1..92c8e792d1 100755 --- a/t/t8008-blame-formats.sh +++ b/t/t8008-blame-formats.sh @@ -87,4 +87,21 @@ test_expect_success 'blame --line-porcelain output' ' test_cmp expect actual ' +test_expect_success '--porcelain detects first non-blank line as subject' ' + ( + GIT_INDEX_FILE=.git/tmp-index && + export GIT_INDEX_FILE && + echo "This is it" >single-file && + git add single-file && + tree=$(git write-tree) && + commit=$(printf "%s\n%s\n%s\n\n\n \noneline\n\nbody\n" \ + "tree $tree" \ + "author A <a@b.c> 123456789 +0000" \ + "committer C <c@d.e> 123456789 +0000" | + git hash-object -w -t commit --stdin) && + git blame --porcelain $commit -- single-file >output && + grep "^summary oneline$" output + ) +' + test_done diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 25bb60b281..4bca35c259 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -2650,6 +2650,21 @@ test_expect_success 'R: ignore non-git options' ' git fast-import <input ' +test_expect_success 'R: corrupt lines do not mess marks file' ' + rm -f io.marks && + blob=$(echo hi | git hash-object --stdin) && + cat >expect <<-EOF && + :3 0000000000000000000000000000000000000000 + :1 $blob + :2 $blob + EOF + cp expect io.marks && + test_must_fail git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF && + + EOF + test_cmp expect io.marks +' + ## ## R: very large blobs ## diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 3978fc0b45..ca40a1289f 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -612,7 +612,7 @@ test_must_fail () { then echo >&2 "test_must_fail: command succeeded: $*" return 1 - elif test $exit_code -eq 141 && list_contains "$_test_ok" sigpipe + elif test_match_signal 13 $exit_code && list_contains "$_test_ok" sigpipe then return 0 elif test $exit_code -gt 129 && test $exit_code -le 192 @@ -939,3 +939,40 @@ mingw_read_file_strip_cr_ () { eval "$1=\$$1\$line" done } + +# Like "env FOO=BAR some-program", but run inside a subshell, which means +# it also works for shell functions (though those functions cannot impact +# the environment outside of the test_env invocation). +test_env () { + ( + while test $# -gt 0 + do + case "$1" in + *=*) + eval "${1%%=*}=\${1#*=}" + eval "export ${1%%=*}" + shift + ;; + *) + "$@" + exit + ;; + esac + done + ) +} + +# Returns true if the numeric exit code in "$2" represents the expected signal +# in "$1". Signals should be given numerically. +test_match_signal () { + if test "$2" = "$((128 + $1))" + then + # POSIX + return 0 + elif test "$2" = "$((256 + $1))" + then + # ksh + return 0 + fi + return 1 +} diff --git a/t/test-lib.sh b/t/test-lib.sh index 0055ebba46..11201e9cf8 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1111,3 +1111,12 @@ run_with_limited_cmdline () { } test_lazy_prereq CMDLINE_LIMIT 'run_with_limited_cmdline true' + +build_option () { + git version --build-options | + sed -ne "s/^$1: //p" +} + +test_lazy_prereq LONG_IS_64BIT ' + test 8 -le "$(build_option sizeof-long)" +' |