diff options
Diffstat (limited to 't')
35 files changed, 959 insertions, 184 deletions
diff --git a/t/helper/.gitignore b/t/helper/.gitignore index 2bad28af92..48c7bb0bbb 100644 --- a/t/helper/.gitignore +++ b/t/helper/.gitignore @@ -1,5 +1,4 @@ -* -!*.sh -!*.[ch] -!*.gitignore - +/test-tool +/test-fake-ssh +/test-line-buffer +/test-svn-fe diff --git a/t/helper/test-date.c b/t/helper/test-date.c index 585347ea48..099eff4f0f 100644 --- a/t/helper/test-date.c +++ b/t/helper/test-date.c @@ -12,13 +12,13 @@ static const char *usage_msg = "\n" " test-tool date is64bit\n" " test-tool date time_t-is64bit\n"; -static void show_relative_dates(const char **argv, struct timeval *now) +static void show_relative_dates(const char **argv) { struct strbuf buf = STRBUF_INIT; for (; *argv; argv++) { time_t t = atoi(*argv); - show_date_relative(t, now, &buf); + show_date_relative(t, &buf); printf("%s -> %s\n", *argv, buf.buf); } strbuf_release(&buf); @@ -74,20 +74,20 @@ static void parse_dates(const char **argv) strbuf_release(&result); } -static void parse_approxidate(const char **argv, struct timeval *now) +static void parse_approxidate(const char **argv) { for (; *argv; argv++) { timestamp_t t; - t = approxidate_relative(*argv, now); + t = approxidate_relative(*argv); printf("%s -> %s\n", *argv, show_date(t, 0, DATE_MODE(ISO8601))); } } -static void parse_approx_timestamp(const char **argv, struct timeval *now) +static void parse_approx_timestamp(const char **argv) { for (; *argv; argv++) { timestamp_t t; - t = approxidate_relative(*argv, now); + t = approxidate_relative(*argv); printf("%s -> %"PRItime"\n", *argv, t); } } @@ -103,22 +103,13 @@ static void getnanos(const char **argv) int cmd__date(int argc, const char **argv) { - struct timeval now; const char *x; - x = getenv("GIT_TEST_DATE_NOW"); - if (x) { - now.tv_sec = atoi(x); - now.tv_usec = 0; - } - else - gettimeofday(&now, NULL); - argv++; if (!*argv) usage(usage_msg); if (!strcmp(*argv, "relative")) - show_relative_dates(argv+1, &now); + show_relative_dates(argv+1); else if (!strcmp(*argv, "human")) show_human_dates(argv+1); else if (skip_prefix(*argv, "show:", &x)) @@ -126,9 +117,9 @@ int cmd__date(int argc, const char **argv) else if (!strcmp(*argv, "parse")) parse_dates(argv+1); else if (!strcmp(*argv, "approxidate")) - parse_approxidate(argv+1, &now); + parse_approxidate(argv+1); else if (!strcmp(*argv, "timestamp")) - parse_approx_timestamp(argv+1, &now); + parse_approx_timestamp(argv+1); else if (!strcmp(*argv, "getnanos")) getnanos(argv+1); else if (!strcmp(*argv, "is64bit")) diff --git a/t/helper/test-progress.c b/t/helper/test-progress.c new file mode 100644 index 0000000000..4e9f7fafdf --- /dev/null +++ b/t/helper/test-progress.c @@ -0,0 +1,81 @@ +/* + * A test helper to exercise the progress display. + * + * Reads instructions from standard input, one instruction per line: + * + * "progress <items>" - Call display_progress() with the given item count + * as parameter. + * "throughput <bytes> <millis> - Call display_throughput() with the given + * byte count as parameter. The 'millis' + * specify the time elapsed since the + * start_progress() call. + * "update" - Set the 'progress_update' flag. + * + * See 't0500-progress-display.sh' for examples. + */ +#include "test-tool.h" +#include "gettext.h" +#include "parse-options.h" +#include "progress.h" +#include "strbuf.h" + +/* + * These are defined in 'progress.c', but are not exposed in 'progress.h', + * because they are exclusively for testing. + */ +extern int progress_testing; +extern uint64_t progress_test_ns; +void progress_test_force_update(void); + +int cmd__progress(int argc, const char **argv) +{ + uint64_t total = 0; + const char *title; + struct strbuf line = STRBUF_INIT; + struct progress *progress; + + const char *usage[] = { + "test-tool progress [--total=<n>] <progress-title>", + NULL + }; + struct option options[] = { + OPT_INTEGER(0, "total", &total, "total number of items"), + OPT_END(), + }; + + argc = parse_options(argc, argv, NULL, options, usage, 0); + if (argc != 1) + die("need a title for the progress output"); + title = argv[0]; + + progress_testing = 1; + progress = start_progress(title, total); + while (strbuf_getline(&line, stdin) != EOF) { + char *end; + + if (skip_prefix(line.buf, "progress ", (const char **) &end)) { + uint64_t item_count = strtoull(end, &end, 10); + if (*end != '\0') + die("invalid input: '%s'\n", line.buf); + display_progress(progress, item_count); + } else if (skip_prefix(line.buf, "throughput ", + (const char **) &end)) { + uint64_t byte_count, test_ms; + + byte_count = strtoull(end, &end, 10); + if (*end != ' ') + die("invalid input: '%s'\n", line.buf); + test_ms = strtoull(end + 1, &end, 10); + if (*end != '\0') + die("invalid input: '%s'\n", line.buf); + progress_test_ns = test_ms * 1000 * 1000; + display_throughput(progress, byte_count); + } else if (!strcmp(line.buf, "update")) + progress_test_force_update(); + else + die("invalid input: '%s'\n", line.buf); + } + stop_progress(&progress); + + return 0; +} diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index ce7e89028c..19ee26d931 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -42,6 +42,7 @@ static struct test_cmd cmds[] = { { "path-utils", cmd__path_utils }, { "pkt-line", cmd__pkt_line }, { "prio-queue", cmd__prio_queue }, + { "progress", cmd__progress }, { "reach", cmd__reach }, { "read-cache", cmd__read_cache }, { "read-midx", cmd__read_midx }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index f805bb39ae..c2aa56ef50 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -32,6 +32,7 @@ int cmd__parse_options(int argc, const char **argv); int cmd__path_utils(int argc, const char **argv); int cmd__pkt_line(int argc, const char **argv); int cmd__prio_queue(int argc, const char **argv); +int cmd__progress(int argc, const char **argv); int cmd__reach(int argc, const char **argv); int cmd__read_cache(int argc, const char **argv); int cmd__read_midx(int argc, const char **argv); diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh index 192c94eccd..608673fb77 100755 --- a/t/t0050-filesystem.sh +++ b/t/t0050-filesystem.sh @@ -131,4 +131,24 @@ $test_unicode 'merge (silent unicode normalization)' ' git merge topic ' +test_expect_success CASE_INSENSITIVE_FS 'checkout with no pathspec and a case insensitive fs' ' + git init repo && + ( + cd repo && + + >Gitweb && + git add Gitweb && + git commit -m "add Gitweb" && + + git checkout --orphan todo && + git reset --hard && + mkdir -p gitweb/subdir && + >gitweb/subdir/file && + git add gitweb && + git commit -m "add gitweb/subdir/file" && + + git checkout master + ) +' + test_done diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index 015fac8b5d..17c9c0f3bb 100755 --- a/t/t0061-run-command.sh +++ b/t/t0061-run-command.sh @@ -210,10 +210,23 @@ test_expect_success MINGW 'verify curlies are quoted properly' ' test_cmp expect actual ' -test_expect_success MINGW 'can spawn with argv[0] containing spaces' ' - cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" ./ && - test_must_fail "$PWD/test-fake-ssh$X" 2>err && - grep TRASH_DIRECTORY err +test_expect_success MINGW 'can spawn .bat with argv[0] containing spaces' ' + bat="$TRASH_DIRECTORY/bat with spaces in name.bat" && + + # Every .bat invocation will log its arguments to file "out" + rm -f out && + echo "echo %* >>out" >"$bat" && + + # Ask git to invoke .bat; clone will fail due to fake SSH helper + test_must_fail env GIT_SSH="$bat" git clone myhost:src ssh-clone && + + # Spawning .bat can fail if there are two quoted cmd.exe arguments. + # .bat itself is first (due to spaces in name), so just one more is + # needed to verify. GIT_SSH will invoke .bat multiple times: + # 1) -G myhost + # 2) myhost "git-upload-pack src" + # First invocation will always succeed. Test the second one. + grep "git-upload-pack" out ' test_done diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index d4b7e535ea..a3988bd4b8 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -429,6 +429,19 @@ test_expect_success 'rev-list dies for missing objects on cmd line' ' done ' +test_expect_success 'single promisor remote can be re-initialized gracefully' ' + # ensure one promisor is in the promisors list + rm -rf repo && + test_create_repo repo && + test_create_repo other && + git -C repo remote add foo "file://$(pwd)/other" && + git -C repo config remote.foo.promisor true && + git -C repo config extensions.partialclone foo && + + # reinitialize the promisors list + git -C repo fetch --filter=blob:none foo +' + test_expect_success 'gc repacks promisor objects separately from non-promisor objects' ' rm -rf repo && test_create_repo repo && @@ -540,6 +553,20 @@ test_expect_success 'gc stops traversal when a missing but promised object is re ! grep "$TREE_HASH" out ' +test_expect_success 'do not fetch when checking existence of tree we construct ourselves' ' + rm -rf repo && + test_create_repo repo && + test_commit -C repo base && + test_commit -C repo side1 && + git -C repo checkout base && + test_commit -C repo side2 && + + git -C repo config core.repositoryformatversion 1 && + git -C repo config extensions.partialclone "arbitrary string" && + + git -C repo cherry-pick side1 +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh new file mode 100755 index 0000000000..24ccbd8d3b --- /dev/null +++ b/t/t0500-progress-display.sh @@ -0,0 +1,286 @@ +#!/bin/sh + +test_description='progress display' + +. ./test-lib.sh + +show_cr () { + tr '\015' Q | sed -e "s/Q/<CR>\\$LF/g" +} + +test_expect_success 'simple progress display' ' + cat >expect <<-\EOF && + Working hard: 1<CR> + Working hard: 2<CR> + Working hard: 5<CR> + Working hard: 5, done. + EOF + + cat >in <<-\EOF && + update + progress 1 + update + progress 2 + progress 3 + progress 4 + update + progress 5 + EOF + test-tool progress "Working hard" <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'progress display with total' ' + cat >expect <<-\EOF && + Working hard: 33% (1/3)<CR> + Working hard: 66% (2/3)<CR> + Working hard: 100% (3/3)<CR> + Working hard: 100% (3/3), done. + EOF + + cat >in <<-\EOF && + progress 1 + progress 2 + progress 3 + EOF + test-tool progress --total=3 "Working hard" <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'progress display breaks long lines #1' ' + sed -e "s/Z$//" >expect <<\EOF && +Working hard.......2.........3.........4.........5.........6: 0% (100/100000)<CR> +Working hard.......2.........3.........4.........5.........6: 1% (1000/100000)<CR> +Working hard.......2.........3.........4.........5.........6: Z + 10% (10000/100000)<CR> + 100% (100000/100000)<CR> + 100% (100000/100000), done. +EOF + + cat >in <<-\EOF && + progress 100 + progress 1000 + progress 10000 + progress 100000 + EOF + test-tool progress --total=100000 \ + "Working hard.......2.........3.........4.........5.........6" \ + <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'progress display breaks long lines #2' ' + # Note: we dont need that many spaces after the title to cover up + # the last line before breaking the progress line. + sed -e "s/Z$//" >expect <<\EOF && +Working hard.......2.........3.........4.........5.........6: 0% (1/100000)<CR> +Working hard.......2.........3.........4.........5.........6: 0% (2/100000)<CR> +Working hard.......2.........3.........4.........5.........6: Z + 10% (10000/100000)<CR> + 100% (100000/100000)<CR> + 100% (100000/100000), done. +EOF + + cat >in <<-\EOF && + update + progress 1 + update + progress 2 + progress 10000 + progress 100000 + EOF + test-tool progress --total=100000 \ + "Working hard.......2.........3.........4.........5.........6" \ + <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'progress display breaks long lines #3 - even the first is too long' ' + # Note: we dont actually need any spaces at the end of the title + # line, because there is no previous progress line to cover up. + sed -e "s/Z$//" >expect <<\EOF && +Working hard.......2.........3.........4.........5.........6: Z + 25% (25000/100000)<CR> + 50% (50000/100000)<CR> + 75% (75000/100000)<CR> + 100% (100000/100000)<CR> + 100% (100000/100000), done. +EOF + + cat >in <<-\EOF && + progress 25000 + progress 50000 + progress 75000 + progress 100000 + EOF + test-tool progress --total=100000 \ + "Working hard.......2.........3.........4.........5.........6" \ + <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'progress display breaks long lines #4 - title line matches terminal width' ' + cat >expect <<\EOF && +Working hard.......2.........3.........4.........5.........6.........7.........: + 25% (25000/100000)<CR> + 50% (50000/100000)<CR> + 75% (75000/100000)<CR> + 100% (100000/100000)<CR> + 100% (100000/100000), done. +EOF + + cat >in <<-\EOF && + progress 25000 + progress 50000 + progress 75000 + progress 100000 + EOF + test-tool progress --total=100000 \ + "Working hard.......2.........3.........4.........5.........6.........7........." \ + <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +# Progress counter goes backwards, this should not happen in practice. +test_expect_success 'progress shortens - crazy caller' ' + cat >expect <<-\EOF && + Working hard: 10% (100/1000)<CR> + Working hard: 20% (200/1000)<CR> + Working hard: 0% (1/1000) <CR> + Working hard: 100% (1000/1000)<CR> + Working hard: 100% (1000/1000), done. + EOF + + cat >in <<-\EOF && + progress 100 + progress 200 + progress 1 + progress 1000 + EOF + test-tool progress --total=1000 "Working hard" <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'progress display with throughput' ' + cat >expect <<-\EOF && + Working hard: 10<CR> + Working hard: 20, 200.00 KiB | 100.00 KiB/s<CR> + Working hard: 30, 300.00 KiB | 100.00 KiB/s<CR> + Working hard: 40, 400.00 KiB | 100.00 KiB/s<CR> + Working hard: 40, 400.00 KiB | 100.00 KiB/s, done. + EOF + + cat >in <<-\EOF && + throughput 102400 1000 + update + progress 10 + throughput 204800 2000 + update + progress 20 + throughput 307200 3000 + update + progress 30 + throughput 409600 4000 + update + progress 40 + EOF + test-tool progress "Working hard" <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'progress display with throughput and total' ' + cat >expect <<-\EOF && + Working hard: 25% (10/40)<CR> + Working hard: 50% (20/40), 200.00 KiB | 100.00 KiB/s<CR> + Working hard: 75% (30/40), 300.00 KiB | 100.00 KiB/s<CR> + Working hard: 100% (40/40), 400.00 KiB | 100.00 KiB/s<CR> + Working hard: 100% (40/40), 400.00 KiB | 100.00 KiB/s, done. + EOF + + cat >in <<-\EOF && + throughput 102400 1000 + progress 10 + throughput 204800 2000 + progress 20 + throughput 307200 3000 + progress 30 + throughput 409600 4000 + progress 40 + EOF + test-tool progress --total=40 "Working hard" <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'cover up after throughput shortens' ' + cat >expect <<-\EOF && + Working hard: 1<CR> + Working hard: 2, 800.00 KiB | 400.00 KiB/s<CR> + Working hard: 3, 1.17 MiB | 400.00 KiB/s <CR> + Working hard: 4, 1.56 MiB | 400.00 KiB/s<CR> + Working hard: 4, 1.56 MiB | 400.00 KiB/s, done. + EOF + + cat >in <<-\EOF && + throughput 409600 1000 + update + progress 1 + throughput 819200 2000 + update + progress 2 + throughput 1228800 3000 + update + progress 3 + throughput 1638400 4000 + update + progress 4 + EOF + test-tool progress "Working hard" <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_expect_success 'cover up after throughput shortens a lot' ' + cat >expect <<-\EOF && + Working hard: 1<CR> + Working hard: 2, 1000.00 KiB | 1000.00 KiB/s<CR> + Working hard: 3, 3.00 MiB | 1.50 MiB/s <CR> + Working hard: 3, 3.00 MiB | 1024.00 KiB/s, done. + EOF + + cat >in <<-\EOF && + throughput 1 1000 + update + progress 1 + throughput 1024000 2000 + update + progress 2 + throughput 3145728 3000 + update + progress 3 + EOF + test-tool progress "Working hard" <in 2>stderr && + + show_cr <stderr >out && + test_i18ncmp expect out +' + +test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index b36e0528d0..50d28e6fdb 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -70,7 +70,6 @@ test_expect_success 'object with bad sha1' ' test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "$sha.*corrupt" out ' @@ -78,7 +77,6 @@ test_expect_success 'branch pointing to non-commit' ' git rev-parse HEAD^{tree} >.git/refs/heads/invalid && test_when_finished "git update-ref -d refs/heads/invalid" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "not a commit" out ' @@ -88,7 +86,6 @@ test_expect_success 'HEAD link pointing at a funny object' ' echo $ZERO_OID >.git/HEAD && # avoid corrupt/broken HEAD from interfering with repo discovery test_must_fail env GIT_DIR=.git git fsck 2>out && - cat out && test_i18ngrep "detached HEAD points" out ' @@ -98,7 +95,6 @@ test_expect_success 'HEAD link pointing at a funny place' ' echo "ref: refs/funny/place" >.git/HEAD && # avoid corrupt/broken HEAD from interfering with repo discovery test_must_fail env GIT_DIR=.git git fsck 2>out && - cat out && test_i18ngrep "HEAD points to something strange" out ' @@ -157,7 +153,6 @@ test_expect_success 'email with embedded > is not okay' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new" out ' @@ -169,7 +164,6 @@ test_expect_success 'missing < email delimiter is reported nicely' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new.* - bad name" out ' @@ -181,7 +175,6 @@ test_expect_success 'missing email is reported nicely' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new.* - missing email" out ' @@ -193,7 +186,6 @@ test_expect_success '> in name is reported' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new" out ' @@ -207,7 +199,6 @@ test_expect_success 'integer overflow in timestamps is reported' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new.*integer overflow" out ' @@ -219,7 +210,6 @@ test_expect_success 'commit with NUL in header' ' git update-ref refs/heads/bogus "$new" && test_when_finished "git update-ref -d refs/heads/bogus" && test_must_fail git fsck 2>out && - cat out && test_i18ngrep "error in commit $new.*unterminated header: NUL at offset" out ' @@ -297,7 +287,6 @@ test_expect_success 'tag pointing to nonexistent' ' echo $tag >.git/refs/tags/invalid && test_when_finished "git update-ref -d refs/tags/invalid" && test_must_fail git fsck --tags >out && - cat out && test_i18ngrep "broken link" out ' @@ -378,7 +367,6 @@ test_expect_success 'tag with NUL in header' ' echo $tag >.git/refs/tags/wrong && test_when_finished "git update-ref -d refs/tags/wrong" && test_must_fail git fsck --tags 2>out && - cat out && test_i18ngrep "error in tag $tag.*unterminated header: NUL at offset" out ' @@ -409,7 +397,6 @@ test_expect_success 'rev-list --verify-objects with bad sha1' ' test_when_finished "git update-ref -d refs/heads/bogus" && test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out && - cat out && test_i18ngrep -q "error: hash mismatch $(dirname $new)$(test_oid ff_2)" out ' @@ -433,7 +420,6 @@ test_expect_success 'fsck notices blob entry pointing to null sha1' ' sha=$(printf "100644 file$_bz$_bzoid" | git hash-object -w --stdin -t tree) && git fsck 2>out && - cat out && test_i18ngrep "warning.*null sha1" out ) ' @@ -444,7 +430,6 @@ test_expect_success 'fsck notices submodule entry pointing to null sha1' ' sha=$(printf "160000 submodule$_bz$_bzoid" | git hash-object -w --stdin -t tree) && git fsck 2>out && - cat out && test_i18ngrep "warning.*null sha1" out ) ' @@ -465,7 +450,6 @@ while read name path pretty; do printf "$mode $type %s\t%s" "$value" "$path" >bad && bad_tree=$(git mktree <bad) && git fsck 2>out && - cat out && test_i18ngrep "warning.*tree $bad_tree" out )' done <<-\EOF diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index 21a9c8ffb2..624d0a588f 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -214,4 +214,12 @@ test_expect_success 'arg before dashdash must be a revision (ambiguous)' ' test_cmp expect actual ' +test_expect_success 'reject Nth parent if N is too high' ' + test_must_fail git rev-parse HEAD^100000000000000000000000000000000 +' + +test_expect_success 'reject Nth ancestor if N is too high' ' + test_must_fail git rev-parse HEAD~100000000000000000000000000000000 +' + test_done diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index ff641b348a..faa8892741 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -452,6 +452,34 @@ test_expect_success 'merge-recursive d/f conflict result' ' ' +test_expect_success SYMLINKS 'dir in working tree with symlink ancestor does not produce d/f conflict' ' + git init sym && + ( + cd sym && + ln -s . foo && + mkdir bar && + >bar/file && + git add foo bar/file && + git commit -m "foo symlink" && + + git checkout -b branch1 && + git commit --allow-empty -m "empty commit" && + + git checkout master && + git rm foo && + mkdir foo && + >foo/bar && + git add foo/bar && + git commit -m "replace foo symlink with real foo dir and foo/bar file" && + + git checkout branch1 && + + git cherry-pick master && + test_path_is_dir foo && + test_path_is_file foo/bar + ) +' + test_expect_success 'reset and 3-way merge' ' git reset --hard "$c2" && diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index 0120f769f1..64b66f2094 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -461,4 +461,8 @@ test_expect_success 'format-patch --range-diff as commentary' ' grep "> 1: .* new message" 0001-* ' +test_expect_success 'range-diff overrides diff.noprefix internally' ' + git -c diff.noprefix=true range-diff HEAD^... +' + test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 29a35840ed..d2dfbe46b9 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -1014,9 +1014,9 @@ test_expect_success 'rebase -i --root fixup root commit' ' test 0 = $(git cat-file commit HEAD | grep -c ^parent\ ) ' -test_expect_success 'rebase -i --root reword root commit' ' +test_expect_success 'rebase -i --root reword original root commit' ' test_when_finished "test_might_fail git rebase --abort" && - git checkout -b reword-root-branch master && + git checkout -b reword-original-root-branch master && set_fake_editor && FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \ git rebase -i --root && @@ -1024,6 +1024,16 @@ test_expect_success 'rebase -i --root reword root commit' ' test -z "$(git show -s --format=%p HEAD^)" ' +test_expect_success 'rebase -i --root reword new root commit' ' + test_when_finished "test_might_fail git rebase --abort" && + git checkout -b reword-now-root-branch master && + set_fake_editor && + FAKE_LINES="reword 3 1" FAKE_COMMIT_MESSAGE="C changed" \ + git rebase -i --root && + git show HEAD^ | grep "C changed" && + test -z "$(git show -s --format=%p HEAD^)" +' + test_expect_success 'rebase -i --root when root has untracked file conflict' ' test_when_finished "reset_rebase" && git checkout -b failing-root-pick A && @@ -1052,7 +1062,7 @@ test_expect_success 'rebase -i --root reword root when root has untracked file c ' test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' ' - git checkout reword-root-branch && + git checkout reword-original-root-branch && git reset --hard && git checkout conflict-branch && set_fake_editor && diff --git a/t/t3429-rebase-edit-todo.sh b/t/t3429-rebase-edit-todo.sh index 76f6d306ea..8739cb60a7 100755 --- a/t/t3429-rebase-edit-todo.sh +++ b/t/t3429-rebase-edit-todo.sh @@ -3,9 +3,15 @@ test_description='rebase should reread the todo file if an exec modifies it' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + +test_expect_success 'setup' ' + test_commit first file && + test_commit second file && + test_commit third file +' test_expect_success 'rebase exec modifies rebase-todo' ' - test_commit initial && todo=.git/rebase-merge/git-rebase-todo && git rebase HEAD -x "echo exec touch F >>$todo" && test -e F @@ -33,4 +39,17 @@ test_expect_success SHA1 'loose object cache vs re-reading todo list' ' git rebase HEAD -x "./append-todo.sh 5 6" ' +test_expect_success 'todo is re-read after reword and squash' ' + write_script reword-editor.sh <<-\EOS && + GIT_SEQUENCE_EDITOR="echo \"exec echo $(cat file) >>actual\" >>" \ + git rebase --edit-todo + EOS + + test_write_lines first third >expected && + set_fake_editor && + GIT_SEQUENCE_EDITOR="$EDITOR" FAKE_LINES="reword 1 squash 2 fixup 3" \ + GIT_EDITOR=./reword-editor.sh git rebase -i --root third && + test_cmp expected actual +' + test_done diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 820b350aeb..580bfbdc23 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -1253,4 +1253,20 @@ test_expect_success 'stash --keep-index with file deleted in index does not resu test_path_is_missing to-remove ' +test_expect_success 'stash apply should succeed with unmodified file' ' + echo base >file && + git add file && + git commit -m base && + + # now stash a modification + echo modified >file && + git stash && + + # make the file stat dirty + cp file other && + mv other file && + + git stash apply +' + test_done diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh index d4afe12554..b9d876efa2 100755 --- a/t/t4038-diff-combined.sh +++ b/t/t4038-diff-combined.sh @@ -509,7 +509,7 @@ test_expect_success FUNNYNAMES '--combined-all-paths and --raw and funny names' test_expect_success FUNNYNAMES '--combined-all-paths and --raw -and -z and funny names' ' printf "aaf8087c3cbd4db8e185a2d074cf27c53cfb75d7\0::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR\0file\twith\ttabs\0i\tam\ttabbed\0fickle\tnaming\0" >expect && git diff-tree -c -M --raw --combined-all-paths -z HEAD >actual && - test_cmp -a expect actual + test_cmp expect actual ' test_expect_success FUNNYNAMES '--combined-all-paths and --cc and funny names' ' diff --git a/t/t4202-log.sh b/t/t4202-log.sh index e88ccb04a9..e803ba402e 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -837,6 +837,21 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' ' test_cmp expect.decorate actual ' +test_expect_success 'decorate-refs-exclude and simplify-by-decoration' ' + cat >expect.decorate <<-\EOF && + Merge-tag-reach (HEAD -> master) + reach (tag: reach, reach) + seventh (tag: seventh) + Merge-branch-tangle + Merge-branch-side-early-part-into-tangle (tangle) + tangle-a (tag: tangle-a) + EOF + git log -n6 --decorate=short --pretty="tformat:%f%d" \ + --decorate-refs-exclude="*octopus*" \ + --simplify-by-decoration >actual && + test_cmp expect.decorate actual +' + test_expect_success 'log.decorate config parsing' ' git log --oneline --decorate=full >expect.full && git log --oneline --decorate=short >expect.short && diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index 7c519436ef..6e61f57f09 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -1,12 +1,15 @@ #!/bin/sh test_description='test log with i18n features' -. ./test-lib.sh +. ./lib-gettext.sh # two forms of é utf8_e=$(printf '\303\251') latin1_e=$(printf '\351') +# invalid UTF-8 +invalid_e=$(printf '\303\50)') # ")" at end to close opening "(" + test_expect_success 'create commits in different encodings' ' test_tick && cat >msg <<-EOF && @@ -48,9 +51,43 @@ test_expect_success !MINGW 'log --grep does not find non-reencoded values (utf8) test_must_be_empty actual ' -test_expect_success 'log --grep does not find non-reencoded values (latin1)' ' +test_expect_success !MINGW 'log --grep does not find non-reencoded values (latin1)' ' git log --encoding=ISO-8859-1 --format=%s --grep=$utf8_e >actual && test_must_be_empty actual ' +for engine in fixed basic extended perl +do + prereq= + if test $engine = "perl" + then + prereq="PCRE" + else + prereq="" + fi + force_regex= + if test $engine != "fixed" + then + force_regex=.* + fi + test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" " + cat >expect <<-\EOF && + latin1 + utf8 + EOF + LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$latin1_e\" >actual && + test_cmp expect actual + " + + test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" " + LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$utf8_e\" >actual && + test_must_be_empty actual + " + + test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" " + LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$invalid_e\" >actual && + test_must_be_empty actual + " +done + test_done diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index ab3eccf0fa..d42b3efe39 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -124,6 +124,42 @@ test_expect_success 'Add more commits' ' git repack ' +test_expect_success 'commit-graph write progress off for redirected stderr' ' + cd "$TRASH_DIRECTORY/full" && + git commit-graph write 2>err && + test_line_count = 0 err +' + +test_expect_success 'commit-graph write force progress on for stderr' ' + cd "$TRASH_DIRECTORY/full" && + git commit-graph write --progress 2>err && + test_file_not_empty err +' + +test_expect_success 'commit-graph write with the --no-progress option' ' + cd "$TRASH_DIRECTORY/full" && + git commit-graph write --no-progress 2>err && + test_line_count = 0 err +' + +test_expect_success 'commit-graph verify progress off for redirected stderr' ' + cd "$TRASH_DIRECTORY/full" && + git commit-graph verify 2>err && + test_line_count = 0 err +' + +test_expect_success 'commit-graph verify force progress on for stderr' ' + cd "$TRASH_DIRECTORY/full" && + git commit-graph verify --progress 2>err && + test_file_not_empty err +' + +test_expect_success 'commit-graph verify with the --no-progress option' ' + cd "$TRASH_DIRECTORY/full" && + git commit-graph verify --no-progress 2>err && + test_line_count = 0 err +' + # Current graph structure: # # __M3___ @@ -585,4 +621,47 @@ test_expect_success 'get_commit_tree_in_graph works for non-the_repository' ' test_cmp expect actual ' +test_expect_success 'corrupt commit-graph write (broken parent)' ' + rm -rf repo && + git init repo && + ( + cd repo && + empty="$(git mktree </dev/null)" && + cat >broken <<-EOF && + tree $empty + parent 0000000000000000000000000000000000000000 + author whatever <whatever@example.com> 1234 -0000 + committer whatever <whatever@example.com> 1234 -0000 + + broken commit + EOF + broken="$(git hash-object -w -t commit --literally broken)" && + git commit-tree -p "$broken" -m "good commit" "$empty" >good && + test_must_fail git commit-graph write --stdin-commits \ + <good 2>test_err && + test_i18ngrep "unable to parse commit" test_err + ) +' + +test_expect_success 'corrupt commit-graph write (missing tree)' ' + rm -rf repo && + git init repo && + ( + cd repo && + tree="$(git mktree </dev/null)" && + cat >broken <<-EOF && + parent 0000000000000000000000000000000000000000 + author whatever <whatever@example.com> 1234 -0000 + committer whatever <whatever@example.com> 1234 -0000 + + broken commit + EOF + broken="$(git hash-object -w -t commit --literally broken)" && + git commit-tree -p "$broken" -m "good" "$tree" >good && + test_must_fail git commit-graph write --stdin-commits \ + <good 2>test_err && + test_i18ngrep "unable to get tree for" test_err + ) +' + test_done diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index e2c39533d3..115aabd141 100755 --- a/t/t5324-split-commit-graph.sh +++ b/t/t5324-split-commit-graph.sh @@ -320,7 +320,7 @@ test_expect_success 'add octopus merge' ' git merge commits/3 commits/4 && git branch merge/octopus && git commit-graph write --reachable --split && - git commit-graph verify 2>err && + git commit-graph verify --progress 2>err && test_line_count = 3 err && test_i18ngrep ! warning err && test_line_count = 3 $graphdir/commit-graph-chain diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 5115711562..6b97923964 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -792,6 +792,44 @@ test_expect_success 'clone shallow since selects no commits' ' ) ' +# A few subtle things about the request in this test: +# +# - the server must have commit-graphs present and enabled +# +# - the history is such that our want/have share a common ancestor ("base" +# here) +# +# - we send only a single have, which is fewer than a normal client would +# send. This ensures that we don't parse "base" up front with +# parse_object(), but rather traverse to it as a parent while deciding if we +# can stop the "have" negotiation, and call parse_commit(). The former +# sees the actual object data and so always loads the three oid, whereas the +# latter will try to load it lazily. +# +# - we must use protocol v2, because it handles the "have" negotiation before +# processing the shallow directives +# +test_expect_success 'shallow since with commit graph and already-seen commit' ' + test_create_repo shallow-since-graph && + ( + cd shallow-since-graph && + test_commit base && + test_commit master && + git checkout -b other HEAD^ && + test_commit other && + git commit-graph write --reachable && + git config core.commitGraph true && + + GIT_PROTOCOL=version=2 git upload-pack . <<-EOF >/dev/null + 0012command=fetch + 00010013deepen-since 1 + 0032want $(git rev-parse other) + 0032have $(git rev-parse master) + 0000 + EOF + ) +' + test_expect_success 'shallow clone exclude tag two' ' test_create_repo shallow-exclude && ( diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index b86ddb60f2..92bac43257 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -262,7 +262,7 @@ test_expect_success TTY 'push shows progress when stderr is a tty' ' cd "$ROOT_PATH"/test_repo_clone && test_commit noisy && test_terminal git push >output 2>&1 && - test_i18ngrep "Writing objects" output + test_i18ngrep "^Writing objects" output ' test_expect_success TTY 'push --quiet silences status and progress' ' @@ -277,7 +277,7 @@ test_expect_success TTY 'push --no-progress silences progress but not status' ' test_commit no-progress && test_terminal git push --no-progress >output 2>&1 && test_i18ngrep "^To http" output && - test_i18ngrep ! "Writing objects" output + test_i18ngrep ! "^Writing objects" output ' test_expect_success 'push --progress shows progress to non-tty' ' @@ -285,7 +285,7 @@ test_expect_success 'push --progress shows progress to non-tty' ' test_commit progress && git push --progress >output 2>&1 && test_i18ngrep "^To http" output && - test_i18ngrep "Writing objects" output + test_i18ngrep "^Writing objects" output ' test_expect_success 'http push gives sane defaults to reflog' ' diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index fc634a56b2..79f7b65f8c 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -260,6 +260,42 @@ test_expect_success 'fetch what is specified on CLI even if already promised' ' ! grep "?$(cat blob)" missing_after ' +test_expect_success 'setup src repo for sparse filter' ' + git init sparse-src && + git -C sparse-src config --local uploadpack.allowfilter 1 && + git -C sparse-src config --local uploadpack.allowanysha1inwant 1 && + test_commit -C sparse-src one && + test_commit -C sparse-src two && + echo /one.t >sparse-src/only-one && + git -C sparse-src add . && + git -C sparse-src commit -m "add sparse checkout files" +' + +test_expect_success 'partial clone with sparse filter succeeds' ' + rm -rf dst.git && + git clone --no-local --bare \ + --filter=sparse:oid=master:only-one \ + sparse-src dst.git && + ( + cd dst.git && + git rev-list --objects --missing=print HEAD >out && + grep "^$(git rev-parse HEAD:one.t)" out && + grep "^?$(git rev-parse HEAD:two.t)" out + ) +' + +test_expect_success 'partial clone with unresolvable sparse filter fails cleanly' ' + rm -rf dst.git && + test_must_fail git clone --no-local --bare \ + --filter=sparse:oid=master:no-such-name \ + sparse-src dst.git 2>err && + test_i18ngrep "unable to access sparse blob in .master:no-such-name" err && + test_must_fail git clone --no-local --bare \ + --filter=sparse:oid=master \ + sparse-src dst.git 2>err && + test_i18ngrep "unable to parse sparse filter data in" err +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index 2d6c4a281e..121e5c6edb 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -247,7 +247,6 @@ clean_mark () { test_expect_success 'proper failure checks for fetching' ' (cd local && test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git fetch 2>error && - cat error && test_i18ngrep -q "error while running fast-import" error ) ' diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 2b883d8174..45047d0a72 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -424,4 +424,19 @@ test_expect_success 'describe complains about missing object' ' test_must_fail git describe $ZERO_OID ' +test_expect_success 'name-rev a rev shortly after epoch' ' + test_when_finished "git checkout master" && + + git checkout --orphan no-timestamp-underflow && + # Any date closer to epoch than the CUTOFF_DATE_SLOP constant + # in builtin/name-rev.c. + GIT_COMMITTER_DATE="@1234 +0000" \ + git commit -m "committer date shortly after epoch" && + old_commit_oid=$(git rev-parse HEAD) && + + echo "$old_commit_oid no-timestamp-underflow" >expect && + git name-rev $old_commit_oid >actual && + test_cmp expect actual +' + test_done diff --git a/t/t7009-filter-branch-null-sha1.sh b/t/t7008-filter-branch-null-sha1.sh index 9ba9f24ad2..9ba9f24ad2 100755 --- a/t/t7009-filter-branch-null-sha1.sh +++ b/t/t7008-filter-branch-null-sha1.sh diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index d01fd120ab..6e6d24c1c3 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -117,6 +117,7 @@ test_expect_success C_LOCALE_OUTPUT 'git clean with relative prefix' ' would_clean=$( cd docs && git clean -n ../src | + grep part3 | sed -n -e "s|^Would remove ||p" ) && verbose test "$would_clean" = ../src/part3.c @@ -129,6 +130,7 @@ test_expect_success C_LOCALE_OUTPUT 'git clean with absolute path' ' would_clean=$( cd docs && git clean -n "$(pwd)/../src" | + grep part3 | sed -n -e "s|^Would remove ||p" ) && verbose test "$would_clean" = ../src/part3.c @@ -547,7 +549,7 @@ test_expect_failure 'nested (non-empty) bare repositories should be cleaned even test_path_is_missing strange_bare ' -test_expect_success 'giving path in nested git work tree will remove it' ' +test_expect_success 'giving path in nested git work tree will NOT remove it' ' rm -fr repo && mkdir repo && ( @@ -559,7 +561,7 @@ test_expect_success 'giving path in nested git work tree will remove it' ' 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_path_is_file repo/bar/baz/hello.world ' test_expect_success 'giving path to nested .git will not remove it' ' @@ -577,7 +579,7 @@ test_expect_success 'giving path to nested .git will not remove it' ' test_path_is_dir untracked/ ' -test_expect_success 'giving path to nested .git/ will remove contents' ' +test_expect_success 'giving path to nested .git/ will NOT remove contents' ' rm -fr repo untracked && mkdir repo untracked && ( @@ -587,7 +589,7 @@ test_expect_success 'giving path to nested .git/ will remove contents' ' ) && git clean -f -d repo/.git/ && test_path_is_dir repo/.git && - test_dir_is_empty repo/.git && + test_path_is_file repo/.git/HEAD && test_path_is_dir untracked/ ' @@ -669,7 +671,7 @@ test_expect_success 'git clean -d skips untracked dirs containing ignored files' test_path_is_missing foo/b/bb ' -test_expect_failure 'git clean -d skips nested repo containing ignored files' ' +test_expect_success 'git clean -d skips nested repo containing ignored files' ' test_when_finished "rm -rf nested-repo-with-ignored-file" && git init nested-repo-with-ignored-file && @@ -691,6 +693,38 @@ test_expect_failure 'git clean -d skips nested repo containing ignored files' ' test_path_is_file nested-repo-with-ignored-file/file ' +test_expect_success 'git clean handles being told what to clean' ' + mkdir -p d1 d2 && + touch d1/ut d2/ut && + git clean -f */ut && + test_path_is_missing d1/ut && + test_path_is_missing d2/ut +' + +test_expect_success 'git clean handles being told what to clean, with -d' ' + mkdir -p d1 d2 && + touch d1/ut d2/ut && + git clean -ffd */ut && + test_path_is_missing d1/ut && + test_path_is_missing d2/ut +' + +test_expect_success 'git clean works if a glob is passed without -d' ' + mkdir -p d1 d2 && + touch d1/ut d2/ut && + git clean -f "*ut" && + test_path_is_missing d1/ut && + test_path_is_missing d2/ut +' + +test_expect_success 'git clean works if a glob is passed with -d' ' + mkdir -p d1 d2 && + touch d1/ut d2/ut && + git clean -ffd "*ut" && + test_path_is_missing d1/ut && + test_path_is_missing d2/ut +' + test_expect_success MINGW 'handle clean & core.longpaths = false nicely' ' test_config core.longpaths false && a50=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index a208cb26e1..691b5fc3bf 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -527,7 +527,6 @@ test_expect_success 'update --init' ' test_must_fail git config submodule.example.url && git submodule update init 2> update.out && - cat update.out && test_i18ngrep "not initialized" update.out && test_must_fail git rev-parse --resolve-git-dir init/.git && @@ -545,7 +544,6 @@ test_expect_success 'update --init from subdirectory' ' ( cd sub && git submodule update ../init 2>update.out && - cat update.out && test_i18ngrep "not initialized" update.out && test_must_fail git rev-parse --resolve-git-dir ../init/.git && diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh index ba8bd1b514..94f85cdf83 100755 --- a/t/t7505-prepare-commit-msg-hook.sh +++ b/t/t7505-prepare-commit-msg-hook.sh @@ -241,13 +241,7 @@ test_rebase () { git add b && git rebase --continue ) && - if test "$mode" = -p # reword amended after pick - then - n=18 - else - n=17 - fi && - git log --pretty=%s -g -n$n HEAD@{1} >actual && + git log --pretty=%s -g -n18 HEAD@{1} >actual && test_cmp "$TEST_DIRECTORY/t7505/expected-rebase${mode:--i}" actual ' } diff --git a/t/t7505/expected-rebase-i b/t/t7505/expected-rebase-i index c514bdbb94..93bada596e 100644 --- a/t/t7505/expected-rebase-i +++ b/t/t7505/expected-rebase-i @@ -7,7 +7,8 @@ message (no editor) [edit rebase-10] message [fixup rebase-9] message (no editor) [fixup rebase-8] message (no editor) [squash rebase-7] -message [reword rebase-6] +HEAD [reword rebase-6] +message (no editor) [reword rebase-6] message [squash rebase-5] message (no editor) [fixup rebase-4] message (no editor) [pick rebase-3] diff --git a/t/t7812-grep-icase-non-ascii.sh b/t/t7812-grep-icase-non-ascii.sh index 0c685d3598..531eb59d57 100755 --- a/t/t7812-grep-icase-non-ascii.sh +++ b/t/t7812-grep-icase-non-ascii.sh @@ -53,4 +53,32 @@ test_expect_success REGEX_LOCALE 'pickaxe -i on non-ascii' ' test_cmp expected actual ' +test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: setup invalid UTF-8 data' ' + printf "\\200\\n" >invalid-0x80 && + echo "ævar" >expected && + cat expected >>invalid-0x80 && + git add invalid-0x80 +' + +test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep ASCII from invalid UTF-8 data' ' + git grep -h "var" invalid-0x80 >actual && + test_cmp expected actual && + git grep -h "(*NO_JIT)var" invalid-0x80 >actual && + test_cmp expected actual +' + +test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-ASCII from invalid UTF-8 data' ' + git grep -h "æ" invalid-0x80 >actual && + test_cmp expected actual && + git grep -h "(*NO_JIT)æ" invalid-0x80 && + test_cmp expected actual +' + +test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-ASCII from invalid UTF-8 data with -i' ' + test_might_fail git grep -hi "Æ" invalid-0x80 >actual && + test_cmp expected actual && + test_must_fail git grep -hi "(*NO_JIT)Æ" invalid-0x80 && + test_cmp expected actual +' + test_done diff --git a/t/t7008-grep-binary.sh b/t/t7815-grep-binary.sh index 2d87c49b75..90ebb64f46 100755 --- a/t/t7008-grep-binary.sh +++ b/t/t7815-grep-binary.sh @@ -4,41 +4,6 @@ test_description='git grep in binary files' . ./test-lib.sh -nul_match () { - matches=$1 - flags=$2 - pattern=$3 - pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g') - - if test "$matches" = 1 - then - test_expect_success "git grep -f f $flags '$pattern_human' a" " - printf '$pattern' | q_to_nul >f && - git grep -f f $flags a - " - elif test "$matches" = 0 - then - test_expect_success "git grep -f f $flags '$pattern_human' a" " - printf '$pattern' | q_to_nul >f && - test_must_fail git grep -f f $flags a - " - elif test "$matches" = T1 - then - test_expect_failure "git grep -f f $flags '$pattern_human' a" " - printf '$pattern' | q_to_nul >f && - git grep -f f $flags a - " - elif test "$matches" = T0 - then - test_expect_failure "git grep -f f $flags '$pattern_human' a" " - printf '$pattern' | q_to_nul >f && - test_must_fail git grep -f f $flags a - " - else - test_expect_success "PANIC: Test framework error. Unknown matches value $matches" 'false' - fi -} - test_expect_success 'setup' " echo 'binaryQfileQm[*]cQ*æQð' | q_to_nul >a && git add a && @@ -102,72 +67,6 @@ test_expect_failure 'git grep .fi a' ' git grep .fi a ' -nul_match 1 '-F' 'yQf' -nul_match 0 '-F' 'yQx' -nul_match 1 '-Fi' 'YQf' -nul_match 0 '-Fi' 'YQx' -nul_match 1 '' 'yQf' -nul_match 0 '' 'yQx' -nul_match 1 '' 'æQð' -nul_match 1 '-F' 'eQm[*]c' -nul_match 1 '-Fi' 'EQM[*]C' - -# Regex patterns that would match but shouldn't with -F -nul_match 0 '-F' 'yQ[f]' -nul_match 0 '-F' '[y]Qf' -nul_match 0 '-Fi' 'YQ[F]' -nul_match 0 '-Fi' '[Y]QF' -nul_match 0 '-F' 'æQ[ð]' -nul_match 0 '-F' '[æ]Qð' -nul_match 0 '-Fi' 'ÆQ[Ð]' -nul_match 0 '-Fi' '[Æ]QÐ' - -# kwset is disabled on -i & non-ASCII. No way to match non-ASCII \0 -# patterns case-insensitively. -nul_match T1 '-i' 'ÆQÐ' - -# \0 implicitly disables regexes. This is an undocumented internal -# limitation. -nul_match T1 '' 'yQ[f]' -nul_match T1 '' '[y]Qf' -nul_match T1 '-i' 'YQ[F]' -nul_match T1 '-i' '[Y]Qf' -nul_match T1 '' 'æQ[ð]' -nul_match T1 '' '[æ]Qð' -nul_match T1 '-i' 'ÆQ[Ð]' - -# ... because of \0 implicitly disabling regexes regexes that -# should/shouldn't match don't do the right thing. -nul_match T1 '' 'eQm.*cQ' -nul_match T1 '-i' 'EQM.*cQ' -nul_match T0 '' 'eQm[*]c' -nul_match T0 '-i' 'EQM[*]C' - -# Due to the REG_STARTEND extension when kwset() is disabled on -i & -# non-ASCII the string will be matched in its entirety, but the -# pattern will be cut off at the first \0. -nul_match 0 '-i' 'NOMATCHQð' -nul_match T0 '-i' '[Æ]QNOMATCH' -nul_match T0 '-i' '[æ]QNOMATCH' -# Matches, but for the wrong reasons, just stops at [æ] -nul_match 1 '-i' '[Æ]Qð' -nul_match 1 '-i' '[æ]Qð' - -# Ensure that the matcher doesn't regress to something that stops at -# \0 -nul_match 0 '-F' 'yQ[f]' -nul_match 0 '-Fi' 'YQ[F]' -nul_match 0 '' 'yQNOMATCH' -nul_match 0 '' 'QNOMATCH' -nul_match 0 '-i' 'YQNOMATCH' -nul_match 0 '-i' 'QNOMATCH' -nul_match 0 '-F' 'æQ[ð]' -nul_match 0 '-Fi' 'ÆQ[Ð]' -nul_match 0 '' 'yQNÓMATCH' -nul_match 0 '' 'QNÓMATCH' -nul_match 0 '-i' 'YQNÓMATCH' -nul_match 0 '-i' 'QNÓMATCH' - test_expect_success 'grep respects binary diff attribute' ' echo text >t && git add t && diff --git a/t/t7816-grep-binary-pattern.sh b/t/t7816-grep-binary-pattern.sh new file mode 100755 index 0000000000..60bab291e4 --- /dev/null +++ b/t/t7816-grep-binary-pattern.sh @@ -0,0 +1,127 @@ +#!/bin/sh + +test_description='git grep with a binary pattern files' + +. ./lib-gettext.sh + +nul_match_internal () { + matches=$1 + prereqs=$2 + lc_all=$3 + extra_flags=$4 + flags=$5 + pattern=$6 + pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g') + + if test "$matches" = 1 + then + test_expect_success $prereqs "LC_ALL='$lc_all' git grep $extra_flags -f f $flags '$pattern_human' a" " + printf '$pattern' | q_to_nul >f && + LC_ALL='$lc_all' git grep $extra_flags -f f $flags a + " + elif test "$matches" = 0 + then + test_expect_success $prereqs "LC_ALL='$lc_all' git grep $extra_flags -f f $flags '$pattern_human' a" " + >stderr && + printf '$pattern' | q_to_nul >f && + test_must_fail env LC_ALL=\"$lc_all\" git grep $extra_flags -f f $flags a 2>stderr && + test_i18ngrep ! 'This is only supported with -P under PCRE v2' stderr + " + elif test "$matches" = P + then + test_expect_success $prereqs "error, PCRE v2 only: LC_ALL='$lc_all' git grep -f f $flags '$pattern_human' a" " + >stderr && + printf '$pattern' | q_to_nul >f && + test_must_fail env LC_ALL=\"$lc_all\" git grep -f f $flags a 2>stderr && + test_i18ngrep 'This is only supported with -P under PCRE v2' stderr + " + else + test_expect_success "PANIC: Test framework error. Unknown matches value $matches" 'false' + fi +} + +nul_match () { + matches=$1 + matches_pcre2=$2 + matches_pcre2_locale=$3 + flags=$4 + pattern=$5 + pattern_human=$(echo "$pattern" | sed 's/Q/<NUL>/g') + + nul_match_internal "$matches" "" "C" "" "$flags" "$pattern" + nul_match_internal "$matches_pcre2" "LIBPCRE2" "C" "-P" "$flags" "$pattern" + nul_match_internal "$matches_pcre2_locale" "LIBPCRE2,GETTEXT_LOCALE" "$is_IS_locale" "-P" "$flags" "$pattern" +} + +test_expect_success 'setup' " + echo 'binaryQfileQm[*]cQ*æQð' | q_to_nul >a && + git add a && + git commit -m. +" + +# Simple fixed-string matching that can use kwset (no -i && non-ASCII) +nul_match P P P '-F' 'yQf' +nul_match P P P '-F' 'yQx' +nul_match P P P '-Fi' 'YQf' +nul_match P P P '-Fi' 'YQx' +nul_match P P 1 '' 'yQf' +nul_match P P 0 '' 'yQx' +nul_match P P 1 '' 'æQð' +nul_match P P P '-F' 'eQm[*]c' +nul_match P P P '-Fi' 'EQM[*]C' + +# Regex patterns that would match but shouldn't with -F +nul_match P P P '-F' 'yQ[f]' +nul_match P P P '-F' '[y]Qf' +nul_match P P P '-Fi' 'YQ[F]' +nul_match P P P '-Fi' '[Y]QF' +nul_match P P P '-F' 'æQ[ð]' +nul_match P P P '-F' '[æ]Qð' + +# The -F kwset codepath can't handle -i && non-ASCII... +nul_match P 1 1 '-i' '[æ]Qð' + +# ...PCRE v2 only matches non-ASCII with -i casefolding under UTF-8 +# semantics +nul_match P P P '-Fi' 'ÆQ[Ð]' +nul_match P 0 1 '-i' 'ÆQ[Ð]' +nul_match P 0 1 '-i' '[Æ]QÐ' +nul_match P 0 1 '-i' '[Æ]Qð' +nul_match P 0 1 '-i' 'ÆQÐ' + +# \0 in regexes can only work with -P & PCRE v2 +nul_match P P 1 '' 'yQ[f]' +nul_match P P 1 '' '[y]Qf' +nul_match P P 1 '-i' 'YQ[F]' +nul_match P P 1 '-i' '[Y]Qf' +nul_match P P 1 '' 'æQ[ð]' +nul_match P P 1 '' '[æ]Qð' +nul_match P P 1 '-i' 'ÆQ[Ð]' +nul_match P P 1 '' 'eQm.*cQ' +nul_match P P 1 '-i' 'EQM.*cQ' +nul_match P P 0 '' 'eQm[*]c' +nul_match P P 0 '-i' 'EQM[*]C' + +# Assert that we're using REG_STARTEND and the pattern doesn't match +# just because it's cut off at the first \0. +nul_match P P 0 '-i' 'NOMATCHQð' +nul_match P P 0 '-i' '[Æ]QNOMATCH' +nul_match P P 0 '-i' '[æ]QNOMATCH' + +# Ensure that the matcher doesn't regress to something that stops at +# \0 +nul_match P P P '-F' 'yQ[f]' +nul_match P P P '-Fi' 'YQ[F]' +nul_match P P 0 '' 'yQNOMATCH' +nul_match P P 0 '' 'QNOMATCH' +nul_match P P 0 '-i' 'YQNOMATCH' +nul_match P P 0 '-i' 'QNOMATCH' +nul_match P P P '-F' 'æQ[ð]' +nul_match P P P '-Fi' 'ÆQ[Ð]' +nul_match P P 1 '-i' 'ÆQ[Ð]' +nul_match P P 0 '' 'yQNÓMATCH' +nul_match P P 0 '' 'QNÓMATCH' +nul_match P P 0 '-i' 'YQNÓMATCH' +nul_match P P 0 '-i' 'QNÓMATCH' + +test_done diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 141b7fa35e..0a44a06239 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -2781,7 +2781,6 @@ test_expect_success 'S: filemodify with garbage after mark must fail' ' COMMIT M 100644 :403x hello.c EOF - cat err && test_i18ngrep "space after mark" err ' @@ -2798,7 +2797,6 @@ test_expect_success 'S: filemodify with garbage after inline must fail' ' inline BLOB EOF - cat err && test_i18ngrep "nvalid dataref" err ' @@ -2812,7 +2810,6 @@ test_expect_success 'S: filemodify with garbage after sha1 must fail' ' COMMIT M 100644 ${sha1}x hello.c EOF - cat err && test_i18ngrep "space after SHA1" err ' @@ -2828,7 +2825,6 @@ test_expect_success 'S: notemodify with garbage after mark dataref must fail' ' COMMIT N :202x :302 EOF - cat err && test_i18ngrep "space after mark" err ' @@ -2844,7 +2840,6 @@ test_expect_success 'S: notemodify with garbage after inline dataref must fail' note blob BLOB EOF - cat err && test_i18ngrep "nvalid dataref" err ' @@ -2858,7 +2853,6 @@ test_expect_success 'S: notemodify with garbage after sha1 dataref must fail' ' COMMIT N ${sha1}x :302 EOF - cat err && test_i18ngrep "space after SHA1" err ' @@ -2874,7 +2868,6 @@ test_expect_success 'S: notemodify with garbage after mark commit-ish must fail' COMMIT N :202 :302x EOF - cat err && test_i18ngrep "after mark" err ' @@ -2908,7 +2901,6 @@ test_expect_success 'S: from with garbage after mark must fail' ' EOF # now evaluate the error - cat err && test_i18ngrep "after mark" err ' @@ -2928,7 +2920,6 @@ test_expect_success 'S: merge with garbage after mark must fail' ' merge :303x M 100644 :403 hello.c EOF - cat err && test_i18ngrep "after mark" err ' @@ -2944,7 +2935,6 @@ test_expect_success 'S: tag with garbage after mark must fail' ' tag S TAG EOF - cat err && test_i18ngrep "after mark" err ' @@ -2955,7 +2945,6 @@ test_expect_success 'S: cat-blob with garbage after mark must fail' ' test_must_fail git fast-import --import-marks=marks <<-EOF 2>err && cat-blob :403x EOF - cat err && test_i18ngrep "after mark" err ' @@ -2966,7 +2955,6 @@ test_expect_success 'S: ls with garbage after mark must fail' ' test_must_fail git fast-import --import-marks=marks <<-EOF 2>err && ls :302x hello.c EOF - cat err && test_i18ngrep "space after mark" err ' @@ -2975,7 +2963,6 @@ test_expect_success 'S: ls with garbage after sha1 must fail' ' test_must_fail git fast-import --import-marks=marks <<-EOF 2>err && ls ${sha1}x hello.c EOF - cat err && test_i18ngrep "space after tree-ish" err ' |