diff options
Diffstat (limited to 't')
167 files changed, 5007 insertions, 1743 deletions
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index 093832fef1..6da48a2e0a 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -320,11 +320,11 @@ test_expect_success 'blame -L ,Y (Y == nlines)' ' test_expect_success 'blame -L ,Y (Y == nlines + 1)' ' n=$(expr $(wc -l <file) + 2) && - test_must_fail $PROG -L,$n file + check_count -L,$n A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1 ' test_expect_success 'blame -L ,Y (Y > nlines)' ' - test_must_fail $PROG -L,12345 file + check_count -L,12345 A 1 B 1 B1 1 B2 1 "A U Thor" 1 C 1 D 1 E 1 ' test_expect_success 'blame -L multiple (disjoint)' ' diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl index e07f028437..d5823f71d8 100755 --- a/t/check-non-portable-shell.pl +++ b/t/check-non-portable-shell.pl @@ -7,22 +7,43 @@ use strict; use warnings; my $exit_code=0; +my %func; sub err { my $msg = shift; + s/^\s+//; + s/\s+$//; + s/\s+/ /g; print "$ARGV:$.: error: $msg: $_\n"; $exit_code = 1; } +# glean names of shell functions +for my $i (@ARGV) { + open(my $f, '<', $i) or die "$0: $i: $!\n"; + while (<$f>) { + $func{$1} = 1 if /^\s*(\w+)\s*\(\)\s*{\s*$/; + } + close $f; +} + while (<>) { chomp; + # stitch together incomplete lines (those ending with "\") + while (s/\\$//) { + $_ .= readline; + chomp; + } + /\bsed\s+-i/ and err 'sed -i is not portable'; - /\becho\s+-[neE]/ and err 'echo with option is not portable (please use printf)'; + /\becho\s+-[neE]/ and err 'echo with option is not portable (use printf)'; /^\s*declare\s+/ and err 'arrays/declare not portable'; - /^\s*[^#]\s*which\s/ and err 'which is not portable (please use type)'; - /\btest\s+[^=]*==/ and err '"test a == b" is not portable (please use =)'; - /\bwc -l.*"\s*=/ and err '`"$(wc -l)"` is not portable (please use test_line_count)'; - /\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (please use FOO=bar && export FOO)'; + /^\s*[^#]\s*which\s/ and err 'which is not portable (use type)'; + /\btest\s+[^=]*==/ and err '"test a == b" is not portable (use =)'; + /\bwc -l.*"\s*=/ and err '`"$(wc -l)"` is not portable (use test_line_count)'; + /\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)'; + /^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and + err '"FOO=bar shell_func" assignment extends beyond "shell_func"'; # this resets our $. for each file close ARGV if eof; } diff --git a/t/helper/test-drop-caches.c b/t/helper/test-drop-caches.c index d6bcfddf13..f65e301f9d 100644 --- a/t/helper/test-drop-caches.c +++ b/t/helper/test-drop-caches.c @@ -16,8 +16,8 @@ static int cmd_sync(void) if ((0 == dwRet) || (dwRet > MAX_PATH)) return error("Error getting current directory"); - if ((Buffer[0] < 'A') || (Buffer[0] > 'Z')) - return error("Invalid drive letter '%c'", Buffer[0]); + if (!has_dos_drive_prefix(Buffer)) + return error("'%s': invalid drive letter", Buffer); szVolumeAccessPath[4] = Buffer[0]; hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE, diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c index 0f19e53c75..30775f986f 100644 --- a/t/helper/test-pkt-line.c +++ b/t/helper/test-pkt-line.c @@ -1,3 +1,4 @@ +#include "cache.h" #include "pkt-line.h" static void pack_line(const char *line) @@ -48,6 +49,36 @@ static void unpack(void) } } +static void unpack_sideband(void) +{ + struct packet_reader reader; + packet_reader_init(&reader, 0, NULL, 0, + PACKET_READ_GENTLE_ON_EOF | + PACKET_READ_CHOMP_NEWLINE); + + while (packet_reader_read(&reader) != PACKET_READ_EOF) { + int band; + int fd; + + switch (reader.status) { + case PACKET_READ_EOF: + break; + case PACKET_READ_NORMAL: + band = reader.line[0] & 0xff; + if (band < 1 || band > 2) + die("unexpected side band %d", band); + fd = band; + + write_or_die(fd, reader.line + 1, reader.pktlen - 1); + break; + case PACKET_READ_FLUSH: + return; + case PACKET_READ_DELIM: + break; + } + } +} + int cmd_main(int argc, const char **argv) { if (argc < 2) @@ -57,6 +88,8 @@ int cmd_main(int argc, const char **argv) pack(argc - 2, argv + 2); else if (!strcmp(argv[1], "unpack")) unpack(); + else if (!strcmp(argv[1], "unpack-sideband")) + unpack_sideband(); else die("invalid argument '%s'", argv[1]); diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 435a37465a..a8729f8232 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -132,6 +132,7 @@ prepare_httpd() { cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH" install_script broken-smart-http.sh install_script error.sh + install_script apply-one-time-sed.sh ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules" @@ -287,3 +288,24 @@ expect_askpass() { test_cmp "$TRASH_DIRECTORY/askpass-expect" \ "$TRASH_DIRECTORY/askpass-query" } + +strip_access_log() { + sed -e " + s/^.* \"// + s/\"// + s/ [1-9][0-9]*\$// + s/^GET /GET / + " "$HTTPD_ROOT_PATH"/access.log +} + +# Requires one argument: the name of a file containing the expected stripped +# access log entries. +check_access_log() { + sort "$1" >"$1".sorted && + strip_access_log >access.log.stripped && + sort access.log.stripped >access.log.sorted && + if ! test_cmp "$1".sorted access.log.sorted + then + test_cmp "$1" access.log.stripped + fi +} diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 724d9ae462..581c010d8f 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -111,9 +111,14 @@ Alias /auth/dumb/ www/auth/dumb/ SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} SetEnv GIT_HTTP_EXPORT_ALL </LocationMatch> +<LocationMatch /one_time_sed/> + SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} + SetEnv GIT_HTTP_EXPORT_ALL +</LocationMatch> ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1 ScriptAlias /broken_smart/ broken-smart-http.sh/ ScriptAlias /error/ error.sh/ +ScriptAliasMatch /one_time_sed/(.*) apply-one-time-sed.sh/$1 <Directory ${GIT_EXEC_PATH}> Options FollowSymlinks </Directory> @@ -123,6 +128,9 @@ ScriptAlias /error/ error.sh/ <Files error.sh> Options ExecCGI </Files> +<Files apply-one-time-sed.sh> + Options ExecCGI +</Files> <Files ${GIT_EXEC_PATH}/git-http-backend> Options ExecCGI </Files> diff --git a/t/lib-httpd/apply-one-time-sed.sh b/t/lib-httpd/apply-one-time-sed.sh new file mode 100644 index 0000000000..fcef728925 --- /dev/null +++ b/t/lib-httpd/apply-one-time-sed.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +# If "one-time-sed" exists in $HTTPD_ROOT_PATH, run sed on the HTTP response, +# using the contents of "one-time-sed" as the sed command to be run. If the +# response was modified as a result, delete "one-time-sed" so that subsequent +# HTTP responses are no longer modified. +# +# This can be used to simulate the effects of the repository changing in +# between HTTP request-response pairs. +if [ -e one-time-sed ]; then + "$GIT_EXEC_PATH/git-http-backend" >out + sed "$(cat one-time-sed)" <out >out_modified + + if diff out out_modified >/dev/null; then + cat out + else + cat out_modified + rm one-time-sed + fi +else + "$GIT_EXEC_PATH/git-http-backend" +fi diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh index 1f38a85371..5b56b23166 100755 --- a/t/lib-submodule-update.sh +++ b/t/lib-submodule-update.sh @@ -235,7 +235,7 @@ reset_work_tree_to_interested () { then mkdir -p submodule_update/.git/modules/sub1/modules && cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2 - GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree + # core.worktree is unset for sub2 as it is not checked out fi && # indicate we are interested in the submodule: git -C submodule_update config submodule.sub1.url "bogus" && @@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() { git branch -t remove_sub1 origin/remove_sub1 && $command remove_sub1 && test_superproject_content origin/remove_sub1 && - ! test -e sub1 + ! test -e sub1 && + test_must_fail git config -f .git/modules/sub1/config core.worktree ) ' # ... absorbing a .git directory along the way. @@ -755,7 +756,7 @@ test_submodule_recursing_with_args_common() { : >sub1/untrackedfile && test_must_fail $command replace_sub1_with_file && test_superproject_content origin/add_sub1 && - test_submodule_content sub1 origin/add_sub1 + test_submodule_content sub1 origin/add_sub1 && test -f sub1/untracked_file ) ' @@ -781,7 +782,8 @@ test_submodule_recursing_with_args_common() { ( cd submodule_update && git branch -t invalid_sub1 origin/invalid_sub1 && - test_must_fail $command invalid_sub1 && + test_must_fail $command invalid_sub1 2>err && + test_i18ngrep sub1 err && test_superproject_content origin/add_sub1 && test_submodule_content sub1 origin/add_sub1 ) @@ -842,7 +844,7 @@ test_submodule_switch_recursing_with_args () { cd submodule_update && git branch -t add_sub1 origin/add_sub1 && : >sub1 && - echo sub1 >.git/info/exclude + echo sub1 >.git/info/exclude && $command add_sub1 && test_superproject_content origin/add_sub1 && test_submodule_content sub1 origin/add_sub1 @@ -969,7 +971,6 @@ test_submodule_forced_switch_recursing_with_args () { rm -rf .git/modules/sub1 && $command replace_sub1_with_directory && test_superproject_content origin/replace_sub1_with_directory && - test_submodule_content sub1 origin/modify_sub1 test_git_directory_exists sub1 ) ' diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index af61d083b4..34859fe4a5 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -1081,7 +1081,7 @@ test_expect_success 'very long name in the index handled sanely' ' ( git ls-files -s path4 | sed -e "s/ .*/ /" | - tr -d "\012" + tr -d "\012" && echo "$a" ) | git update-index --index-info && len=$(git ls-files "a*" | wc -c) && diff --git a/t/t0001-init.sh b/t/t0001-init.sh index c413bff9cf..ca85aae51e 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -287,6 +287,7 @@ test_expect_success 'init notices EEXIST (2)' ' ' test_expect_success POSIXPERM,SANITY 'init notices EPERM' ' + test_when_finished "chmod +w newdir" && rm -fr newdir && mkdir newdir && chmod -w newdir && @@ -407,7 +408,7 @@ is_hidden () { test_expect_success MINGW '.git hidden' ' rm -rf newdir && ( - unset GIT_DIR GIT_WORK_TREE + sane_unset GIT_DIR GIT_WORK_TREE && mkdir newdir && cd newdir && git init && @@ -419,7 +420,7 @@ test_expect_success MINGW '.git hidden' ' test_expect_success MINGW 'bare git dir not hidden' ' rm -rf newdir && ( - unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG && mkdir newdir && cd newdir && git --bare init diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index f19ae4f8cc..5c37c2e1f8 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -34,15 +34,15 @@ test_expect_success 'open-quoted pathname' ' test_expect_success 'setup' ' mkdir -p a/b/d a/c b && ( - echo "[attr]notest !test" - echo "\" d \" test=d" - echo " e test=e" - echo " e\" test=e" - echo "f test=f" - echo "a/i test=a/i" - echo "onoff test -test" - echo "offon -test test" - echo "no notest" + echo "[attr]notest !test" && + echo "\" d \" test=d" && + echo " e test=e" && + echo " e\" test=e" && + echo "f test=f" && + echo "a/i test=a/i" && + echo "onoff test -test" && + echo "offon -test test" && + echo "no notest" && echo "A/e/F test=A/e/F" ) >.gitattributes && ( @@ -51,7 +51,7 @@ test_expect_success 'setup' ' ) >a/.gitattributes && ( echo "h test=a/b/h" && - echo "d/* test=a/b/d/*" + echo "d/* test=a/b/d/*" && echo "d/yes notest" ) >a/b/.gitattributes && ( @@ -287,7 +287,7 @@ test_expect_success 'bare repository: check that .gitattribute is ignored' ' ( cd bare.git && ( - echo "f test=f" + echo "f test=f" && echo "a/i test=a/i" ) >.gitattributes && attr_check f unspecified && @@ -312,7 +312,7 @@ test_expect_success 'bare repository: test info/attributes' ' ( cd bare.git && ( - echo "f test=f" + echo "f test=f" && echo "a/i test=a/i" ) >info/attributes && attr_check f f && diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 71350e0657..5f056982a5 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -98,6 +98,16 @@ test_expect_success 'safecrlf: git diff demotes safecrlf=true to warn' ' ' +test_expect_success 'safecrlf: no warning with safecrlf=false' ' + git config core.autocrlf input && + git config core.safecrlf false && + + for w in I am all CRLF; do echo $w; done | append_cr >allcrlf && + git add allcrlf 2>err && + test_must_be_empty err +' + + test_expect_success 'switch off autocrlf, safecrlf, reset HEAD' ' git config core.autocrlf false && git config core.safecrlf false && diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index 9479a4aaab..6a213608cc 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -785,7 +785,7 @@ test_expect_success PERL 'missing file in delayed checkout' ' cd repo && git init && echo "*.a filter=bug" >.gitattributes && - cp "$TEST_ROOT/test.o" missing-delay.a + cp "$TEST_ROOT/test.o" missing-delay.a && git add . && git commit -m "test commit" ) && @@ -807,7 +807,7 @@ test_expect_success PERL 'invalid file in delayed checkout' ' git init && echo "*.a filter=bug" >.gitattributes && cp "$TEST_ROOT/test.o" invalid-delay.a && - cp "$TEST_ROOT/test.o" unfiltered + cp "$TEST_ROOT/test.o" unfiltered && git add . && git commit -m "test commit" ) && diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh index 23fbe6434a..7b111a56fd 100755 --- a/t/t0070-fundamental.sh +++ b/t/t0070-fundamental.sh @@ -19,8 +19,8 @@ test_expect_success 'mktemp to nonexistent directory prints filename' ' test_expect_success POSIXPERM,SANITY 'mktemp to unwritable directory prints filename' ' mkdir cannotwrite && - chmod -w cannotwrite && test_when_finished "chmod +w cannotwrite" && + chmod -w cannotwrite && test_must_fail test-tool mktemp cannotwrite/testXXXXXX 2>err && grep "cannotwrite/test" err ' diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh index 0c61268fd2..28ea93f509 100755 --- a/t/t0090-cache-tree.sh +++ b/t/t0090-cache-tree.sh @@ -156,7 +156,7 @@ test_expect_success PERL 'commit --interactive gives cache-tree on partial commi return 44; } EOT - (echo p; echo 1; echo; echo s; echo n; echo y; echo q) | + test_write_lines p 1 "" s n y q | git commit --interactive -m foo && test_cache_tree ' diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index cc18b75c03..4984ca583d 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -23,7 +23,15 @@ promise_and_delete () { delete_object repo "$HASH" } +test_expect_success 'extensions.partialclone without filter' ' + test_create_repo server && + git clone --filter="blob:none" "file://$(pwd)/server" client && + git -C client config --unset core.partialclonefilter && + git -C client fetch origin +' + test_expect_success 'missing reflog object, but promised by a commit, passes fsck' ' + rm -rf repo && test_create_repo repo && test_commit -C repo my_commit && diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh index c7ce5d8bb5..c13578a635 100755 --- a/t/t1004-read-tree-m-u-wf.sh +++ b/t/t1004-read-tree-m-u-wf.sh @@ -179,6 +179,8 @@ test_expect_success 'funny symlink in work tree' ' test_expect_success SANITY 'funny symlink in work tree, un-unlink-able' ' + test_when_finished "chmod u+w a 2>/dev/null; rm -fr a b" && + rm -fr a b && git reset --hard && @@ -188,10 +190,6 @@ test_expect_success SANITY 'funny symlink in work tree, un-unlink-able' ' ' -# clean-up from the above test -chmod a+w a 2>/dev/null -rm -fr a b - test_expect_success 'D/F setup' ' git reset --hard && @@ -212,10 +210,10 @@ test_expect_success 'D/F' ' read_tree_u_must_succeed -m -u branch-point side-b side-a && git ls-files -u >actual && ( - a=$(git rev-parse branch-point:subdir/file2) - b=$(git rev-parse side-a:subdir/file2/another) - echo "100644 $a 1 subdir/file2" - echo "100644 $a 2 subdir/file2" + a=$(git rev-parse branch-point:subdir/file2) && + b=$(git rev-parse side-a:subdir/file2/another) && + echo "100644 $a 1 subdir/file2" && + echo "100644 $a 2 subdir/file2" && echo "100644 $b 3 subdir/file2/another" ) >expect && test_cmp expect actual diff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh index 074568500a..83b09e1310 100755 --- a/t/t1005-read-tree-reset.sh +++ b/t/t1005-read-tree-reset.sh @@ -33,7 +33,7 @@ test_expect_success 'reset should remove remnants from a failed merge' ' git ls-files -s >expect && sha1=$(git rev-parse :new) && ( - echo "100644 $sha1 1 old" + echo "100644 $sha1 1 old" && echo "100644 $sha1 3 old" ) | git update-index --index-info && >old && @@ -48,7 +48,7 @@ test_expect_success 'two-way reset should remove remnants too' ' git ls-files -s >expect && sha1=$(git rev-parse :new) && ( - echo "100644 $sha1 1 old" + echo "100644 $sha1 1 old" && echo "100644 $sha1 3 old" ) | git update-index --index-info && >old && @@ -63,7 +63,7 @@ test_expect_success 'Porcelain reset should remove remnants too' ' git ls-files -s >expect && sha1=$(git rev-parse :new) && ( - echo "100644 $sha1 1 old" + echo "100644 $sha1 1 old" && echo "100644 $sha1 3 old" ) | git update-index --index-info && >old && @@ -78,7 +78,7 @@ test_expect_success 'Porcelain checkout -f should remove remnants too' ' git ls-files -s >expect && sha1=$(git rev-parse :new) && ( - echo "100644 $sha1 1 old" + echo "100644 $sha1 1 old" && echo "100644 $sha1 3 old" ) | git update-index --index-info && >old && @@ -93,7 +93,7 @@ test_expect_success 'Porcelain checkout -f HEAD should remove remnants too' ' git ls-files -s >expect && sha1=$(git rev-parse :new) && ( - echo "100644 $sha1 1 old" + echo "100644 $sha1 1 old" && echo "100644 $sha1 3 old" ) | git update-index --index-info && >old && diff --git a/t/t1008-read-tree-overlay.sh b/t/t1008-read-tree-overlay.sh index 4c50ed955e..cf96016844 100755 --- a/t/t1008-read-tree-overlay.sh +++ b/t/t1008-read-tree-overlay.sh @@ -23,7 +23,7 @@ test_expect_success setup ' test_expect_success 'multi-read' ' read_tree_must_succeed initial master side && - (echo a; echo b/c) >expect && + test_write_lines a b/c >expect && git ls-files >actual && test_cmp expect actual ' diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh index df3183ea1a..c2df75e495 100755 --- a/t/t1020-subdirectory.sh +++ b/t/t1020-subdirectory.sh @@ -148,7 +148,7 @@ test_expect_success 'GIT_PREFIX for built-ins' ' ( cd dir && echo "change" >two && - GIT_EXTERNAL_DIFF=./diff git diff >../actual + GIT_EXTERNAL_DIFF=./diff git diff >../actual && git checkout -- two ) && test_cmp expect actual diff --git a/t/t1050-large.sh b/t/t1050-large.sh index f9eb143f43..1a9b21b293 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -108,7 +108,7 @@ test_expect_success 'packsize limit' ' test-tool genrandom "c" $(( 128 * 1024 )) >mid3 && git add mid1 mid2 mid3 && - count=0 + count=0 && for pi in .git/objects/pack/pack-*.idx do test -f "$pi" && count=$(( $count + 1 )) @@ -116,8 +116,8 @@ test_expect_success 'packsize limit' ' test $count = 2 && ( - git hash-object --stdin <mid1 - git hash-object --stdin <mid2 + git hash-object --stdin <mid1 && + git hash-object --stdin <mid2 && git hash-object --stdin <mid3 ) | sort >expect && diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 03c223708e..24706ba412 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -888,7 +888,7 @@ EOF test_expect_success !MINGW 'get --path copes with unset $HOME' ' ( - unset HOME; + sane_unset HOME && test_must_fail git config --get --path path.home \ >result 2>msg && git config --get --path path.normal >>result && diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 553e26d9ce..8293131001 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -339,8 +339,8 @@ test_expect_failure 'reflog with non-commit entries displays all entries' ' ' test_expect_success 'reflog expire operates on symref not referrent' ' - git branch -l the_symref && - git branch -l referrent && + git branch --create-reflog the_symref && + git branch --create-reflog referrent && git update-ref referrent HEAD && git symbolic-ref refs/heads/the_symref refs/heads/referrent && test_when_finished "rm -f .git/refs/heads/referrent.lock" && diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh index 596907758d..4d62ceef9c 100755 --- a/t/t1411-reflog-show.sh +++ b/t/t1411-reflog-show.sh @@ -159,9 +159,9 @@ test_expect_success 'git log -g -p shows diffs vs. parents' ' git log -1 -p HEAD^ >log.one && git log -1 -p HEAD >log.two && ( - cat log.one; echo - cat log.two; echo - cat log.one; echo + cat log.one && echo && + cat log.two && echo && + cat log.one && echo && cat log.two ) >expect && test_cmp expect actual diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index 93c77eac45..349f6e10af 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -123,9 +123,9 @@ test_expect_success 'checkout -b new my-side@{u} forks from the same' ' test_expect_success 'merge my-side@{u} records the correct name' ' ( - cd clone || exit - git checkout master || exit - git branch -D new ;# can fail but is ok + cd clone && + git checkout master && + test_might_fail git branch -D new && git branch -t new my-side@{u} && git merge -s ours new@{u} && git show -s --pretty=tformat:%s >actual && diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh index 96fe3754c8..e4d5b56014 100755 --- a/t/t1512-rev-parse-disambiguation.sh +++ b/t/t1512-rev-parse-disambiguation.sh @@ -34,8 +34,8 @@ test_expect_success 'blob and tree' ' for i in 0 1 2 3 4 5 6 7 8 9 do echo $i - done - echo + done && + echo && echo b1rwzyc3 ) >a0blgqsjc && @@ -222,7 +222,7 @@ test_expect_success 'more history' ' test_might_fail git rm -f a0blgqsjc && ( - git cat-file blob $side:f5518nwu + git cat-file blob $side:f5518nwu && echo j3l0i9s6 ) >ab2gs879 && git add ab2gs879 && diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh index 1e81b33b2e..39133bcbc8 100755 --- a/t/t1700-split-index.sh +++ b/t/t1700-split-index.sh @@ -435,7 +435,7 @@ test_expect_success 'writing split index with null sha1 does not write cache tre commit=$(git commit-tree $tree -p HEAD <msg) && git update-ref HEAD "$commit" && GIT_ALLOW_NULL_SHA1=1 git reset --hard && - (test-tool dump-cache-tree >cache-tree.out || true) && + test_might_fail test-tool dump-cache-tree >cache-tree.out && test_line_count = 0 cache-tree.out ' diff --git a/t/t2016-checkout-patch.sh b/t/t2016-checkout-patch.sh index 9cd0ac4ba3..47aeb0b167 100755 --- a/t/t2016-checkout-patch.sh +++ b/t/t2016-checkout-patch.sh @@ -20,33 +20,33 @@ test_expect_success PERL 'setup' ' test_expect_success PERL 'saying "n" does nothing' ' set_and_save_state dir/foo work head && - (echo n; echo n) | git checkout -p && + test_write_lines n n | git checkout -p && verify_saved_state bar && verify_saved_state dir/foo ' test_expect_success PERL 'git checkout -p' ' - (echo n; echo y) | git checkout -p && + test_write_lines n y | git checkout -p && verify_saved_state bar && verify_state dir/foo head head ' test_expect_success PERL 'git checkout -p with staged changes' ' set_state dir/foo work index && - (echo n; echo y) | git checkout -p && + test_write_lines n y | git checkout -p && verify_saved_state bar && verify_state dir/foo index index ' test_expect_success PERL 'git checkout -p HEAD with NO staged changes: abort' ' set_and_save_state dir/foo work head && - (echo n; echo y; echo n) | git checkout -p HEAD && + test_write_lines n y n | git checkout -p HEAD && verify_saved_state bar && verify_saved_state dir/foo ' test_expect_success PERL 'git checkout -p HEAD with NO staged changes: apply' ' - (echo n; echo y; echo y) | git checkout -p HEAD && + test_write_lines n y y | git checkout -p HEAD && verify_saved_state bar && verify_state dir/foo head head ' @@ -54,14 +54,14 @@ test_expect_success PERL 'git checkout -p HEAD with NO staged changes: apply' ' test_expect_success PERL 'git checkout -p HEAD with change already staged' ' set_state dir/foo index index && # the third n is to get out in case it mistakenly does not apply - (echo n; echo y; echo n) | git checkout -p HEAD && + test_write_lines n y n | git checkout -p HEAD && verify_saved_state bar && verify_state dir/foo head head ' test_expect_success PERL 'git checkout -p HEAD^' ' # the third n is to get out in case it mistakenly does not apply - (echo n; echo y; echo n) | git checkout -p HEAD^ && + test_write_lines n y n | git checkout -p HEAD^ && verify_saved_state bar && verify_state dir/foo parent parent ' @@ -69,7 +69,7 @@ test_expect_success PERL 'git checkout -p HEAD^' ' test_expect_success PERL 'git checkout -p handles deletion' ' set_state dir/foo work index && rm dir/foo && - (echo n; echo y) | git checkout -p && + test_write_lines n y | git checkout -p && verify_saved_state bar && verify_state dir/foo index index ' @@ -81,21 +81,21 @@ test_expect_success PERL 'git checkout -p handles deletion' ' test_expect_success PERL 'path limiting works: dir' ' set_state dir/foo work head && - (echo y; echo n) | git checkout -p dir && + test_write_lines y n | git checkout -p dir && verify_saved_state bar && verify_state dir/foo head head ' test_expect_success PERL 'path limiting works: -- dir' ' set_state dir/foo work head && - (echo y; echo n) | git checkout -p -- dir && + test_write_lines y n | git checkout -p -- dir && verify_saved_state bar && verify_state dir/foo head head ' test_expect_success PERL 'path limiting works: HEAD^ -- dir' ' # the third n is to get out in case it mistakenly does not apply - (echo y; echo n; echo n) | git checkout -p HEAD^ -- dir && + test_write_lines y n n | git checkout -p HEAD^ -- dir && verify_saved_state bar && verify_state dir/foo parent parent ' @@ -103,7 +103,7 @@ test_expect_success PERL 'path limiting works: HEAD^ -- dir' ' test_expect_success PERL 'path limiting works: foo inside dir' ' set_state dir/foo work head && # the third n is to get out in case it mistakenly does not apply - (echo y; echo n; echo n) | (cd dir && git checkout -p foo) && + test_write_lines y n n | (cd dir && git checkout -p foo) && verify_saved_state bar && verify_state dir/foo head head ' diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh index 3e5ac81bd2..26dc3f1fc0 100755 --- a/t/t2024-checkout-dwim.sh +++ b/t/t2024-checkout-dwim.sh @@ -23,6 +23,12 @@ test_branch_upstream () { test_cmp expect.upstream actual.upstream } +status_uno_is_clean () { + >status.expect && + git status -uno --porcelain >status.actual && + test_cmp status.expect status.actual +} + test_expect_success 'setup' ' test_commit my_master && git init repo_a && @@ -55,6 +61,7 @@ test_expect_success 'checkout of non-existing branch fails' ' test_might_fail git branch -D xyzzy && test_must_fail git checkout xyzzy && + status_uno_is_clean && test_must_fail git rev-parse --verify refs/heads/xyzzy && test_branch master ' @@ -64,15 +71,47 @@ test_expect_success 'checkout of branch from multiple remotes fails #1' ' test_might_fail git branch -D foo && test_must_fail git checkout foo && + status_uno_is_clean && test_must_fail git rev-parse --verify refs/heads/foo && test_branch master ' +test_expect_success 'checkout of branch from multiple remotes fails with advice' ' + git checkout -B master && + test_might_fail git branch -D foo && + test_must_fail git checkout foo 2>stderr && + test_branch master && + status_uno_is_clean && + test_i18ngrep "^hint: " stderr && + test_must_fail git -c advice.checkoutAmbiguousRemoteBranchName=false \ + checkout foo 2>stderr && + test_branch master && + status_uno_is_clean && + test_i18ngrep ! "^hint: " stderr && + # Make sure the likes of checkout -p do not print this hint + git checkout -p foo 2>stderr && + test_i18ngrep ! "^hint: " stderr && + status_uno_is_clean +' + +test_expect_success 'checkout of branch from multiple remotes succeeds with checkout.defaultRemote #1' ' + git checkout -B master && + status_uno_is_clean && + test_might_fail git branch -D foo && + + git -c checkout.defaultRemote=repo_a checkout foo && + status_uno_is_clean && + test_branch foo && + test_cmp_rev remotes/repo_a/foo HEAD && + test_branch_upstream foo repo_a foo +' + test_expect_success 'checkout of branch from a single remote succeeds #1' ' git checkout -B master && test_might_fail git branch -D bar && git checkout bar && + status_uno_is_clean && test_branch bar && test_cmp_rev remotes/repo_a/bar HEAD && test_branch_upstream bar repo_a bar @@ -83,6 +122,7 @@ test_expect_success 'checkout of branch from a single remote succeeds #2' ' test_might_fail git branch -D baz && git checkout baz && + status_uno_is_clean && test_branch baz && test_cmp_rev remotes/other_b/baz HEAD && test_branch_upstream baz repo_b baz @@ -90,6 +130,7 @@ test_expect_success 'checkout of branch from a single remote succeeds #2' ' test_expect_success '--no-guess suppresses branch auto-vivification' ' git checkout -B master && + status_uno_is_clean && test_might_fail git branch -D bar && test_must_fail git checkout --no-guess bar && @@ -99,6 +140,7 @@ test_expect_success '--no-guess suppresses branch auto-vivification' ' test_expect_success 'setup more remotes with unconventional refspecs' ' git checkout -B master && + status_uno_is_clean && git init repo_c && ( cd repo_c && @@ -128,27 +170,33 @@ test_expect_success 'setup more remotes with unconventional refspecs' ' test_expect_success 'checkout of branch from multiple remotes fails #2' ' git checkout -B master && + status_uno_is_clean && test_might_fail git branch -D bar && test_must_fail git checkout bar && + status_uno_is_clean && test_must_fail git rev-parse --verify refs/heads/bar && test_branch master ' test_expect_success 'checkout of branch from multiple remotes fails #3' ' git checkout -B master && + status_uno_is_clean && test_might_fail git branch -D baz && test_must_fail git checkout baz && + status_uno_is_clean && test_must_fail git rev-parse --verify refs/heads/baz && test_branch master ' test_expect_success 'checkout of branch from a single remote succeeds #3' ' git checkout -B master && + status_uno_is_clean && test_might_fail git branch -D spam && git checkout spam && + status_uno_is_clean && test_branch spam && test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD && test_branch_upstream spam repo_c spam @@ -156,9 +204,11 @@ test_expect_success 'checkout of branch from a single remote succeeds #3' ' test_expect_success 'checkout of branch from a single remote succeeds #4' ' git checkout -B master && + status_uno_is_clean && test_might_fail git branch -D eggs && git checkout eggs && + status_uno_is_clean && test_branch eggs && test_cmp_rev refs/repo_d/eggs HEAD && test_branch_upstream eggs repo_d eggs @@ -166,32 +216,38 @@ test_expect_success 'checkout of branch from a single remote succeeds #4' ' test_expect_success 'checkout of branch with a file having the same name fails' ' git checkout -B master && + status_uno_is_clean && test_might_fail git branch -D spam && >spam && test_must_fail git checkout spam && + status_uno_is_clean && test_must_fail git rev-parse --verify refs/heads/spam && test_branch master ' test_expect_success 'checkout of branch with a file in subdir having the same name fails' ' git checkout -B master && + status_uno_is_clean && test_might_fail git branch -D spam && >spam && mkdir sub && mv spam sub/spam && test_must_fail git -C sub checkout spam && + status_uno_is_clean && test_must_fail git rev-parse --verify refs/heads/spam && test_branch master ' test_expect_success 'checkout <branch> -- succeeds, even if a file with the same name exists' ' git checkout -B master && + status_uno_is_clean && test_might_fail git branch -D spam && >spam && git checkout spam -- && + status_uno_is_clean && test_branch spam && test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD && test_branch_upstream spam repo_c spam @@ -200,6 +256,7 @@ test_expect_success 'checkout <branch> -- succeeds, even if a file with the same test_expect_success 'loosely defined local base branch is reported correctly' ' git checkout master && + status_uno_is_clean && git branch strict && git branch loose && git commit --allow-empty -m "a bit more" && @@ -210,7 +267,9 @@ test_expect_success 'loosely defined local base branch is reported correctly' ' test_config branch.loose.merge master && git checkout strict | sed -e "s/strict/BRANCHNAME/g" >expect && + status_uno_is_clean && git checkout loose | sed -e "s/loose/BRANCHNAME/g" >actual && + status_uno_is_clean && test_cmp expect actual ' diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh index d2e49f7632..be6e093142 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2025-worktree-add.sh @@ -402,6 +402,27 @@ test_expect_success '"add" <path> <branch> dwims' ' ) ' +test_expect_success '"add" <path> <branch> dwims with checkout.defaultRemote' ' + test_when_finished rm -rf repo_upstream repo_dwim foo && + setup_remote_repo repo_upstream repo_dwim && + git init repo_dwim && + ( + cd repo_dwim && + git remote add repo_upstream2 ../repo_upstream && + git fetch repo_upstream2 && + test_must_fail git worktree add ../foo foo && + git -c checkout.defaultRemote=repo_upstream worktree add ../foo foo && + >status.expect && + git status -uno --porcelain >status.actual && + test_cmp status.expect status.actual + ) && + ( + cd foo && + test_branch_upstream foo repo_upstream foo && + test_cmp_rev refs/remotes/repo_upstream/foo refs/heads/foo + ) +' + test_expect_success 'git worktree add does not match remote' ' test_when_finished rm -rf repo_a repo_b foo && setup_remote_repo repo_a repo_b && diff --git a/t/t2103-update-index-ignore-missing.sh b/t/t2103-update-index-ignore-missing.sh index 332694e7d3..0114f05228 100755 --- a/t/t2103-update-index-ignore-missing.sh +++ b/t/t2103-update-index-ignore-missing.sh @@ -32,7 +32,7 @@ test_expect_success basics ' test_create_repo xyzzy && cd xyzzy && >file && - git add file + git add file && git commit -m "sub initial" ) && git add xyzzy && diff --git a/t/t2202-add-addremove.sh b/t/t2202-add-addremove.sh index 6a5a3166b1..17744e8c57 100755 --- a/t/t2202-add-addremove.sh +++ b/t/t2202-add-addremove.sh @@ -6,12 +6,12 @@ test_description='git add --all' test_expect_success setup ' ( - echo .gitignore + echo .gitignore && echo will-remove ) >expect && ( - echo actual - echo expect + echo actual && + echo expect && echo ignored ) >.gitignore && git --literal-pathspecs add --all && @@ -25,10 +25,10 @@ test_expect_success setup ' test_expect_success 'git add --all' ' ( - echo .gitignore - echo not-ignored - echo "M .gitignore" - echo "A not-ignored" + echo .gitignore && + echo not-ignored && + echo "M .gitignore" && + echo "A not-ignored" && echo "D will-remove" ) >expect && >ignored && diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index 04d840a544..e7a400b4c7 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -70,8 +70,7 @@ test_expect_success 'i-t-a entry is simply ignored' ' git commit -m second && test $(git ls-tree HEAD -- nitfol | wc -l) = 0 && test $(git diff --name-only HEAD -- nitfol | wc -l) = 1 && - test $(git diff --name-only --ita-invisible-in-index HEAD -- nitfol | wc -l) = 0 && - test $(git diff --name-only --ita-invisible-in-index -- nitfol | wc -l) = 1 + test $(git diff --name-only -- nitfol | wc -l) = 1 ' test_expect_success 'can commit with an unrelated i-t-a entry in index' ' @@ -99,13 +98,13 @@ test_expect_success 'cache-tree invalidates i-t-a paths' ' : >dir/bar && git add -N dir/bar && - git diff --cached --name-only >actual && + git diff --name-only >actual && echo dir/bar >expect && test_cmp expect actual && git write-tree >/dev/null && - git diff --cached --name-only >actual && + git diff --name-only >actual && echo dir/bar >expect && test_cmp expect actual ' @@ -186,7 +185,19 @@ test_expect_success 'rename detection finds the right names' ' cat >expected.3 <<-EOF && 2 .R N... 100644 100644 100644 $hash $hash R100 third first EOF - test_cmp expected.3 actual.3 + test_cmp expected.3 actual.3 && + + git diff --stat >actual.4 && + cat >expected.4 <<-EOF && + first => third | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + EOF + test_cmp expected.4 actual.4 && + + git diff --cached --stat >actual.5 && + : >expected.5 && + test_cmp expected.5 actual.5 + ) ' @@ -222,5 +233,46 @@ test_expect_success 'double rename detection in status' ' ) ' -test_done +test_expect_success 'diff-files/diff-cached shows ita as new/not-new files' ' + git reset --hard && + echo new >new-ita && + git add -N new-ita && + git diff --summary >actual && + echo " create mode 100644 new-ita" >expected && + test_cmp expected actual && + git diff --cached --summary >actual2 && + : >expected2 && + test_cmp expected2 actual2 +' + +test_expect_success '"diff HEAD" includes ita as new files' ' + git reset --hard && + echo new >new-ita && + git add -N new-ita && + git diff HEAD >actual && + cat >expected <<-\EOF && + diff --git a/new-ita b/new-ita + new file mode 100644 + index 0000000..3e75765 + --- /dev/null + +++ b/new-ita + @@ -0,0 +1 @@ + +new + EOF + test_cmp expected actual +' + +test_expect_success 'apply --intent-to-add' ' + git reset --hard && + echo new >new-ita && + git add -N new-ita && + git diff >expected && + grep "new file" expected && + git reset --hard && + git apply --intent-to-add expected && + git diff >actual && + test_cmp expected actual +' + +test_done diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh index c525656b2c..afd4756134 100755 --- a/t/t3000-ls-files-others.sh +++ b/t/t3000-ls-files-others.sh @@ -84,7 +84,7 @@ test_expect_success SYMLINKS 'ls-files --others with symlinked submodule' ' ) && ( cd super && - "$SHELL_PATH" "$TEST_DIRECTORY/../contrib/workdir/git-new-workdir" ../sub sub + "$SHELL_PATH" "$TEST_DIRECTORY/../contrib/workdir/git-new-workdir" ../sub sub && git ls-files --others --exclude-standard >../actual ) && echo sub/ >expect && diff --git a/t/t3006-ls-files-long.sh b/t/t3006-ls-files-long.sh index 202ad658b8..e109c3fbfb 100755 --- a/t/t3006-ls-files-long.sh +++ b/t/t3006-ls-files-long.sh @@ -29,7 +29,7 @@ test_expect_success 'overly-long path does not replace another by mistake' ' printf "$pat" "$blob_a" "$path_a" "$blob_z" "$path_z" | git update-index --add --index-info && ( - echo "$path_a" + echo "$path_a" && echo "$path_z" ) >expect && git ls-files >actual && diff --git a/t/t3008-ls-files-lazy-init-name-hash.sh b/t/t3008-ls-files-lazy-init-name-hash.sh index 08af596ba6..64f047332b 100755 --- a/t/t3008-ls-files-lazy-init-name-hash.sh +++ b/t/t3008-ls-files-lazy-init-name-hash.sh @@ -14,10 +14,10 @@ LAZY_THREAD_COST=2000 test_expect_success 'no buffer overflow in lazy_init_name_hash' ' ( - test_seq $LAZY_THREAD_COST | sed "s/^/a_/" - echo b/b/b - test_seq $LAZY_THREAD_COST | sed "s/^/c_/" - test_seq 50 | sed "s/^/d_/" | tr "\n" "/"; echo d + test_seq $LAZY_THREAD_COST | sed "s/^/a_/" && + echo b/b/b && + test_seq $LAZY_THREAD_COST | sed "s/^/c_/" && + test_seq 50 | sed "s/^/d_/" | tr "\n" "/" && echo d ) | sed "s/^/100644 $EMPTY_BLOB /" | git update-index --index-info && diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index 3563e77b37..ff641b348a 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -36,15 +36,15 @@ test_expect_success 'setup 1' ' test_tick && git commit -m "master modifies a and d/e" && c1=$(git rev-parse --verify HEAD) && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o1 a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o1 d/e" - echo "100644 $o1 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o1 a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o1 d/e" && + echo "100644 $o1 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o1 0 d/e" ) >expected && test_cmp expected actual @@ -54,15 +54,15 @@ test_expect_success 'setup 2' ' rm -rf [abcd] && git checkout side && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o0 a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o0 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o0 a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o0 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual && @@ -75,15 +75,15 @@ test_expect_success 'setup 2' ' test_tick && git commit -m "side modifies a" && c2=$(git rev-parse --verify HEAD) && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o2 a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o2 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o2 a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o2 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual @@ -93,15 +93,15 @@ test_expect_success 'setup 3' ' rm -rf [abcd] && git checkout df-1 && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o0 a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o0 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o0 a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o0 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual && @@ -112,15 +112,15 @@ test_expect_success 'setup 3' ' test_tick && git commit -m "df-1 makes b/c" && c3=$(git rev-parse --verify HEAD) && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o0 a" - echo "100644 blob $o3 b/c" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o0 0 a" - echo "100644 $o3 0 b/c" - echo "100644 $o0 0 c" + echo "100644 blob $o0 a" && + echo "100644 blob $o3 b/c" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o0 0 a" && + echo "100644 $o3 0 b/c" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual @@ -130,15 +130,15 @@ test_expect_success 'setup 4' ' rm -rf [abcd] && git checkout df-2 && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o0 a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o0 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o0 a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o0 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual && @@ -149,15 +149,15 @@ test_expect_success 'setup 4' ' test_tick && git commit -m "df-2 makes a/c" && c4=$(git rev-parse --verify HEAD) && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o4 a/c" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o4 0 a/c" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o4 a/c" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o4 0 a/c" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual @@ -167,15 +167,15 @@ test_expect_success 'setup 5' ' rm -rf [abcd] && git checkout remove && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o0 a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o0 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o0 a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o0 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual && @@ -190,13 +190,13 @@ test_expect_success 'setup 5' ' test_tick && git commit -m "remove removes b and modifies a" && c5=$(git rev-parse --verify HEAD) && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o5 a" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o5 0 a" - echo "100644 $o0 0 c" + echo "100644 blob $o5 a" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o5 0 a" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual @@ -207,15 +207,15 @@ test_expect_success 'setup 6' ' rm -rf [abcd] && git checkout df-3 && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o0 a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 $o0 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o0 a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 $o0 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o0 0 d/e" ) >expected && test_cmp expected actual && @@ -226,15 +226,15 @@ test_expect_success 'setup 6' ' test_tick && git commit -m "df-3 makes d" && c6=$(git rev-parse --verify HEAD) && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o0 a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o6 d" - echo "100644 $o0 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 blob $o0 a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o6 d" && + echo "100644 $o0 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o6 0 d" ) >expected && test_cmp expected actual @@ -286,11 +286,11 @@ test_expect_success 'merge-recursive result' ' git ls-files -s >actual && ( - echo "100644 $o0 1 a" - echo "100644 $o2 2 a" - echo "100644 $o1 3 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 $o0 1 a" && + echo "100644 $o2 2 a" && + echo "100644 $o1 3 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o1 0 d/e" ) >expected && test_cmp expected actual @@ -325,10 +325,10 @@ test_expect_success 'merge-recursive remove conflict' ' git ls-files -s >actual && ( - echo "100644 $o0 1 a" - echo "100644 $o1 2 a" - echo "100644 $o5 3 a" - echo "100644 $o0 0 c" + echo "100644 $o0 1 a" && + echo "100644 $o1 2 a" && + echo "100644 $o5 3 a" && + echo "100644 $o0 0 c" && echo "100644 $o1 0 d/e" ) >expected && test_cmp expected actual @@ -347,9 +347,9 @@ test_expect_success 'merge-recursive result' ' git ls-files -s >actual && ( - echo "100644 $o1 0 a" - echo "100644 $o3 0 b/c" - echo "100644 $o0 0 c" + echo "100644 $o1 0 a" && + echo "100644 $o3 0 b/c" && + echo "100644 $o0 0 c" && echo "100644 $o1 0 d/e" ) >expected && test_cmp expected actual @@ -369,11 +369,11 @@ test_expect_success 'merge-recursive d/f conflict result' ' git ls-files -s >actual && ( - echo "100644 $o0 1 a" - echo "100644 $o1 2 a" - echo "100644 $o4 0 a/c" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 $o0 1 a" && + echo "100644 $o1 2 a" && + echo "100644 $o4 0 a/c" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o1 0 d/e" ) >expected && test_cmp expected actual @@ -393,11 +393,11 @@ test_expect_success 'merge-recursive d/f conflict result the other way' ' git ls-files -s >actual && ( - echo "100644 $o0 1 a" - echo "100644 $o1 3 a" - echo "100644 $o4 0 a/c" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 $o0 1 a" && + echo "100644 $o1 3 a" && + echo "100644 $o4 0 a/c" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o1 0 d/e" ) >expected && test_cmp expected actual @@ -417,11 +417,11 @@ test_expect_success 'merge-recursive d/f conflict result' ' git ls-files -s >actual && ( - echo "100644 $o1 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" - echo "100644 $o6 3 d" - echo "100644 $o0 1 d/e" + echo "100644 $o1 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && + echo "100644 $o6 3 d" && + echo "100644 $o0 1 d/e" && echo "100644 $o1 2 d/e" ) >expected && test_cmp expected actual @@ -441,11 +441,11 @@ test_expect_success 'merge-recursive d/f conflict result' ' git ls-files -s >actual && ( - echo "100644 $o1 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" - echo "100644 $o6 2 d" - echo "100644 $o0 1 d/e" + echo "100644 $o1 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && + echo "100644 $o6 2 d" && + echo "100644 $o0 1 d/e" && echo "100644 $o1 3 d/e" ) >expected && test_cmp expected actual @@ -465,13 +465,13 @@ test_expect_success 'reset and bind merge' ' git read-tree --prefix=M/ master && git ls-files -s >actual && ( - echo "100644 $o1 0 M/a" - echo "100644 $o0 0 M/b" - echo "100644 $o0 0 M/c" - echo "100644 $o1 0 M/d/e" - echo "100644 $o1 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 $o1 0 M/a" && + echo "100644 $o0 0 M/b" && + echo "100644 $o0 0 M/c" && + echo "100644 $o1 0 M/d/e" && + echo "100644 $o1 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o1 0 d/e" ) >expected && test_cmp expected actual && @@ -479,17 +479,17 @@ test_expect_success 'reset and bind merge' ' git read-tree --prefix=a1/ master && git ls-files -s >actual && ( - echo "100644 $o1 0 M/a" - echo "100644 $o0 0 M/b" - echo "100644 $o0 0 M/c" - echo "100644 $o1 0 M/d/e" - echo "100644 $o1 0 a" - echo "100644 $o1 0 a1/a" - echo "100644 $o0 0 a1/b" - echo "100644 $o0 0 a1/c" - echo "100644 $o1 0 a1/d/e" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" + echo "100644 $o1 0 M/a" && + echo "100644 $o0 0 M/b" && + echo "100644 $o0 0 M/c" && + echo "100644 $o1 0 M/d/e" && + echo "100644 $o1 0 a" && + echo "100644 $o1 0 a1/a" && + echo "100644 $o0 0 a1/b" && + echo "100644 $o0 0 a1/c" && + echo "100644 $o1 0 a1/d/e" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && echo "100644 $o1 0 d/e" ) >expected && test_cmp expected actual && @@ -497,21 +497,21 @@ test_expect_success 'reset and bind merge' ' git read-tree --prefix=z/ master && git ls-files -s >actual && ( - echo "100644 $o1 0 M/a" - echo "100644 $o0 0 M/b" - echo "100644 $o0 0 M/c" - echo "100644 $o1 0 M/d/e" - echo "100644 $o1 0 a" - echo "100644 $o1 0 a1/a" - echo "100644 $o0 0 a1/b" - echo "100644 $o0 0 a1/c" - echo "100644 $o1 0 a1/d/e" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" - echo "100644 $o1 0 d/e" - echo "100644 $o1 0 z/a" - echo "100644 $o0 0 z/b" - echo "100644 $o0 0 z/c" + echo "100644 $o1 0 M/a" && + echo "100644 $o0 0 M/b" && + echo "100644 $o0 0 M/c" && + echo "100644 $o1 0 M/d/e" && + echo "100644 $o1 0 a" && + echo "100644 $o1 0 a1/a" && + echo "100644 $o0 0 a1/b" && + echo "100644 $o0 0 a1/c" && + echo "100644 $o1 0 a1/d/e" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && + echo "100644 $o1 0 d/e" && + echo "100644 $o1 0 z/a" && + echo "100644 $o0 0 z/b" && + echo "100644 $o0 0 z/c" && echo "100644 $o1 0 z/d/e" ) >expected && test_cmp expected actual @@ -589,8 +589,8 @@ test_expect_success 'merge-recursive simple w/submodule result' ' git ls-files -s >actual && ( - echo "100644 $o5 0 a" - echo "100644 $o0 0 c" + echo "100644 $o5 0 a" && + echo "100644 $o0 0 c" && echo "160000 $c1 0 d" ) >expected && test_cmp expected actual @@ -601,13 +601,13 @@ test_expect_success 'merge-recursive copy vs. rename' ' git merge rename && ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 blob $o0 e" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" - echo "100644 $o0 0 d/e" + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 blob $o0 e" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && + echo "100644 $o0 0 d/e" && echo "100644 $o0 0 e" ) >expected && test_cmp expected actual @@ -617,17 +617,17 @@ test_expect_failure 'merge-recursive rename vs. rename/symlink' ' git checkout -f rename && git merge rename-ln && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( git ls-tree -r HEAD && git ls-files -s ) >actual && ( - echo "120000 blob $oln a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 blob $o0 e" - echo "120000 $oln 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" - echo "100644 $o0 0 d/e" + echo "120000 blob $oln a" && + echo "100644 blob $o0 b" && + echo "100644 blob $o0 c" && + echo "100644 blob $o0 d/e" && + echo "100644 blob $o0 e" && + echo "120000 $oln 0 a" && + echo "100644 $o0 0 b" && + echo "100644 $o0 0 c" && + echo "100644 $o0 0 d/e" && echo "100644 $o0 0 e" ) >expected && test_cmp expected actual diff --git a/t/t3035-merge-sparse.sh b/t/t3035-merge-sparse.sh new file mode 100755 index 0000000000..0c0b433bd3 --- /dev/null +++ b/t/t3035-merge-sparse.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +test_description='merge with sparse files' + +. ./test-lib.sh + +# test_file $filename $content +test_file () { + echo "$2" > "$1" && + git add "$1" +} + +# test_commit_this $message_and_tag +test_commit_this () { + git commit -m "$1" && + git tag "$1" +} + +test_expect_success 'setup' ' + : >empty && + test_file checked-out init && + test_file modify_delete modify_delete_init && + test_commit_this init && + test_file modify_delete modify_delete_theirs && + test_commit_this theirs && + git reset --hard init && + git rm modify_delete && + test_commit_this ours && + git config core.sparseCheckout true && + echo "/checked-out" >.git/info/sparse-checkout && + git reset --hard && + ! git merge theirs +' + +test_expect_success 'reset --hard works after the conflict' ' + git reset --hard +' + +test_expect_success 'is reset properly' ' + git status --porcelain -- modify_delete >out && + test_cmp empty out && + test_path_is_missing modify_delete +' + +test_expect_success 'setup: conflict back' ' + ! git merge theirs +' + +test_expect_success 'Merge abort works after the conflict' ' + git merge --abort +' + +test_expect_success 'is aborted properly' ' + git status --porcelain -- modify_delete >out && + test_cmp empty out && + test_path_is_missing modify_delete +' + +test_done diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh index 2f5f41a012..f1f09abdd9 100755 --- a/t/t3050-subprojects-fetch.sh +++ b/t/t3050-subprojects-fetch.sh @@ -21,10 +21,10 @@ test_expect_success setup ' test_expect_success clone ' git clone "file://$(pwd)/.git" cloned && - (git rev-parse HEAD; git ls-files -s) >expected && + (git rev-parse HEAD && git ls-files -s) >expected && ( cd cloned && - (git rev-parse HEAD; git ls-files -s) >../actual + (git rev-parse HEAD && git ls-files -s) >../actual ) && test_cmp expected actual ' @@ -40,11 +40,11 @@ test_expect_success advance ' ' test_expect_success fetch ' - (git rev-parse HEAD; git ls-files -s) >expected && + (git rev-parse HEAD && git ls-files -s) >expected && ( cd cloned && git pull && - (git rev-parse HEAD; git ls-files -s) >../actual + (git rev-parse HEAD && git ls-files -s) >../actual ) && test_cmp expected actual ' diff --git a/t/t3102-ls-tree-wildcards.sh b/t/t3102-ls-tree-wildcards.sh index e804377f1c..1e16c6b8ea 100755 --- a/t/t3102-ls-tree-wildcards.sh +++ b/t/t3102-ls-tree-wildcards.sh @@ -23,7 +23,7 @@ test_expect_success 'ls-tree outside prefix' ' cat >expect <<-EOF && 100644 blob $EMPTY_BLOB ../a[a]/three EOF - ( cd aa && git ls-tree -r HEAD "../a[a]"; ) >actual && + ( cd aa && git ls-tree -r HEAD "../a[a]" ) >actual && test_cmp expect actual ' diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 08467982f6..dbca665da4 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -49,9 +49,9 @@ test_expect_success 'git branch HEAD should fail' ' cat >expect <<EOF $ZERO_OID $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master EOF -test_expect_success 'git branch -l d/e/f should create a branch and a log' ' +test_expect_success 'git branch --create-reflog d/e/f should create a branch and a log' ' GIT_COMMITTER_DATE="2005-05-26 23:30" \ - git branch -l d/e/f && + git -c core.logallrefupdates=false branch --create-reflog d/e/f && test_path_is_file .git/refs/heads/d/e/f && test_path_is_file .git/logs/refs/heads/d/e/f && test_cmp expect .git/logs/refs/heads/d/e/f @@ -82,7 +82,7 @@ test_expect_success 'git branch -m dumps usage' ' test_expect_success 'git branch -m m broken_symref should work' ' test_when_finished "git branch -D broken_symref" && - git branch -l m && + git branch --create-reflog m && git symbolic-ref refs/heads/broken_symref refs/heads/i_am_broken && git branch -m m broken_symref && git reflog exists refs/heads/broken_symref && @@ -90,13 +90,13 @@ test_expect_success 'git branch -m m broken_symref should work' ' ' test_expect_success 'git branch -m m m/m should work' ' - git branch -l m && + git branch --create-reflog m && git branch -m m m/m && git reflog exists refs/heads/m/m ' test_expect_success 'git branch -m n/n n should work' ' - git branch -l n/n && + git branch --create-reflog n/n && git branch -m n/n n && git reflog exists refs/heads/n ' @@ -378,9 +378,9 @@ mv .git/config-saved .git/config git config branch.s/s.dummy Hello test_expect_success 'git branch -m s/s s should work when s/t is deleted' ' - git branch -l s/s && + git branch --create-reflog s/s && git reflog exists refs/heads/s/s && - git branch -l s/t && + git branch --create-reflog s/t && git reflog exists refs/heads/s/t && git branch -d s/t && git branch -m s/s s && @@ -444,7 +444,7 @@ test_expect_success 'git branch --copy dumps usage' ' ' test_expect_success 'git branch -c d e should work' ' - git branch -l d && + git branch --create-reflog d && git reflog exists refs/heads/d && git config branch.d.dummy Hello && git branch -c d e && @@ -459,7 +459,7 @@ test_expect_success 'git branch -c d e should work' ' ' test_expect_success 'git branch --copy is a synonym for -c' ' - git branch -l copy && + git branch --create-reflog copy && git reflog exists refs/heads/copy && git config branch.copy.dummy Hello && git branch --copy copy copy-to && @@ -486,7 +486,7 @@ test_expect_success 'git branch -c ee ef should copy ee to create branch ef' ' ' test_expect_success 'git branch -c f/f g/g should work' ' - git branch -l f/f && + git branch --create-reflog f/f && git reflog exists refs/heads/f/f && git config branch.f/f.dummy Hello && git branch -c f/f g/g && @@ -497,7 +497,7 @@ test_expect_success 'git branch -c f/f g/g should work' ' ' test_expect_success 'git branch -c m2 m2 should work' ' - git branch -l m2 && + git branch --create-reflog m2 && git reflog exists refs/heads/m2 && git config branch.m2.dummy Hello && git branch -c m2 m2 && @@ -506,18 +506,18 @@ test_expect_success 'git branch -c m2 m2 should work' ' ' test_expect_success 'git branch -c zz zz/zz should fail' ' - git branch -l zz && + git branch --create-reflog zz && git reflog exists refs/heads/zz && test_must_fail git branch -c zz zz/zz ' test_expect_success 'git branch -c b/b b should fail' ' - git branch -l b/b && + git branch --create-reflog b/b && test_must_fail git branch -c b/b b ' test_expect_success 'git branch -C o/q o/p should work when o/p exists' ' - git branch -l o/q && + git branch --create-reflog o/q && git reflog exists refs/heads/o/q && git reflog exists refs/heads/o/p && git branch -C o/q o/p @@ -570,10 +570,10 @@ test_expect_success 'git branch -C master5 master5 should work when master is ch ' test_expect_success 'git branch -C ab cd should overwrite existing config for cd' ' - git branch -l cd && + git branch --create-reflog cd && git reflog exists refs/heads/cd && git config branch.cd.dummy CD && - git branch -l ab && + git branch --create-reflog ab && git reflog exists refs/heads/ab && git config branch.ab.dummy AB && git branch -C ab cd && @@ -685,7 +685,7 @@ test_expect_success 'renaming a symref is not allowed' ' ' test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for u is a symlink' ' - git branch -l u && + git branch --create-reflog u && mv .git/logs/refs/heads/u real-u && ln -s real-u .git/logs/refs/heads/u && test_must_fail git branch -m u v diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index afa27ffe2d..724b4b9bc0 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -231,9 +231,9 @@ test_expect_success 'timeout if packed-refs.lock exists' ' test_expect_success 'retry acquiring packed-refs.lock' ' LOCK=.git/packed-refs.lock && >"$LOCK" && - test_when_finished "wait; rm -f $LOCK" && + test_when_finished "wait && rm -f $LOCK" && { - ( sleep 1 ; rm -f $LOCK ) & + ( sleep 1 && rm -f $LOCK ) & } && git -c core.packedrefstimeout=3000 pack-refs --all --prune ' diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index 2d200fdf36..ac62dc0e8f 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -914,7 +914,7 @@ test_expect_success 'git notes copy --stdin' ' ${indent} ${indent}yet another note EOF - (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \ + (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) && echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) | git notes copy --stdin && git log -2 >actual && @@ -939,7 +939,7 @@ test_expect_success 'git notes copy --for-rewrite (unconfigured)' ' EOF test_commit 14th && test_commit 15th && - (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \ + (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) && echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) | git notes copy --for-rewrite=foo && git log -2 >actual && @@ -972,7 +972,7 @@ test_expect_success 'git notes copy --for-rewrite (enabled)' ' EOF test_config notes.rewriteMode overwrite && test_config notes.rewriteRef "refs/notes/*" && - (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^); \ + (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) && echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) | git notes copy --for-rewrite=foo && git log -2 >actual && @@ -1059,7 +1059,7 @@ test_expect_success 'git notes copy --for-rewrite (append two to one)' ' git notes add -f -m"append 2" HEAD^^ && test_config notes.rewriteMode concatenate && test_config notes.rewriteRef "refs/notes/*" && - (echo $(git rev-parse HEAD^) $(git rev-parse HEAD); + (echo $(git rev-parse HEAD^) $(git rev-parse HEAD) && echo $(git rev-parse HEAD^^) $(git rev-parse HEAD)) | git notes copy --for-rewrite=foo && git log -1 >actual && diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 72d9564747..3996ee0135 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -200,10 +200,10 @@ test_expect_success 'rebase -q is quiet' ' test_expect_success 'Rebase a commit that sprinkles CRs in' ' ( - echo "One" - echo "TwoQ" - echo "Three" - echo "FQur" + echo "One" && + echo "TwoQ" && + echo "Three" && + echo "FQur" && echo "Five" ) | q_to_cr >CR && git add CR && diff --git a/t/t3401-rebase-and-am-rename.sh b/t/t3401-rebase-and-am-rename.sh new file mode 100755 index 0000000000..8f832957fc --- /dev/null +++ b/t/t3401-rebase-and-am-rename.sh @@ -0,0 +1,105 @@ +#!/bin/sh + +test_description='git rebase + directory rename tests' + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + +test_expect_success 'setup testcase' ' + test_create_repo dir-rename && + ( + cd dir-rename && + + mkdir x && + test_seq 1 10 >x/a && + test_seq 11 20 >x/b && + test_seq 21 30 >x/c && + test_write_lines a b c d e f g h i >l && + git add x l && + git commit -m "Initial" && + + git branch O && + git branch A && + git branch B && + + git checkout A && + git mv x y && + git mv l letters && + git commit -m "Rename x to y, l to letters" && + + git checkout B && + echo j >>l && + test_seq 31 40 >x/d && + git add l x/d && + git commit -m "Modify l, add x/d" + ) +' + +test_expect_success 'rebase --interactive: directory rename detected' ' + ( + cd dir-rename && + + git checkout B^0 && + + set_fake_editor && + FAKE_LINES="1" git rebase --interactive A && + + git ls-files -s >out && + test_line_count = 5 out && + + test_path_is_file y/d && + test_path_is_missing x/d + ) +' + +test_expect_failure 'rebase (am): directory rename detected' ' + ( + cd dir-rename && + + git checkout B^0 && + + git rebase A && + + git ls-files -s >out && + test_line_count = 5 out && + + test_path_is_file y/d && + test_path_is_missing x/d + ) +' + +test_expect_success 'rebase --merge: directory rename detected' ' + ( + cd dir-rename && + + git checkout B^0 && + + git rebase --merge A && + + git ls-files -s >out && + test_line_count = 5 out && + + test_path_is_file y/d && + test_path_is_missing x/d + ) +' + +test_expect_failure 'am: directory rename detected' ' + ( + cd dir-rename && + + git checkout A^0 && + + git format-patch -1 B && + + git am --3way 0001*.patch && + + git ls-files -s >out && + test_line_count = 5 out && + + test_path_is_file y/d && + test_path_is_missing x/d + ) +' + +test_done diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh index 488945e007..a1ec501a87 100755 --- a/t/t3402-rebase-merge.sh +++ b/t/t3402-rebase-merge.sh @@ -25,7 +25,7 @@ test_expect_success setup ' git commit -a -m"master updates a bit more." && git checkout side && - (echo "0 $T" ; cat original) >renamed && + (echo "0 $T" && cat original) >renamed && git add renamed && git update-index --force-remove original && git commit -a -m"side renames and edits." && @@ -143,7 +143,7 @@ test_expect_success 'rebase -s funny -Xopt' ' git checkout -b test-funny master^ && test_commit funny && ( - PATH=./test-bin:$PATH + PATH=./test-bin:$PATH && git rebase -s funny -Xopt master ) && test -f funny.was.run diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 352a52e59d..640fddc9c3 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -119,6 +119,15 @@ test_expect_success 'rebase -i with exec allows git commands in subdirs' ' ) ' +test_expect_success 'rebase -i sets work tree properly' ' + test_when_finished "rm -rf subdir" && + test_when_finished "test_might_fail git rebase --abort" && + mkdir subdir && + git rebase -x "(cd subdir && git rev-parse --show-toplevel)" HEAD^ \ + >actual && + ! grep "/subdir$" actual +' + test_expect_success 'rebase -i with the exec command checks tree cleanness' ' git checkout master && set_fake_editor && @@ -264,11 +273,18 @@ test_expect_success 'retain authorship' ' ' test_expect_success 'retain authorship w/ conflicts' ' + oGIT_AUTHOR_NAME=$GIT_AUTHOR_NAME && + test_when_finished "GIT_AUTHOR_NAME=\$oGIT_AUTHOR_NAME" && + git reset --hard twerp && test_commit a conflict a conflict-a && git reset --hard twerp && - GIT_AUTHOR_NAME=AttributeMe \ + + GIT_AUTHOR_NAME=AttributeMe && + export GIT_AUTHOR_NAME && test_commit b conflict b conflict-b && + GIT_AUTHOR_NAME=$oGIT_AUTHOR_NAME && + set_fake_editor && test_must_fail git rebase -i conflict-a && echo resolved >conflict && @@ -509,7 +525,7 @@ test_expect_success 'interrupted squash works as expected' ' one=$(git rev-parse HEAD~3) && set_fake_editor && test_must_fail env FAKE_LINES="1 squash 3 2" git rebase -i HEAD~3 && - (echo one; echo two; echo four) > conflict && + test_write_lines one two four > conflict && git add conflict && test_must_fail git rebase --continue && echo resolved > conflict && @@ -523,10 +539,10 @@ test_expect_success 'interrupted squash works as expected (case 2)' ' one=$(git rev-parse HEAD~3) && set_fake_editor && test_must_fail env FAKE_LINES="3 squash 1 2" git rebase -i HEAD~3 && - (echo one; echo four) > conflict && + test_write_lines one four > conflict && git add conflict && test_must_fail git rebase --continue && - (echo one; echo two; echo four) > conflict && + test_write_lines one two four > conflict && git add conflict && test_must_fail git rebase --continue && echo resolved > conflict && @@ -553,15 +569,16 @@ test_expect_success '--continue tries to commit, even for "edit"' ' ' test_expect_success 'aborted --continue does not squash commits after "edit"' ' + test_when_finished "git rebase --abort" && old=$(git rev-parse HEAD) && test_tick && set_fake_editor && FAKE_LINES="edit 1" git rebase -i HEAD^ && echo "edited again" > file7 && git add file7 && - test_must_fail env FAKE_COMMIT_MESSAGE=" " git rebase --continue && - test $old = $(git rev-parse HEAD) && - git rebase --abort + echo all the things >>conflict && + test_must_fail git rebase --continue && + test $old = $(git rev-parse HEAD) ' test_expect_success 'auto-amend only edited commits after "edit"' ' @@ -981,7 +998,35 @@ test_expect_success 'rebase -i --root reword root commit' ' test -z "$(git show -s --format=%p HEAD^)" ' +test_expect_success 'rebase -i --root when root has untracked file confilct' ' + test_when_finished "reset_rebase" && + git checkout -b failing-root-pick A && + echo x >file2 && + git rm file1 && + git commit -m "remove file 1 add file 2" && + echo z >file1 && + set_fake_editor && + test_must_fail env FAKE_LINES="1 2" git rebase -i --root && + rm file1 && + git rebase --continue && + test "$(git log -1 --format=%B)" = "remove file 1 add file 2" && + test "$(git rev-list --count HEAD)" = 2 +' + +test_expect_success 'rebase -i --root reword root when root has untracked file conflict' ' + test_when_finished "reset_rebase" && + echo z>file1 && + set_fake_editor && + test_must_fail env FAKE_LINES="reword 1 2" \ + FAKE_COMMIT_MESSAGE="Modified A" git rebase -i --root && + rm file1 && + FAKE_COMMIT_MESSAGE="Reworded A" git rebase --continue && + test "$(git log -1 --format=%B HEAD^)" = "Reworded A" && + test "$(git rev-list --count HEAD)" = 2 +' + test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' ' + git checkout reword-root-branch && git reset --hard && git checkout conflict-branch && set_fake_editor && diff --git a/t/t3405-rebase-malformed.sh b/t/t3405-rebase-malformed.sh index cb7c6de84a..da94dddc86 100755 --- a/t/t3405-rebase-malformed.sh +++ b/t/t3405-rebase-malformed.sh @@ -77,19 +77,14 @@ test_expect_success 'rebase commit with diff in message' ' ' test_expect_success 'rebase -m commit with empty message' ' - test_must_fail git rebase -m master empty-message-merge && - git rebase --abort && - git rebase -m --allow-empty-message master empty-message-merge + git rebase -m master empty-message-merge ' test_expect_success 'rebase -i commit with empty message' ' git checkout diff-in-message && set_fake_editor && - test_must_fail env FAKE_COMMIT_MESSAGE=" " FAKE_LINES="reword 1" \ - git rebase -i HEAD^ && - git rebase --abort && - FAKE_COMMIT_MESSAGE=" " FAKE_LINES="reword 1" \ - git rebase -i --allow-empty-message HEAD^ + env FAKE_COMMIT_MESSAGE=" " FAKE_LINES="reword 1" \ + git rebase -i HEAD^ ' test_done diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index 03bf1b8a3b..65ed7db159 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -60,7 +60,7 @@ test_expect_success 'rebase --continue remembers merge strategy and options' ' EOF chmod +x test-bin/git-merge-funny && ( - PATH=./test-bin:$PATH + PATH=./test-bin:$PATH && test_must_fail git rebase -s funny -Xopt master topic ) && test -f funny.was.run && @@ -68,7 +68,39 @@ test_expect_success 'rebase --continue remembers merge strategy and options' ' echo "Resolved" >F2 && git add F2 && ( - PATH=./test-bin:$PATH + PATH=./test-bin:$PATH && + git rebase --continue + ) && + test -f funny.was.run +' + +test_expect_success 'rebase -i --continue handles merge strategy and options' ' + rm -fr .git/rebase-* && + git reset --hard commit-new-file-F2-on-topic-branch && + test_commit "commit-new-file-F3-on-topic-branch-for-dash-i" F3 32 && + test_when_finished "rm -fr test-bin funny.was.run funny.args" && + mkdir test-bin && + cat >test-bin/git-merge-funny <<-EOF && + #!$SHELL_PATH + echo "\$@" >>funny.args + case "\$1" in --opt) ;; *) exit 2 ;; esac + case "\$2" in --foo) ;; *) exit 2 ;; esac + case "\$4" in --) ;; *) exit 2 ;; esac + shift 2 && + >funny.was.run && + exec git merge-recursive "\$@" + EOF + chmod +x test-bin/git-merge-funny && + ( + PATH=./test-bin:$PATH && + test_must_fail git rebase -i -s funny -Xopt -Xfoo master topic + ) && + test -f funny.was.run && + rm funny.was.run && + echo "Resolved" >F2 && + git add F2 && + ( + PATH=./test-bin:$PATH && git rebase --continue ) && test -f funny.was.run diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh new file mode 100755 index 0000000000..bb78a6ec86 --- /dev/null +++ b/t/t3422-rebase-incompatible-options.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +test_description='test if rebase detects and aborts on incompatible options' +. ./test-lib.sh + +test_expect_success 'setup' ' + test_seq 2 9 >foo && + git add foo && + git commit -m orig && + + git branch A && + git branch B && + + git checkout A && + test_seq 1 9 >foo && + git add foo && + git commit -m A && + + git checkout B && + echo "q qfoo();" | q_to_tab >>foo && + git add foo && + git commit -m B +' + +# +# Rebase has lots of useful options like --whitepsace=fix, which are +# actually all built in terms of flags to git-am. Since neither +# --merge nor --interactive (nor any options that imply those two) use +# git-am, using them together will result in flags like --whitespace=fix +# being ignored. Make sure rebase warns the user and aborts instead. +# + +test_rebase_am_only () { + opt=$1 + shift + test_expect_success "$opt incompatible with --merge" " + git checkout B^0 && + test_must_fail git rebase $opt --merge A + " + + test_expect_success "$opt incompatible with --strategy=ours" " + git checkout B^0 && + test_must_fail git rebase $opt --strategy=ours A + " + + test_expect_success "$opt incompatible with --strategy-option=ours" " + git checkout B^0 && + test_must_fail git rebase $opt --strategy-option=ours A + " + + test_expect_success "$opt incompatible with --interactive" " + git checkout B^0 && + test_must_fail git rebase $opt --interactive A + " + + test_expect_success "$opt incompatible with --exec" " + git checkout B^0 && + test_must_fail git rebase $opt --exec 'true' A + " + +} + +test_rebase_am_only --whitespace=fix +test_rebase_am_only --ignore-whitespace +test_rebase_am_only --committer-date-is-author-date +test_rebase_am_only -C4 + +test_expect_success '--preserve-merges incompatible with --signoff' ' + git checkout B^0 && + test_must_fail git rebase --preserve-merges --signoff A +' + +test_expect_success '--preserve-merges incompatible with --rebase-merges' ' + git checkout B^0 && + test_must_fail git rebase --preserve-merges --rebase-merges A +' + +test_expect_success '--rebase-merges incompatible with --strategy' ' + git checkout B^0 && + test_must_fail git rebase --rebase-merges -s resolve A +' + +test_expect_success '--rebase-merges incompatible with --strategy-option' ' + git checkout B^0 && + test_must_fail git rebase --rebase-merges -Xignore-space-change A +' + +test_done diff --git a/t/t3423-rebase-reword.sh b/t/t3423-rebase-reword.sh new file mode 100755 index 0000000000..6963750794 --- /dev/null +++ b/t/t3423-rebase-reword.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +test_description='git rebase interactive with rewording' + +. ./test-lib.sh + +. "$TEST_DIRECTORY"/lib-rebase.sh + +test_expect_success 'setup' ' + test_commit master file-1 test && + + git checkout -b stuff && + + test_commit feature_a file-2 aaa && + test_commit feature_b file-2 ddd +' + +test_expect_success 'reword without issues functions as intended' ' + test_when_finished "reset_rebase" && + + git checkout stuff^0 && + + set_fake_editor && + FAKE_LINES="pick 1 reword 2" FAKE_COMMIT_MESSAGE="feature_b_reworded" \ + git rebase -i -v master && + + test "$(git log -1 --format=%B)" = "feature_b_reworded" && + test $(git rev-list --count HEAD) = 3 +' + +test_expect_success 'reword after a conflict preserves commit' ' + test_when_finished "reset_rebase" && + + git checkout stuff^0 && + + set_fake_editor && + test_must_fail env FAKE_LINES="reword 2" \ + git rebase -i -v master && + + git checkout --theirs file-2 && + git add file-2 && + FAKE_COMMIT_MESSAGE="feature_b_reworded" git rebase --continue && + + test "$(git log -1 --format=%B)" = "feature_b_reworded" && + test $(git rev-list --count HEAD) = 2 +' + +test_done diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index 78f7c99580..9e62297274 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -329,4 +329,38 @@ test_expect_success 'labels that are object IDs are rewritten' ' ! grep "^label $third$" .git/ORIGINAL-TODO ' +test_expect_success 'octopus merges' ' + git checkout -b three && + test_commit before-octopus && + test_commit three && + git checkout -b two HEAD^ && + test_commit two && + git checkout -b one HEAD^ && + test_commit one && + test_tick && + (GIT_AUTHOR_NAME="Hank" GIT_AUTHOR_EMAIL="hank@sea.world" \ + git merge -m "Tüntenfüsch" two three) && + + : fast forward if possible && + before="$(git rev-parse --verify HEAD)" && + test_tick && + git rebase -i -r HEAD^^ && + test_cmp_rev HEAD $before && + + test_tick && + git rebase -i --force -r HEAD^^ && + test "Hank" = "$(git show -s --format=%an HEAD)" && + test "$before" != $(git rev-parse HEAD) && + test_cmp_graph HEAD^^.. <<-\EOF + *-. Tüntenfüsch + |\ \ + | | * three + | * | two + | |/ + * | one + |/ + o before-octopus + EOF +' + test_done diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh index b42cd66d3a..3505b6aa14 100755 --- a/t/t3510-cherry-pick-sequence.sh +++ b/t/t3510-cherry-pick-sequence.sh @@ -480,11 +480,16 @@ test_expect_success 'malformed instruction sheet 2' ' test_expect_code 128 git cherry-pick --continue ' -test_expect_success 'empty commit set' ' +test_expect_success 'empty commit set (no commits to walk)' ' pristine_detach initial && test_expect_code 128 git cherry-pick base..base ' +test_expect_success 'empty commit set (culled during walk)' ' + pristine_detach initial && + test_expect_code 128 git cherry-pick -2 --author=no.such.author base +' + test_expect_success 'malformed instruction sheet 3' ' pristine_detach initial && test_expect_code 1 git cherry-pick base..anotherpick && diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 07af05d7ae..618750167a 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -156,9 +156,9 @@ test_expect_success 'git add with filemode=0, symlinks=0, and unmerged entries' test_expect_success 'git add with filemode=0, symlinks=0 prefers stage 2 over stage 1' ' git rm --cached -f file symlink && ( - echo "100644 $(git hash-object -w stage1) 1 file" - echo "100755 $(git hash-object -w stage2) 2 file" - echo "100644 $(printf 1 | git hash-object -w -t blob --stdin) 1 symlink" + echo "100644 $(git hash-object -w stage1) 1 file" && + echo "100755 $(git hash-object -w stage2) 2 file" && + echo "100644 $(printf 1 | git hash-object -w -t blob --stdin) 1 symlink" && echo "120000 $(printf 2 | git hash-object -w -t blob --stdin) 2 symlink" ) | git update-index --index-info && git config core.filemode 0 && @@ -265,7 +265,7 @@ test_expect_success 'git add to resolve conflicts on otherwise ignored path' ' git reset --hard && H=$(git rev-parse :1/2/a) && ( - echo "100644 $H 1 track-this" + echo "100644 $H 1 track-this" && echo "100644 $H 3 track-this" ) | git update-index --index-info && echo track-this >>.gitignore && diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b170fb02b8..609fbfdc31 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -46,13 +46,13 @@ test_expect_success 'setup expected' ' ' test_expect_success 'diff works (initial)' ' - (echo d; echo 1) | git add -i >output && + test_write_lines d 1 | git add -i >output && sed -ne "/new file/,/content/p" <output >diff && diff_cmp expected diff ' test_expect_success 'revert works (initial)' ' git add file && - (echo r; echo 1) | git add -i && + test_write_lines r 1 | git add -i && git ls-files >output && ! grep . output ' @@ -83,13 +83,13 @@ test_expect_success 'setup expected' ' ' test_expect_success 'diff works (commit)' ' - (echo d; echo 1) | git add -i >output && + test_write_lines d 1 | git add -i >output && sed -ne "/^index/,/content/p" <output >diff && diff_cmp expected diff ' test_expect_success 'revert works (commit)' ' git add file && - (echo r; echo 1) | git add -i && + test_write_lines r 1 | git add -i && git add -i </dev/null >output && grep "unchanged *+3/-0 file" output ' @@ -102,7 +102,7 @@ test_expect_success 'setup expected' ' test_expect_success 'dummy edit works' ' test_set_editor : && - (echo e; echo a) | git add -p && + test_write_lines e a | git add -p && git diff > diff && diff_cmp expected diff ' @@ -127,7 +127,7 @@ test_expect_success 'setup fake editor' ' test_expect_success 'bad edit rejected' ' git reset && - (echo e; echo n; echo d) | git add -p >output && + test_write_lines e n d | git add -p >output && grep "hunk does not apply" output ' @@ -140,7 +140,7 @@ test_expect_success 'setup patch' ' test_expect_success 'garbage edit rejected' ' git reset && - (echo e; echo n; echo d) | git add -p >output && + test_write_lines e n d | git add -p >output && grep "hunk does not apply" output ' @@ -170,7 +170,50 @@ test_expect_success 'setup expected' ' ' test_expect_success 'real edit works' ' - (echo e; echo n; echo d) | git add -p && + test_write_lines e n d | git add -p && + git diff >output && + diff_cmp expected output +' + +test_expect_success 'setup file' ' + test_write_lines a "" b "" c >file && + git add file && + test_write_lines a "" d "" c >file +' + +test_expect_success 'setup patch' ' + SP=" " && + NULL="" && + cat >patch <<-EOF + @@ -1,4 +1,4 @@ + a + $NULL + -b + +f + $SP + c + EOF +' + +test_expect_success 'setup expected' ' + cat >expected <<-EOF + diff --git a/file b/file + index b5dd6c9..f910ae9 100644 + --- a/file + +++ b/file + @@ -1,5 +1,5 @@ + a + $SP + -f + +d + $SP + c + EOF +' + +test_expect_success 'edit can strip spaces from empty context lines' ' + test_write_lines e n q | git add -p 2>error && + test_must_be_empty error && git diff >output && diff_cmp expected output ' diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh index 83744f8c93..9546b6f8a4 100755 --- a/t/t3904-stash-patch.sh +++ b/t/t3904-stash-patch.sh @@ -29,14 +29,14 @@ test_expect_success 'setup' ' test_expect_success 'saying "n" does nothing' ' set_state HEAD HEADfile_work HEADfile_index && set_state dir/foo work index && - (echo n; echo n; echo n) | test_must_fail git stash save -p && + test_write_lines n n n | test_must_fail git stash save -p && verify_state HEAD HEADfile_work HEADfile_index && verify_saved_state bar && verify_state dir/foo work index ' test_expect_success 'git stash -p' ' - (echo y; echo n; echo y) | git stash save -p && + test_write_lines y n y | git stash save -p && verify_state HEAD committed HEADfile_index && verify_saved_state bar && verify_state dir/foo head index && @@ -51,7 +51,7 @@ test_expect_success 'git stash -p --no-keep-index' ' set_state HEAD HEADfile_work HEADfile_index && set_state bar bar_work bar_index && set_state dir/foo work index && - (echo y; echo n; echo y) | git stash save -p --no-keep-index && + test_write_lines y n y | git stash save -p --no-keep-index && verify_state HEAD committed committed && verify_state bar bar_work dummy && verify_state dir/foo head head && @@ -66,7 +66,7 @@ test_expect_success 'git stash --no-keep-index -p' ' set_state HEAD HEADfile_work HEADfile_index && set_state bar bar_work bar_index && set_state dir/foo work index && - (echo y; echo n; echo y) | git stash save --no-keep-index -p && + test_write_lines y n y | git stash save --no-keep-index -p && verify_state HEAD committed committed && verify_state dir/foo head head && verify_state bar bar_work dummy && diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index bf4030371a..c16486a9d4 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -180,7 +180,7 @@ test_expect_success 'setup for many rename source candidates' ' git add "path??" && test_tick && git commit -m "hundred" && - (cat path1; echo new) >new-path && + (cat path1 && echo new) >new-path && echo old >>path1 && git add new-path path1 && git diff -l 4 -C -C --cached --name-status >actual 2>actual.err && diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index 35b35a81c8..b7f25071cf 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -111,10 +111,10 @@ test_expect_success 'diff-tree -r with wildcard' ' test_expect_success 'setup submodules' ' test_tick && git init submod && - ( cd submod && test_commit first; ) && + ( cd submod && test_commit first ) && git add submod && git commit -m first && - ( cd submod && test_commit second; ) && + ( cd submod && test_commit second ) && git add submod && git commit -m second ' diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index cf0f3a1ee7..108c012a3a 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -139,11 +139,13 @@ test_expect_success SYMLINKS 'setup symlinks with attributes' ' test_expect_success SYMLINKS 'symlinks do not respect userdiff config by path' ' cat >expect <<-\EOF && diff --git a/file.bin b/file.bin - index e69de29..d95f3ad 100644 - Binary files a/file.bin and b/file.bin differ + new file mode 100644 + index 0000000..d95f3ad + Binary files /dev/null and b/file.bin differ diff --git a/link.bin b/link.bin - index e69de29..dce41ec 120000 - --- a/link.bin + new file mode 120000 + index 0000000..dce41ec + --- /dev/null +++ b/link.bin @@ -0,0 +1 @@ +file.bin diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh index 0a8af76aab..6579c81216 100755 --- a/t/t4012-diff-binary.sh +++ b/t/t4012-diff-binary.sh @@ -102,10 +102,8 @@ test_expect_success 'apply binary patch' ' test_expect_success 'diff --no-index with binary creation' ' echo Q | q_to_nul >binary && - (: hide error code from diff, which just indicates differences - git diff --binary --no-index /dev/null binary >current || - true - ) && + # hide error code from diff, which just indicates differences + test_might_fail git diff --binary --no-index /dev/null binary >current && rm binary && git apply --binary <current && echo Q >expected && diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 028d5507a6..53880da7bb 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1554,13 +1554,15 @@ test_expect_success 'format-patch -o overrides format.outputDirectory' ' test_expect_success 'format-patch --base' ' git checkout side && - git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual && + git format-patch --stdout --base=HEAD~3 -1 | tail -n 7 >actual1 && + git format-patch --stdout --base=HEAD~3 HEAD~.. | tail -n 7 >actual2 && echo >expected && echo "base-commit: $(git rev-parse HEAD~3)" >>expected && echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected && echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected && signature >> expected && - test_cmp expected actual + test_cmp expected actual1 && + test_cmp expected actual2 ' test_expect_success 'format-patch --base errors out when base commit is in revision list' ' diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 17df491a3a..41facf7abf 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -1223,7 +1223,7 @@ test_expect_success 'plain moved code, inside file' ' test_cmp expected actual ' -test_expect_success 'detect permutations inside moved code -- dimmed_zebra' ' +test_expect_success 'detect blocks of moved code' ' git reset --hard && cat <<-\EOF >lines.txt && long line 1 @@ -1271,9 +1271,52 @@ test_expect_success 'detect permutations inside moved code -- dimmed_zebra' ' test_config color.diff.newMovedDimmed "normal cyan" && test_config color.diff.oldMovedAlternativeDimmed "normal blue" && test_config color.diff.newMovedAlternativeDimmed "normal yellow" && - git diff HEAD --no-renames --color-moved=dimmed_zebra --color | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --no-renames --color-moved=blocks --color >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && + cat <<-\EOF >expected && + <BOLD>diff --git a/lines.txt b/lines.txt<RESET> + <BOLD>--- a/lines.txt<RESET> + <BOLD>+++ b/lines.txt<RESET> + <CYAN>@@ -1,16 +1,16 @@<RESET> + <MAGENTA>-long line 1<RESET> + <MAGENTA>-long line 2<RESET> + <MAGENTA>-long line 3<RESET> + line 4<RESET> + line 5<RESET> + line 6<RESET> + line 7<RESET> + line 8<RESET> + line 9<RESET> + <CYAN>+<RESET><CYAN>long line 1<RESET> + <CYAN>+<RESET><CYAN>long line 2<RESET> + <CYAN>+<RESET><CYAN>long line 3<RESET> + <CYAN>+<RESET><CYAN>long line 14<RESET> + <CYAN>+<RESET><CYAN>long line 15<RESET> + <CYAN>+<RESET><CYAN>long line 16<RESET> + line 10<RESET> + line 11<RESET> + line 12<RESET> + line 13<RESET> + <MAGENTA>-long line 14<RESET> + <MAGENTA>-long line 15<RESET> + <MAGENTA>-long line 16<RESET> + EOF + test_cmp expected actual + +' + +test_expect_success 'detect permutations inside moved code -- dimmed_zebra' ' + # reuse setup from test before! + test_config color.diff.oldMoved "magenta" && + test_config color.diff.newMoved "cyan" && + test_config color.diff.oldMovedAlternative "blue" && + test_config color.diff.newMovedAlternative "yellow" && + test_config color.diff.oldMovedDimmed "normal magenta" && + test_config color.diff.newMovedDimmed "normal cyan" && + test_config color.diff.oldMovedAlternativeDimmed "normal blue" && + test_config color.diff.newMovedAlternativeDimmed "normal yellow" && + git diff HEAD --no-renames --color-moved=dimmed_zebra --color >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat <<-\EOF >expected && <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> @@ -1315,9 +1358,8 @@ test_expect_success 'cmd option assumes configured colored-moved' ' test_config color.diff.oldMovedAlternativeDimmed "normal blue" && test_config color.diff.newMovedAlternativeDimmed "normal yellow" && test_config diff.colorMoved zebra && - git diff HEAD --no-renames --color-moved --color | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --no-renames --color-moved --color >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat <<-\EOF >expected && <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> @@ -1395,9 +1437,8 @@ test_expect_success 'move detection ignoring whitespace ' ' line 4 line 5 EOF - git diff HEAD --no-renames --color-moved --color | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --no-renames --color-moved --color >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat <<-\EOF >expected && <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> @@ -1419,9 +1460,9 @@ test_expect_success 'move detection ignoring whitespace ' ' EOF test_cmp expected actual && - git diff HEAD --no-renames -w --color-moved --color | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --no-renames --color-moved --color \ + --color-moved-ws=ignore-all-space >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat <<-\EOF >expected && <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> @@ -1459,9 +1500,8 @@ test_expect_success 'move detection ignoring whitespace changes' ' line 5 EOF - git diff HEAD --no-renames --color-moved --color | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --no-renames --color-moved --color >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat <<-\EOF >expected && <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> @@ -1483,9 +1523,9 @@ test_expect_success 'move detection ignoring whitespace changes' ' EOF test_cmp expected actual && - git diff HEAD --no-renames -b --color-moved --color | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --no-renames --color-moved --color \ + --color-moved-ws=ignore-space-change >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat <<-\EOF >expected && <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> @@ -1526,9 +1566,8 @@ test_expect_success 'move detection ignoring whitespace at eol' ' # avoid cluttering the output with complaints about our eol whitespace test_config core.whitespace -blank-at-eol && - git diff HEAD --no-renames --color-moved --color | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --no-renames --color-moved --color >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat <<-\EOF >expected && <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> @@ -1550,9 +1589,9 @@ test_expect_success 'move detection ignoring whitespace at eol' ' EOF test_cmp expected actual && - git diff HEAD --no-renames --ignore-space-at-eol --color-moved --color | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --no-renames --color-moved --color \ + --color-moved-ws=ignore-space-at-eol >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat <<-\EOF >expected && <BOLD>diff --git a/lines.txt b/lines.txt<RESET> <BOLD>--- a/lines.txt<RESET> @@ -1597,9 +1636,8 @@ test_expect_success '--color-moved block at end of diff output respects MIN_ALNU irrelevant_line EOF - git diff HEAD --color-moved=zebra --color --no-renames | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --color-moved=zebra --color --no-renames >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat >expected <<-\EOF && <BOLD>diff --git a/bar b/bar<RESET> <BOLD>--- a/bar<RESET> @@ -1636,9 +1674,8 @@ test_expect_success '--color-moved respects MIN_ALNUM_COUNT' ' nineteen chars 456789 EOF - git diff HEAD --color-moved=zebra --color --no-renames | - grep -v "index" | - test_decode_color >actual && + git diff HEAD --color-moved=zebra --color --no-renames >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat >expected <<-\EOF && <BOLD>diff --git a/bar b/bar<RESET> <BOLD>--- a/bar<RESET> @@ -1679,7 +1716,8 @@ test_expect_success '--color-moved treats adjacent blocks as separate for MIN_AL 7charsA EOF - git diff HEAD --color-moved=zebra --color --no-renames | grep -v "index" | test_decode_color >actual && + git diff HEAD --color-moved=zebra --color --no-renames >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && cat >expected <<-\EOF && <BOLD>diff --git a/bar b/bar<RESET> <BOLD>--- a/bar<RESET> @@ -1722,7 +1760,146 @@ test_expect_success 'move detection with submodules' ' # nor did we mess with it another way git diff --submodule=diff --color | test_decode_color >expect && - test_cmp expect decoded_actual + test_cmp expect decoded_actual && + rm -rf bananas && + git submodule deinit bananas +' + +test_expect_success 'only move detection ignores white spaces' ' + git reset --hard && + q_to_tab <<-\EOF >text.txt && + a long line to exceed per-line minimum + another long line to exceed per-line minimum + original file + EOF + git add text.txt && + git commit -m "add text" && + q_to_tab <<-\EOF >text.txt && + Qa long line to exceed per-line minimum + Qanother long line to exceed per-line minimum + new file + EOF + + # Make sure we get a different diff using -w + git diff --color --color-moved -w >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && + q_to_tab <<-\EOF >expected && + <BOLD>diff --git a/text.txt b/text.txt<RESET> + <BOLD>--- a/text.txt<RESET> + <BOLD>+++ b/text.txt<RESET> + <CYAN>@@ -1,3 +1,3 @@<RESET> + Qa long line to exceed per-line minimum<RESET> + Qanother long line to exceed per-line minimum<RESET> + <RED>-original file<RESET> + <GREEN>+<RESET><GREEN>new file<RESET> + EOF + test_cmp expected actual && + + # And now ignoring white space only in the move detection + git diff --color --color-moved \ + --color-moved-ws=ignore-all-space,ignore-space-change,ignore-space-at-eol >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && + q_to_tab <<-\EOF >expected && + <BOLD>diff --git a/text.txt b/text.txt<RESET> + <BOLD>--- a/text.txt<RESET> + <BOLD>+++ b/text.txt<RESET> + <CYAN>@@ -1,3 +1,3 @@<RESET> + <BOLD;MAGENTA>-a long line to exceed per-line minimum<RESET> + <BOLD;MAGENTA>-another long line to exceed per-line minimum<RESET> + <RED>-original file<RESET> + <BOLD;YELLOW>+<RESET>Q<BOLD;YELLOW>a long line to exceed per-line minimum<RESET> + <BOLD;YELLOW>+<RESET>Q<BOLD;YELLOW>another long line to exceed per-line minimum<RESET> + <GREEN>+<RESET><GREEN>new file<RESET> + EOF + test_cmp expected actual +' + +test_expect_success 'compare whitespace delta across moved blocks' ' + + git reset --hard && + q_to_tab <<-\EOF >text.txt && + QIndented + QText across + Qsome lines + QBut! <- this stands out + QAdjusting with + QQdifferent starting + Qwhite spaces + QAnother outlier + QQQIndented + QQQText across + QQQfive lines + QQQthat has similar lines + QQQto previous blocks, but with different indent + QQQYetQAnotherQoutlierQ + EOF + + git add text.txt && + git commit -m "add text.txt" && + + q_to_tab <<-\EOF >text.txt && + QQIndented + QQText across + QQsome lines + QQQBut! <- this stands out + Adjusting with + Qdifferent starting + white spaces + AnotherQoutlier + QQIndented + QQText across + QQfive lines + QQthat has similar lines + QQto previous blocks, but with different indent + QQYetQAnotherQoutlier + EOF + + git diff --color --color-moved --color-moved-ws=allow-indentation-change >actual.raw && + grep -v "index" actual.raw | test_decode_color >actual && + + q_to_tab <<-\EOF >expected && + <BOLD>diff --git a/text.txt b/text.txt<RESET> + <BOLD>--- a/text.txt<RESET> + <BOLD>+++ b/text.txt<RESET> + <CYAN>@@ -1,14 +1,14 @@<RESET> + <BOLD;MAGENTA>-QIndented<RESET> + <BOLD;MAGENTA>-QText across<RESET> + <BOLD;MAGENTA>-Qsome lines<RESET> + <RED>-QBut! <- this stands out<RESET> + <BOLD;MAGENTA>-QAdjusting with<RESET> + <BOLD;MAGENTA>-QQdifferent starting<RESET> + <BOLD;MAGENTA>-Qwhite spaces<RESET> + <RED>-QAnother outlier<RESET> + <BOLD;MAGENTA>-QQQIndented<RESET> + <BOLD;MAGENTA>-QQQText across<RESET> + <BOLD;MAGENTA>-QQQfive lines<RESET> + <BOLD;MAGENTA>-QQQthat has similar lines<RESET> + <BOLD;MAGENTA>-QQQto previous blocks, but with different indent<RESET> + <RED>-QQQYetQAnotherQoutlierQ<RESET> + <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET> + <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET> + <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>some lines<RESET> + <GREEN>+<RESET>QQQ<GREEN>But! <- this stands out<RESET> + <BOLD;CYAN>+<RESET><BOLD;CYAN>Adjusting with<RESET> + <BOLD;CYAN>+<RESET>Q<BOLD;CYAN>different starting<RESET> + <BOLD;CYAN>+<RESET><BOLD;CYAN>white spaces<RESET> + <GREEN>+<RESET><GREEN>AnotherQoutlier<RESET> + <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Indented<RESET> + <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>Text across<RESET> + <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>five lines<RESET> + <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>that has similar lines<RESET> + <BOLD;CYAN>+<RESET>QQ<BOLD;CYAN>to previous blocks, but with different indent<RESET> + <GREEN>+<RESET>QQ<GREEN>YetQAnotherQoutlier<RESET> + EOF + + test_cmp expected actual +' + +test_expect_success 'compare whitespace delta incompatible with other space options' ' + test_must_fail git diff \ + --color-moved-ws=allow-indentation-change,ignore-all-space \ + 2>err && + test_i18ngrep allow-indentation-change err ' test_done diff --git a/t/t4018/php-abstract-class b/t/t4018/php-abstract-class new file mode 100644 index 0000000000..5213e12494 --- /dev/null +++ b/t/t4018/php-abstract-class @@ -0,0 +1,4 @@ +abstract class RIGHT +{ + const FOO = 'ChangeMe'; +} diff --git a/t/t4018/php-class b/t/t4018/php-class new file mode 100644 index 0000000000..7785b6303c --- /dev/null +++ b/t/t4018/php-class @@ -0,0 +1,4 @@ +class RIGHT +{ + const FOO = 'ChangeMe'; +} diff --git a/t/t4018/php-final-class b/t/t4018/php-final-class new file mode 100644 index 0000000000..69f5710552 --- /dev/null +++ b/t/t4018/php-final-class @@ -0,0 +1,4 @@ +final class RIGHT +{ + const FOO = 'ChangeMe'; +} diff --git a/t/t4018/php-function b/t/t4018/php-function new file mode 100644 index 0000000000..35717c51c3 --- /dev/null +++ b/t/t4018/php-function @@ -0,0 +1,4 @@ +function RIGHT() +{ + return 'ChangeMe'; +} diff --git a/t/t4018/php-interface b/t/t4018/php-interface new file mode 100644 index 0000000000..86b49ad5d9 --- /dev/null +++ b/t/t4018/php-interface @@ -0,0 +1,4 @@ +interface RIGHT +{ + public function foo($ChangeMe); +} diff --git a/t/t4018/php-method b/t/t4018/php-method new file mode 100644 index 0000000000..03af1a6d9d --- /dev/null +++ b/t/t4018/php-method @@ -0,0 +1,7 @@ +class Klass +{ + public static function RIGHT() + { + return 'ChangeMe'; + } +} diff --git a/t/t4018/php-trait b/t/t4018/php-trait new file mode 100644 index 0000000000..65b8c82a61 --- /dev/null +++ b/t/t4018/php-trait @@ -0,0 +1,7 @@ +trait RIGHT +{ + public function foo($ChangeMe) + { + return 'foo'; + } +} diff --git a/t/t4024-diff-optimize-common.sh b/t/t4024-diff-optimize-common.sh index 7e76018296..6b44ce1493 100755 --- a/t/t4024-diff-optimize-common.sh +++ b/t/t4024-diff-optimize-common.sh @@ -127,17 +127,17 @@ test_expect_success setup ' for n in $sample do - ( zs $n ; echo a ) >file-a$n && - ( echo b; zs $n; echo ) >file-b$n && - ( printf c; zs $n ) >file-c$n && - ( echo d; zs $n ) >file-d$n && + ( zs $n && echo a ) >file-a$n && + ( echo b && zs $n && echo ) >file-b$n && + ( printf c && zs $n ) >file-c$n && + ( echo d && zs $n ) >file-d$n && git add file-a$n file-b$n file-c$n file-d$n && - ( zs $n ; echo A ) >file-a$n && - ( echo B; zs $n; echo ) >file-b$n && - ( printf C; zs $n ) >file-c$n && - ( echo D; zs $n ) >file-d$n && + ( zs $n && echo A ) >file-a$n && + ( echo B && zs $n && echo ) >file-b$n && + ( printf C && zs $n ) >file-c$n && + ( echo D && zs $n ) >file-d$n && expect_pattern $n || return 1 diff --git a/t/t4025-hunk-header.sh b/t/t4025-hunk-header.sh index 7a3dbc1ea2..fa44e78869 100755 --- a/t/t4025-hunk-header.sh +++ b/t/t4025-hunk-header.sh @@ -12,12 +12,12 @@ NS="$N$N$N$N$N$N$N$N$N$N$N$N$N" test_expect_success setup ' ( - echo "A $NS" + echo "A $NS" && for c in B C D E F G H I J K do echo " $c" - done - echo "L $NS" + done && + echo "L $NS" && for c in M N O P Q R S T U V do echo " $c" @@ -34,7 +34,7 @@ test_expect_success 'hunk header truncation with an overly long line' ' git diff | sed -n -e "s/^.*@@//p" >actual && ( - echo " A $N$N$N$N$N$N$N$N$N2" + echo " A $N$N$N$N$N$N$N$N$N2" && echo " L $N$N$N$N$N$N$N$N$N1" ) >expected && test_cmp actual expected diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh index 058ee0829d..4e3499ef84 100755 --- a/t/t4041-diff-submodule-option.sh +++ b/t/t4041-diff-submodule-option.sh @@ -498,7 +498,7 @@ test_expect_success 'given commit --submodule=short' ' test_expect_success 'setup .git file for sm2' ' (cd sm2 && REAL="$(pwd)/../.real" && - mv .git "$REAL" + mv .git "$REAL" && echo "gitdir: $REAL" >.git) ' @@ -527,7 +527,7 @@ test_expect_success 'diff --submodule with objects referenced by alternates' ' git commit -m "sub a" ) && (cd sub_alt && - sha1_before=$(git rev-parse --short HEAD) + sha1_before=$(git rev-parse --short HEAD) && echo b >b && git add b && git commit -m b && diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh index 4b168d0ed7..0eba4620f0 100755 --- a/t/t4060-diff-submodule-option-diff-format.sh +++ b/t/t4060-diff-submodule-option-diff-format.sh @@ -721,7 +721,7 @@ test_expect_success 'given commit' ' test_expect_success 'setup .git file for sm2' ' (cd sm2 && REAL="$(pwd)/../.real" && - mv .git "$REAL" + mv .git "$REAL" && echo "gitdir: $REAL" >.git) ' diff --git a/t/t4121-apply-diffs.sh b/t/t4121-apply-diffs.sh index aff551a1d7..66368effd5 100755 --- a/t/t4121-apply-diffs.sh +++ b/t/t4121-apply-diffs.sh @@ -27,6 +27,6 @@ test_expect_success 'setup' \ test_expect_success \ 'check if contextually independent diffs for the same file apply' \ - '( git diff test~2 test~1; git diff test~1 test~0 )| git apply' + '( git diff test~2 test~1 && git diff test~1 test~0 )| git apply' test_done diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh index 62f335b2d9..4c8f3b8e1b 100755 --- a/t/t4208-log-magic-pathspec.sh +++ b/t/t4208-log-magic-pathspec.sh @@ -25,6 +25,32 @@ test_expect_success '"git log :/a -- " should not be ambiguous' ' git log :/a -- ' +test_expect_success '"git log :/detached -- " should find a commit only in HEAD' ' + test_when_finished "git checkout master" && + git checkout --detach && + # Must manually call `test_tick` instead of using `test_commit`, + # because the latter additionally creates a tag, which would make + # the commit reachable not only via HEAD. + test_tick && + git commit --allow-empty -m detached && + test_tick && + git commit --allow-empty -m something-else && + git log :/detached -- +' + +test_expect_success '"git log :/detached -- " should not find an orphaned commit' ' + test_must_fail git log :/detached -- +' + +test_expect_success '"git log :/detached -- " should find HEAD only of own worktree' ' + git worktree add other-tree HEAD && + git -C other-tree checkout --detach && + test_tick && + git -C other-tree commit --allow-empty -m other-detached && + git -C other-tree log :/other-detached -- && + test_must_fail git log :/other-detached -- +' + test_expect_success '"git log -- :/a" should not be ambiguous' ' git log -- :/a ' diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index d0377fae5c..436b13ad21 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -60,7 +60,6 @@ test_bad_opts "-L 1:nonexistent" "There is no path" test_bad_opts "-L 1:simple" "There is no path" test_bad_opts "-L '/foo:b.c'" "argument not .start,end:file" test_bad_opts "-L 1000:b.c" "has only.*lines" -test_bad_opts "-L 1,1000:b.c" "has only.*lines" test_bad_opts "-L :b.c" "argument not .start,end:file" test_bad_opts "-L :foo:b.c" "no match" @@ -86,12 +85,12 @@ test_expect_success '-L ,Y (Y == nlines)' ' test_expect_success '-L ,Y (Y == nlines + 1)' ' n=$(expr $(wc -l <b.c) + 1) && - test_must_fail git log -L ,$n:b.c + git log -L ,$n:b.c ' test_expect_success '-L ,Y (Y == nlines + 2)' ' n=$(expr $(wc -l <b.c) + 2) && - test_must_fail git log -L ,$n:b.c + git log -L ,$n:b.c ' test_expect_success '-L with --first-parent and a merge' ' diff --git a/t/t4254-am-corrupt.sh b/t/t4254-am-corrupt.sh index 168739c721..fd3bdbfe2c 100755 --- a/t/t4254-am-corrupt.sh +++ b/t/t4254-am-corrupt.sh @@ -25,7 +25,7 @@ test_expect_success setup ' # fatal: unable to write file '(null)' mode 100644: Bad address # Also, it had the unwanted side-effect of deleting f. test_expect_success 'try to apply corrupted patch' ' - test_must_fail git am bad-patch.diff 2>actual + test_must_fail git -c advice.amWorkDir=false am bad-patch.diff 2>actual ' test_expect_success 'compare diagnostic; ensure file is still here' ' diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 2336d09dcc..6c620cd540 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -191,7 +191,7 @@ test_expect_success 'survive missing objects/pack directory' ' mkdir missing-pack && cd missing-pack && git init && - GOP=.git/objects/pack + GOP=.git/objects/pack && rm -fr $GOP && git index-pack --stdin --keep=test <../test-3-${packname_3}.pack && test -f $GOP/pack-${packname_3}.pack && diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index bb9b8bb309..91d51b35f9 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -237,7 +237,7 @@ test_expect_success 'running index-pack in the object store' ' rm -f .git/objects/pack/* && cp test-1-${pack1}.pack .git/objects/pack/pack-${pack1}.pack && ( - cd .git/objects/pack + cd .git/objects/pack && git index-pack pack-${pack1}.pack ) && test -f .git/objects/pack/pack-${pack1}.idx diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh index 1b0acc383b..6710c8bc8c 100755 --- a/t/t5317-pack-objects-filter-objects.sh +++ b/t/t5317-pack-objects-filter-objects.sh @@ -160,6 +160,22 @@ test_expect_success 'verify blob:limit=1k' ' test_cmp observed expected ' +test_expect_success 'verify explicitly specifying oversized blob in input' ' + git -C r2 ls-files -s large.1000 large.10000 \ + | awk -f print_2.awk \ + | sort >expected && + git -C r2 pack-objects --rev --stdout --filter=blob:limit=1k >filter.pack <<-EOF && + HEAD + $(git -C r2 rev-parse HEAD:large.10000) + EOF + git -C r2 index-pack ../filter.pack && + git -C r2 verify-pack -v ../filter.pack \ + | grep blob \ + | awk -f print_1.awk \ + | sort >observed && + test_cmp observed expected +' + test_expect_success 'verify blob:limit=1m' ' git -C r2 ls-files -s large.1000 large.10000 \ | awk -f print_2.awk \ diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index a380419b65..5947de3d24 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -11,6 +11,11 @@ test_expect_success 'setup full repo' ' objdir=".git/objects" ' +test_expect_success 'verify graph with no graph file' ' + cd "$TRASH_DIRECTORY/full" && + git commit-graph verify +' + test_expect_success 'write graph with no packs' ' cd "$TRASH_DIRECTORY/full" && git commit-graph write --object-dir . && @@ -28,8 +33,8 @@ test_expect_success 'create commits and repack' ' ' graph_git_two_modes() { - git -c core.graph=true $1 >output - git -c core.graph=false $1 >expect + git -c core.commitGraph=true $1 >output + git -c core.commitGraph=false $1 >expect test_cmp output expect } @@ -200,6 +205,16 @@ test_expect_success 'build graph from commits with append' ' graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1 graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2 +test_expect_success 'build graph using --reachable' ' + cd "$TRASH_DIRECTORY/full" && + git commit-graph write --reachable && + test_path_is_file $objdir/info/commit-graph && + graph_read_expect "11" "large_edges" +' + +graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1 +graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2 + test_expect_success 'setup bare repo' ' cd "$TRASH_DIRECTORY" && git clone --bare --no-local full bare && @@ -221,4 +236,199 @@ test_expect_success 'write graph in bare repo' ' graph_git_behavior 'bare repo with graph, commit 8 vs merge 1' bare commits/8 merge/1 graph_git_behavior 'bare repo with graph, commit 8 vs merge 2' bare commits/8 merge/2 +test_expect_success 'perform fast-forward merge in full repo' ' + cd "$TRASH_DIRECTORY/full" && + git checkout -b merge-5-to-8 commits/5 && + git merge commits/8 && + git show-ref -s merge-5-to-8 >output && + git show-ref -s commits/8 >expect && + test_cmp expect output +' + +test_expect_success 'check that gc computes commit-graph' ' + cd "$TRASH_DIRECTORY/full" && + git commit --allow-empty -m "blank" && + git commit-graph write --reachable && + cp $objdir/info/commit-graph commit-graph-before-gc && + git reset --hard HEAD~1 && + git config gc.writeCommitGraph true && + git gc && + cp $objdir/info/commit-graph commit-graph-after-gc && + ! test_cmp commit-graph-before-gc commit-graph-after-gc && + git commit-graph write --reachable && + test_cmp commit-graph-after-gc $objdir/info/commit-graph +' + +# the verify tests below expect the commit-graph to contain +# exactly the commits reachable from the commits/8 branch. +# If the file changes the set of commits in the list, then the +# offsets into the binary file will result in different edits +# and the tests will likely break. + +test_expect_success 'git commit-graph verify' ' + cd "$TRASH_DIRECTORY/full" && + git rev-parse commits/8 | git commit-graph write --stdin-commits && + git commit-graph verify >output +' + +NUM_COMMITS=9 +NUM_OCTOPUS_EDGES=2 +HASH_LEN=20 +GRAPH_BYTE_VERSION=4 +GRAPH_BYTE_HASH=5 +GRAPH_BYTE_CHUNK_COUNT=6 +GRAPH_CHUNK_LOOKUP_OFFSET=8 +GRAPH_CHUNK_LOOKUP_WIDTH=12 +GRAPH_CHUNK_LOOKUP_ROWS=5 +GRAPH_BYTE_OID_FANOUT_ID=$GRAPH_CHUNK_LOOKUP_OFFSET +GRAPH_BYTE_OID_LOOKUP_ID=$(($GRAPH_CHUNK_LOOKUP_OFFSET + \ + 1 * $GRAPH_CHUNK_LOOKUP_WIDTH)) +GRAPH_BYTE_COMMIT_DATA_ID=$(($GRAPH_CHUNK_LOOKUP_OFFSET + \ + 2 * $GRAPH_CHUNK_LOOKUP_WIDTH)) +GRAPH_FANOUT_OFFSET=$(($GRAPH_CHUNK_LOOKUP_OFFSET + \ + $GRAPH_CHUNK_LOOKUP_WIDTH * $GRAPH_CHUNK_LOOKUP_ROWS)) +GRAPH_BYTE_FANOUT1=$(($GRAPH_FANOUT_OFFSET + 4 * 4)) +GRAPH_BYTE_FANOUT2=$(($GRAPH_FANOUT_OFFSET + 4 * 255)) +GRAPH_OID_LOOKUP_OFFSET=$(($GRAPH_FANOUT_OFFSET + 4 * 256)) +GRAPH_BYTE_OID_LOOKUP_ORDER=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * 8)) +GRAPH_BYTE_OID_LOOKUP_MISSING=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * 4 + 10)) +GRAPH_COMMIT_DATA_OFFSET=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * $NUM_COMMITS)) +GRAPH_BYTE_COMMIT_TREE=$GRAPH_COMMIT_DATA_OFFSET +GRAPH_BYTE_COMMIT_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN)) +GRAPH_BYTE_COMMIT_EXTRA_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 4)) +GRAPH_BYTE_COMMIT_WRONG_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 3)) +GRAPH_BYTE_COMMIT_GENERATION=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 11)) +GRAPH_BYTE_COMMIT_DATE=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 12)) +GRAPH_COMMIT_DATA_WIDTH=$(($HASH_LEN + 16)) +GRAPH_OCTOPUS_DATA_OFFSET=$(($GRAPH_COMMIT_DATA_OFFSET + \ + $GRAPH_COMMIT_DATA_WIDTH * $NUM_COMMITS)) +GRAPH_BYTE_OCTOPUS=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4)) +GRAPH_BYTE_FOOTER=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4 * $NUM_OCTOPUS_EDGES)) + +# usage: corrupt_graph_and_verify <position> <data> <string> +# Manipulates the commit-graph file at the position +# by inserting the data, then runs 'git commit-graph verify' +# and places the output in the file 'err'. Test 'err' for +# the given string. +corrupt_graph_and_verify() { + pos=$1 + data="${2:-\0}" + grepstr=$3 + cd "$TRASH_DIRECTORY/full" && + test_when_finished mv commit-graph-backup $objdir/info/commit-graph && + cp $objdir/info/commit-graph commit-graph-backup && + printf "$data" | dd of="$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc && + test_must_fail git commit-graph verify 2>test_err && + grep -v "^+" test_err >err + test_i18ngrep "$grepstr" err +} + +test_expect_success 'detect bad signature' ' + corrupt_graph_and_verify 0 "\0" \ + "graph signature" +' + +test_expect_success 'detect bad version' ' + corrupt_graph_and_verify $GRAPH_BYTE_VERSION "\02" \ + "graph version" +' + +test_expect_success 'detect bad hash version' ' + corrupt_graph_and_verify $GRAPH_BYTE_HASH "\02" \ + "hash version" +' + +test_expect_success 'detect low chunk count' ' + corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\02" \ + "missing the .* chunk" +' + +test_expect_success 'detect missing OID fanout chunk' ' + corrupt_graph_and_verify $GRAPH_BYTE_OID_FANOUT_ID "\0" \ + "missing the OID Fanout chunk" +' + +test_expect_success 'detect missing OID lookup chunk' ' + corrupt_graph_and_verify $GRAPH_BYTE_OID_LOOKUP_ID "\0" \ + "missing the OID Lookup chunk" +' + +test_expect_success 'detect missing commit data chunk' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_DATA_ID "\0" \ + "missing the Commit Data chunk" +' + +test_expect_success 'detect incorrect fanout' ' + corrupt_graph_and_verify $GRAPH_BYTE_FANOUT1 "\01" \ + "fanout value" +' + +test_expect_success 'detect incorrect fanout final value' ' + corrupt_graph_and_verify $GRAPH_BYTE_FANOUT2 "\01" \ + "fanout value" +' + +test_expect_success 'detect incorrect OID order' ' + corrupt_graph_and_verify $GRAPH_BYTE_OID_LOOKUP_ORDER "\01" \ + "incorrect OID order" +' + +test_expect_success 'detect OID not in object database' ' + corrupt_graph_and_verify $GRAPH_BYTE_OID_LOOKUP_MISSING "\01" \ + "from object database" +' + +test_expect_success 'detect incorrect tree OID' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_TREE "\01" \ + "root tree OID for commit" +' + +test_expect_success 'detect incorrect parent int-id' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_PARENT "\01" \ + "invalid parent" +' + +test_expect_success 'detect extra parent int-id' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_EXTRA_PARENT "\00" \ + "is too long" +' + +test_expect_success 'detect wrong parent' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_WRONG_PARENT "\01" \ + "commit-graph parent for" +' + +test_expect_success 'detect incorrect generation number' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION "\070" \ + "generation for commit" +' + +test_expect_success 'detect incorrect generation number' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION "\01" \ + "non-zero generation number" +' + +test_expect_success 'detect incorrect commit date' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_DATE "\01" \ + "commit date" +' + +test_expect_success 'detect incorrect parent for octopus merge' ' + corrupt_graph_and_verify $GRAPH_BYTE_OCTOPUS "\01" \ + "invalid parent" +' + +test_expect_success 'detect invalid checksum hash' ' + corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ + "incorrect checksum" +' + +test_expect_success 'git fsck (checks commit-graph)' ' + cd "$TRASH_DIRECTORY/full" && + git fsck && + corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ + "incorrect checksum" && + test_must_fail git fsck +' + test_done diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index 911eae1bf7..f1932ea431 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -86,7 +86,7 @@ test_expect_success 'push can be used to delete a ref' ' test_expect_success 'refuse deleting push with denyDeletes' ' ( cd victim && - ( git branch -D extra || : ) && + test_might_fail git branch -D extra && git config receive.denyDeletes true && git branch extra master ) && @@ -119,7 +119,7 @@ test_expect_success 'override denyDeletes with git -c receive-pack' ' test_expect_success 'denyNonFastforwards trumps --force' ' ( cd victim && - ( git branch -D extra || : ) && + test_might_fail git branch -D extra && git config receive.denyNonFastforwards true ) && victim_orig=$(cd victim && git rev-parse --verify master) && diff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh index 7f278d8ce9..b5f886a0e2 100755 --- a/t/t5401-update-hooks.sh +++ b/t/t5401-update-hooks.sh @@ -82,13 +82,13 @@ test_expect_success 'hooks ran' ' ' test_expect_success 'pre-receive hook input' ' - (echo $commit0 $commit1 refs/heads/master; + (echo $commit0 $commit1 refs/heads/master && echo $commit1 $commit0 refs/heads/tofail ) | test_cmp - victim.git/pre-receive.stdin ' test_expect_success 'update hook arguments' ' - (echo refs/heads/master $commit0 $commit1; + (echo refs/heads/master $commit0 $commit1 && echo refs/heads/tofail $commit1 $commit0 ) | test_cmp - victim.git/update.args ' diff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh index 4bda18a662..235fb7686a 100755 --- a/t/t5405-send-pack-rewind.sh +++ b/t/t5405-send-pack-rewind.sh @@ -25,8 +25,7 @@ test_expect_success 'non forced push should die not segfault' ' ( cd another && - git push .. master:master - test $? = 1 + test_must_fail git push .. master:master ) ' diff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh index 59e80a5ea2..ff06f99649 100755 --- a/t/t5406-remote-rejects.sh +++ b/t/t5406-remote-rejects.sh @@ -6,8 +6,9 @@ test_description='remote push rejects are reported by client' test_expect_success 'setup' ' mkdir .git/hooks && - (echo "#!/bin/sh" ; echo "exit 1") >.git/hooks/update && - chmod +x .git/hooks/update && + write_script .git/hooks/update <<-\EOF && + exit 1 + EOF echo 1 >file && git add file && git commit -m 1 && diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh index 7a48236e87..9b2a274c71 100755 --- a/t/t5407-post-rewrite-hook.sh +++ b/t/t5407-post-rewrite-hook.sh @@ -113,7 +113,7 @@ test_expect_success 'git rebase -m' ' test_expect_success 'git rebase -m --skip' ' git reset --hard D && clear_hook_input && - test_must_fail git rebase --onto A B && + test_must_fail git rebase -m --onto A B && test_must_fail git rebase --skip && echo D > foo && git add foo && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index d4f435155f..fa03f56a20 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -259,7 +259,7 @@ test_expect_success 'clone shallow object count' ' test_expect_success 'pull in shallow repo with missing merge base' ' ( cd shallow && - git fetch --depth 4 .. A + git fetch --depth 4 .. A && test_must_fail git merge --allow-unrelated-histories FETCH_HEAD ) ' @@ -518,6 +518,54 @@ test_expect_success 'test --all, --depth, and explicit tag' ' ) >out-adt 2>error-adt ' +test_expect_success 'test --all with tag to non-tip' ' + git commit --allow-empty -m non-tip && + git commit --allow-empty -m tip && + git tag -m "annotated" non-tip HEAD^ && + ( + cd client && + git fetch-pack --all .. + ) +' + +test_expect_success 'test --all wrt tag to non-commits' ' + # create tag-to-{blob,tree,commit,tag}, making sure all tagged objects + # are reachable only via created tag references. + blob=$(echo "hello blob" | git hash-object -t blob -w --stdin) && + git tag -a -m "tag -> blob" tag-to-blob $blob && + + tree=$(printf "100644 blob $blob\tfile" | git mktree) && + git tag -a -m "tag -> tree" tag-to-tree $tree && + + tree2=$(printf "100644 blob $blob\tfile2" | git mktree) && + commit=$(git commit-tree -m "hello commit" $tree) && + git tag -a -m "tag -> commit" tag-to-commit $commit && + + blob2=$(echo "hello blob2" | git hash-object -t blob -w --stdin) && + tag=$(git mktag <<-EOF + object $blob2 + type blob + tag tag-to-blob2 + tagger author A U Thor <author@example.com> 0 +0000 + + hello tag + EOF + ) && + git tag -a -m "tag -> tag" tag-to-tag $tag && + + # `fetch-pack --all` should succeed fetching all those objects. + mkdir fetchall && + ( + cd fetchall && + git init && + git fetch-pack --all .. && + git cat-file blob $blob >/dev/null && + git cat-file tree $tree >/dev/null && + git cat-file commit $commit >/dev/null && + git cat-file tag $tag >/dev/null + ) +' + test_expect_success 'shallow fetch with tags does not break the repository' ' mkdir repo1 && ( @@ -711,6 +759,17 @@ test_expect_success 'fetch shallow since ...' ' test_cmp expected actual ' +test_expect_success 'clone shallow since selects no commits' ' + test_create_repo shallow-since-the-future && + ( + cd shallow-since-the-future && + GIT_COMMITTER_DATE="100000000 +0700" git commit --allow-empty -m one && + GIT_COMMITTER_DATE="200000000 +0700" git commit --allow-empty -m two && + GIT_COMMITTER_DATE="300000000 +0700" git commit --allow-empty -m three && + test_must_fail git clone --shallow-since "900000000 +0700" "file://$(pwd)/." ../shallow111 + ) +' + test_expect_success 'shallow clone exclude tag two' ' test_create_repo shallow-exclude && ( @@ -755,6 +814,39 @@ test_expect_success 'fetching deepen' ' ) ' +test_expect_success 'use ref advertisement to prune "have" lines sent' ' + rm -rf server client && + git init server && + test_commit -C server both_have_1 && + git -C server tag -d both_have_1 && + test_commit -C server both_have_2 && + + git clone server client && + test_commit -C server server_has && + test_commit -C client client_has && + + # In both protocol v0 and v2, ensure that the parent of both_have_2 is + # not sent as a "have" line. The client should know that the server has + # both_have_2, so it only needs to inform the server that it has + # both_have_2, and the server can infer the rest. + + rm -f trace && + cp -r client clientv0 && + GIT_TRACE_PACKET="$(pwd)/trace" git -C clientv0 \ + fetch origin server_has both_have_2 && + grep "have $(git -C client rev-parse client_has)" trace && + grep "have $(git -C client rev-parse both_have_2)" trace && + ! grep "have $(git -C client rev-parse both_have_2^)" trace && + + rm -f trace && + cp -r client clientv2 && + GIT_TRACE_PACKET="$(pwd)/trace" git -C clientv2 -c protocol.version=2 \ + fetch origin server_has both_have_2 && + grep "have $(git -C client rev-parse client_has)" trace && + grep "have $(git -C client rev-parse both_have_2)" trace && + ! grep "have $(git -C client rev-parse both_have_2^)" trace +' + test_expect_success 'filtering by size' ' rm -rf server client && test_create_repo server && diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index a6c0178f3a..11e14a1e0f 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -348,17 +348,13 @@ URL: $(pwd)/one EOF test_expect_success 'prune --dry-run' ' - ( - cd one && - git branch -m side2 side) && + git -C one branch -m side2 side && + test_when_finished "git -C one branch -m side side2" && ( cd test && git remote prune --dry-run origin >output && git rev-parse refs/remotes/origin/side2 && test_must_fail git rev-parse refs/remotes/origin/side && - ( - cd ../one && - git branch -m side side2) && test_i18ncmp expect output ) ' @@ -848,7 +844,7 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/branches (2)' git remote rename origin origin && test_path_is_missing .git/branches/origin && test "$(git config remote.origin.url)" = "quux" && - test "$(git config remote.origin.fetch)" = "refs/heads/foom:refs/heads/origin" + test "$(git config remote.origin.fetch)" = "refs/heads/foom:refs/heads/origin" && test "$(git config remote.origin.push)" = "HEAD:refs/heads/foom" ) ' diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index e402aee6a2..62308be499 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -828,9 +828,11 @@ test_expect_success 'fetching with auto-gc does not lock up' ' test_commit test2 && ( cd auto-gc && + git config fetch.unpackLimit 1 && git config gc.autoPackLimit 1 && git config gc.autoDetach false && GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 && + test_i18ngrep "Auto packing the repository" fetch.out && ! grep "Should I try again" fetch.out ) ' @@ -865,4 +867,82 @@ test_expect_success C_LOCALE_OUTPUT 'fetch compact output' ' test_cmp expect actual ' +setup_negotiation_tip () { + SERVER="$1" + URL="$2" + USE_PROTOCOL_V2="$3" + + rm -rf "$SERVER" client trace && + git init "$SERVER" && + test_commit -C "$SERVER" alpha_1 && + test_commit -C "$SERVER" alpha_2 && + git -C "$SERVER" checkout --orphan beta && + test_commit -C "$SERVER" beta_1 && + test_commit -C "$SERVER" beta_2 && + + git clone "$URL" client && + + if test "$USE_PROTOCOL_V2" -eq 1 + then + git -C "$SERVER" config protocol.version 2 && + git -C client config protocol.version 2 + fi && + + test_commit -C "$SERVER" beta_s && + git -C "$SERVER" checkout master && + test_commit -C "$SERVER" alpha_s && + git -C "$SERVER" tag -d alpha_1 alpha_2 beta_1 beta_2 +} + +check_negotiation_tip () { + # Ensure that {alpha,beta}_1 are sent as "have", but not {alpha_beta}_2 + ALPHA_1=$(git -C client rev-parse alpha_1) && + grep "fetch> have $ALPHA_1" trace && + BETA_1=$(git -C client rev-parse beta_1) && + grep "fetch> have $BETA_1" trace && + ALPHA_2=$(git -C client rev-parse alpha_2) && + ! grep "fetch> have $ALPHA_2" trace && + BETA_2=$(git -C client rev-parse beta_2) && + ! grep "fetch> have $BETA_2" trace +} + +test_expect_success '--negotiation-tip limits "have" lines sent' ' + setup_negotiation_tip server server 0 && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \ + --negotiation-tip=alpha_1 --negotiation-tip=beta_1 \ + origin alpha_s beta_s && + check_negotiation_tip +' + +test_expect_success '--negotiation-tip understands globs' ' + setup_negotiation_tip server server 0 && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \ + --negotiation-tip=*_1 \ + origin alpha_s beta_s && + check_negotiation_tip +' + +test_expect_success '--negotiation-tip understands abbreviated SHA-1' ' + setup_negotiation_tip server server 0 && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \ + --negotiation-tip=$(git -C client rev-parse --short alpha_1) \ + --negotiation-tip=$(git -C client rev-parse --short beta_1) \ + origin alpha_s beta_s && + check_negotiation_tip +' + +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +test_expect_success '--negotiation-tip limits "have" lines sent with HTTP protocol v2' ' + setup_negotiation_tip "$HTTPD_DOCUMENT_ROOT_PATH/server" \ + "$HTTPD_URL/smart/server" 1 && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client fetch \ + --negotiation-tip=alpha_1 --negotiation-tip=beta_1 \ + origin alpha_s beta_s && + check_negotiation_tip +' + +stop_httpd + test_done diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index 6a949484d0..ea020040e8 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -15,7 +15,7 @@ test_expect_success setup ' git tag mark1.10 && git show-ref --tags -d | sed -e "s/ / /" >expected.tag && ( - echo "$(git rev-parse HEAD) HEAD" + echo "$(git rev-parse HEAD) HEAD" && git show-ref -d | sed -e "s/ / /" ) >expected.all && @@ -105,7 +105,7 @@ test_expect_success 'use branch.<name>.remote if possible' ' git clone . other.git && ( cd other.git && - echo "$(git rev-parse HEAD) HEAD" + echo "$(git rev-parse HEAD) HEAD" && git show-ref | sed -e "s/ / /" ) >exp && diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index a5077d8b7c..bd8f23e430 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -923,7 +923,7 @@ test_expect_success 'push into aliased refs (consistent)' ' ( cd child1 && git branch foo && - git symbolic-ref refs/heads/bar refs/heads/foo + git symbolic-ref refs/heads/bar refs/heads/foo && git config receive.denyCurrentBranch false ) && ( @@ -945,7 +945,7 @@ test_expect_success 'push into aliased refs (inconsistent)' ' ( cd child1 && git branch foo && - git symbolic-ref refs/heads/bar refs/heads/foo + git symbolic-ref refs/heads/bar refs/heads/foo && git config receive.denyCurrentBranch false ) && ( @@ -1011,7 +1011,7 @@ test_expect_success 'push --porcelain rejected' ' mk_empty testrepo && git push testrepo refs/heads/master:refs/remotes/origin/master && (cd testrepo && - git reset --hard origin/master^ + git reset --hard origin/master^ && git config receive.denyCurrentBranch true) && echo >.git/foo "To testrepo" && @@ -1025,7 +1025,7 @@ test_expect_success 'push --porcelain --dry-run rejected' ' mk_empty testrepo && git push testrepo refs/heads/master:refs/remotes/origin/master && (cd testrepo && - git reset --hard origin/master + git reset --hard origin/master && git config receive.denyCurrentBranch true) && echo >.git/foo "To testrepo" && @@ -1333,7 +1333,7 @@ test_expect_success 'push --follow-tag only pushes relevant tags' ' git commit --allow-empty -m "future commit" && git tag -m "future" future && git checkout master && - git for-each-ref refs/heads/master refs/tags/tag >../expect + git for-each-ref refs/heads/master refs/tags/tag >../expect && git push --follow-tag ../dst master ) && ( diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh index 02f160aae0..c05a661400 100755 --- a/t/t5517-push-mirror.sh +++ b/t/t5517-push-mirror.sh @@ -71,7 +71,7 @@ test_expect_success 'push mirror force updates existing branches' ' git push --mirror up && echo two >foo && git add foo && git commit -m two && git push --mirror up && - git reset --hard HEAD^ + git reset --hard HEAD^ && git push --mirror up ) && master_master=$(cd master && git show-ref -s --verify refs/heads/master) && @@ -88,7 +88,7 @@ test_expect_success 'push mirror removes branches' ' echo one >foo && git add foo && git commit -m one && git branch remove master && git push --mirror up && - git branch -D remove + git branch -D remove && git push --mirror up ) && ( @@ -170,7 +170,7 @@ test_expect_success 'push mirror force updates existing tags' ' echo two >foo && git add foo && git commit -m two && git tag -f tmaster master && git push --mirror up && - git reset --hard HEAD^ + git reset --hard HEAD^ && git tag -f tmaster master && git push --mirror up ) && @@ -188,7 +188,7 @@ test_expect_success 'push mirror removes tags' ' echo one >foo && git add foo && git commit -m one && git tag -f tremove master && git push --mirror up && - git tag -d tremove + git tag -d tremove && git push --mirror up ) && ( @@ -235,7 +235,7 @@ test_expect_success 'remote.foo.mirror adds and removes branches' ' git branch keep master && git branch remove master && git push up && - git branch -D remove + git branch -D remove && git push up ) && ( diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 59c4b778d3..68aa5f0340 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -618,6 +618,18 @@ test_expect_success 'pull --rebase fails on unborn branch with staged changes' ' ) ' +test_expect_success 'pull --rebase fails on corrupt HEAD' ' + test_when_finished "rm -rf corrupt" && + git init corrupt && + ( + cd corrupt && + test_commit one && + obj=$(git rev-parse --verify HEAD | sed "s#^..#&/#") && + rm -f .git/objects/$obj && + test_must_fail git pull --rebase + ) +' + test_expect_success 'setup for detecting upstreamed changes' ' mkdir src && (cd src && diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh index 9cc4b569c0..0f730d7781 100755 --- a/t/t5526-fetch-submodules.sh +++ b/t/t5526-fetch-submodules.sh @@ -379,7 +379,7 @@ test_expect_success "'--recurse-submodules=on-demand' recurses as deep as necess git config -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive false ) && git fetch --recurse-submodules=on-demand >../actual.out 2>../actual.err && - git config --unset fetch.recurseSubmodules + git config --unset fetch.recurseSubmodules && ( cd submodule && git config --unset -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive @@ -574,11 +574,7 @@ test_expect_success "fetch new commits when submodule got renamed" ' git clone . downstream_rename && ( cd downstream_rename && - git submodule update --init && -# NEEDSWORK: we omitted --recursive for the submodule update here since -# that does not work. See test 7001 for mv "moving nested submodules" -# for details. Once that is fixed we should add the --recursive option -# here. + git submodule update --init --recursive && git checkout -b rename && git mv submodule submodule_renamed && ( diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index 39cb2c1c34..e2c37fd978 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -354,7 +354,7 @@ test_expect_success 'push succeeds if submodule has no remote and is on the firs git clone a a1 && ( cd a1 && - git init b + git init b && ( cd b && >junk && diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh index df8d2f095a..7045685e2d 100755 --- a/t/t5537-fetch-shallow.sh +++ b/t/t5537-fetch-shallow.sh @@ -175,8 +175,8 @@ EOF test_expect_success POSIXPERM,SANITY 'shallow fetch from a read-only repo' ' cp -R .git read-only.git && - find read-only.git -print | xargs chmod -w && test_when_finished "find read-only.git -type d -print | xargs chmod +w" && + find read-only.git -print | xargs chmod -w && git clone --no-local --depth=2 read-only.git from-read-only && git --git-dir=from-read-only/.git log --format=%s >actual && cat >expect <<EOF && @@ -186,4 +186,47 @@ EOF test_cmp expect actual ' +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo" + +test_expect_success 'shallow fetches check connectivity before writing shallow file' ' + rm -rf "$REPO" client && + + git init "$REPO" && + test_commit -C "$REPO" one && + test_commit -C "$REPO" two && + test_commit -C "$REPO" three && + + git init client && + + # Use protocol v2 to ensure that shallow information is sent exactly + # once by the server, since we are planning to manipulate it. + git -C "$REPO" config protocol.version 2 && + git -C client config protocol.version 2 && + + git -C client fetch --depth=2 "$HTTPD_URL/one_time_sed/repo" master:a_branch && + + # Craft a situation in which the server sends back an unshallow request + # with an empty packfile. This is done by refetching with a shorter + # depth (to ensure that the packfile is empty), and overwriting the + # shallow line in the response with the unshallow line we want. + printf "s/0034shallow %s/0036unshallow %s/" \ + "$(git -C "$REPO" rev-parse HEAD)" \ + "$(git -C "$REPO" rev-parse HEAD^)" \ + >"$HTTPD_ROOT_PATH/one-time-sed" && + test_must_fail git -C client fetch --depth=1 "$HTTPD_URL/one_time_sed/repo" \ + master:a_branch && + + # Ensure that the one-time-sed script was used. + ! test -e "$HTTPD_ROOT_PATH/one-time-sed" && + + # Ensure that the resulting repo is consistent, despite our failure to + # fetch. + git -C client fsck +' + +stop_httpd + test_done diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index a2af693068..a0fc4005e0 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -38,25 +38,16 @@ GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200 POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200 EOF test_expect_success 'no empty path components' ' + # Clear the log, so that it does not affect the "used receive-pack + # service" test which reads the log too. + test_when_finished ">\"\$HTTPD_ROOT_PATH\"/access.log" && + # In the URL, add a trailing slash, and see if git appends yet another # slash. cd "$ROOT_PATH" && git clone $HTTPD_URL/smart/test_repo.git/ test_repo_clone && - sed -e " - s/^.* \"// - s/\"// - s/ [1-9][0-9]*\$// - s/^GET /GET / - " >act <"$HTTPD_ROOT_PATH"/access.log && - - # Clear the log, so that it does not affect the "used receive-pack - # service" test which reads the log too. - # - # We do this before the actual comparison to ensure the log is cleared. - echo > "$HTTPD_ROOT_PATH"/access.log && - - test_cmp exp act + check_access_log exp ' test_expect_success 'clone remote repository' ' @@ -124,7 +115,6 @@ test_expect_success 'rejected update prints status' ' rm -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" cat >exp <<EOF - GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200 POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200 GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200 @@ -138,13 +128,7 @@ GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200 POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200 EOF test_expect_success 'used receive-pack service' ' - sed -e " - s/^.* \"// - s/\"// - s/ [1-9][0-9]*\$// - s/^GET /GET / - " >act <"$HTTPD_ROOT_PATH"/access.log && - test_cmp exp act + check_access_log exp ' test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \ diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh index 3480b33007..7079bcf9a0 100755 --- a/t/t5543-atomic-push.sh +++ b/t/t5543-atomic-push.sh @@ -178,7 +178,7 @@ test_expect_success 'atomic push obeys update hook preventing a branch to be pus test_expect_success 'atomic push is not advertised if configured' ' mk_repo_pair && ( - cd upstream + cd upstream && git config receive.advertiseatomic 0 ) && ( diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index 913089b144..3aab44bdcb 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -103,13 +103,7 @@ GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 200 POST /smart/repo.git/git-upload-pack HTTP/1.1 200 EOF test_expect_success 'used upload-pack service' ' - sed -e " - s/^.* \"// - s/\"// - s/ [1-9][0-9]*\$// - s/^GET /GET / - " >act <"$HTTPD_ROOT_PATH"/access.log && - test_cmp exp act + check_access_log exp ' test_expect_success 'follow redirects (301)' ' diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh index 84a955770a..1c49054595 100755 --- a/t/t5561-http-backend.sh +++ b/t/t5561-http-backend.sh @@ -129,13 +129,7 @@ GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 403 - POST /smart/repo.git/git-receive-pack HTTP/1.1 403 - EOF test_expect_success 'server request log matches test results' ' - sed -e " - s/^.* \"// - s/\"// - s/ [1-9][0-9]*\$// - s/^GET /GET / - " >act <"$HTTPD_ROOT_PATH"/access.log && - test_cmp exp act + check_access_log exp ' stop_httpd diff --git a/t/t5573-pull-verify-signatures.sh b/t/t5573-pull-verify-signatures.sh index 9594e891f4..747775c147 100755 --- a/t/t5573-pull-verify-signatures.sh +++ b/t/t5573-pull-verify-signatures.sh @@ -29,7 +29,7 @@ test_expect_success GPG 'create repositories with signed commits' ' echo 4 >d && git add d && test_tick && git commit -S -m "bad" && git cat-file commit HEAD >raw && - sed -e "s/bad/forged bad/" raw >forged && + sed -e "s/^bad/forged bad/" raw >forged && git hash-object -w -t commit forged >forged.commit && git checkout $(cat forged.commit) ) && diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 0b62037744..ddaa96ac4f 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -618,7 +618,7 @@ hex2oct () { test_expect_success 'clone on case-insensitive fs' ' git init icasefs && ( - cd icasefs + cd icasefs && o=$(git hash-object -w --stdin </dev/null | hex2oct) && t=$(printf "100644 X\0${o}100644 x\0${o}" | git hash-object -w -t tree --stdin) && diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh index 3c087e907c..af23419ebf 100755 --- a/t/t5605-clone-local.sh +++ b/t/t5605-clone-local.sh @@ -94,7 +94,7 @@ test_expect_success 'clone empty repository' ' git config receive.denyCurrentBranch warn) && git clone empty empty-clone && test_tick && - (cd empty-clone + (cd empty-clone && echo "content" >> foo && git add foo && git commit -m "Initial commit" && diff --git a/t/t5608-clone-2gb.sh b/t/t5608-clone-2gb.sh index df822d9a3e..2c6bc07344 100755 --- a/t/t5608-clone-2gb.sh +++ b/t/t5608-clone-2gb.sh @@ -23,7 +23,7 @@ test_expect_success CLONE_2GB 'setup' ' printf "blob\nmark :$i\ndata $blobsize\n" && #test-tool genrandom $i $blobsize && printf "%-${blobsize}s" $i && - echo "M 100644 :$i $i" >> commit + echo "M 100644 :$i $i" >> commit && i=$(($i+1)) || echo $? > exit-status done && diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index cee5565367..44d8e80171 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -154,4 +154,68 @@ test_expect_success 'partial clone with transfer.fsckobjects=1 uses index-pack - grep "git index-pack.*--fsck-objects" trace ' +test_expect_success 'partial clone fetches blobs pointed to by refs even if normally filtered out' ' + rm -rf src dst && + git init src && + test_commit -C src x && + test_config -C src uploadpack.allowfilter 1 && + test_config -C src uploadpack.allowanysha1inwant 1 && + + # Create a tag pointing to a blob. + BLOB=$(echo blob-contents | git -C src hash-object --stdin -w) && + git -C src tag myblob "$BLOB" && + + git clone --filter="blob:none" "file://$(pwd)/src" dst 2>err && + ! grep "does not point to a valid object" err && + git -C dst fsck +' + +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +# Converts bytes into a form suitable for inclusion in a sed command. For +# example, "printf 'ab\r\n' | hex_unpack" results in '\x61\x62\x0d\x0a'. +sed_escape () { + perl -e '$/ = undef; $input = <>; print unpack("H2" x length($input), $input)' | + sed 's/\(..\)/\\x\1/g' +} + +test_expect_success 'upon cloning, check that all refs point to objects' ' + SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" && + rm -rf "$SERVER" repo && + test_create_repo "$SERVER" && + test_commit -C "$SERVER" foo && + test_config -C "$SERVER" uploadpack.allowfilter 1 && + test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 && + + # Create a tag pointing to a blob. + BLOB=$(echo blob-contents | git -C "$SERVER" hash-object --stdin -w) && + git -C "$SERVER" tag myblob "$BLOB" && + + # Craft a packfile not including that blob. + git -C "$SERVER" rev-parse HEAD | + git -C "$SERVER" pack-objects --stdout >incomplete.pack && + + # Replace the existing packfile with the crafted one. The protocol + # requires that the packfile be sent in sideband 1, hence the extra + # \x01 byte at the beginning. + printf "1,/packfile/!c %04x\\\\x01%s0000" \ + "$(($(wc -c <incomplete.pack) + 5))" \ + "$(sed_escape <incomplete.pack)" \ + >"$HTTPD_ROOT_PATH/one-time-sed" && + + # Use protocol v2 because the sed command looks for the "packfile" + # section header. + test_config -C "$SERVER" protocol.version 2 && + test_must_fail git -c protocol.version=2 clone \ + --filter=blob:none $HTTPD_URL/one_time_sed/server repo 2>err && + + grep "did not send all necessary objects" err && + + # Ensure that the one-time-sed script was used. + ! test -e "$HTTPD_ROOT_PATH/one-time-sed" +' + +stop_httpd + test_done diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh new file mode 100755 index 0000000000..a73c55a47e --- /dev/null +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -0,0 +1,377 @@ +#!/bin/sh + +test_description='upload-pack ref-in-want' + +. ./test-lib.sh + +get_actual_refs () { + sed -n -e '/wanted-refs/,/0001/{ + /wanted-refs/d + /0001/d + p + }' <out | test-pkt-line unpack >actual_refs +} + +get_actual_commits () { + sed -n -e '/packfile/,/0000/{ + /packfile/d + p + }' <out | test-pkt-line unpack-sideband >o.pack && + git index-pack o.pack && + git verify-pack -v o.idx | grep commit | cut -c-40 | sort >actual_commits +} + +check_output () { + get_actual_refs && + test_cmp expected_refs actual_refs && + get_actual_commits && + test_cmp expected_commits actual_commits +} + +# c(o/foo) d(o/bar) +# \ / +# b e(baz) f(master) +# \__ | __/ +# \ | / +# a +test_expect_success 'setup repository' ' + test_commit a && + git checkout -b o/foo && + test_commit b && + test_commit c && + git checkout -b o/bar b && + test_commit d && + git checkout -b baz a && + test_commit e && + git checkout master && + test_commit f +' + +test_expect_success 'config controls ref-in-want advertisement' ' + git serve --advertise-capabilities >out && + ! grep -a ref-in-want out && + + git config uploadpack.allowRefInWant false && + git serve --advertise-capabilities >out && + ! grep -a ref-in-want out && + + git config uploadpack.allowRefInWant true && + git serve --advertise-capabilities >out && + grep -a ref-in-want out +' + +test_expect_success 'invalid want-ref line' ' + test-pkt-line pack >in <<-EOF && + command=fetch + 0001 + no-progress + want-ref refs/heads/non-existent + done + 0000 + EOF + + test_must_fail git serve --stateless-rpc 2>out <in && + grep "unknown ref" out +' + +test_expect_success 'basic want-ref' ' + cat >expected_refs <<-EOF && + $(git rev-parse f) refs/heads/master + EOF + git rev-parse f | sort >expected_commits && + + test-pkt-line pack >in <<-EOF && + command=fetch + 0001 + no-progress + want-ref refs/heads/master + have $(git rev-parse a) + done + 0000 + EOF + + git serve --stateless-rpc >out <in && + check_output +' + +test_expect_success 'multiple want-ref lines' ' + cat >expected_refs <<-EOF && + $(git rev-parse c) refs/heads/o/foo + $(git rev-parse d) refs/heads/o/bar + EOF + git rev-parse c d | sort >expected_commits && + + test-pkt-line pack >in <<-EOF && + command=fetch + 0001 + no-progress + want-ref refs/heads/o/foo + want-ref refs/heads/o/bar + have $(git rev-parse b) + done + 0000 + EOF + + git serve --stateless-rpc >out <in && + check_output +' + +test_expect_success 'mix want and want-ref' ' + cat >expected_refs <<-EOF && + $(git rev-parse f) refs/heads/master + EOF + git rev-parse e f | sort >expected_commits && + + test-pkt-line pack >in <<-EOF && + command=fetch + 0001 + no-progress + want-ref refs/heads/master + want $(git rev-parse e) + have $(git rev-parse a) + done + 0000 + EOF + + git serve --stateless-rpc >out <in && + check_output +' + +test_expect_success 'want-ref with ref we already have commit for' ' + cat >expected_refs <<-EOF && + $(git rev-parse c) refs/heads/o/foo + EOF + >expected_commits && + + test-pkt-line pack >in <<-EOF && + command=fetch + 0001 + no-progress + want-ref refs/heads/o/foo + have $(git rev-parse c) + done + 0000 + EOF + + git serve --stateless-rpc >out <in && + check_output +' + +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +REPO="$HTTPD_DOCUMENT_ROOT_PATH/repo" +LOCAL_PRISTINE="$(pwd)/local_pristine" + +test_expect_success 'setup repos for change-while-negotiating test' ' + ( + git init "$REPO" && + cd "$REPO" && + >.git/git-daemon-export-ok && + test_commit m1 && + git tag -d m1 && + + # Local repo with many commits (so that negotiation will take + # more than 1 request/response pair) + git clone "http://127.0.0.1:$LIB_HTTPD_PORT/smart/repo" "$LOCAL_PRISTINE" && + cd "$LOCAL_PRISTINE" && + git checkout -b side && + for i in $(seq 1 33); do test_commit s$i; done && + + # Add novel commits to upstream + git checkout master && + cd "$REPO" && + test_commit m2 && + test_commit m3 && + git tag -d m2 m3 + ) && + git -C "$LOCAL_PRISTINE" remote set-url origin "http://127.0.0.1:$LIB_HTTPD_PORT/one_time_sed/repo" && + git -C "$LOCAL_PRISTINE" config protocol.version 2 +' + +inconsistency () { + # Simulate that the server initially reports $2 as the ref + # corresponding to $1, and after that, $1 as the ref corresponding to + # $1. This corresponds to the real-life situation where the server's + # repository appears to change during negotiation, for example, when + # different servers in a load-balancing arrangement serve (stateless) + # RPCs during a single negotiation. + printf "s/%s/%s/" \ + $(git -C "$REPO" rev-parse $1 | tr -d "\n") \ + $(git -C "$REPO" rev-parse $2 | tr -d "\n") \ + >"$HTTPD_ROOT_PATH/one-time-sed" +} + +test_expect_success 'server is initially ahead - no ref in want' ' + git -C "$REPO" config uploadpack.allowRefInWant false && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + inconsistency master 1234567890123456789012345678901234567890 && + test_must_fail git -C local fetch 2>err && + grep "ERR upload-pack: not our ref" err +' + +test_expect_success 'server is initially ahead - ref in want' ' + git -C "$REPO" config uploadpack.allowRefInWant true && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + inconsistency master 1234567890123456789012345678901234567890 && + git -C local fetch && + + git -C "$REPO" rev-parse --verify master >expected && + git -C local rev-parse --verify refs/remotes/origin/master >actual && + test_cmp expected actual +' + +test_expect_success 'server is initially behind - no ref in want' ' + git -C "$REPO" config uploadpack.allowRefInWant false && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + inconsistency master "master^" && + git -C local fetch && + + git -C "$REPO" rev-parse --verify "master^" >expected && + git -C local rev-parse --verify refs/remotes/origin/master >actual && + test_cmp expected actual +' + +test_expect_success 'server is initially behind - ref in want' ' + git -C "$REPO" config uploadpack.allowRefInWant true && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + inconsistency master "master^" && + git -C local fetch && + + git -C "$REPO" rev-parse --verify "master" >expected && + git -C local rev-parse --verify refs/remotes/origin/master >actual && + test_cmp expected actual +' + +test_expect_success 'server loses a ref - ref in want' ' + git -C "$REPO" config uploadpack.allowRefInWant true && + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-sed" && + test_must_fail git -C local fetch 2>err && + + grep "ERR unknown ref refs/heads/raster" err +' + +stop_httpd + +REPO="$(pwd)/repo" +LOCAL_PRISTINE="$(pwd)/local_pristine" + +# $REPO +# c(o/foo) d(o/bar) +# \ / +# b e(baz) f(master) +# \__ | __/ +# \ | / +# a +# +# $LOCAL_PRISTINE +# s32(side) +# | +# . +# . +# | +# a(master) +test_expect_success 'setup repos for fetching with ref-in-want tests' ' + ( + git init "$REPO" && + cd "$REPO" && + test_commit a && + + # Local repo with many commits (so that negotiation will take + # more than 1 request/response pair) + rm -rf "$LOCAL_PRISTINE" && + git clone "file://$REPO" "$LOCAL_PRISTINE" && + cd "$LOCAL_PRISTINE" && + git checkout -b side && + for i in $(seq 1 33); do test_commit s$i; done && + + # Add novel commits to upstream + git checkout master && + cd "$REPO" && + git checkout -b o/foo && + test_commit b && + test_commit c && + git checkout -b o/bar b && + test_commit d && + git checkout -b baz a && + test_commit e && + git checkout master && + test_commit f + ) && + git -C "$REPO" config uploadpack.allowRefInWant true && + git -C "$LOCAL_PRISTINE" config protocol.version 2 +' + +test_expect_success 'fetching with exact OID' ' + test_when_finished "rm -f log" && + + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \ + $(git -C "$REPO" rev-parse d):refs/heads/actual && + + git -C "$REPO" rev-parse "d" >expected && + git -C local rev-parse refs/heads/actual >actual && + test_cmp expected actual && + grep "want $(git -C "$REPO" rev-parse d)" log +' + +test_expect_success 'fetching multiple refs' ' + test_when_finished "rm -f log" && + + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin master baz && + + git -C "$REPO" rev-parse "master" "baz" >expected && + git -C local rev-parse refs/remotes/origin/master refs/remotes/origin/baz >actual && + test_cmp expected actual && + grep "want-ref refs/heads/master" log && + grep "want-ref refs/heads/baz" log +' + +test_expect_success 'fetching ref and exact OID' ' + test_when_finished "rm -f log" && + + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \ + master $(git -C "$REPO" rev-parse b):refs/heads/actual && + + git -C "$REPO" rev-parse "master" "b" >expected && + git -C local rev-parse refs/remotes/origin/master refs/heads/actual >actual && + test_cmp expected actual && + grep "want $(git -C "$REPO" rev-parse b)" log && + grep "want-ref refs/heads/master" log +' + +test_expect_success 'fetching with wildcard that does not match any refs' ' + test_when_finished "rm -f log" && + + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + git -C local fetch origin refs/heads/none*:refs/heads/* >out && + test_must_be_empty out +' + +test_expect_success 'fetching with wildcard that matches multiple refs' ' + test_when_finished "rm -f log" && + + rm -rf local && + cp -r "$LOCAL_PRISTINE" local && + GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin refs/heads/o*:refs/heads/o* && + + git -C "$REPO" rev-parse "o/foo" "o/bar" >expected && + git -C local rev-parse "o/foo" "o/bar" >actual && + test_cmp expected actual && + grep "want-ref refs/heads/o/foo" log && + grep "want-ref refs/heads/o/bar" log +' + +test_done diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index 362b1581e0..ee5757966f 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -96,7 +96,7 @@ test_expect_success 'push new branch with old:new refspec' ' test_expect_success 'push new branch with HEAD:new refspec' ' (cd local && - git checkout new-name + git checkout new-name && git push origin HEAD:new-refspec-2 ) && compare_refs local HEAD server refs/heads/new-refspec-2 diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh index aa2d360ce3..44c726ea39 100755 --- a/t/t6010-merge-base.sh +++ b/t/t6010-merge-base.sh @@ -245,7 +245,7 @@ test_expect_success 'using reflog to find the fork point' ' git commit --allow-empty -m "Derived #$count" && git rev-parse HEAD >derived$count && git checkout -B base $E || exit 1 - done + done && for count in 1 2 3 do diff --git a/t/t6029-merge-subtree.sh b/t/t6029-merge-subtree.sh index 3e692454a7..7d5bc78472 100755 --- a/t/t6029-merge-subtree.sh +++ b/t/t6029-merge-subtree.sh @@ -55,7 +55,7 @@ test_expect_success 'initial merge' ' git checkout -b work && git ls-files -s >actual && ( - echo "100644 $o1 0 git-gui/git-gui.sh" + echo "100644 $o1 0 git-gui/git-gui.sh" && echo "100644 $o2 0 git.c" ) >expected && test_cmp expected actual @@ -72,7 +72,7 @@ test_expect_success 'merge update' ' git pull -s subtree gui master2 && git ls-files -s >actual && ( - echo "100644 $o3 0 git-gui/git-gui.sh" + echo "100644 $o3 0 git-gui/git-gui.sh" && echo "100644 $o2 0 git.c" ) >expected && test_cmp expected actual @@ -88,8 +88,8 @@ test_expect_success 'initial ambiguous subtree' ' git checkout -b work2 && git ls-files -s >actual && ( - echo "100644 $o1 0 git-gui/git-gui.sh" - echo "100644 $o1 0 git-gui2/git-gui.sh" + echo "100644 $o1 0 git-gui/git-gui.sh" && + echo "100644 $o1 0 git-gui2/git-gui.sh" && echo "100644 $o2 0 git.c" ) >expected && test_cmp expected actual @@ -101,8 +101,8 @@ test_expect_success 'merge using explicit' ' git pull -Xsubtree=git-gui gui master2 && git ls-files -s >actual && ( - echo "100644 $o3 0 git-gui/git-gui.sh" - echo "100644 $o1 0 git-gui2/git-gui.sh" + echo "100644 $o3 0 git-gui/git-gui.sh" && + echo "100644 $o1 0 git-gui2/git-gui.sh" && echo "100644 $o2 0 git.c" ) >expected && test_cmp expected actual @@ -114,8 +114,8 @@ test_expect_success 'merge2 using explicit' ' git pull -Xsubtree=git-gui2 gui master2 && git ls-files -s >actual && ( - echo "100644 $o1 0 git-gui/git-gui.sh" - echo "100644 $o3 0 git-gui2/git-gui.sh" + echo "100644 $o1 0 git-gui/git-gui.sh" && + echo "100644 $o3 0 git-gui2/git-gui.sh" && echo "100644 $o2 0 git.c" ) >expected && test_cmp expected actual diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index 18aa88b5c0..59e52c5a09 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -4,12 +4,6 @@ test_description='recursive merge corner cases involving criss-cross merges' . ./test-lib.sh -get_clean_checkout () { - git reset --hard && - git clean -fdqx && - git checkout "$1" -} - # # L1 L2 # o---o @@ -21,51 +15,66 @@ get_clean_checkout () { # test_expect_success 'setup basic criss-cross + rename with no modifications' ' - ten="0 1 2 3 4 5 6 7 8 9" && - for i in $ten - do - echo line $i in a sample file - done >one && - for i in $ten - do - echo line $i in another sample file - done >two && - git add one two && - test_tick && git commit -m initial && - - git branch L1 && - git checkout -b R1 && - git mv one three && - test_tick && git commit -m R1 && - - git checkout L1 && - git mv two three && - test_tick && git commit -m L1 && - - git checkout L1^0 && - test_tick && git merge -s ours R1 && - git tag L2 && - - git checkout R1^0 && - test_tick && git merge -s ours L1 && - git tag R2 + test_create_repo basic-rename && + ( + cd basic-rename && + + ten="0 1 2 3 4 5 6 7 8 9" && + for i in $ten + do + echo line $i in a sample file + done >one && + for i in $ten + do + echo line $i in another sample file + done >two && + git add one two && + test_tick && git commit -m initial && + + git branch L1 && + git checkout -b R1 && + git mv one three && + test_tick && git commit -m R1 && + + git checkout L1 && + git mv two three && + test_tick && git commit -m L1 && + + git checkout L1^0 && + test_tick && git merge -s ours R1 && + git tag L2 && + + git checkout R1^0 && + test_tick && git merge -s ours L1 && + git tag R2 + ) ' test_expect_success 'merge simple rename+criss-cross with no modifications' ' - git reset --hard && - git checkout L2^0 && - - test_must_fail git merge -s recursive R2^0 && - - test 2 = $(git ls-files -s | wc -l) && - test 2 = $(git ls-files -u | wc -l) && - test 2 = $(git ls-files -o | wc -l) && - - test $(git rev-parse :2:three) = $(git rev-parse L2:three) && - test $(git rev-parse :3:three) = $(git rev-parse R2:three) && - - test $(git rev-parse L2:three) = $(git hash-object three~HEAD) && - test $(git rev-parse R2:three) = $(git hash-object three~R2^0) + ( + cd basic-rename && + + git reset --hard && + git checkout L2^0 && + + test_must_fail git merge -s recursive R2^0 && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 3 out && + + git rev-parse >expect \ + L2:three R2:three \ + L2:three R2:three && + git rev-parse >actual \ + :2:three :3:three && + git hash-object >>actual \ + three~HEAD three~R2^0 && + test_cmp expect actual + ) ' # @@ -81,58 +90,67 @@ test_expect_success 'merge simple rename+criss-cross with no modifications' ' # test_expect_success 'setup criss-cross + rename merges with basic modification' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - ten="0 1 2 3 4 5 6 7 8 9" && - for i in $ten - do - echo line $i in a sample file - done >one && - for i in $ten - do - echo line $i in another sample file - done >two && - git add one two && - test_tick && git commit -m initial && - - git branch L1 && - git checkout -b R1 && - git mv one three && - echo more >>two && - git add two && - test_tick && git commit -m R1 && - - git checkout L1 && - git mv two three && - test_tick && git commit -m L1 && - - git checkout L1^0 && - test_tick && git merge -s ours R1 && - git tag L2 && - - git checkout R1^0 && - test_tick && git merge -s ours L1 && - git tag R2 + test_create_repo rename-modify && + ( + cd rename-modify && + + ten="0 1 2 3 4 5 6 7 8 9" && + for i in $ten + do + echo line $i in a sample file + done >one && + for i in $ten + do + echo line $i in another sample file + done >two && + git add one two && + test_tick && git commit -m initial && + + git branch L1 && + git checkout -b R1 && + git mv one three && + echo more >>two && + git add two && + test_tick && git commit -m R1 && + + git checkout L1 && + git mv two three && + test_tick && git commit -m L1 && + + git checkout L1^0 && + test_tick && git merge -s ours R1 && + git tag L2 && + + git checkout R1^0 && + test_tick && git merge -s ours L1 && + git tag R2 + ) ' test_expect_success 'merge criss-cross + rename merges with basic modification' ' - git reset --hard && - git checkout L2^0 && - - test_must_fail git merge -s recursive R2^0 && - - test 2 = $(git ls-files -s | wc -l) && - test 2 = $(git ls-files -u | wc -l) && - test 2 = $(git ls-files -o | wc -l) && - - test $(git rev-parse :2:three) = $(git rev-parse L2:three) && - test $(git rev-parse :3:three) = $(git rev-parse R2:three) && - - test $(git rev-parse L2:three) = $(git hash-object three~HEAD) && - test $(git rev-parse R2:three) = $(git hash-object three~R2^0) + ( + cd rename-modify && + + git checkout L2^0 && + + test_must_fail git merge -s recursive R2^0 && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 3 out && + + git rev-parse >expect \ + L2:three R2:three \ + L2:three R2:three && + git rev-parse >actual \ + :2:three :3:three && + git hash-object >>actual \ + three~HEAD three~R2^0 && + test_cmp expect actual + ) ' # @@ -156,64 +174,74 @@ test_expect_success 'merge criss-cross + rename merges with basic modification' # test_expect_success 'setup differently handled merges of rename/add conflict' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n" >a && - git add a && - test_tick && git commit -m A && - - git branch B && - git checkout -b C && - echo 10 >>a && - echo "other content" >>new_a && - git add a new_a && - test_tick && git commit -m C && - - git checkout B && - git mv a new_a && - test_tick && git commit -m B && - - git checkout B^0 && - test_must_fail git merge C && - git clean -f && - test_tick && git commit -m D && - git tag D && - - git checkout C^0 && - test_must_fail git merge B && - rm new_a~HEAD new_a && - printf "Incorrectly merged content" >>new_a && - git add -u && - test_tick && git commit -m E && - git tag E + test_create_repo rename-add && + ( + cd rename-add && + + printf "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n" >a && + git add a && + test_tick && git commit -m A && + + git branch B && + git checkout -b C && + echo 10 >>a && + echo "other content" >>new_a && + git add a new_a && + test_tick && git commit -m C && + + git checkout B && + git mv a new_a && + test_tick && git commit -m B && + + git checkout B^0 && + test_must_fail git merge C && + git clean -f && + test_tick && git commit -m D && + git tag D && + + git checkout C^0 && + test_must_fail git merge B && + rm new_a~HEAD new_a && + printf "Incorrectly merged content" >>new_a && + git add -u && + test_tick && git commit -m E && + git tag E + ) ' test_expect_success 'git detects differently handled merges conflict' ' - git reset --hard && - git checkout D^0 && - - test_must_fail git merge -s recursive E^0 && - - test 3 = $(git ls-files -s | wc -l) && - test 3 = $(git ls-files -u | wc -l) && - test 0 = $(git ls-files -o | wc -l) && - - test $(git rev-parse :2:new_a) = $(git rev-parse D:new_a) && - test $(git rev-parse :3:new_a) = $(git rev-parse E:new_a) && - - git cat-file -p B:new_a >>merged && - git cat-file -p C:new_a >>merge-me && - >empty && - test_must_fail git merge-file \ - -L "Temporary merge branch 2" \ - -L "" \ - -L "Temporary merge branch 1" \ - merged empty merge-me && - sed -e "s/^\([<=>]\)/\1\1\1/" merged >merged-internal && - test $(git rev-parse :1:new_a) = $(git hash-object merged-internal) + ( + cd rename-add && + + git checkout D^0 && + + test_must_fail git merge -s recursive E^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 3 out && + git ls-files -o >out && + test_line_count = 1 out && + + git rev-parse >expect \ + D:new_a E:new_a && + git rev-parse >actual \ + :2:new_a :3:new_a && + test_cmp expect actual && + + git cat-file -p B:new_a >ours && + git cat-file -p C:new_a >theirs && + >empty && + test_must_fail git merge-file \ + -L "Temporary merge branch 2" \ + -L "" \ + -L "Temporary merge branch 1" \ + ours empty theirs && + sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect && + git cat-file -p :1:new_a >actual && + test_cmp expect actual + ) ' # @@ -236,220 +264,428 @@ test_expect_success 'git detects differently handled merges conflict' ' # Merging commits D & E should result in modify/delete conflict. test_expect_success 'setup criss-cross + modify/delete resolved differently' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - echo A >file && - git add file && - test_tick && - git commit -m A && - - git branch B && - git checkout -b C && - git rm file && - test_tick && - git commit -m C && - - git checkout B && - echo B >file && - git add file && - test_tick && - git commit -m B && - - git checkout B^0 && - test_must_fail git merge C && - echo B >file && - git add file && - test_tick && - git commit -m D && - git tag D && - - git checkout C^0 && - test_must_fail git merge B && - git rm file && - test_tick && - git commit -m E && - git tag E + test_create_repo modify-delete && + ( + cd modify-delete && + + echo A >file && + git add file && + test_tick && + git commit -m A && + + git branch B && + git checkout -b C && + git rm file && + test_tick && + git commit -m C && + + git checkout B && + echo B >file && + git add file && + test_tick && + git commit -m B && + + git checkout B^0 && + test_must_fail git merge C && + echo B >file && + git add file && + test_tick && + git commit -m D && + git tag D && + + git checkout C^0 && + test_must_fail git merge B && + git rm file && + test_tick && + git commit -m E && + git tag E + ) ' test_expect_success 'git detects conflict merging criss-cross+modify/delete' ' - git checkout D^0 && + ( + cd modify-delete && - test_must_fail git merge -s recursive E^0 && + git checkout D^0 && - test 2 -eq $(git ls-files -s | wc -l) && - test 2 -eq $(git ls-files -u | wc -l) && + test_must_fail git merge -s recursive E^0 && - test $(git rev-parse :1:file) = $(git rev-parse master:file) && - test $(git rev-parse :2:file) = $(git rev-parse B:file) + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + + git rev-parse >expect \ + master:file B:file && + git rev-parse >actual \ + :1:file :2:file && + test_cmp expect actual + ) ' test_expect_success 'git detects conflict merging criss-cross+modify/delete, reverse direction' ' - git reset --hard && - git checkout E^0 && + ( + cd modify-delete && + + git reset --hard && + git checkout E^0 && - test_must_fail git merge -s recursive D^0 && + test_must_fail git merge -s recursive D^0 && - test 2 -eq $(git ls-files -s | wc -l) && - test 2 -eq $(git ls-files -u | wc -l) && + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && - test $(git rev-parse :1:file) = $(git rev-parse master:file) && - test $(git rev-parse :3:file) = $(git rev-parse B:file) + git rev-parse >expect \ + master:file B:file && + git rev-parse >actual \ + :1:file :3:file && + test_cmp expect actual + ) ' +# SORRY FOR THE SUPER LONG DESCRIPTION, BUT THIS NEXT ONE IS HAIRY # # criss-cross + d/f conflict via add/add: # Commit A: Neither file 'a' nor directory 'a/' exists. # Commit B: Introduce 'a' # Commit C: Introduce 'a/file' -# Commit D: Merge B & C, keeping 'a' and deleting 'a/' -# -# Two different later cases: +# Commit D1: Merge B & C, keeping 'a' and deleting 'a/' # Commit E1: Merge B & C, deleting 'a' but keeping 'a/file' -# Commit E2: Merge B & C, deleting 'a' but keeping a slightly modified 'a/file' # -# B D +# B D1 or D2 # o---o # / \ / \ # A o X ? F # \ / \ / # o---o -# C E1 or E2 +# C E1 or E2 or E3 +# +# I'll describe D2, E2, & E3 (which are alternatives for D1 & E1) more below... +# +# Merging D1 & E1 requires we first create a virtual merge base X from +# merging A & B in memory. There are several possibilities for the merge-base: +# 1: Keep both 'a' and 'a/file' (assuming crazy filesystem allowing a tree +# with a directory and file at same path): results in merge of D1 & E1 +# being clean with both files deleted. Bad (no conflict detected). +# 2: Keep 'a' but not 'a/file': Merging D1 & E1 is clean and matches E1. Bad. +# 3: Keep 'a/file' but not 'a': Merging D1 & E1 is clean and matches D1. Bad. +# 4: Keep neither file: Merging D1 & E1 reports the D/F add/add conflict. # -# Merging D & E1 requires we first create a virtual merge base X from -# merging A & B in memory. Now, if X could keep both 'a' and 'a/file' in -# the index, then the merge of D & E1 could be resolved cleanly with both -# 'a' and 'a/file' removed. Since git does not currently allow creating -# such a tree, the best we can do is have X contain both 'a~<unique>' and -# 'a/file' resulting in the merge of D and E1 having a rename/delete -# conflict for 'a'. (Although this merge appears to be unsolvable with git -# currently, git could do a lot better than it currently does with these -# d/f conflicts, which is the purpose of this test.) +# So 4 sounds good for this case, but if we were to merge D1 & E3, where E3 +# is defined as: +# Commit E3: Merge B & C, keeping modified a, and deleting a/ +# then we'd get an add/add conflict for 'a', which seems suboptimal. A little +# creativity leads us to an alternate choice: +# 5: Keep 'a' as 'a~$UNIQUE' and a/file; results: +# Merge D1 & E1: rename/delete conflict for 'a'; a/file silently deleted +# Merge D1 & E3 is clean, as expected. # -# Merge of D & E2 has similar issues for path 'a', but should always result -# in a modify/delete conflict for path 'a/file'. +# So choice 5 at least provides some kind of conflict for the original case, +# and can merge cleanly as expected with D1 and E3. It also made things just +# slightly funny for merging D1 and e$, where E4 is defined as: +# Commit E4: Merge B & C, modifying 'a' and renaming to 'a2', and deleting 'a/' +# in this case, we'll get a rename/rename(1to2) conflict because a~$UNIQUE +# gets renamed to 'a' in D1 and to 'a2' in E4. But that's better than having +# two files (both 'a' and 'a2') sitting around without the user being notified +# that we could detect they were related and need to be merged. Also, choice +# 5 makes the handling of 'a/file' seem suboptimal. What if we were to merge +# D2 and E4, where D2 is: +# Commit D2: Merge B & C, renaming 'a'->'a2', keeping 'a/file' +# This would result in a clean merge with 'a2' having three-way merged +# contents (good), and deleting 'a/' (bad) -- it doesn't detect the +# conflict in how the different sides treated a/file differently. +# Continuing down the creative route: +# 6: Keep 'a' as 'a~$UNIQUE1' and keep 'a/' as 'a~$UNIQUE2/'; results: +# Merge D1 & E1: rename/delete conflict for 'a' and each path under 'a/'. +# Merge D1 & E3: clean, as expected. +# Merge D1 & E4: rename/rename(1to2) conflict on 'a' vs 'a2'. +# Merge D2 & E4: clean for 'a2', rename/delete for a/file # -# We run each merge in both directions, to check for directional issues -# with D/F conflict handling. +# Choice 6 could cause rename detection to take longer (providing more targets +# that need to be searched). Also, the conflict message for each path under +# 'a/' might be annoying unless we can detect it at the directory level, print +# it once, and then suppress it for individual filepaths underneath. +# +# +# As of time of writing, git uses choice 5. Directory rename detection and +# rename detection performance improvements might make choice 6 a desirable +# improvement. But we can at least document where we fall short for now... +# +# +# Historically, this testcase also used: +# Commit E2: Merge B & C, deleting 'a' but keeping slightly modified 'a/file' +# The merge of D1 & E2 is very similar to D1 & E1 -- it has similar issues for +# path 'a', but should always result in a modify/delete conflict for path +# 'a/file'. These tests ran the two merges +# D1 & E1 +# D1 & E2 +# in both directions, to check for directional issues with D/F conflict +# handling. Later we added +# D1 & E3 +# D1 & E4 +# D2 & E4 +# for good measure, though we only ran those one way because we had pretty +# good confidence in merge-recursive's directional handling of D/F issues. +# +# Just to summarize all the intermediate merge commits: +# Commit D1: Merge B & C, keeping a and deleting a/ +# Commit D2: Merge B & C, renaming a->a2, keeping a/file +# Commit E1: Merge B & C, deleting a but keeping a/file +# Commit E2: Merge B & C, deleting a but keeping slightly modified a/file +# Commit E3: Merge B & C, keeping modified a, and deleting a/ +# Commit E4: Merge B & C, modifying 'a' and renaming to 'a2', and deleting 'a/' # test_expect_success 'setup differently handled merges of directory/file conflict' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - >ignore-me && - git add ignore-me && - test_tick && - git commit -m A && - git tag A && - - git branch B && - git checkout -b C && - mkdir a && - echo 10 >a/file && - git add a/file && - test_tick && - git commit -m C && - - git checkout B && - echo 5 >a && - git add a && - test_tick && - git commit -m B && - - git checkout B^0 && - test_must_fail git merge C && - git clean -f && - rm -rf a/ && - echo 5 >a && - git add a && - test_tick && - git commit -m D && - git tag D && - - git checkout C^0 && - test_must_fail git merge B && - git clean -f && - git rm --cached a && - echo 10 >a/file && - git add a/file && - test_tick && - git commit -m E1 && - git tag E1 && - - git checkout C^0 && - test_must_fail git merge B && - git clean -f && - git rm --cached a && - printf "10\n11\n" >a/file && - git add a/file && - test_tick && - git commit -m E2 && - git tag E2 + test_create_repo directory-file && + ( + cd directory-file && + + >ignore-me && + git add ignore-me && + test_tick && + git commit -m A && + git tag A && + + git branch B && + git checkout -b C && + mkdir a && + test_write_lines a b c d e f g >a/file && + git add a/file && + test_tick && + git commit -m C && + + git checkout B && + test_write_lines 1 2 3 4 5 6 7 >a && + git add a && + test_tick && + git commit -m B && + + git checkout B^0 && + git merge -s ours -m D1 C^0 && + git tag D1 && + + git checkout B^0 && + test_must_fail git merge C^0 && + git clean -fd && + git rm -rf a/ && + git rm a && + git cat-file -p B:a >a2 && + git add a2 && + git commit -m D2 && + git tag D2 && + + git checkout C^0 && + git merge -s ours -m E1 B^0 && + git tag E1 && + + git checkout C^0 && + git merge -s ours -m E2 B^0 && + test_write_lines a b c d e f g h >a/file && + git add a/file && + git commit --amend -C HEAD && + git tag E2 && + + git checkout C^0 && + test_must_fail git merge B^0 && + git clean -fd && + git rm -rf a/ && + test_write_lines 1 2 3 4 5 6 7 8 >a && + git add a && + git commit -m E3 && + git tag E3 && + + git checkout C^0 && + test_must_fail git merge B^0 && + git clean -fd && + git rm -rf a/ && + git rm a && + test_write_lines 1 2 3 4 5 6 7 8 >a2 && + git add a2 && + git commit -m E4 && + git tag E4 + ) ' -test_expect_success 'merge of D & E1 fails but has appropriate contents' ' - get_clean_checkout D^0 && +test_expect_success 'merge of D1 & E1 fails but has appropriate contents' ' + test_when_finished "git -C directory-file reset --hard" && + test_when_finished "git -C directory-file clean -fdqx" && + ( + cd directory-file && + + git checkout D1^0 && + + test_must_fail git merge -s recursive E1^0 && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 1 out && + git ls-files -o >out && + test_line_count = 1 out && + + git rev-parse >expect \ + A:ignore-me B:a && + git rev-parse >actual \ + :0:ignore-me :2:a && + test_cmp expect actual + ) +' - test_must_fail git merge -s recursive E1^0 && +test_expect_success 'merge of E1 & D1 fails but has appropriate contents' ' + test_when_finished "git -C directory-file reset --hard" && + test_when_finished "git -C directory-file clean -fdqx" && + ( + cd directory-file && + + git checkout E1^0 && + + test_must_fail git merge -s recursive D1^0 && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 1 out && + git ls-files -o >out && + test_line_count = 1 out && + + git rev-parse >expect \ + A:ignore-me B:a && + git rev-parse >actual \ + :0:ignore-me :3:a && + test_cmp expect actual + ) +' - test 2 -eq $(git ls-files -s | wc -l) && - test 1 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && +test_expect_success 'merge of D1 & E2 fails but has appropriate contents' ' + test_when_finished "git -C directory-file reset --hard" && + test_when_finished "git -C directory-file clean -fdqx" && + ( + cd directory-file && - test $(git rev-parse :0:ignore-me) = $(git rev-parse A:ignore-me) && - test $(git rev-parse :2:a) = $(git rev-parse B:a) -' + git checkout D1^0 && -test_expect_success 'merge of E1 & D fails but has appropriate contents' ' - get_clean_checkout E1^0 && + test_must_fail git merge -s recursive E2^0 && - test_must_fail git merge -s recursive D^0 && + git ls-files -s >out && + test_line_count = 4 out && + git ls-files -u >out && + test_line_count = 3 out && + git ls-files -o >out && + test_line_count = 2 out && - test 2 -eq $(git ls-files -s | wc -l) && - test 1 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && + git rev-parse >expect \ + B:a E2:a/file C:a/file A:ignore-me && + git rev-parse >actual \ + :2:a :3:a/file :1:a/file :0:ignore-me && + test_cmp expect actual && - test $(git rev-parse :0:ignore-me) = $(git rev-parse A:ignore-me) && - test $(git rev-parse :3:a) = $(git rev-parse B:a) + test_path_is_file a~HEAD + ) ' -test_expect_success 'merge of D & E2 fails but has appropriate contents' ' - get_clean_checkout D^0 && +test_expect_success 'merge of E2 & D1 fails but has appropriate contents' ' + test_when_finished "git -C directory-file reset --hard" && + test_when_finished "git -C directory-file clean -fdqx" && + ( + cd directory-file && - test_must_fail git merge -s recursive E2^0 && + git checkout E2^0 && - test 4 -eq $(git ls-files -s | wc -l) && - test 3 -eq $(git ls-files -u | wc -l) && - test 1 -eq $(git ls-files -o | wc -l) && + test_must_fail git merge -s recursive D1^0 && - test $(git rev-parse :2:a) = $(git rev-parse B:a) && - test $(git rev-parse :3:a/file) = $(git rev-parse E2:a/file) && - test $(git rev-parse :1:a/file) = $(git rev-parse C:a/file) && - test $(git rev-parse :0:ignore-me) = $(git rev-parse A:ignore-me) && + git ls-files -s >out && + test_line_count = 4 out && + git ls-files -u >out && + test_line_count = 3 out && + git ls-files -o >out && + test_line_count = 2 out && - test -f a~HEAD -' - -test_expect_success 'merge of E2 & D fails but has appropriate contents' ' - get_clean_checkout E2^0 && + git rev-parse >expect \ + B:a E2:a/file C:a/file A:ignore-me && + git rev-parse >actual \ + :3:a :2:a/file :1:a/file :0:ignore-me && + test_cmp expect actual && - test_must_fail git merge -s recursive D^0 && + test_path_is_file a~D1^0 + ) +' - test 4 -eq $(git ls-files -s | wc -l) && - test 3 -eq $(git ls-files -u | wc -l) && - test 1 -eq $(git ls-files -o | wc -l) && +test_expect_success 'merge of D1 & E3 succeeds' ' + test_when_finished "git -C directory-file reset --hard" && + test_when_finished "git -C directory-file clean -fdqx" && + ( + cd directory-file && + + git checkout D1^0 && + + git merge -s recursive E3^0 && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 0 out && + git ls-files -o >out && + test_line_count = 1 out && + + git rev-parse >expect \ + A:ignore-me E3:a && + git rev-parse >actual \ + :0:ignore-me :0:a && + test_cmp expect actual + ) +' - test $(git rev-parse :3:a) = $(git rev-parse B:a) && - test $(git rev-parse :2:a/file) = $(git rev-parse E2:a/file) && - test $(git rev-parse :1:a/file) = $(git rev-parse C:a/file) && - test $(git rev-parse :0:ignore-me) = $(git rev-parse A:ignore-me) && +test_expect_success 'merge of D1 & E4 notifies user a and a2 are related' ' + test_when_finished "git -C directory-file reset --hard" && + test_when_finished "git -C directory-file clean -fdqx" && + ( + cd directory-file && + + git checkout D1^0 && + + test_must_fail git merge -s recursive E4^0 && + + git ls-files -s >out && + test_line_count = 4 out && + git ls-files -u >out && + test_line_count = 3 out && + git ls-files -o >out && + test_line_count = 1 out && + + git rev-parse >expect \ + A:ignore-me B:a D1:a E4:a2 && + git rev-parse >actual \ + :0:ignore-me :1:a~Temporary\ merge\ branch\ 2 :2:a :3:a2 && + test_cmp expect actual + ) +' - test -f a~D^0 +test_expect_failure 'merge of D2 & E4 merges a2s & reports conflict for a/file' ' + test_when_finished "git -C directory-file reset --hard" && + test_when_finished "git -C directory-file clean -fdqx" && + ( + cd directory-file && + + git checkout D2^0 && + + test_must_fail git merge -s recursive E4^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 1 out && + git ls-files -o >out && + test_line_count = 1 out && + + git rev-parse >expect \ + A:ignore-me E4:a2 D2:a/file && + git rev-parse >actual \ + :0:ignore-me :0:a2 :2:a/file && + test_cmp expect actual + ) ' # @@ -492,52 +728,58 @@ test_expect_success 'merge of E2 & D fails but has appropriate contents' ' # but that may cancel out at the final merge stage". test_expect_success 'setup rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' ' - git reset --hard && - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "1\n2\n3\n4\n5\n6\n" >a && - git add a && - git commit -m A && - git tag A && - - git checkout -b B A && - git mv a b && - echo 7 >>b && - git add -u && - git commit -m B && - - git checkout -b C A && - git mv a c && - git commit -m C && - - git checkout -q B^0 && - git merge --no-commit -s ours C^0 && - git mv b newname && - git commit -m "Merge commit C^0 into HEAD" && - git tag D && - - git checkout -q C^0 && - git merge --no-commit -s ours B^0 && - git mv c newname && - printf "7\n8\n" >>newname && - git add -u && - git commit -m "Merge commit B^0 into HEAD" && - git tag E + test_create_repo rename-squared-squared && + ( + cd rename-squared-squared && + + printf "1\n2\n3\n4\n5\n6\n" >a && + git add a && + git commit -m A && + git tag A && + + git checkout -b B A && + git mv a b && + echo 7 >>b && + git add -u && + git commit -m B && + + git checkout -b C A && + git mv a c && + git commit -m C && + + git checkout -q B^0 && + git merge --no-commit -s ours C^0 && + git mv b newname && + git commit -m "Merge commit C^0 into HEAD" && + git tag D && + + git checkout -q C^0 && + git merge --no-commit -s ours B^0 && + git mv c newname && + printf "7\n8\n" >>newname && + git add -u && + git commit -m "Merge commit B^0 into HEAD" && + git tag E + ) ' test_expect_success 'handle rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' ' - git checkout D^0 && + ( + cd rename-squared-squared && + + git checkout D^0 && - git merge -s recursive E^0 && + git merge -s recursive E^0 && - test 1 -eq $(git ls-files -s | wc -l) && - test 0 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && + git ls-files -s >out && + test_line_count = 1 out && + git ls-files -u >out && + test_line_count = 0 out && + git ls-files -o >out && + test_line_count = 1 out && - test $(git rev-parse HEAD:newname) = $(git rev-parse E:newname) + test $(git rev-parse HEAD:newname) = $(git rev-parse E:newname) + ) ' # @@ -562,59 +804,72 @@ test_expect_success 'handle rename/rename(1to2)/modify followed by what looks li # renaming carefully (both in the virtual merge base and later), and getting # content merge handled. -test_expect_success 'setup criss-cross + rename/rename/add + modify/modify' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "lots\nof\nwords\nand\ncontent\n" >a && - git add a && - git commit -m A && - git tag A && - - git checkout -b B A && - git mv a b && - git commit -m B && - - git checkout -b C A && - git mv a c && - printf "2\n3\n4\n5\n6\n7\n" >a && - git add a && - git commit -m C && - - git checkout B^0 && - git merge --no-commit -s ours C^0 && - git checkout C -- a c && - mv a old_a && - echo 1 >a && - cat old_a >>a && - rm old_a && - git add -u && - git commit -m "Merge commit C^0 into HEAD" && - git tag D && - - git checkout C^0 && - git merge --no-commit -s ours B^0 && - git checkout B -- b && - echo 8 >>a && - git add -u && - git commit -m "Merge commit B^0 into HEAD" && - git tag E +test_expect_success 'setup criss-cross + rename/rename/add-source + modify/modify' ' + test_create_repo rename-rename-add-source && + ( + cd rename-rename-add-source && + + printf "lots\nof\nwords\nand\ncontent\n" >a && + git add a && + git commit -m A && + git tag A && + + git checkout -b B A && + git mv a b && + git commit -m B && + + git checkout -b C A && + git mv a c && + printf "2\n3\n4\n5\n6\n7\n" >a && + git add a && + git commit -m C && + + git checkout B^0 && + git merge --no-commit -s ours C^0 && + git checkout C -- a c && + mv a old_a && + echo 1 >a && + cat old_a >>a && + rm old_a && + git add -u && + git commit -m "Merge commit C^0 into HEAD" && + git tag D && + + git checkout C^0 && + git merge --no-commit -s ours B^0 && + git checkout B -- b && + echo 8 >>a && + git add -u && + git commit -m "Merge commit B^0 into HEAD" && + git tag E + ) ' test_expect_failure 'detect rename/rename/add-source for virtual merge-base' ' - git checkout D^0 && - - git merge -s recursive E^0 && - - test 3 -eq $(git ls-files -s | wc -l) && - test 0 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && - - test $(git rev-parse HEAD:b) = $(git rev-parse A:a) && - test $(git rev-parse HEAD:c) = $(git rev-parse A:a) && - test "$(cat a)" = "$(printf "1\n2\n3\n4\n5\n6\n7\n8\n")" + ( + cd rename-rename-add-source && + + git checkout D^0 && + + git merge -s recursive E^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 0 out && + git ls-files -o >out && + test_line_count = 1 out && + + printf "1\n2\n3\n4\n5\n6\n7\n8\n" >correct && + git rev-parse >expect \ + A:a A:a \ + correct && + git rev-parse >actual \ + :0:b :0:c && + git hash-object >>actual \ + a && + test_cmp expect actual + ) ' # @@ -638,52 +893,513 @@ test_expect_failure 'detect rename/rename/add-source for virtual merge-base' ' # base of B & C needs to not delete B:c for that to work, though... test_expect_success 'setup criss-cross+rename/rename/add-dest + simple modify' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - >a && - git add a && - git commit -m A && - git tag A && - - git checkout -b B A && - git mv a b && - printf "1\n2\n3\n4\n5\n6\n7\n" >c && - git add c && - git commit -m B && - - git checkout -b C A && - git mv a c && - git commit -m C && - - git checkout B^0 && - git merge --no-commit -s ours C^0 && - git mv b a && - git commit -m "D is like B but renames b back to a" && - git tag D && - - git checkout B^0 && - git merge --no-commit -s ours C^0 && - git mv b a && - echo 8 >>c && - git add c && - git commit -m "E like D but has mod in c" && - git tag E + test_create_repo rename-rename-add-dest && + ( + cd rename-rename-add-dest && + + >a && + git add a && + git commit -m A && + git tag A && + + git checkout -b B A && + git mv a b && + printf "1\n2\n3\n4\n5\n6\n7\n" >c && + git add c && + git commit -m B && + + git checkout -b C A && + git mv a c && + git commit -m C && + + git checkout B^0 && + git merge --no-commit -s ours C^0 && + git mv b a && + git commit -m "D is like B but renames b back to a" && + git tag D && + + git checkout B^0 && + git merge --no-commit -s ours C^0 && + git mv b a && + echo 8 >>c && + git add c && + git commit -m "E like D but has mod in c" && + git tag E + ) ' test_expect_success 'virtual merge base handles rename/rename(1to2)/add-dest' ' - git checkout D^0 && + ( + cd rename-rename-add-dest && + + git checkout D^0 && + + git merge -s recursive E^0 && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 0 out && + git ls-files -o >out && + test_line_count = 1 out && + + git rev-parse >expect \ + A:a E:c && + git rev-parse >actual \ + :0:a :0:c && + test_cmp expect actual + ) +' + +# +# criss-cross with modify/modify on a symlink: +# +# B D +# o---o +# / \ / \ +# A o X ? F +# \ / \ / +# o---o +# C E +# +# Commit A: simple simlink fickle->lagoon +# Commit B: redirect fickle->disneyland +# Commit C: redirect fickle->home +# Commit D: merge B&C, resolving in favor of B +# Commit E: merge B&C, resolving in favor of C +# +# This is an obvious modify/modify conflict for the symlink 'fickle'. Can +# git detect it? + +test_expect_success 'setup symlink modify/modify' ' + test_create_repo symlink-modify-modify && + ( + cd symlink-modify-modify && + + test_ln_s_add lagoon fickle && + git commit -m A && + git tag A && + + git checkout -b B A && + git rm fickle && + test_ln_s_add disneyland fickle && + git commit -m B && + + git checkout -b C A && + git rm fickle && + test_ln_s_add home fickle && + git add fickle && + git commit -m C && + + git checkout -q B^0 && + git merge -s ours -m D C^0 && + git tag D && + + git checkout -q C^0 && + git merge -s ours -m E B^0 && + git tag E + ) +' + +test_expect_failure 'check symlink modify/modify' ' + ( + cd symlink-modify-modify && + + git checkout D^0 && + + test_must_fail git merge -s recursive E^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 3 out && + git ls-files -o >out && + test_line_count = 1 out + ) +' + +# +# criss-cross with add/add of a symlink: +# +# B D +# o---o +# / \ / \ +# A o X ? F +# \ / \ / +# o---o +# C E +# +# Commit A: No symlink or path exists yet +# Commit B: set up symlink: fickle->disneyland +# Commit C: set up symlink: fickle->home +# Commit D: merge B&C, resolving in favor of B +# Commit E: merge B&C, resolving in favor of C +# +# This is an obvious add/add conflict for the symlink 'fickle'. Can +# git detect it? + +test_expect_success 'setup symlink add/add' ' + test_create_repo symlink-add-add && + ( + cd symlink-add-add && + + touch ignoreme && + git add ignoreme && + git commit -m A && + git tag A && + + git checkout -b B A && + test_ln_s_add disneyland fickle && + git commit -m B && + + git checkout -b C A && + test_ln_s_add home fickle && + git add fickle && + git commit -m C && + + git checkout -q B^0 && + git merge -s ours -m D C^0 && + git tag D && + + git checkout -q C^0 && + git merge -s ours -m E B^0 && + git tag E + ) +' + +test_expect_failure 'check symlink add/add' ' + ( + cd symlink-add-add && + + git checkout D^0 && + + test_must_fail git merge -s recursive E^0 && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out + ) +' + +# +# criss-cross with modify/modify on a submodule: +# +# B D +# o---o +# / \ / \ +# A o X ? F +# \ / \ / +# o---o +# C E +# +# Commit A: simple submodule repo +# Commit B: update repo +# Commit C: update repo differently +# Commit D: merge B&C, resolving in favor of B +# Commit E: merge B&C, resolving in favor of C +# +# This is an obvious modify/modify conflict for the submodule 'repo'. Can +# git detect it? + +test_expect_success 'setup submodule modify/modify' ' + test_create_repo submodule-modify-modify && + ( + cd submodule-modify-modify && + + test_create_repo submod && + ( + cd submod && + touch file-A && + git add file-A && + git commit -m A && + git tag A && + + git checkout -b B A && + touch file-B && + git add file-B && + git commit -m B && + git tag B && + + git checkout -b C A && + touch file-C && + git add file-C && + git commit -m C && + git tag C + ) && + + git -C submod reset --hard A && + git add submod && + git commit -m A && + git tag A && + + git checkout -b B A && + git -C submod reset --hard B && + git add submod && + git commit -m B && + + git checkout -b C A && + git -C submod reset --hard C && + git add submod && + git commit -m C && + + git checkout -q B^0 && + git merge -s ours -m D C^0 && + git tag D && + + git checkout -q C^0 && + git merge -s ours -m E B^0 && + git tag E + ) +' + +test_expect_failure 'check submodule modify/modify' ' + ( + cd submodule-modify-modify && + + git checkout D^0 && + + test_must_fail git merge -s recursive E^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 3 out && + git ls-files -o >out && + test_line_count = 1 out + ) +' + +# +# criss-cross with add/add on a submodule: +# +# B D +# o---o +# / \ / \ +# A o X ? F +# \ / \ / +# o---o +# C E +# +# Commit A: nothing of note +# Commit B: introduce submodule repo +# Commit C: introduce submodule repo at different commit +# Commit D: merge B&C, resolving in favor of B +# Commit E: merge B&C, resolving in favor of C +# +# This is an obvious add/add conflict for the submodule 'repo'. Can +# git detect it? + +test_expect_success 'setup submodule add/add' ' + test_create_repo submodule-add-add && + ( + cd submodule-add-add && + + test_create_repo submod && + ( + cd submod && + touch file-A && + git add file-A && + git commit -m A && + git tag A && + + git checkout -b B A && + touch file-B && + git add file-B && + git commit -m B && + git tag B && + + git checkout -b C A && + touch file-C && + git add file-C && + git commit -m C && + git tag C + ) && + + touch irrelevant-file && + git add irrelevant-file && + git commit -m A && + git tag A && + + git checkout -b B A && + git -C submod reset --hard B && + git add submod && + git commit -m B && + + git checkout -b C A && + git -C submod reset --hard C && + git add submod && + git commit -m C && + + git checkout -q B^0 && + git merge -s ours -m D C^0 && + git tag D && + + git checkout -q C^0 && + git merge -s ours -m E B^0 && + git tag E + ) +' + +test_expect_failure 'check submodule add/add' ' + ( + cd submodule-add-add && + + git checkout D^0 && + + test_must_fail git merge -s recursive E^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out + ) +' + +# +# criss-cross with conflicting entry types: +# +# B D +# o---o +# / \ / \ +# A o X ? F +# \ / \ / +# o---o +# C E +# +# Commit A: nothing of note +# Commit B: introduce submodule 'path' +# Commit C: introduce symlink 'path' +# Commit D: merge B&C, resolving in favor of B +# Commit E: merge B&C, resolving in favor of C +# +# This is an obvious add/add conflict for 'path'. Can git detect it? + +test_expect_success 'setup conflicting entry types (submodule vs symlink)' ' + test_create_repo submodule-symlink-add-add && + ( + cd submodule-symlink-add-add && + + test_create_repo path && + ( + cd path && + touch file-B && + git add file-B && + git commit -m B && + git tag B + ) && + + touch irrelevant-file && + git add irrelevant-file && + git commit -m A && + git tag A && + + git checkout -b B A && + git -C path reset --hard B && + git add path && + git commit -m B && + + git checkout -b C A && + rm -rf path/ && + test_ln_s_add irrelevant-file path && + git commit -m C && + + git checkout -q B^0 && + git merge -s ours -m D C^0 && + git tag D && + + git checkout -q C^0 && + git merge -s ours -m E B^0 && + git tag E + ) +' + +test_expect_failure 'check conflicting entry types (submodule vs symlink)' ' + ( + cd submodule-symlink-add-add && + + git checkout D^0 && + + test_must_fail git merge -s recursive E^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out + ) +' + +# +# criss-cross with regular files that have conflicting modes: +# +# B D +# o---o +# / \ / \ +# A o X ? F +# \ / \ / +# o---o +# C E +# +# Commit A: nothing of note +# Commit B: introduce file source_me.bash, not executable +# Commit C: introduce file source_me.bash, executable +# Commit D: merge B&C, resolving in favor of B +# Commit E: merge B&C, resolving in favor of C +# +# This is an obvious add/add mode conflict. Can git detect it? + +test_expect_success 'setup conflicting modes for regular file' ' + test_create_repo regular-file-mode-conflict && + ( + cd regular-file-mode-conflict && + + touch irrelevant-file && + git add irrelevant-file && + git commit -m A && + git tag A && + + git checkout -b B A && + echo "command_to_run" >source_me.bash && + git add source_me.bash && + git commit -m B && + + git checkout -b C A && + echo "command_to_run" >source_me.bash && + git add source_me.bash && + test_chmod +x source_me.bash && + git commit -m C && + + git checkout -q B^0 && + git merge -s ours -m D C^0 && + git tag D && + + git checkout -q C^0 && + git merge -s ours -m E B^0 && + git tag E + ) +' + +test_expect_failure 'check conflicting modes for regular file' ' + ( + cd regular-file-mode-conflict && - git merge -s recursive E^0 && + git checkout D^0 && - test 2 -eq $(git ls-files -s | wc -l) && - test 0 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && + test_must_fail git merge -s recursive E^0 && - test $(git rev-parse HEAD:a) = $(git rev-parse A:a) && - test $(git rev-parse HEAD:c) = $(git rev-parse E:c) + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out + ) ' test_done diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh index 411550d2b6..07dd09d985 100755 --- a/t/t6042-merge-rename-corner-cases.sh +++ b/t/t6042-merge-rename-corner-cases.sh @@ -6,31 +6,40 @@ test_description="recursive merge corner cases w/ renames but not criss-crosses" . ./test-lib.sh test_expect_success 'setup rename/delete + untracked file' ' - echo "A pretty inscription" >ring && - git add ring && - test_tick && - git commit -m beginning && - - git branch people && - git checkout -b rename-the-ring && - git mv ring one-ring-to-rule-them-all && - test_tick && - git commit -m fullname && - - git checkout people && - git rm ring && - echo gollum >owner && - git add owner && - test_tick && - git commit -m track-people-instead-of-objects && - echo "Myyy PRECIOUSSS" >ring + test_create_repo rename-delete-untracked && + ( + cd rename-delete-untracked && + + echo "A pretty inscription" >ring && + git add ring && + test_tick && + git commit -m beginning && + + git branch people && + git checkout -b rename-the-ring && + git mv ring one-ring-to-rule-them-all && + test_tick && + git commit -m fullname && + + git checkout people && + git rm ring && + echo gollum >owner && + git add owner && + test_tick && + git commit -m track-people-instead-of-objects && + echo "Myyy PRECIOUSSS" >ring + ) ' test_expect_success "Does git preserve Gollum's precious artifact?" ' - test_must_fail git merge -s recursive rename-the-ring && + ( + cd rename-delete-untracked && - # Make sure git did not delete an untracked file - test -f ring + test_must_fail git merge -s recursive rename-the-ring && + + # Make sure git did not delete an untracked file + test_path_is_file ring + ) ' # Testcase setup for rename/modify/add-source: @@ -41,96 +50,125 @@ test_expect_success "Does git preserve Gollum's precious artifact?" ' # We should be able to merge B & C cleanly test_expect_success 'setup rename/modify/add-source conflict' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "1\n2\n3\n4\n5\n6\n7\n" >a && - git add a && - git commit -m A && - git tag A && - - git checkout -b B A && - echo 8 >>a && - git add a && - git commit -m B && - - git checkout -b C A && - git mv a b && - echo something completely different >a && - git add a && - git commit -m C + test_create_repo rename-modify-add-source && + ( + cd rename-modify-add-source && + + printf "1\n2\n3\n4\n5\n6\n7\n" >a && + git add a && + git commit -m A && + git tag A && + + git checkout -b B A && + echo 8 >>a && + git add a && + git commit -m B && + + git checkout -b C A && + git mv a b && + echo something completely different >a && + git add a && + git commit -m C + ) ' test_expect_failure 'rename/modify/add-source conflict resolvable' ' - git checkout B^0 && + ( + cd rename-modify-add-source && - git merge -s recursive C^0 && + git checkout B^0 && - test $(git rev-parse B:a) = $(git rev-parse b) && - test $(git rev-parse C:a) = $(git rev-parse a) + git merge -s recursive C^0 && + + git rev-parse >expect \ + B:a C:a && + git rev-parse >actual \ + b c && + test_cmp expect actual + ) ' test_expect_success 'setup resolvable conflict missed if rename missed' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "1\n2\n3\n4\n5\n" >a && - echo foo >b && - git add a b && - git commit -m A && - git tag A && - - git checkout -b B A && - git mv a c && - echo "Completely different content" >a && - git add a && - git commit -m B && - - git checkout -b C A && - echo 6 >>a && - git add a && - git commit -m C + test_create_repo break-detection-1 && + ( + cd break-detection-1 && + + printf "1\n2\n3\n4\n5\n" >a && + echo foo >b && + git add a b && + git commit -m A && + git tag A && + + git checkout -b B A && + git mv a c && + echo "Completely different content" >a && + git add a && + git commit -m B && + + git checkout -b C A && + echo 6 >>a && + git add a && + git commit -m C + ) ' test_expect_failure 'conflict caused if rename not detected' ' - git checkout -q C^0 && - git merge -s recursive B^0 && - - test 3 -eq $(git ls-files -s | wc -l) && - test 0 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && - - test_line_count = 6 c && - test $(git rev-parse HEAD:a) = $(git rev-parse B:a) && - test $(git rev-parse HEAD:b) = $(git rev-parse A:b) + ( + cd break-detection-1 && + + git checkout -q C^0 && + git merge -s recursive B^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 0 out && + git ls-files -o >out && + test_line_count = 1 out && + + test_line_count = 6 c && + git rev-parse >expect \ + B:a A:b && + git rev-parse >actual \ + :0:a :0:b && + test_cmp expect actual + ) ' test_expect_success 'setup conflict resolved wrong if rename missed' ' - git reset --hard && - git clean -f && - - git checkout -b D A && - echo 7 >>a && - git add a && - git mv a c && - echo "Completely different content" >a && - git add a && - git commit -m D && - - git checkout -b E A && - git rm a && - echo "Completely different content" >>a && - git add a && - git commit -m E + test_create_repo break-detection-2 && + ( + cd break-detection-2 && + + printf "1\n2\n3\n4\n5\n" >a && + echo foo >b && + git add a b && + git commit -m A && + git tag A && + + git checkout -b D A && + echo 7 >>a && + git add a && + git mv a c && + echo "Completely different content" >a && + git add a && + git commit -m D && + + git checkout -b E A && + git rm a && + echo "Completely different content" >>a && + git add a && + git commit -m E + ) ' test_expect_failure 'missed conflict if rename not detected' ' - git checkout -q E^0 && - test_must_fail git merge -s recursive D^0 + ( + cd break-detection-2 && + + git checkout -q E^0 && + test_must_fail git merge -s recursive D^0 + ) ' # Tests for undetected rename/add-source causing a file to erroneously be @@ -145,198 +183,233 @@ test_expect_failure 'missed conflict if rename not detected' ' # Commit C: rename a->b, add unrelated a test_expect_success 'setup undetected rename/add-source causes data loss' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "1\n2\n3\n4\n5\n" >a && - git add a && - git commit -m A && - git tag A && - - git checkout -b B A && - git mv a b && - git commit -m B && - - git checkout -b C A && - git mv a b && - echo foobar >a && - git add a && - git commit -m C + test_create_repo break-detection-3 && + ( + cd break-detection-3 && + + printf "1\n2\n3\n4\n5\n" >a && + git add a && + git commit -m A && + git tag A && + + git checkout -b B A && + git mv a b && + git commit -m B && + + git checkout -b C A && + git mv a b && + echo foobar >a && + git add a && + git commit -m C + ) ' test_expect_failure 'detect rename/add-source and preserve all data' ' - git checkout B^0 && + ( + cd break-detection-3 && - git merge -s recursive C^0 && + git checkout B^0 && - test 2 -eq $(git ls-files -s | wc -l) && - test 2 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && + git merge -s recursive C^0 && - test -f a && - test -f b && + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out && - test $(git rev-parse HEAD:b) = $(git rev-parse A:a) && - test $(git rev-parse HEAD:a) = $(git rev-parse C:a) + test_path_is_file a && + test_path_is_file b && + + git rev-parse >expect \ + A:a C:a && + git rev-parse >actual \ + :0:b :0:a && + test_cmp expect actual + ) ' test_expect_failure 'detect rename/add-source and preserve all data, merge other way' ' - git checkout C^0 && + ( + cd break-detection-3 && + + git checkout C^0 && - git merge -s recursive B^0 && + git merge -s recursive B^0 && - test 2 -eq $(git ls-files -s | wc -l) && - test 2 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out && - test -f a && - test -f b && + test_path_is_file a && + test_path_is_file b && - test $(git rev-parse HEAD:b) = $(git rev-parse A:a) && - test $(git rev-parse HEAD:a) = $(git rev-parse C:a) + git rev-parse >expect \ + A:a C:a && + git rev-parse >actual \ + :0:b :0:a && + test_cmp expect actual + ) ' test_expect_success 'setup content merge + rename/directory conflict' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "1\n2\n3\n4\n5\n6\n" >file && - git add file && - test_tick && - git commit -m base && - git tag base && - - git checkout -b right && - echo 7 >>file && - mkdir newfile && - echo junk >newfile/realfile && - git add file newfile/realfile && - test_tick && - git commit -m right && - - git checkout -b left-conflict base && - echo 8 >>file && - git add file && - git mv file newfile && - test_tick && - git commit -m left && - - git checkout -b left-clean base && - echo 0 >newfile && - cat file >>newfile && - git add newfile && - git rm file && - test_tick && - git commit -m left + test_create_repo rename-directory-1 && + ( + cd rename-directory-1 && + + printf "1\n2\n3\n4\n5\n6\n" >file && + git add file && + test_tick && + git commit -m base && + git tag base && + + git checkout -b right && + echo 7 >>file && + mkdir newfile && + echo junk >newfile/realfile && + git add file newfile/realfile && + test_tick && + git commit -m right && + + git checkout -b left-conflict base && + echo 8 >>file && + git add file && + git mv file newfile && + test_tick && + git commit -m left && + + git checkout -b left-clean base && + echo 0 >newfile && + cat file >>newfile && + git add newfile && + git rm file && + test_tick && + git commit -m left + ) ' test_expect_success 'rename/directory conflict + clean content merge' ' - git reset --hard && - git reset --hard && - git clean -fdqx && + ( + cd rename-directory-1 && - git checkout left-clean^0 && + git checkout left-clean^0 && - test_must_fail git merge -s recursive right^0 && + test_must_fail git merge -s recursive right^0 && - test 2 -eq $(git ls-files -s | wc -l) && - test 1 -eq $(git ls-files -u | wc -l) && - test 1 -eq $(git ls-files -o | wc -l) && + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 1 out && + git ls-files -o >out && + test_line_count = 2 out && - echo 0 >expect && - git cat-file -p base:file >>expect && - echo 7 >>expect && - test_cmp expect newfile~HEAD && + echo 0 >expect && + git cat-file -p base:file >>expect && + echo 7 >>expect && + test_cmp expect newfile~HEAD && - test $(git rev-parse :2:newfile) = $(git hash-object expect) && + test $(git rev-parse :2:newfile) = $(git hash-object expect) && - test -f newfile/realfile && - test -f newfile~HEAD + test_path_is_file newfile/realfile && + test_path_is_file newfile~HEAD + ) ' test_expect_success 'rename/directory conflict + content merge conflict' ' - git reset --hard && - git reset --hard && - git clean -fdqx && - - git checkout left-conflict^0 && - - test_must_fail git merge -s recursive right^0 && - - test 4 -eq $(git ls-files -s | wc -l) && - test 3 -eq $(git ls-files -u | wc -l) && - test 1 -eq $(git ls-files -o | wc -l) && - - git cat-file -p left-conflict:newfile >left && - git cat-file -p base:file >base && - git cat-file -p right:file >right && - test_must_fail git merge-file \ - -L "HEAD:newfile" \ - -L "" \ - -L "right^0:file" \ - left base right && - test_cmp left newfile~HEAD && - - test $(git rev-parse :1:newfile) = $(git rev-parse base:file) && - test $(git rev-parse :2:newfile) = $(git rev-parse left-conflict:newfile) && - test $(git rev-parse :3:newfile) = $(git rev-parse right:file) && - - test -f newfile/realfile && - test -f newfile~HEAD + ( + cd rename-directory-1 && + + git reset --hard && + git reset --hard && + git clean -fdqx && + + git checkout left-conflict^0 && + + test_must_fail git merge -s recursive right^0 && + + git ls-files -s >out && + test_line_count = 4 out && + git ls-files -u >out && + test_line_count = 3 out && + git ls-files -o >out && + test_line_count = 2 out && + + git cat-file -p left-conflict:newfile >left && + git cat-file -p base:file >base && + git cat-file -p right:file >right && + test_must_fail git merge-file \ + -L "HEAD:newfile" \ + -L "" \ + -L "right^0:file" \ + left base right && + test_cmp left newfile~HEAD && + + git rev-parse >expect \ + base:file left-conflict:newfile right:file && + git rev-parse >actual \ + :1:newfile :2:newfile :3:newfile && + test_cmp expect actual && + + test_path_is_file newfile/realfile && + test_path_is_file newfile~HEAD + ) ' test_expect_success 'setup content merge + rename/directory conflict w/ disappearing dir' ' - git reset --hard && - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - mkdir sub && - printf "1\n2\n3\n4\n5\n6\n" >sub/file && - git add sub/file && - test_tick && - git commit -m base && - git tag base && - - git checkout -b right && - echo 7 >>sub/file && - git add sub/file && - test_tick && - git commit -m right && - - git checkout -b left base && - echo 0 >newfile && - cat sub/file >>newfile && - git rm sub/file && - mv newfile sub && - git add sub && - test_tick && - git commit -m left + test_create_repo rename-directory-2 && + ( + cd rename-directory-2 && + + mkdir sub && + printf "1\n2\n3\n4\n5\n6\n" >sub/file && + git add sub/file && + test_tick && + git commit -m base && + git tag base && + + git checkout -b right && + echo 7 >>sub/file && + git add sub/file && + test_tick && + git commit -m right && + + git checkout -b left base && + echo 0 >newfile && + cat sub/file >>newfile && + git rm sub/file && + mv newfile sub && + git add sub && + test_tick && + git commit -m left + ) ' test_expect_success 'disappearing dir in rename/directory conflict handled' ' - git reset --hard && - git clean -fdqx && + ( + cd rename-directory-2 && - git checkout left^0 && + git checkout left^0 && - git merge -s recursive right^0 && + git merge -s recursive right^0 && - test 1 -eq $(git ls-files -s | wc -l) && - test 0 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && + git ls-files -s >out && + test_line_count = 1 out && + git ls-files -u >out && + test_line_count = 0 out && + git ls-files -o >out && + test_line_count = 1 out && - echo 0 >expect && - git cat-file -p base:sub/file >>expect && - echo 7 >>expect && - test_cmp expect sub && + echo 0 >expect && + git cat-file -p base:sub/file >>expect && + echo 7 >>expect && + test_cmp expect sub && - test -f sub + test_path_is_file sub + ) ' # Test for all kinds of things that can go wrong with rename/rename (2to1): @@ -352,48 +425,59 @@ test_expect_success 'disappearing dir in rename/directory conflict handled' ' # * Nothing else should be present. Is anything? test_expect_success 'setup rename/rename (2to1) + modify/modify' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "1\n2\n3\n4\n5\n" >a && - printf "5\n4\n3\n2\n1\n" >b && - git add a b && - git commit -m A && - git tag A && - - git checkout -b B A && - git mv a c && - echo 0 >>b && - git add b && - git commit -m B && - - git checkout -b C A && - git mv b c && - echo 6 >>a && - git add a && - git commit -m C + test_create_repo rename-rename-2to1 && + ( + cd rename-rename-2to1 && + + printf "1\n2\n3\n4\n5\n" >a && + printf "5\n4\n3\n2\n1\n" >b && + git add a b && + git commit -m A && + git tag A && + + git checkout -b B A && + git mv a c && + echo 0 >>b && + git add b && + git commit -m B && + + git checkout -b C A && + git mv b c && + echo 6 >>a && + git add a && + git commit -m C + ) ' test_expect_success 'handle rename/rename (2to1) conflict correctly' ' - git checkout B^0 && - - test_must_fail git merge -s recursive C^0 >out && - test_i18ngrep "CONFLICT (rename/rename)" out && - - test 2 -eq $(git ls-files -s | wc -l) && - test 2 -eq $(git ls-files -u | wc -l) && - test 2 -eq $(git ls-files -u c | wc -l) && - test 3 -eq $(git ls-files -o | wc -l) && - - test ! -f a && - test ! -f b && - test -f c~HEAD && - test -f c~C^0 && - - test $(git hash-object c~HEAD) = $(git rev-parse C:a) && - test $(git hash-object c~C^0) = $(git rev-parse B:b) + ( + cd rename-rename-2to1 && + + git checkout B^0 && + + test_must_fail git merge -s recursive C^0 >out && + test_i18ngrep "CONFLICT (rename/rename)" out && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -u >out && + test_line_count = 2 out && + git ls-files -u c >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 3 out && + + test_path_is_missing a && + test_path_is_missing b && + test_path_is_file c~HEAD && + test_path_is_file c~C^0 && + + git rev-parse >expect \ + C:a B:b && + git hash-object >actual \ + c~HEAD c~C^0 && + test_cmp expect actual + ) ' # Testcase setup for simple rename/rename (1to2) conflict: @@ -401,44 +485,53 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' ' # Commit B: rename a->b # Commit C: rename a->c test_expect_success 'setup simple rename/rename (1to2) conflict' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - echo stuff >a && - git add a && - test_tick && - git commit -m A && - git tag A && - - git checkout -b B A && - git mv a b && - test_tick && - git commit -m B && - - git checkout -b C A && - git mv a c && - test_tick && - git commit -m C + test_create_repo rename-rename-1to2 && + ( + cd rename-rename-1to2 && + + echo stuff >a && + git add a && + test_tick && + git commit -m A && + git tag A && + + git checkout -b B A && + git mv a b && + test_tick && + git commit -m B && + + git checkout -b C A && + git mv a c && + test_tick && + git commit -m C + ) ' test_expect_success 'merge has correct working tree contents' ' - git checkout C^0 && - - test_must_fail git merge -s recursive B^0 && - - test 3 -eq $(git ls-files -s | wc -l) && - test 3 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && - - test $(git rev-parse :1:a) = $(git rev-parse A:a) && - test $(git rev-parse :3:b) = $(git rev-parse A:a) && - test $(git rev-parse :2:c) = $(git rev-parse A:a) && - - test ! -f a && - test $(git hash-object b) = $(git rev-parse A:a) && - test $(git hash-object c) = $(git rev-parse A:a) + ( + cd rename-rename-1to2 && + + git checkout C^0 && + + test_must_fail git merge -s recursive B^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 3 out && + git ls-files -o >out && + test_line_count = 1 out && + + test_path_is_missing a && + git rev-parse >expect \ + A:a A:a A:a \ + A:a A:a && + git rev-parse >actual \ + :1:a :3:b :2:c && + git hash-object >>actual \ + b c && + test_cmp expect actual + ) ' # Testcase setup for rename/rename(1to2)/add-source conflict: @@ -449,130 +542,400 @@ test_expect_success 'merge has correct working tree contents' ' # Merging of B & C should NOT be clean; there's a rename/rename conflict test_expect_success 'setup rename/rename(1to2)/add-source conflict' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - printf "1\n2\n3\n4\n5\n6\n7\n" >a && - git add a && - git commit -m A && - git tag A && - - git checkout -b B A && - git mv a b && - git commit -m B && - - git checkout -b C A && - git mv a c && - echo something completely different >a && - git add a && - git commit -m C + test_create_repo rename-rename-1to2-add-source-1 && + ( + cd rename-rename-1to2-add-source-1 && + + printf "1\n2\n3\n4\n5\n6\n7\n" >a && + git add a && + git commit -m A && + git tag A && + + git checkout -b B A && + git mv a b && + git commit -m B && + + git checkout -b C A && + git mv a c && + echo something completely different >a && + git add a && + git commit -m C + ) ' test_expect_failure 'detect conflict with rename/rename(1to2)/add-source merge' ' - git checkout B^0 && + ( + cd rename-rename-1to2-add-source-1 && + + git checkout B^0 && - test_must_fail git merge -s recursive C^0 && + test_must_fail git merge -s recursive C^0 && - test 4 -eq $(git ls-files -s | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && + git ls-files -s >out && + test_line_count = 4 out && + git ls-files -o >out && + test_line_count = 1 out && - test $(git rev-parse 3:a) = $(git rev-parse C:a) && - test $(git rev-parse 1:a) = $(git rev-parse A:a) && - test $(git rev-parse 2:b) = $(git rev-parse B:b) && - test $(git rev-parse 3:c) = $(git rev-parse C:c) && + git rev-parse >expect \ + C:a A:a B:b C:C && + git rev-parse >actual \ + :3:a :1:a :2:b :3:c && + test_cmp expect actual && - test -f a && - test -f b && - test -f c + test_path_is_file a && + test_path_is_file b && + test_path_is_file c + ) ' test_expect_success 'setup rename/rename(1to2)/add-source resolvable conflict' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - >a && - git add a && - test_tick && - git commit -m base && - git tag A && - - git checkout -b B A && - git mv a b && - test_tick && - git commit -m one && - - git checkout -b C A && - git mv a b && - echo important-info >a && - git add a && - test_tick && - git commit -m two + test_create_repo rename-rename-1to2-add-source-2 && + ( + cd rename-rename-1to2-add-source-2 && + + >a && + git add a && + test_tick && + git commit -m base && + git tag A && + + git checkout -b B A && + git mv a b && + test_tick && + git commit -m one && + + git checkout -b C A && + git mv a b && + echo important-info >a && + git add a && + test_tick && + git commit -m two + ) ' test_expect_failure 'rename/rename/add-source still tracks new a file' ' - git checkout C^0 && - git merge -s recursive B^0 && - - test 2 -eq $(git ls-files -s | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && - - test $(git rev-parse HEAD:a) = $(git rev-parse C:a) && - test $(git rev-parse HEAD:b) = $(git rev-parse A:a) + ( + cd rename-rename-1to2-add-source-2 && + + git checkout C^0 && + git merge -s recursive B^0 && + + git ls-files -s >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 1 out && + + git rev-parse >expect \ + C:a A:a && + git rev-parse >actual \ + :0:a :0:b && + test_cmp expect actual + ) ' test_expect_success 'setup rename/rename(1to2)/add-dest conflict' ' - git rm -rf . && - git clean -fdqx && - rm -rf .git && - git init && - - echo stuff >a && - git add a && - test_tick && - git commit -m base && - git tag A && - - git checkout -b B A && - git mv a b && - echo precious-data >c && - git add c && - test_tick && - git commit -m one && - - git checkout -b C A && - git mv a c && - echo important-info >b && - git add b && - test_tick && - git commit -m two + test_create_repo rename-rename-1to2-add-dest && + ( + cd rename-rename-1to2-add-dest && + + echo stuff >a && + git add a && + test_tick && + git commit -m base && + git tag A && + + git checkout -b B A && + git mv a b && + echo precious-data >c && + git add c && + test_tick && + git commit -m one && + + git checkout -b C A && + git mv a c && + echo important-info >b && + git add b && + test_tick && + git commit -m two + ) ' test_expect_success 'rename/rename/add-dest merge still knows about conflicting file versions' ' - git checkout C^0 && - test_must_fail git merge -s recursive B^0 && - - test 5 -eq $(git ls-files -s | wc -l) && - test 2 -eq $(git ls-files -u b | wc -l) && - test 2 -eq $(git ls-files -u c | wc -l) && - test 4 -eq $(git ls-files -o | wc -l) && - - test $(git rev-parse :1:a) = $(git rev-parse A:a) && - test $(git rev-parse :2:b) = $(git rev-parse C:b) && - test $(git rev-parse :3:b) = $(git rev-parse B:b) && - test $(git rev-parse :2:c) = $(git rev-parse C:c) && - test $(git rev-parse :3:c) = $(git rev-parse B:c) && - - test $(git hash-object c~HEAD) = $(git rev-parse C:c) && - test $(git hash-object c~B\^0) = $(git rev-parse B:c) && - test $(git hash-object b~HEAD) = $(git rev-parse C:b) && - test $(git hash-object b~B\^0) = $(git rev-parse B:b) && - - test ! -f b && - test ! -f c + ( + cd rename-rename-1to2-add-dest && + + git checkout C^0 && + test_must_fail git merge -s recursive B^0 && + + git ls-files -s >out && + test_line_count = 5 out && + git ls-files -u b >out && + test_line_count = 2 out && + git ls-files -u c >out && + test_line_count = 2 out && + git ls-files -o >out && + test_line_count = 5 out && + + git rev-parse >expect \ + A:a C:b B:b C:c B:c && + git rev-parse >actual \ + :1:a :2:b :3:b :2:c :3:c && + test_cmp expect actual && + + git rev-parse >expect \ + C:c B:c C:b B:b && + git hash-object >actual \ + c~HEAD c~B\^0 b~HEAD b~B\^0 && + test_cmp expect actual && + + test_path_is_missing b && + test_path_is_missing c + ) +' + +# Testcase rad, rename/add/delete +# Commit O: foo +# Commit A: rm foo, add different bar +# Commit B: rename foo->bar +# Expected: CONFLICT (rename/add/delete), two-way merged bar + +test_expect_success 'rad-setup: rename/add/delete conflict' ' + test_create_repo rad && + ( + cd rad && + echo "original file" >foo && + git add foo && + git commit -m "original" && + + git branch O && + git branch A && + git branch B && + + git checkout A && + git rm foo && + echo "different file" >bar && + git add bar && + git commit -m "Remove foo, add bar" && + + git checkout B && + git mv foo bar && + git commit -m "rename foo to bar" + ) +' + +test_expect_failure 'rad-check: rename/add/delete conflict' ' + ( + cd rad && + + git checkout B^0 && + test_must_fail git merge -s recursive A^0 >out 2>err && + + # Not sure whether the output should contain just one + # "CONFLICT (rename/add/delete)" line, or if it should break + # it into a pair of "CONFLICT (rename/delete)" and + # "CONFLICT (rename/add)"; allow for either. + test_i18ngrep "CONFLICT (rename.*add)" out && + test_i18ngrep "CONFLICT (rename.*delete)" out && + test_must_be_empty err && + + git ls-files -s >file_count && + test_line_count = 2 file_count && + git ls-files -u >file_count && + test_line_count = 2 file_count && + git ls-files -o >file_count && + test_line_count = 2 file_count && + + git rev-parse >actual \ + :2:bar :3:bar && + git rev-parse >expect \ + B:bar A:bar && + + test_cmp file_is_missing foo && + # bar should have two-way merged contents of the different + # versions of bar; check that content from both sides is + # present. + grep original bar && + grep different bar + ) +' + +# Testcase rrdd, rename/rename(2to1)/delete/delete +# Commit O: foo, bar +# Commit A: rename foo->baz, rm bar +# Commit B: rename bar->baz, rm foo +# Expected: CONFLICT (rename/rename/delete/delete), two-way merged baz + +test_expect_success 'rrdd-setup: rename/rename(2to1)/delete/delete conflict' ' + test_create_repo rrdd && + ( + cd rrdd && + echo foo >foo && + echo bar >bar && + git add foo bar && + git commit -m O && + + git branch O && + git branch A && + git branch B && + + git checkout A && + git mv foo baz && + git rm bar && + git commit -m "Rename foo, remove bar" && + + git checkout B && + git mv bar baz && + git rm foo && + git commit -m "Rename bar, remove foo" + ) +' + +test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' ' + ( + cd rrdd && + + git checkout A^0 && + test_must_fail git merge -s recursive B^0 >out 2>err && + + # Not sure whether the output should contain just one + # "CONFLICT (rename/rename/delete/delete)" line, or if it + # should break it into three: "CONFLICT (rename/rename)" and + # two "CONFLICT (rename/delete)" lines; allow for either. + test_i18ngrep "CONFLICT (rename/rename)" out && + test_i18ngrep "CONFLICT (rename.*delete)" out && + test_must_be_empty err && + + git ls-files -s >file_count && + test_line_count = 2 file_count && + git ls-files -u >file_count && + test_line_count = 2 file_count && + git ls-files -o >file_count && + test_line_count = 2 file_count && + + git rev-parse >actual \ + :2:baz :3:baz && + git rev-parse >expect \ + O:foo O:bar && + + test_cmp file_is_missing foo && + test_cmp file_is_missing bar && + # baz should have two-way merged contents of the original + # contents of foo and bar; check that content from both sides + # is present. + grep foo baz && + grep bar baz + ) +' + +# Testcase mod6, chains of rename/rename(1to2) and rename/rename(2to1) +# Commit O: one, three, five +# Commit A: one->two, three->four, five->six +# Commit B: one->six, three->two, five->four +# Expected: six CONFLICT(rename/rename) messages, each path in two of the +# multi-way merged contents found in two, four, six + +test_expect_success 'mod6-setup: chains of rename/rename(1to2) and rename/rename(2to1)' ' + test_create_repo mod6 && + ( + cd mod6 && + test_seq 11 19 >one && + test_seq 31 39 >three && + test_seq 51 59 >five && + git add . && + test_tick && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git checkout A && + test_seq 10 19 >one && + echo 40 >>three && + git add one three && + git mv one two && + git mv three four && + git mv five six && + test_tick && + git commit -m "A" && + + git checkout B && + echo 20 >>one && + echo forty >>three && + echo 60 >>five && + git add one three five && + git mv one six && + git mv three two && + git mv five four && + test_tick && + git commit -m "B" + ) +' + +test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' ' + ( + cd mod6 && + + git checkout A^0 && + + test_must_fail git merge -s recursive B^0 >out 2>err && + + test_i18ngrep "CONFLICT (rename/rename)" out && + test_must_be_empty err && + + git ls-files -s >file_count && + test_line_count = 6 file_count && + git ls-files -u >file_count && + test_line_count = 6 file_count && + git ls-files -o >file_count && + test_line_count = 3 file_count && + + test_seq 10 20 >merged-one && + test_seq 51 60 >merged-five && + # Determine what the merge of three would give us. + test_seq 30 40 >three-side-A && + test_seq 31 39 >three-side-B && + echo forty >three-side-B && + >empty && + test_must_fail git merge-file \ + -L "HEAD" \ + -L "" \ + -L "B^0" \ + three-side-A empty three-side-B && + sed -e "s/^\([<=>]\)/\1\1\1/" three-side-A >merged-three && + + # Verify the index is as expected + git rev-parse >actual \ + :2:two :3:two \ + :2:four :3:four \ + :2:six :3:six && + git hash-object >expect \ + merged-one merged-three \ + merged-three merged-five \ + merged-five merged-one && + test_cmp expect actual && + + git cat-file -p :2:two >expect && + git cat-file -p :3:two >other && + test_must_fail git merge-file \ + -L "HEAD" -L "" -L "B^0" \ + expect empty other && + test_cmp expect two && + + git cat-file -p :2:four >expect && + git cat-file -p :3:four >other && + test_must_fail git merge-file \ + -L "HEAD" -L "" -L "B^0" \ + expect empty other && + test_cmp expect four && + + git cat-file -p :2:six >expect && + git cat-file -p :3:six >other && + test_must_fail git merge-file \ + -L "HEAD" -L "" -L "B^0" \ + expect empty other && + test_cmp expect six + ) ' test_done diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh index 2e28f2908d..4a71f17edd 100755 --- a/t/t6043-merge-rename-directories.sh +++ b/t/t6043-merge-rename-directories.sh @@ -3583,7 +3583,7 @@ test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conf grep -q stuff z/c && test_seq 1 10 >expected && echo stuff >>expected && - test_cmp expected z/c + test_cmp expected z/c && git ls-files -s >out && test_line_count = 4 out && diff --git a/t/t6044-merge-unrelated-index-changes.sh b/t/t6044-merge-unrelated-index-changes.sh index 23b86fb977..5e3779ebc9 100755 --- a/t/t6044-merge-unrelated-index-changes.sh +++ b/t/t6044-merge-unrelated-index-changes.sh @@ -82,7 +82,8 @@ test_expect_success 'ff update, important file modified' ' touch subdir/e && git add subdir/e && - test_must_fail git merge E^0 + test_must_fail git merge E^0 && + test_path_is_missing .git/MERGE_HEAD ' test_expect_success 'resolve, trivial' ' @@ -91,7 +92,8 @@ test_expect_success 'resolve, trivial' ' touch random_file && git add random_file && - test_must_fail git merge -s resolve C^0 + test_must_fail git merge -s resolve C^0 && + test_path_is_missing .git/MERGE_HEAD ' test_expect_success 'resolve, non-trivial' ' @@ -100,7 +102,8 @@ test_expect_success 'resolve, non-trivial' ' touch random_file && git add random_file && - test_must_fail git merge -s resolve D^0 + test_must_fail git merge -s resolve D^0 && + test_path_is_missing .git/MERGE_HEAD ' test_expect_success 'recursive' ' @@ -109,7 +112,8 @@ test_expect_success 'recursive' ' touch random_file && git add random_file && - test_must_fail git merge -s recursive C^0 + test_must_fail git merge -s recursive C^0 && + test_path_is_missing .git/MERGE_HEAD ' test_expect_success 'recursive, when merge branch matches merge base' ' @@ -118,7 +122,45 @@ test_expect_success 'recursive, when merge branch matches merge base' ' touch random_file && git add random_file && - test_must_fail git merge -s recursive F^0 + test_must_fail git merge -s recursive F^0 && + test_path_is_missing .git/MERGE_HEAD +' + +test_expect_success 'merge-recursive, when index==head but head!=HEAD' ' + git reset --hard && + git checkout C^0 && + + # Make index match B + git diff C B -- | git apply --cached && + # Merge B & F, with B as "head" + git merge-recursive A -- B F > out && + test_i18ngrep "Already up to date" out +' + +test_expect_success 'recursive, when file has staged changes not matching HEAD nor what a merge would give' ' + git reset --hard && + git checkout B^0 && + + mkdir subdir && + test_seq 1 10 >subdir/a && + git add subdir/a && + + # We have staged changes; merge should error out + test_must_fail git merge -s recursive E^0 2>err && + test_i18ngrep "changes to the following files would be overwritten" err +' + +test_expect_success 'recursive, when file has staged changes matching what a merge would give' ' + git reset --hard && + git checkout B^0 && + + mkdir subdir && + test_seq 1 11 >subdir/a && + git add subdir/a && + + # We have staged changes; merge should error out + test_must_fail git merge -s recursive E^0 2>err && + test_i18ngrep "changes to the following files would be overwritten" err ' test_expect_success 'octopus, unrelated file touched' ' @@ -127,7 +169,8 @@ test_expect_success 'octopus, unrelated file touched' ' touch random_file && git add random_file && - test_must_fail git merge C^0 D^0 + test_must_fail git merge C^0 D^0 && + test_path_is_missing .git/MERGE_HEAD ' test_expect_success 'octopus, related file removed' ' @@ -136,7 +179,8 @@ test_expect_success 'octopus, related file removed' ' git rm b && - test_must_fail git merge C^0 D^0 + test_must_fail git merge C^0 D^0 && + test_path_is_missing .git/MERGE_HEAD ' test_expect_success 'octopus, related file modified' ' @@ -145,7 +189,8 @@ test_expect_success 'octopus, related file modified' ' echo 12 >>a && git add a && - test_must_fail git merge C^0 D^0 + test_must_fail git merge C^0 D^0 && + test_path_is_missing .git/MERGE_HEAD ' test_expect_success 'ours' ' @@ -154,7 +199,8 @@ test_expect_success 'ours' ' touch random_file && git add random_file && - test_must_fail git merge -s ours C^0 + test_must_fail git merge -s ours C^0 && + test_path_is_missing .git/MERGE_HEAD ' test_expect_success 'subtree' ' @@ -163,7 +209,8 @@ test_expect_success 'subtree' ' touch random_file && git add random_file && - test_must_fail git merge -s subtree E^0 + test_must_fail git merge -s subtree E^0 && + test_path_is_missing .git/MERGE_HEAD ' test_done diff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh index fcefffcaec..38e24f787c 100755 --- a/t/t6046-merge-skip-unneeded-updates.sh +++ b/t/t6046-merge-skip-unneeded-updates.sh @@ -366,7 +366,9 @@ test_expect_success '2c-check: Modify b & add c VS rename b->c' ' git checkout A^0 && - GIT_MERGE_VERBOSITY=3 test_must_fail git merge -s recursive B^0 >out 2>err && + GIT_MERGE_VERBOSITY=3 && + export GIT_MERGE_VERBOSITY && + test_must_fail git merge -s recursive B^0 >out 2>err && test_i18ngrep "CONFLICT (rename/add): Rename b->c" out && test_i18ngrep ! "Skipped c" out && diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 48379aa0ee..e0496da812 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -795,4 +795,15 @@ test_expect_success ':remotename and :remoteref' ' ) ' +test_expect_success 'for-each-ref --ignore-case ignores case' ' + >expect && + git for-each-ref --format="%(refname)" refs/heads/MASTER >actual && + test_cmp expect actual && + + echo refs/heads/master >expect && + git for-each-ref --format="%(refname)" --ignore-case \ + refs/heads/MASTER >actual && + test_cmp expect actual +' + test_done diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index cc3fd2baf2..9e59e5a5dd 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -509,7 +509,7 @@ test_expect_success 'moving nested submodules' ' touch nested_level1 && git init && git add . && - git commit -m "nested level 1" + git commit -m "nested level 1" && git submodule add ../sub_nested_nested && git commit -m "add nested level 2" ) && diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index ec4b160ddb..e23de7d0b5 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -107,6 +107,21 @@ test_expect_success 'test that the directory was renamed' ' test dir/D = "$(cat diroh/D.t)" ' +V=$(git rev-parse HEAD) + +test_expect_success 'populate --state-branch' ' + git filter-branch --state-branch state -f --tree-filter "touch file || :" HEAD +' + +W=$(git rev-parse HEAD) + +test_expect_success 'using --state-branch to skip already rewritten commits' ' + test_when_finished git reset --hard $V && + git reset --hard $V && + git filter-branch --state-branch state -f --tree-filter "touch file || :" HEAD && + test_cmp_rev $W HEAD +' + git tag oldD HEAD~4 test_expect_success 'rewrite one branch, keeping a side branch' ' git branch modD oldD && diff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh index b4b49eeb08..291a1e2b07 100755 --- a/t/t7030-verify-tag.sh +++ b/t/t7030-verify-tag.sh @@ -74,7 +74,7 @@ test_expect_success GPG 'verify and show signatures' ' test_expect_success GPG 'detect fudged signature' ' git cat-file tag seventh-signed >raw && - sed -e "s/seventh/7th forged/" raw >forged1 && + sed -e "/^tag / s/seventh/7th forged/" raw >forged1 && git hash-object -w -t tag forged1 >forged1.tag && test_must_fail git verify-tag $(cat forged1.tag) 2>actual1 && grep "BAD signature from" actual1 && diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh index 98b7d7b969..bd10a96727 100755 --- a/t/t7105-reset-patch.sh +++ b/t/t7105-reset-patch.sh @@ -19,20 +19,20 @@ test_expect_success PERL 'setup' ' test_expect_success PERL 'saying "n" does nothing' ' set_and_save_state dir/foo work work && - (echo n; echo n) | git reset -p && + test_write_lines n n | git reset -p && verify_saved_state dir/foo && verify_saved_state bar ' test_expect_success PERL 'git reset -p' ' - (echo n; echo y) | git reset -p >output && + test_write_lines n y | git reset -p >output && verify_state dir/foo work head && verify_saved_state bar && test_i18ngrep "Unstage" output ' test_expect_success PERL 'git reset -p HEAD^' ' - (echo n; echo y) | git reset -p HEAD^ >output && + test_write_lines n y | git reset -p HEAD^ >output && verify_state dir/foo work parent && verify_saved_state bar && test_i18ngrep "Apply" output @@ -45,20 +45,20 @@ test_expect_success PERL 'git reset -p HEAD^' ' test_expect_success PERL 'git reset -p dir' ' set_state dir/foo work work && - (echo y; echo n) | git reset -p dir && + test_write_lines y n | git reset -p dir && verify_state dir/foo work head && verify_saved_state bar ' test_expect_success PERL 'git reset -p -- foo (inside dir)' ' set_state dir/foo work work && - (echo y; echo n) | (cd dir && git reset -p -- foo) && + test_write_lines y n | (cd dir && git reset -p -- foo) && verify_state dir/foo work head && verify_saved_state bar ' test_expect_success PERL 'git reset -p HEAD^ -- dir' ' - (echo y; echo n) | git reset -p HEAD^ -- dir && + test_write_lines y n | git reset -p HEAD^ -- dir && verify_state dir/foo work parent && verify_saved_state bar ' diff --git a/t/t7201-co.sh b/t/t7201-co.sh index ab9da61da3..94cb039a03 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -528,10 +528,10 @@ test_expect_success 'checkout with --merge' ' cat sample >filf && git checkout -m -- fild file filf && ( - echo "<<<<<<< ours" - echo ourside - echo "=======" - echo theirside + echo "<<<<<<< ours" && + echo ourside && + echo "=======" && + echo theirside && echo ">>>>>>> theirs" ) >merged && test_cmp expect fild && @@ -549,12 +549,12 @@ test_expect_success 'checkout with --merge, in diff3 -m style' ' cat sample >filf && git checkout -m -- fild file filf && ( - echo "<<<<<<< ours" - echo ourside - echo "||||||| base" - echo original - echo "=======" - echo theirside + echo "<<<<<<< ours" && + echo ourside && + echo "||||||| base" && + echo original && + echo "=======" && + echo theirside && echo ">>>>>>> theirs" ) >merged && test_cmp expect fild && @@ -572,10 +572,10 @@ test_expect_success 'checkout --conflict=merge, overriding config' ' cat sample >filf && git checkout --conflict=merge -- fild file filf && ( - echo "<<<<<<< ours" - echo ourside - echo "=======" - echo theirside + echo "<<<<<<< ours" && + echo ourside && + echo "=======" && + echo theirside && echo ">>>>>>> theirs" ) >merged && test_cmp expect fild && @@ -593,12 +593,12 @@ test_expect_success 'checkout --conflict=diff3' ' cat sample >filf && git checkout --conflict=diff3 -- fild file filf && ( - echo "<<<<<<< ours" - echo ourside - echo "||||||| base" - echo original - echo "=======" - echo theirside + echo "<<<<<<< ours" && + echo ourside && + echo "||||||| base" && + echo original && + echo "=======" && + echo theirside && echo ">>>>>>> theirs" ) >merged && test_cmp expect fild && @@ -673,7 +673,6 @@ test_expect_success 'custom merge driver with checkout -m' ' do grep $t arm || exit 1 done - exit 0 ) && mv arm expect && diff --git a/t/t7301-clean-interactive.sh b/t/t7301-clean-interactive.sh index 1bf9789c8a..a07e8b86de 100755 --- a/t/t7301-clean-interactive.sh +++ b/t/t7301-clean-interactive.sh @@ -107,7 +107,7 @@ test_expect_success 'git clean -id (filter all)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo f; echo "*"; echo; echo c) | \ + test_write_lines f "*" "" c | git clean -id && test -f Makefile && test -f README && @@ -129,7 +129,7 @@ test_expect_success 'git clean -id (filter patterns)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo f; echo "part3.* *.out"; echo; echo c) | \ + test_write_lines f "part3.* *.out" "" c | git clean -id && test -f Makefile && test -f README && @@ -151,7 +151,7 @@ test_expect_success 'git clean -id (filter patterns 2)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo f; echo "* !*.out"; echo; echo c) | \ + test_write_lines f "* !*.out" "" c | git clean -id && test -f Makefile && test -f README && @@ -173,7 +173,7 @@ test_expect_success 'git clean -id (select - all)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo s; echo "*"; echo; echo c) | \ + test_write_lines s "*" "" c | git clean -id && test -f Makefile && test -f README && @@ -195,7 +195,7 @@ test_expect_success 'git clean -id (select - none)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo s; echo; echo c) | \ + test_write_lines s "" c | git clean -id && test -f Makefile && test -f README && @@ -217,7 +217,7 @@ test_expect_success 'git clean -id (select - number)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo s; echo 3; echo; echo c) | \ + test_write_lines s 3 "" c | git clean -id && test -f Makefile && test -f README && @@ -239,7 +239,7 @@ test_expect_success 'git clean -id (select - number 2)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo s; echo 2 3; echo 5; echo; echo c) | \ + test_write_lines s "2 3" 5 "" c | git clean -id && test -f Makefile && test -f README && @@ -261,7 +261,7 @@ test_expect_success 'git clean -id (select - number 3)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo s; echo 3,4 5; echo; echo c) | \ + test_write_lines s "3,4 5" "" c | git clean -id && test -f Makefile && test -f README && @@ -282,7 +282,7 @@ test_expect_success 'git clean -id (select - filenames)' ' mkdir -p build docs && touch a.out foo.txt bar.txt baz.txt && - (echo s; echo a.out fo ba bar; echo; echo c) | \ + test_write_lines s "a.out fo ba bar" "" c | git clean -id && test -f Makefile && test ! -f a.out && @@ -298,7 +298,7 @@ test_expect_success 'git clean -id (select - range)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo s; echo 1,3-4; echo 2; echo; echo c) | \ + test_write_lines s "1,3-4" 2 "" c | git clean -id && test -f Makefile && test -f README && @@ -320,7 +320,7 @@ test_expect_success 'git clean -id (select - range 2)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo s; echo 4- 1; echo; echo c) | \ + test_write_lines s "4- 1" "" c | git clean -id && test -f Makefile && test -f README && @@ -342,7 +342,7 @@ test_expect_success 'git clean -id (inverse select)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo s; echo "*"; echo -5- 1 -2; echo; echo c) | \ + test_write_lines s "*" "-5- 1 -2" "" c | git clean -id && test -f Makefile && test -f README && @@ -364,7 +364,7 @@ test_expect_success 'git clean -id (ask)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo a; echo Y; echo y; echo no; echo yes; echo bad; echo) | \ + test_write_lines a Y y no yes bad "" | git clean -id && test -f Makefile && test -f README && @@ -386,7 +386,7 @@ test_expect_success 'git clean -id (ask - Ctrl+D)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (echo a; echo Y; echo no; echo yes; echo "\04") | \ + test_write_lines a Y no yes "\04" | git clean -id && test -f Makefile && test -f README && @@ -408,8 +408,8 @@ test_expect_success 'git clean -id with prefix and path (filter)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (cd build/ && \ - (echo f; echo "docs"; echo "*.h"; echo ; echo c) | \ + (cd build/ && + test_write_lines f docs "*.h" "" c | git clean -id ..) && test -f Makefile && test -f README && @@ -431,9 +431,8 @@ test_expect_success 'git clean -id with prefix and path (select by name)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (cd build/ && \ - (echo s; echo "../docs/"; echo "../src/part3.c"; \ - echo "../src/part4.c"; echo; echo c) | \ + (cd build/ && + test_write_lines s ../docs/ ../src/part3.c ../src/part4.c "" c | git clean -id ..) && test -f Makefile && test -f README && @@ -455,8 +454,8 @@ test_expect_success 'git clean -id with prefix and path (ask)' ' mkdir -p build docs && touch a.out src/part3.c src/part3.h src/part4.c src/part4.h \ docs/manual.txt obj.o build/lib.so && - (cd build/ && \ - (echo a; echo Y; echo y; echo no; echo yes; echo bad; echo) | \ + (cd build/ && + test_write_lines a Y y no yes bad "" | git clean -id ..) && test -f Makefile && test -f README && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 812db137b8..2c2c97e144 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -171,12 +171,13 @@ test_expect_success 'submodule add to .gitignored path with --force' ' test_expect_success 'submodule add to reconfigure existing submodule with --force' ' ( cd addtest-ignore && - git submodule add --force bogus-url submod && - git submodule add -b initial "$submodurl" submod-branch && - test "bogus-url" = "$(git config -f .gitmodules submodule.submod.url)" && - test "bogus-url" = "$(git config submodule.submod.url)" && + bogus_url="$(pwd)/bogus-url" && + git submodule add --force "$bogus_url" submod && + git submodule add --force -b initial "$submodurl" submod-branch && + test "$bogus_url" = "$(git config -f .gitmodules submodule.submod.url)" && + test "$bogus_url" = "$(git config submodule.submod.url)" && # Restore the url - git submodule add --force "$submodurl" submod + git submodule add --force "$submodurl" submod && test "$submodurl" = "$(git config -f .gitmodules submodule.submod.url)" && test "$submodurl" = "$(git config submodule.submod.url)" ) @@ -818,7 +819,7 @@ test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.gi cp pristine-.git-config .git/config && cp pristine-.gitmodules .gitmodules && mkdir -p a/b/c && - (cd a/b/c; git init) && + (cd a/b/c && git init) && git config remote.origin.url ../foo/bar.git && git submodule add ../bar/a/b/c ./a/b/c && git submodule init && @@ -993,6 +994,11 @@ test_expect_success 'submodule deinit should remove the whole submodule section rmdir init ' +test_expect_success 'submodule deinit should unset core.worktree' ' + test_path_is_file .git/modules/example/config && + test_must_fail git config -f .git/modules/example/config core.worktree +' + test_expect_success 'submodule deinit from subdirectory' ' git submodule update --init && git config submodule.example.foo bar && diff --git a/t/t7405-submodule-merge.sh b/t/t7405-submodule-merge.sh index 7bfb2f498d..7855bd8648 100755 --- a/t/t7405-submodule-merge.sh +++ b/t/t7405-submodule-merge.sh @@ -279,4 +279,177 @@ test_expect_success 'recursive merge with submodule' ' grep "$(cat expect3)" actual > /dev/null) ' +# File/submodule conflict +# Commit O: <empty> +# Commit A: path (submodule) +# Commit B: path +# Expected: path/ is submodule and file contents for B's path are somewhere + +test_expect_success 'setup file/submodule conflict' ' + test_create_repo file-submodule && + ( + cd file-submodule && + + git commit --allow-empty -m O && + + git branch A && + git branch B && + + git checkout B && + echo content >path && + git add path && + git commit -m B && + + git checkout A && + test_create_repo path && + test_commit -C path world && + git submodule add ./path && + git commit -m A + ) +' + +test_expect_failure 'file/submodule conflict' ' + test_when_finished "git -C file-submodule reset --hard" && + ( + cd file-submodule && + + git checkout A^0 && + test_must_fail git merge B^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 2 out && + + # path/ is still a submodule + test_path_is_dir path/.git && + + # There is a submodule at "path", so B:path cannot be written + # there. We expect it to be written somewhere in the same + # directory, though, so just grep for its content in all + # files, and ignore "grep: path: Is a directory" message + echo Checking if contents from B:path showed up anywhere && + grep -q content * 2>/dev/null + ) +' + +test_expect_success 'file/submodule conflict; merge --abort works afterward' ' + test_when_finished "git -C file-submodule reset --hard" && + ( + cd file-submodule && + + git checkout A^0 && + test_must_fail git merge B^0 >out 2>err && + + test_path_is_file .git/MERGE_HEAD && + git merge --abort + ) +' + +# Directory/submodule conflict +# Commit O: <empty> +# Commit A: path (submodule), with sole tracked file named 'world' +# Commit B1: path/file +# Commit B2: path/world +# +# Expected from merge of A & B1: +# Contents under path/ from commit B1 are renamed elsewhere; we do not +# want to write files from one of our tracked directories into a submodule +# +# Expected from merge of A & B2: +# Similar to last merge, but with a slight twist: we don't want paths +# under the submodule to be treated as untracked or in the way. + +test_expect_success 'setup directory/submodule conflict' ' + test_create_repo directory-submodule && + ( + cd directory-submodule && + + git commit --allow-empty -m O && + + git branch A && + git branch B1 && + git branch B2 && + + git checkout B1 && + mkdir path && + echo contents >path/file && + git add path/file && + git commit -m B1 && + + git checkout B2 && + mkdir path && + echo contents >path/world && + git add path/world && + git commit -m B2 && + + git checkout A && + test_create_repo path && + test_commit -C path hello world && + git submodule add ./path && + git commit -m A + ) +' + +test_expect_failure 'directory/submodule conflict; keep submodule clean' ' + test_when_finished "git -C directory-submodule reset --hard" && + ( + cd directory-submodule && + + git checkout A^0 && + test_must_fail git merge B1^0 && + + git ls-files -s >out && + test_line_count = 3 out && + git ls-files -u >out && + test_line_count = 1 out && + + # path/ is still a submodule + test_path_is_dir path/.git && + + echo Checking if contents from B1:path/file showed up && + # Would rather use grep -r, but that is GNU extension... + git ls-files -co | xargs grep -q contents 2>/dev/null && + + # However, B1:path/file should NOT have shown up at path/file, + # because we should not write into the submodule + test_path_is_missing path/file + ) +' + +test_expect_failure 'directory/submodule conflict; should not treat submodule files as untracked or in the way' ' + test_when_finished "git -C directory-submodule/path reset --hard" && + test_when_finished "git -C directory-submodule reset --hard" && + ( + cd directory-submodule && + + git checkout A^0 && + test_must_fail git merge B2^0 >out 2>err && + + # We do not want files within the submodule to prevent the + # merge from starting; we should not be writing to such paths + # anyway. + test_i18ngrep ! "refusing to lose untracked file at" err + ) +' + +test_expect_failure 'directory/submodule conflict; merge --abort works afterward' ' + test_when_finished "git -C directory-submodule/path reset --hard" && + test_when_finished "git -C directory-submodule reset --hard" && + ( + cd directory-submodule && + + git checkout A^0 && + test_must_fail git merge B2^0 && + test_path_is_file .git/MERGE_HEAD && + + # merge --abort should succeed, should clear .git/MERGE_HEAD, + # and should not leave behind any conflicted files + git merge --abort && + test_path_is_missing .git/MERGE_HEAD && + git ls-files -u >conflicts && + test_must_be_empty conflicts + ) +' + test_done diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 9e0d31700e..f604ef7a72 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -865,9 +865,9 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re (cd submodule/subsubmodule && git log > ../../expected ) && - (cd .git/modules/submodule/modules/subsubmodule + (cd .git/modules/submodule/modules/subsubmodule && git log > ../../../../../actual - ) + ) && test_cmp actual expected ) ' @@ -886,7 +886,7 @@ test_expect_success 'submodule update properly revives a moved submodule' ' git commit -am "pre move" && H2=$(git rev-parse --short HEAD) && git status | sed "s/$H/XXX/" >expect && - H=$(cd submodule2; git rev-parse HEAD) && + H=$(cd submodule2 && git rev-parse HEAD) && git rm --cached submodule2 && rm -rf submodule2 && mkdir -p "moved/sub module" && diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 6ba5daf42e..77729ac4aa 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -82,16 +82,16 @@ test_expect_success 'test basic "submodule foreach" usage' ' cat >expect <<EOF Entering '../sub1' -$pwd/clone-foo1-../sub1-$sub1sha1 +$pwd/clone-foo1-sub1-../sub1-$sub1sha1 Entering '../sub3' -$pwd/clone-foo3-../sub3-$sub3sha1 +$pwd/clone-foo3-sub3-../sub3-$sub3sha1 EOF test_expect_success 'test "submodule foreach" from subdirectory' ' mkdir clone/sub && ( cd clone/sub && - git submodule foreach "echo \$toplevel-\$name-\$sm_path-\$sha1" >../../actual + git submodule foreach "echo \$toplevel-\$name-\$sm_path-\$displaypath-\$sha1" >../../actual ) && test_i18ncmp expect actual ' @@ -196,6 +196,38 @@ test_expect_success 'test messages from "foreach --recursive" from subdirectory' ) && test_i18ncmp expect actual ' +sub1sha1=$(cd clone2/sub1 && git rev-parse HEAD) +sub2sha1=$(cd clone2/sub2 && git rev-parse HEAD) +sub3sha1=$(cd clone2/sub3 && git rev-parse HEAD) +nested1sha1=$(cd clone2/nested1 && git rev-parse HEAD) +nested2sha1=$(cd clone2/nested1/nested2 && git rev-parse HEAD) +nested3sha1=$(cd clone2/nested1/nested2/nested3 && git rev-parse HEAD) +submodulesha1=$(cd clone2/nested1/nested2/nested3/submodule && git rev-parse HEAD) + +cat >expect <<EOF +Entering '../nested1' +toplevel: $pwd/clone2 name: nested1 path: nested1 displaypath: ../nested1 hash: $nested1sha1 +Entering '../nested1/nested2' +toplevel: $pwd/clone2/nested1 name: nested2 path: nested2 displaypath: ../nested1/nested2 hash: $nested2sha1 +Entering '../nested1/nested2/nested3' +toplevel: $pwd/clone2/nested1/nested2 name: nested3 path: nested3 displaypath: ../nested1/nested2/nested3 hash: $nested3sha1 +Entering '../nested1/nested2/nested3/submodule' +toplevel: $pwd/clone2/nested1/nested2/nested3 name: submodule path: submodule displaypath: ../nested1/nested2/nested3/submodule hash: $submodulesha1 +Entering '../sub1' +toplevel: $pwd/clone2 name: foo1 path: sub1 displaypath: ../sub1 hash: $sub1sha1 +Entering '../sub2' +toplevel: $pwd/clone2 name: foo2 path: sub2 displaypath: ../sub2 hash: $sub2sha1 +Entering '../sub3' +toplevel: $pwd/clone2 name: foo3 path: sub3 displaypath: ../sub3 hash: $sub3sha1 +EOF + +test_expect_success 'test "submodule foreach --recursive" from subdirectory' ' + ( + cd clone2/untracked && + git submodule foreach --recursive "echo toplevel: \$toplevel name: \$name path: \$sm_path displaypath: \$displaypath hash: \$sha1" >../../actual + ) && + test_i18ncmp expect actual +' cat > expect <<EOF nested1-nested1 diff --git a/t/t7408-submodule-reference.sh b/t/t7408-submodule-reference.sh index 08d9add05e..34ac28c056 100755 --- a/t/t7408-submodule-reference.sh +++ b/t/t7408-submodule-reference.sh @@ -148,7 +148,7 @@ test_expect_success 'preparing second superproject with a nested submodule plus cd supersuper && echo "I am super super." >file && git add file && - git commit -m B-super-super-initial + git commit -m B-super-super-initial && git submodule add "file://$base_dir/super" subwithsub && git commit -m B-super-super-added && git submodule update --init --recursive && diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh index b68c5f5e85..293e2e1963 100755 --- a/t/t7415-submodule-names.sh +++ b/t/t7415-submodule-names.sh @@ -176,4 +176,19 @@ test_expect_success 'fsck detects non-blob .gitmodules' ' ) ' +test_expect_success 'fsck detects corrupt .gitmodules' ' + git init corrupt && + ( + cd corrupt && + + echo "[broken" >.gitmodules && + git add .gitmodules && + git commit -m "broken gitmodules" && + + git fsck 2>output && + grep gitmodulesParse output && + test_i18ngrep ! "bad config" output + ) +' + test_done diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index 9dbbd01fc0..51646d8019 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -47,7 +47,7 @@ test_expect_success 'paths and -a do not mix' ' test_expect_success PERL 'can use paths with --interactive' ' echo bong-o-bong >file && # 2: update, 1:st path, that is all, 7: quit - ( echo 2; echo 1; echo; echo 7 ) | + test_write_lines 2 1 "" 7 | git commit -m foo --interactive file && git reset --hard HEAD^ ' @@ -293,7 +293,7 @@ test_expect_success PERL 'interactive add' ' test_expect_success PERL "commit --interactive doesn't change index if editor aborts" ' echo zoo >file && test_must_fail git diff --exit-code >diff1 && - (echo u ; echo "*" ; echo q) | + test_write_lines u "*" q | ( EDITOR=: && export EDITOR && @@ -411,8 +411,8 @@ test_expect_success 'sign off (1)' ' git commit -s -m "thank you" && git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && ( - echo thank you - echo + echo thank you && + echo && git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ) >expected && @@ -430,9 +430,9 @@ test_expect_success 'sign off (2)' ' $existing" && git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && ( - echo thank you - echo - echo $existing + echo thank you && + echo && + echo $existing && git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ) >expected && @@ -450,9 +450,9 @@ test_expect_success 'signoff gap' ' $alt" && git cat-file commit HEAD | sed -e "1,/^\$/d" > actual && ( - echo welcome - echo - echo $alt + echo welcome && + echo && + echo $alt && git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ) >expected && @@ -470,11 +470,11 @@ We have now $alt" && git cat-file commit HEAD | sed -e "1,/^\$/d" > actual && ( - echo welcome - echo - echo We have now - echo $alt - echo + echo welcome && + echo && + echo We have now && + echo $alt && + echo && git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ) >expected && @@ -491,11 +491,11 @@ non-trailer line Myfooter: x" && git cat-file commit HEAD | sed -e "1,/^\$/d" > actual && ( - echo subject - echo - echo non-trailer line - echo Myfooter: x - echo + echo subject && + echo && + echo non-trailer line && + echo Myfooter: x && + echo && echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" ) >expected && test_cmp expected actual && @@ -508,10 +508,10 @@ non-trailer line Myfooter: x" && git cat-file commit HEAD | sed -e "1,/^\$/d" > actual && ( - echo subject - echo - echo non-trailer line - echo Myfooter: x + echo subject && + echo && + echo non-trailer line && + echo Myfooter: x && echo "Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" ) >expected && test_cmp expected actual @@ -524,10 +524,10 @@ test_expect_success 'multiple -m' ' git commit -m "one" -m "two" -m "three" && git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && ( - echo one - echo - echo two - echo + echo one && + echo && + echo two && + echo && echo three ) >expected && test_cmp expected actual diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh index 302a3a2082..31b9c6a2c1 100755 --- a/t/t7504-commit-msg-hook.sh +++ b/t/t7504-commit-msg-hook.sh @@ -157,6 +157,7 @@ test_expect_success 'merge bypasses failing hook with --no-verify' ' test_when_finished "git branch -D newbranch" && test_when_finished "git checkout -f master" && git checkout --orphan newbranch && + git rm -f file && : >file2 && git add file2 && git commit --no-verify file2 -m in-side-branch && @@ -168,7 +169,7 @@ test_expect_success 'merge bypasses failing hook with --no-verify' ' chmod -x "$HOOK" test_expect_success POSIXPERM 'with non-executable hook' ' - echo "content" >> file && + echo "content" >file && git add file && git commit -m "content" @@ -249,6 +250,7 @@ test_expect_success 'hook called in git-merge picks up commit message' ' test_when_finished "git branch -D newbranch" && test_when_finished "git checkout -f master" && git checkout --orphan newbranch && + git rm -f file && : >file2 && git add file2 && git commit --no-verify file2 -m in-side-branch && diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh index b4b74dbe29..943708fb04 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -193,9 +193,9 @@ test_expect_success 'status with added and untracked file in modified submodule test_expect_success 'setup .git file for sub' ' (cd sub && - rm -f new-file + rm -f new-file && REAL="$(pwd)/../.real" && - mv .git "$REAL" + mv .git "$REAL" && echo "gitdir: $REAL" >.git) && echo .real >>.gitignore && git commit -m "added .real to .gitignore" .gitignore @@ -209,12 +209,12 @@ test_expect_success 'status with added file in modified submodule with .git file test_expect_success 'status with a lot of untracked files in the submodule' ' ( - cd sub + cd sub && i=0 && while test $i -lt 1024 do - >some-file-$i - i=$(( $i + 1 )) + >some-file-$i && + i=$(( $i + 1 )) || exit 1 done ) && git status --porcelain sub 2>err.actual && diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 18a40257fb..e1f11293e2 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -1099,6 +1099,7 @@ EOF ' test_expect_success POSIXPERM,SANITY 'status succeeds in a read-only repository' ' + test_when_finished "chmod 775 .git" && ( chmod a-w .git && # make dir1/tracked stat-dirty @@ -1108,9 +1109,6 @@ test_expect_success POSIXPERM,SANITY 'status succeeds in a read-only repository' # make sure "status" succeeded without writing index out git diff-files | grep dir1/tracked ) - status=$? - chmod 775 .git - (exit $status) ' (cd sm && echo > bar && git add bar && git commit -q -m 'Add bar') && git add sm diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 762135adea..6e2015ed9a 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -142,10 +142,9 @@ test_expect_success GPG 'show signed commit with signature' ' test_expect_success GPG 'detect fudged signature' ' git cat-file commit seventh-signed >raw && - - sed -e "s/seventh/7th forged/" raw >forged1 && + sed -e "s/^seventh/7th forged/" raw >forged1 && git hash-object -w -t commit forged1 >forged1.commit && - ! git verify-commit $(cat forged1.commit) && + test_must_fail git verify-commit $(cat forged1.commit) && git show --pretty=short --show-signature $(cat forged1.commit) >actual1 && grep "BAD signature from" actual1 && ! grep "Good signature from" actual1 @@ -156,7 +155,7 @@ test_expect_success GPG 'detect fudged signature with NUL' ' cat raw >forged2 && echo Qwik | tr "Q" "\000" >>forged2 && git hash-object -w -t commit forged2 >forged2.commit && - ! git verify-commit $(cat forged2.commit) && + test_must_fail git verify-commit $(cat forged2.commit) && git show --pretty=short --show-signature $(cat forged2.commit) >actual2 && grep "BAD signature from" actual2 && ! grep "Good signature from" actual2 diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index 1a430b9c40..047156e9d5 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -57,18 +57,18 @@ test_expect_success 'setup' ' git checkout -b delete-base branch1 && mkdir -p a/a && - (echo one; echo two; echo 3; echo 4) >a/a/file.txt && + test_write_lines one two 3 4 >a/a/file.txt && git add a/a/file.txt && git commit -m"base file" && git checkout -b move-to-b delete-base && mkdir -p b/b && git mv a/a/file.txt b/b/file.txt && - (echo one; echo two; echo 4) >b/b/file.txt && + test_write_lines one two 4 >b/b/file.txt && git commit -a -m"move to b" && git checkout -b move-to-c delete-base && mkdir -p c/c && git mv a/a/file.txt c/c/file.txt && - (echo one; echo two; echo 3) >c/c/file.txt && + test_write_lines one two 3 >c/c/file.txt && git commit -a -m"move to c" && git checkout -b stash1 master && @@ -349,7 +349,7 @@ test_expect_success 'mergetool keeps tempfiles when aborting delete/delete' ' git checkout -b test$test_count move-to-c && test_config mergetool.keepTemporaries true && test_must_fail git merge move-to-b && - ! (echo a; echo n) | git mergetool a/a/file.txt && + ! test_write_lines a n | git mergetool a/a/file.txt && test -d a/a && cat >expect <<-\EOF && file_BASE_.txt diff --git a/t/t7611-merge-abort.sh b/t/t7611-merge-abort.sh index 7b4798e8e4..7c84a518aa 100755 --- a/t/t7611-merge-abort.sh +++ b/t/t7611-merge-abort.sh @@ -187,31 +187,6 @@ test_expect_success 'Fail clean merge with matching dirty worktree' ' test_cmp expect actual ' -test_expect_success 'Abort clean merge with matching dirty index' ' - git add bar && - git diff --staged > expect && - git merge --no-commit clean_branch && - test -f .git/MERGE_HEAD && - ### When aborting the merge, git will discard all staged changes, - ### including those that were staged pre-merge. In other words, - ### --abort will LOSE any staged changes (the staged changes that - ### are lost must match the merge result, or the merge would not - ### have been allowed to start). Change expectations accordingly: - rm expect && - touch expect && - # Abort merge - git merge --abort && - test ! -f .git/MERGE_HEAD && - test "$pre_merge_head" = "$(git rev-parse HEAD)" && - git diff --staged > actual && - test_cmp expect actual && - test -z "$(git diff)" -' - -test_expect_success 'Reset worktree changes' ' - git reset --hard "$pre_merge_head" -' - test_expect_success 'Fail conflicting merge with matching dirty worktree' ' echo barf > bar && git diff > expect && @@ -223,97 +198,4 @@ test_expect_success 'Fail conflicting merge with matching dirty worktree' ' test_cmp expect actual ' -test_expect_success 'Abort conflicting merge with matching dirty index' ' - git add bar && - git diff --staged > expect && - test_must_fail git merge conflict_branch && - test -f .git/MERGE_HEAD && - ### When aborting the merge, git will discard all staged changes, - ### including those that were staged pre-merge. In other words, - ### --abort will LOSE any staged changes (the staged changes that - ### are lost must match the merge result, or the merge would not - ### have been allowed to start). Change expectations accordingly: - rm expect && - touch expect && - # Abort merge - git merge --abort && - test ! -f .git/MERGE_HEAD && - test "$pre_merge_head" = "$(git rev-parse HEAD)" && - git diff --staged > actual && - test_cmp expect actual && - test -z "$(git diff)" -' - -test_expect_success 'Reset worktree changes' ' - git reset --hard "$pre_merge_head" -' - -test_expect_success 'Abort merge with pre- and post-merge worktree changes' ' - # Pre-merge worktree changes - echo xyzzy > foo && - echo barf > bar && - git add bar && - git diff > expect && - git diff --staged > expect-staged && - # Perform merge - test_must_fail git merge conflict_branch && - test -f .git/MERGE_HEAD && - # Post-merge worktree changes - echo yzxxz > foo && - echo blech > baz && - ### When aborting the merge, git will discard staged changes (bar) - ### and unmerged changes (baz). Other changes that are neither - ### staged nor marked as unmerged (foo), will be preserved. For - ### these changed, git cannot tell pre-merge changes apart from - ### post-merge changes, so the post-merge changes will be - ### preserved. Change expectations accordingly: - git diff -- foo > expect && - rm expect-staged && - touch expect-staged && - # Abort merge - git merge --abort && - test ! -f .git/MERGE_HEAD && - test "$pre_merge_head" = "$(git rev-parse HEAD)" && - git diff > actual && - test_cmp expect actual && - git diff --staged > actual-staged && - test_cmp expect-staged actual-staged -' - -test_expect_success 'Reset worktree changes' ' - git reset --hard "$pre_merge_head" -' - -test_expect_success 'Abort merge with pre- and post-merge index changes' ' - # Pre-merge worktree changes - echo xyzzy > foo && - echo barf > bar && - git add bar && - git diff > expect && - git diff --staged > expect-staged && - # Perform merge - test_must_fail git merge conflict_branch && - test -f .git/MERGE_HEAD && - # Post-merge worktree changes - echo yzxxz > foo && - echo blech > baz && - git add foo bar && - ### When aborting the merge, git will discard all staged changes - ### (foo, bar and baz), and no changes will be preserved. Whether - ### the changes were staged pre- or post-merge does not matter - ### (except for not preventing starting the merge). - ### Change expectations accordingly: - rm expect expect-staged && - touch expect && - touch expect-staged && - # Abort merge - git merge --abort && - test ! -f .git/MERGE_HEAD && - test "$pre_merge_head" = "$(git rev-parse HEAD)" && - git diff > actual && - test_cmp expect actual && - git diff --staged > actual-staged && - test_cmp expect-staged actual-staged -' - test_done diff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh index e797c74112..e2b1df817a 100755 --- a/t/t7612-merge-verify-signatures.sh +++ b/t/t7612-merge-verify-signatures.sh @@ -23,7 +23,7 @@ test_expect_success GPG 'create signed commits' ' echo 3 >bar && git add bar && test_tick && git commit -S -m "bad on side" && git cat-file commit side-bad >raw && - sed -e "s/bad/forged bad/" raw >forged && + sed -e "s/^bad/forged bad/" raw >forged && git hash-object -w -t commit forged >forged.commit && git checkout initial && diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 1797f632a3..dcaab1557b 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -99,6 +99,101 @@ do test_cmp expected actual ' + test_expect_success "grep -w $L (with --column)" ' + { + echo ${HC}file:5:foo mmap bar + echo ${HC}file:14:foo_mmap bar mmap + echo ${HC}file:5:foo mmap bar_mmap + echo ${HC}file:14:foo_mmap bar mmap baz + } >expected && + git grep --column -w -e mmap $H >actual && + test_cmp expected actual + ' + + test_expect_success "grep -w $L (with --column, extended OR)" ' + { + echo ${HC}file:14:foo_mmap bar mmap + echo ${HC}file:19:foo_mmap bar mmap baz + } >expected && + git grep --column -w -e mmap$ --or -e baz $H >actual && + test_cmp expected actual + ' + + test_expect_success "grep -w $L (with --column, --invert)" ' + { + echo ${HC}file:1:foo mmap bar + echo ${HC}file:1:foo_mmap bar + echo ${HC}file:1:foo_mmap bar mmap + echo ${HC}file:1:foo mmap bar_mmap + } >expected && + git grep --column --invert -w -e baz $H -- file >actual && + test_cmp expected actual + ' + + test_expect_success "grep $L (with --column, --invert, extended OR)" ' + { + echo ${HC}hello_world:6:HeLLo_world + } >expected && + git grep --column --invert -e ll --or --not -e _ $H -- hello_world \ + >actual && + test_cmp expected actual + ' + + test_expect_success "grep $L (with --column, --invert, extended AND)" ' + { + echo ${HC}hello_world:3:Hello world + echo ${HC}hello_world:3:Hello_world + echo ${HC}hello_world:6:HeLLo_world + } >expected && + git grep --column --invert --not -e _ --and --not -e ll $H -- hello_world \ + >actual && + test_cmp expected actual + ' + + test_expect_success "grep $L (with --column, double-negation)" ' + { + echo ${HC}file:1:foo_mmap bar mmap baz + } >expected && + git grep --column --not \( --not -e foo --or --not -e baz \) $H -- file \ + >actual && + test_cmp expected actual + ' + + test_expect_success "grep -w $L (with --column, -C)" ' + { + echo ${HC}file:5:foo mmap bar + echo ${HC}file-foo_mmap bar + echo ${HC}file:14:foo_mmap bar mmap + echo ${HC}file:5:foo mmap bar_mmap + echo ${HC}file:14:foo_mmap bar mmap baz + } >expected && + git grep --column -w -C1 -e mmap $H >actual && + test_cmp expected actual + ' + + test_expect_success "grep -w $L (with --line-number, --column)" ' + { + echo ${HC}file:1:5:foo mmap bar + echo ${HC}file:3:14:foo_mmap bar mmap + echo ${HC}file:4:5:foo mmap bar_mmap + echo ${HC}file:5:14:foo_mmap bar mmap baz + } >expected && + git grep -n --column -w -e mmap $H >actual && + test_cmp expected actual + ' + + test_expect_success "grep -w $L (with non-extended patterns, --column)" ' + { + echo ${HC}file:5:foo mmap bar + echo ${HC}file:10:foo_mmap bar + echo ${HC}file:10:foo_mmap bar mmap + echo ${HC}file:5:foo mmap bar_mmap + echo ${HC}file:10:foo_mmap bar mmap baz + } >expected && + git grep --column -w -e bar -e mmap $H >actual && + test_cmp expected actual + ' + test_expect_success "grep -w $L" ' { echo ${HC}file:1:foo mmap bar @@ -167,6 +262,21 @@ do fi ' + test_expect_success "grep $L (with --column, --only-matching)" ' + { + echo ${HC}file:1:5:mmap + echo ${HC}file:2:5:mmap + echo ${HC}file:3:5:mmap + echo ${HC}file:3:13:mmap + echo ${HC}file:4:5:mmap + echo ${HC}file:4:13:mmap + echo ${HC}file:5:5:mmap + echo ${HC}file:5:13:mmap + } >expected && + git grep --column -n -o -e mmap $H >actual && + test_cmp expected actual + ' + test_expect_success "grep $L (t-1)" ' echo "${HC}t/t:1:test" >expected && git grep -n -e test $H >actual && @@ -845,10 +955,9 @@ test_expect_success 'grep from a subdirectory to search wider area (1)' ' test_expect_success 'grep from a subdirectory to search wider area (2)' ' mkdir -p s && ( - cd s || exit 1 - ( git grep xxyyzz .. >out ; echo $? >status ) - ! test -s out && - test 1 = $(cat status) + cd s && + test_expect_code 1 git grep xxyyzz .. >out && + ! test -s out ) ' diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh index 661f9d430d..c92a47b6d5 100755 --- a/t/t8003-blame-corner-cases.sh +++ b/t/t8003-blame-corner-cases.sh @@ -216,14 +216,18 @@ test_expect_success 'blame -L with invalid start' ' ' test_expect_success 'blame -L with invalid end' ' - test_must_fail git blame -L1,5 tres 2>errors && - test_i18ngrep "has only 2 lines" errors + git blame -L1,5 tres >out && + test_line_count = 2 out ' test_expect_success 'blame parses <end> part of -L' ' git blame -L1,1 tres >out && - cat out && - test $(wc -l < out) -eq 1 + test_line_count = 1 out +' + +test_expect_success 'blame -Ln,-(n+1)' ' + git blame -L3,-4 nine_lines >out && + test_line_count = 3 out ' test_expect_success 'indent of line numbers, nine lines' ' diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index e80eacbb1b..b8e919e25d 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -225,6 +225,8 @@ X-Mailer: X-MAILER-STRING In-Reply-To: <unique-message-id@example.com> References: <unique-message-id@example.com> Reply-To: Reply <reply@example.com> +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -330,7 +332,7 @@ test_expect_success $PREREQ 'Show all headers' ' test_expect_success $PREREQ 'Prompting works' ' clean_fake_sendmail && - (echo "to@example.com" + (echo "to@example.com" && echo "" ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \ --smtp-server="$(pwd)/fake.sendmail" \ @@ -415,6 +417,7 @@ test_expect_success $PREREQ 'reject long lines' ' --from="Example <nobody@example.com>" \ --to=nobody@example.com \ --smtp-server="$(pwd)/fake.sendmail" \ + --transfer-encoding=8bit \ $patches longline.patch \ 2>errors && grep longline.patch errors @@ -456,6 +459,42 @@ test_expect_success $PREREQ 'allow long lines with --no-validate' ' 2>errors ' +test_expect_success $PREREQ 'short lines with auto encoding are 8bit' ' + clean_fake_sendmail && + git send-email \ + --from="A <author@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + --transfer-encoding=auto \ + $patches && + grep "Content-Transfer-Encoding: 8bit" msgtxt1 +' + +test_expect_success $PREREQ 'long lines with auto encoding are quoted-printable' ' + clean_fake_sendmail && + git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + --transfer-encoding=auto \ + --no-validate \ + longline.patch && + grep "Content-Transfer-Encoding: quoted-printable" msgtxt1 +' + +for enc in auto quoted-printable base64 +do + test_expect_success $PREREQ "--validate passes with encoding $enc" ' + git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + --transfer-encoding=$enc \ + --validate \ + $patches longline.patch + ' +done + test_expect_success $PREREQ 'Invalid In-Reply-To' ' clean_fake_sendmail && git send-email \ @@ -470,8 +509,8 @@ test_expect_success $PREREQ 'Invalid In-Reply-To' ' test_expect_success $PREREQ 'Valid In-Reply-To when prompting' ' clean_fake_sendmail && - (echo "From Example <from@example.com>" - echo "To Example <to@example.com>" + (echo "From Example <from@example.com>" && + echo "To Example <to@example.com>" && echo "" ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \ --smtp-server="$(pwd)/fake.sendmail" \ @@ -573,6 +612,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -617,6 +658,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -652,6 +695,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -678,6 +723,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -712,6 +759,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -743,6 +792,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -774,6 +825,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -809,6 +862,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -837,6 +892,8 @@ Subject: [PATCH 1/1] Second. Date: DATE-STRING Message-Id: MESSAGE-ID-STRING X-Mailer: X-MAILER-STRING +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit Result: OK EOF @@ -1966,11 +2023,11 @@ test_expect_success $PREREQ 'invoke hook' ' # Verify error message when a patch is rejected by the hook sed -e "s/add master/x/" ../0001-add-master.patch >../another.patch && - git send-email \ + test_must_fail git send-email \ --from="Example <nobody@example.com>" \ --to=nobody@example.com \ --smtp-server="$(pwd)/../fake.sendmail" \ - ../another.patch 2>err + ../another.patch 2>err && test_i18ngrep "rejected by sendemail-validate hook" err ) ' diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index c937330a5f..9af6078844 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -31,7 +31,7 @@ test_expect_success \ ( cd import && echo foo >foo && - ln -s foo foo.link + ln -s foo foo.link && mkdir -p dir/a/b/c/d/e && echo "deep dir" >dir/a/b/c/d/e/file && mkdir bar && diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index 07bfb63777..8a5c8dc1aa 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -149,7 +149,7 @@ test_expect_success 'test show-ignore' " svn_cmd up && svn_cmd propset -R svn:ignore ' no-such-file* -' . +' . && svn_cmd commit -m 'propset svn:ignore' ) && git svn show-ignore > show-ignore.got && diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index 9c49b6c1fe..5e0ad19177 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -215,7 +215,9 @@ test_expect_success "multi-fetch continues to work" " " test_expect_success "multi-fetch works off a 'clean' repository" ' - rm -rf "$GIT_DIR/svn" "$GIT_DIR/refs/remotes" && + rm -rf "$GIT_DIR/svn" && + git for-each-ref --format="option no-deref%0adelete %(refname)" refs/remotes | + git update-ref --stdin && git reflog expire --all --expire=all && mkdir "$GIT_DIR/svn" && git svn multi-fetch diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh index 88241baee3..8201c3e808 100755 --- a/t/t9119-git-svn-info.sh +++ b/t/t9119-git-svn-info.sh @@ -22,8 +22,8 @@ esac # same value as "svn info" (i.e. the commit timestamp that touched the # path most recently); do not expect that field to match. test_cmp_info () { - sed -e '/^Text Last Updated:/d' "$1" >tmp.expect - sed -e '/^Text Last Updated:/d' "$2" >tmp.actual + sed -e '/^Text Last Updated:/d' "$1" >tmp.expect && + sed -e '/^Text Last Updated:/d' "$2" >tmp.actual && test_cmp tmp.expect tmp.actual && rm -f tmp.expect tmp.actual } @@ -59,24 +59,24 @@ test_expect_success 'setup repository and import' ' ' test_expect_success 'info' " - (cd svnwc; svn info) > expected.info && - (cd gitwc; git svn info) > actual.info && + (cd svnwc && svn info) > expected.info && + (cd gitwc && git svn info) > actual.info && test_cmp_info expected.info actual.info " test_expect_success 'info --url' ' - test "$(cd gitwc; git svn info --url)" = "$quoted_svnrepo" + test "$(cd gitwc && git svn info --url)" = "$quoted_svnrepo" ' test_expect_success 'info .' " - (cd svnwc; svn info .) > expected.info-dot && - (cd gitwc; git svn info .) > actual.info-dot && + (cd svnwc && svn info .) > expected.info-dot && + (cd gitwc && git svn info .) > actual.info-dot && test_cmp_info expected.info-dot actual.info-dot " test_expect_success 'info $(pwd)' ' - (cd svnwc; svn info "$(pwd)") >expected.info-pwd && - (cd gitwc; git svn info "$(pwd)") >actual.info-pwd && + (cd svnwc && svn info "$(pwd)") >expected.info-pwd && + (cd gitwc && git svn info "$(pwd)") >actual.info-pwd && grep -v ^Path: <expected.info-pwd >expected.info-np && grep -v ^Path: <actual.info-pwd >actual.info-np && test_cmp_info expected.info-np actual.info-np && @@ -85,8 +85,8 @@ test_expect_success 'info $(pwd)' ' ' test_expect_success 'info $(pwd)/../___wc' ' - (cd svnwc; svn info "$(pwd)/../svnwc") >expected.info-pwd && - (cd gitwc; git svn info "$(pwd)/../gitwc") >actual.info-pwd && + (cd svnwc && svn info "$(pwd)/../svnwc") >expected.info-pwd && + (cd gitwc && git svn info "$(pwd)/../gitwc") >actual.info-pwd && grep -v ^Path: <expected.info-pwd >expected.info-np && grep -v ^Path: <actual.info-pwd >actual.info-np && test_cmp_info expected.info-np actual.info-np && @@ -95,8 +95,8 @@ test_expect_success 'info $(pwd)/../___wc' ' ' test_expect_success 'info $(pwd)/../___wc//file' ' - (cd svnwc; svn info "$(pwd)/../svnwc//file") >expected.info-pwd && - (cd gitwc; git svn info "$(pwd)/../gitwc//file") >actual.info-pwd && + (cd svnwc && svn info "$(pwd)/../svnwc//file") >expected.info-pwd && + (cd gitwc && git svn info "$(pwd)/../gitwc//file") >actual.info-pwd && grep -v ^Path: <expected.info-pwd >expected.info-np && grep -v ^Path: <actual.info-pwd >actual.info-np && test_cmp_info expected.info-np actual.info-np && @@ -105,56 +105,56 @@ test_expect_success 'info $(pwd)/../___wc//file' ' ' test_expect_success 'info --url .' ' - test "$(cd gitwc; git svn info --url .)" = "$quoted_svnrepo" + test "$(cd gitwc && git svn info --url .)" = "$quoted_svnrepo" ' test_expect_success 'info file' " - (cd svnwc; svn info file) > expected.info-file && - (cd gitwc; git svn info file) > actual.info-file && + (cd svnwc && svn info file) > expected.info-file && + (cd gitwc && git svn info file) > actual.info-file && test_cmp_info expected.info-file actual.info-file " test_expect_success 'info --url file' ' - test "$(cd gitwc; git svn info --url file)" = "$quoted_svnrepo/file" + test "$(cd gitwc && git svn info --url file)" = "$quoted_svnrepo/file" ' test_expect_success 'info directory' " - (cd svnwc; svn info directory) > expected.info-directory && - (cd gitwc; git svn info directory) > actual.info-directory && + (cd svnwc && svn info directory) > expected.info-directory && + (cd gitwc && git svn info directory) > actual.info-directory && test_cmp_info expected.info-directory actual.info-directory " test_expect_success 'info inside directory' " - (cd svnwc/directory; svn info) > expected.info-inside-directory && - (cd gitwc/directory; git svn info) > actual.info-inside-directory && + (cd svnwc/directory && svn info) > expected.info-inside-directory && + (cd gitwc/directory && git svn info) > actual.info-inside-directory && test_cmp_info expected.info-inside-directory actual.info-inside-directory " test_expect_success 'info --url directory' ' - test "$(cd gitwc; git svn info --url directory)" = "$quoted_svnrepo/directory" + test "$(cd gitwc && git svn info --url directory)" = "$quoted_svnrepo/directory" ' test_expect_success 'info symlink-file' " - (cd svnwc; svn info symlink-file) > expected.info-symlink-file && - (cd gitwc; git svn info symlink-file) > actual.info-symlink-file && + (cd svnwc && svn info symlink-file) > expected.info-symlink-file && + (cd gitwc && git svn info symlink-file) > actual.info-symlink-file && test_cmp_info expected.info-symlink-file actual.info-symlink-file " test_expect_success 'info --url symlink-file' ' - test "$(cd gitwc; git svn info --url symlink-file)" \ + test "$(cd gitwc && git svn info --url symlink-file)" \ = "$quoted_svnrepo/symlink-file" ' test_expect_success 'info symlink-directory' " - (cd svnwc; svn info symlink-directory) \ + (cd svnwc && svn info symlink-directory) \ > expected.info-symlink-directory && - (cd gitwc; git svn info symlink-directory) \ + (cd gitwc && git svn info symlink-directory) \ > actual.info-symlink-directory && test_cmp_info expected.info-symlink-directory actual.info-symlink-directory " test_expect_success 'info --url symlink-directory' ' - test "$(cd gitwc; git svn info --url symlink-directory)" \ + test "$(cd gitwc && git svn info --url symlink-directory)" \ = "$quoted_svnrepo/symlink-directory" ' @@ -169,13 +169,13 @@ test_expect_success 'info added-file' " cd svnwc && svn_cmd add added-file > /dev/null ) && - (cd svnwc; svn info added-file) > expected.info-added-file && - (cd gitwc; git svn info added-file) > actual.info-added-file && + (cd svnwc && svn info added-file) > expected.info-added-file && + (cd gitwc && git svn info added-file) > actual.info-added-file && test_cmp_info expected.info-added-file actual.info-added-file " test_expect_success 'info --url added-file' ' - test "$(cd gitwc; git svn info --url added-file)" \ + test "$(cd gitwc && git svn info --url added-file)" \ = "$quoted_svnrepo/added-file" ' @@ -190,15 +190,15 @@ test_expect_success 'info added-directory' " cd gitwc && git add added-directory ) && - (cd svnwc; svn info added-directory) \ + (cd svnwc && svn info added-directory) \ > expected.info-added-directory && - (cd gitwc; git svn info added-directory) \ + (cd gitwc && git svn info added-directory) \ > actual.info-added-directory && test_cmp_info expected.info-added-directory actual.info-added-directory " test_expect_success 'info --url added-directory' ' - test "$(cd gitwc; git svn info --url added-directory)" \ + test "$(cd gitwc && git svn info --url added-directory)" \ = "$quoted_svnrepo/added-directory" ' @@ -213,16 +213,16 @@ test_expect_success 'info added-symlink-file' " ln -s added-file added-symlink-file && svn_cmd add added-symlink-file > /dev/null ) && - (cd svnwc; svn info added-symlink-file) \ + (cd svnwc && svn info added-symlink-file) \ > expected.info-added-symlink-file && - (cd gitwc; git svn info added-symlink-file) \ + (cd gitwc && git svn info added-symlink-file) \ > actual.info-added-symlink-file && test_cmp_info expected.info-added-symlink-file \ actual.info-added-symlink-file " test_expect_success 'info --url added-symlink-file' ' - test "$(cd gitwc; git svn info --url added-symlink-file)" \ + test "$(cd gitwc && git svn info --url added-symlink-file)" \ = "$quoted_svnrepo/added-symlink-file" ' @@ -237,16 +237,16 @@ test_expect_success 'info added-symlink-directory' " ln -s added-directory added-symlink-directory && svn_cmd add added-symlink-directory > /dev/null ) && - (cd svnwc; svn info added-symlink-directory) \ + (cd svnwc && svn info added-symlink-directory) \ > expected.info-added-symlink-directory && - (cd gitwc; git svn info added-symlink-directory) \ + (cd gitwc && git svn info added-symlink-directory) \ > actual.info-added-symlink-directory && test_cmp_info expected.info-added-symlink-directory \ actual.info-added-symlink-directory " test_expect_success 'info --url added-symlink-directory' ' - test "$(cd gitwc; git svn info --url added-symlink-directory)" \ + test "$(cd gitwc && git svn info --url added-symlink-directory)" \ = "$quoted_svnrepo/added-symlink-directory" ' @@ -259,13 +259,13 @@ test_expect_success 'info deleted-file' " cd svnwc && svn_cmd rm --force file > /dev/null ) && - (cd svnwc; svn info file) >expected.info-deleted-file && - (cd gitwc; git svn info file) >actual.info-deleted-file && + (cd svnwc && svn info file) >expected.info-deleted-file && + (cd gitwc && git svn info file) >actual.info-deleted-file && test_cmp_info expected.info-deleted-file actual.info-deleted-file " test_expect_success 'info --url file (deleted)' ' - test "$(cd gitwc; git svn info --url file)" \ + test "$(cd gitwc && git svn info --url file)" \ = "$quoted_svnrepo/file" ' @@ -278,13 +278,13 @@ test_expect_success 'info deleted-directory' " cd svnwc && svn_cmd rm --force directory > /dev/null ) && - (cd svnwc; svn info directory) >expected.info-deleted-directory && - (cd gitwc; git svn info directory) >actual.info-deleted-directory && + (cd svnwc && svn info directory) >expected.info-deleted-directory && + (cd gitwc && git svn info directory) >actual.info-deleted-directory && test_cmp_info expected.info-deleted-directory actual.info-deleted-directory " test_expect_success 'info --url directory (deleted)' ' - test "$(cd gitwc; git svn info --url directory)" \ + test "$(cd gitwc && git svn info --url directory)" \ = "$quoted_svnrepo/directory" ' @@ -297,13 +297,13 @@ test_expect_success 'info deleted-symlink-file' " cd svnwc && svn_cmd rm --force symlink-file > /dev/null ) && - (cd svnwc; svn info symlink-file) >expected.info-deleted-symlink-file && - (cd gitwc; git svn info symlink-file) >actual.info-deleted-symlink-file && + (cd svnwc && svn info symlink-file) >expected.info-deleted-symlink-file && + (cd gitwc && git svn info symlink-file) >actual.info-deleted-symlink-file && test_cmp_info expected.info-deleted-symlink-file actual.info-deleted-symlink-file " test_expect_success 'info --url symlink-file (deleted)' ' - test "$(cd gitwc; git svn info --url symlink-file)" \ + test "$(cd gitwc && git svn info --url symlink-file)" \ = "$quoted_svnrepo/symlink-file" ' @@ -316,13 +316,13 @@ test_expect_success 'info deleted-symlink-directory' " cd svnwc && svn_cmd rm --force symlink-directory > /dev/null ) && - (cd svnwc; svn info symlink-directory) >expected.info-deleted-symlink-directory && - (cd gitwc; git svn info symlink-directory) >actual.info-deleted-symlink-directory && + (cd svnwc && svn info symlink-directory) >expected.info-deleted-symlink-directory && + (cd gitwc && git svn info symlink-directory) >actual.info-deleted-symlink-directory && test_cmp_info expected.info-deleted-symlink-directory actual.info-deleted-symlink-directory " test_expect_success 'info --url symlink-directory (deleted)' ' - test "$(cd gitwc; git svn info --url symlink-directory)" \ + test "$(cd gitwc && git svn info --url symlink-directory)" \ = "$quoted_svnrepo/symlink-directory" ' @@ -331,27 +331,27 @@ test_expect_success 'info --url symlink-directory (deleted)' ' test_expect_success 'info unknown-file' " echo two > gitwc/unknown-file && - (cd gitwc; test_must_fail git svn info unknown-file) \ + (cd gitwc && test_must_fail git svn info unknown-file) \ 2> actual.info-unknown-file && grep unknown-file actual.info-unknown-file " test_expect_success 'info --url unknown-file' ' echo two > gitwc/unknown-file && - (cd gitwc; test_must_fail git svn info --url unknown-file) \ + (cd gitwc && test_must_fail git svn info --url unknown-file) \ 2> actual.info-url-unknown-file && grep unknown-file actual.info-url-unknown-file ' test_expect_success 'info unknown-directory' " mkdir gitwc/unknown-directory svnwc/unknown-directory && - (cd gitwc; test_must_fail git svn info unknown-directory) \ + (cd gitwc && test_must_fail git svn info unknown-directory) \ 2> actual.info-unknown-directory && grep unknown-directory actual.info-unknown-directory " test_expect_success 'info --url unknown-directory' ' - (cd gitwc; test_must_fail git svn info --url unknown-directory) \ + (cd gitwc && test_must_fail git svn info --url unknown-directory) \ 2> actual.info-url-unknown-directory && grep unknown-directory actual.info-url-unknown-directory ' @@ -361,13 +361,13 @@ test_expect_success 'info unknown-symlink-file' " cd gitwc && ln -s unknown-file unknown-symlink-file ) && - (cd gitwc; test_must_fail git svn info unknown-symlink-file) \ + (cd gitwc && test_must_fail git svn info unknown-symlink-file) \ 2> actual.info-unknown-symlink-file && grep unknown-symlink-file actual.info-unknown-symlink-file " test_expect_success 'info --url unknown-symlink-file' ' - (cd gitwc; test_must_fail git svn info --url unknown-symlink-file) \ + (cd gitwc && test_must_fail git svn info --url unknown-symlink-file) \ 2> actual.info-url-unknown-symlink-file && grep unknown-symlink-file actual.info-url-unknown-symlink-file ' @@ -377,13 +377,13 @@ test_expect_success 'info unknown-symlink-directory' " cd gitwc && ln -s unknown-directory unknown-symlink-directory ) && - (cd gitwc; test_must_fail git svn info unknown-symlink-directory) \ + (cd gitwc && test_must_fail git svn info unknown-symlink-directory) \ 2> actual.info-unknown-symlink-directory && grep unknown-symlink-directory actual.info-unknown-symlink-directory " test_expect_success 'info --url unknown-symlink-directory' ' - (cd gitwc; test_must_fail git svn info --url unknown-symlink-directory) \ + (cd gitwc && test_must_fail git svn info --url unknown-symlink-directory) \ 2> actual.info-url-unknown-symlink-directory && grep unknown-symlink-directory actual.info-url-unknown-symlink-directory ' diff --git a/t/t9122-git-svn-author.sh b/t/t9122-git-svn-author.sh index 30013b7bb9..9e8fe38e7e 100755 --- a/t/t9122-git-svn-author.sh +++ b/t/t9122-git-svn-author.sh @@ -7,8 +7,8 @@ test_expect_success 'setup svn repository' ' svn_cmd checkout "$svnrepo" work.svn && ( cd work.svn && - echo >file - svn_cmd add file + echo >file && + svn_cmd add file && svn_cmd commit -m "first commit" file ) ' @@ -17,7 +17,7 @@ test_expect_success 'interact with it via git svn' ' mkdir work.git && ( cd work.git && - git svn init "$svnrepo" + git svn init "$svnrepo" && git svn fetch && echo modification >file && diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index 8dbd6476fa..2c213ae654 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -51,7 +51,7 @@ do git add F && git commit -a -F "$TEST_DIRECTORY"/t3900/$H.txt && E=$(git cat-file commit HEAD | sed -ne "s/^encoding //p") && - test "z$E" = "z$H" + test "z$E" = "z$H" && compare_git_head_with "$TEST_DIRECTORY"/t3900/$H.txt ) ' diff --git a/t/t9130-git-svn-authors-file.sh b/t/t9130-git-svn-authors-file.sh index d8262854bb..cb764bcadc 100755 --- a/t/t9130-git-svn-authors-file.sh +++ b/t/t9130-git-svn-authors-file.sh @@ -25,7 +25,7 @@ test_expect_success 'start import with incomplete authors file' ' test_expect_success 'imported 2 revisions successfully' ' ( - cd x + cd x && git rev-list refs/remotes/git-svn >actual && test_line_count = 2 actual && git rev-list -1 --pretty=raw refs/remotes/git-svn >actual && @@ -42,7 +42,7 @@ EOF test_expect_success 'continues to import once authors have been added' ' ( - cd x + cd x && git svn fetch --authors-file=../svn-authors && git rev-list refs/remotes/git-svn >actual && test_line_count = 4 actual && diff --git a/t/t9134-git-svn-ignore-paths.sh b/t/t9134-git-svn-ignore-paths.sh index 09ff10cd9b..fff49c4100 100755 --- a/t/t9134-git-svn-ignore-paths.sh +++ b/t/t9134-git-svn-ignore-paths.sh @@ -82,7 +82,7 @@ test_expect_success 'update git svn-cloned repo (option ignore)' ' test_expect_success 'SVN-side change inside of ignored www' ' ( cd s && - echo zaq >> www/test_www.txt + echo zaq >> www/test_www.txt && svn_cmd commit -m "SVN-side change inside of www/test_www.txt" && svn_cmd up && svn_cmd log -v | fgrep "SVN-side change inside of www/test_www.txt" @@ -114,8 +114,8 @@ test_expect_success 'update git svn-cloned repo (option ignore)' ' test_expect_success 'SVN-side change in and out of ignored www' ' ( cd s && - echo cvf >> www/test_www.txt - echo ygg >> qqq/test_qqq.txt + echo cvf >> www/test_www.txt && + echo ygg >> qqq/test_qqq.txt && svn_cmd commit -m "SVN-side change in and out of ignored www" && svn_cmd up && svn_cmd log -v | fgrep "SVN-side change in and out of ignored www" diff --git a/t/t9137-git-svn-dcommit-clobber-series.sh b/t/t9137-git-svn-dcommit-clobber-series.sh index 5fa07a369f..067b15bad2 100755 --- a/t/t9137-git-svn-dcommit-clobber-series.sh +++ b/t/t9137-git-svn-dcommit-clobber-series.sh @@ -7,7 +7,7 @@ test_description='git svn dcommit clobber series' test_expect_success 'initialize repo' ' mkdir import && (cd import && - awk "BEGIN { for (i = 1; i < 64; i++) { print i } }" > file + awk "BEGIN { for (i = 1; i < 64; i++) { print i } }" > file && svn_cmd import -m "initial" . "$svnrepo" ) && git svn init "$svnrepo" && diff --git a/t/t9138-git-svn-authors-prog.sh b/t/t9138-git-svn-authors-prog.sh index 93ef44fae8..027b416720 100755 --- a/t/t9138-git-svn-authors-prog.sh +++ b/t/t9138-git-svn-authors-prog.sh @@ -38,7 +38,7 @@ test_expect_success 'import authors with prog and file' ' test_expect_success 'imported 6 revisions successfully' ' ( - cd x + cd x && git rev-list refs/remotes/git-svn >actual && test_line_count = 6 actual ) @@ -46,7 +46,7 @@ test_expect_success 'imported 6 revisions successfully' ' test_expect_success 'authors-prog ran correctly' ' ( - cd x + cd x && git rev-list -1 --pretty=raw refs/remotes/git-svn~1 >actual && grep "^author ee-foo <ee-foo@example\.com> " actual && git rev-list -1 --pretty=raw refs/remotes/git-svn~2 >actual && @@ -62,7 +62,7 @@ test_expect_success 'authors-prog ran correctly' ' test_expect_success 'authors-file overrode authors-prog' ' ( - cd x + cd x && git rev-list -1 --pretty=raw refs/remotes/git-svn >actual && grep "^author FFFFFFF FFFFFFF <fFf@other\.example\.com> " actual ) diff --git a/t/t9146-git-svn-empty-dirs.sh b/t/t9146-git-svn-empty-dirs.sh index 6d3130e618..5f91c0d68b 100755 --- a/t/t9146-git-svn-empty-dirs.sh +++ b/t/t9146-git-svn-empty-dirs.sh @@ -21,7 +21,7 @@ test_expect_success 'empty directories exist' ' do if ! test -d "$i" then - echo >&2 "$i does not exist" + echo >&2 "$i does not exist" && exit 1 fi done @@ -38,7 +38,7 @@ test_expect_success 'option automkdirs set to false' ' do if test -d "$i" then - echo >&2 "$i exists" + echo >&2 "$i exists" && exit 1 fi done @@ -63,7 +63,7 @@ test_expect_success 'git svn mkdirs recreates empty directories' ' do if ! test -d "$i" then - echo >&2 "$i does not exist" + echo >&2 "$i does not exist" && exit 1 fi done @@ -79,21 +79,21 @@ test_expect_success 'git svn mkdirs -r works' ' do if ! test -d "$i" then - echo >&2 "$i does not exist" + echo >&2 "$i does not exist" && exit 1 fi - done + done && if test -d "! !" then - echo >&2 "$i should not exist" + echo >&2 "$i should not exist" && exit 1 - fi + fi && git svn mkdirs -r8 && if ! test -d "! !" then - echo >&2 "$i not exist" + echo >&2 "$i not exist" && exit 1 fi ) @@ -115,7 +115,7 @@ test_expect_success 'empty directories in trunk exist' ' do if ! test -d "$i" then - echo >&2 "$i does not exist" + echo >&2 "$i does not exist" && exit 1 fi done @@ -148,7 +148,7 @@ test_expect_success 'git svn gc-ed files work' ' do if ! test -d "$i" then - echo >&2 "$i does not exist" + echo >&2 "$i does not exist" && exit 1 fi done diff --git a/t/t9147-git-svn-include-paths.sh b/t/t9147-git-svn-include-paths.sh index a90ff58629..d292bf9f55 100755 --- a/t/t9147-git-svn-include-paths.sh +++ b/t/t9147-git-svn-include-paths.sh @@ -84,7 +84,7 @@ test_expect_success 'update git svn-cloned repo (option include)' ' test_expect_success 'SVN-side change inside of ignored www' ' ( cd s && - echo zaq >> www/test_www.txt + echo zaq >> www/test_www.txt && svn_cmd commit -m "SVN-side change inside of www/test_www.txt" && svn_cmd up && svn_cmd log -v | fgrep "SVN-side change inside of www/test_www.txt" @@ -116,8 +116,8 @@ test_expect_success 'update git svn-cloned repo (option include)' ' test_expect_success 'SVN-side change in and out of included qqq' ' ( cd s && - echo cvf >> www/test_www.txt - echo ygg >> qqq/test_qqq.txt + echo cvf >> www/test_www.txt && + echo ygg >> qqq/test_qqq.txt && svn_cmd commit -m "SVN-side change in and out of ignored www" && svn_cmd up && svn_cmd log -v | fgrep "SVN-side change in and out of ignored www" diff --git a/t/t9152-svn-empty-dirs-after-gc.sh b/t/t9152-svn-empty-dirs-after-gc.sh index 301e779709..89f285d082 100755 --- a/t/t9152-svn-empty-dirs-after-gc.sh +++ b/t/t9152-svn-empty-dirs-after-gc.sh @@ -30,7 +30,7 @@ test_expect_success 'git svn mkdirs recreates empty directories after git svn gc do if ! test -d "$i" then - echo >&2 "$i does not exist" + echo >&2 "$i does not exist" && exit 1 fi done diff --git a/t/t9164-git-svn-dcommit-concurrent.sh b/t/t9164-git-svn-dcommit-concurrent.sh index d8464d4218..90346ff4e9 100755 --- a/t/t9164-git-svn-dcommit-concurrent.sh +++ b/t/t9164-git-svn-dcommit-concurrent.sh @@ -12,7 +12,7 @@ test_expect_success 'setup svn repository' ' svn_cmd checkout "$svnrepo" work.svn && ( cd work.svn && - echo >file && echo > auto_updated_file + echo >file && echo > auto_updated_file && svn_cmd add file auto_updated_file && svn_cmd commit -m "initial commit" ) && diff --git a/t/t9165-git-svn-fetch-merge-branch-of-branch.sh b/t/t9165-git-svn-fetch-merge-branch-of-branch.sh index fa3ef3b1f7..a4813c2b09 100755 --- a/t/t9165-git-svn-fetch-merge-branch-of-branch.sh +++ b/t/t9165-git-svn-fetch-merge-branch-of-branch.sh @@ -39,7 +39,7 @@ test_expect_success 'initialize source svn repo' ' svn_cmd commit -m trunk && svn_cmd switch "$svnrepo"/branches/branch2 && svn_cmd merge "$svnrepo"/trunk && - svn_cmd commit -m "merge trunk" + svn_cmd commit -m "merge trunk" && svn_cmd switch "$svnrepo"/trunk && svn_cmd merge --reintegrate "$svnrepo"/branches/branch2 && svn_cmd commit -m "merge branch2" diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index 1319415ba8..cd61288aa1 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -187,7 +187,7 @@ test_expect_success \ git commit -a -m "Update with spaces" && id=$(git rev-list --max-count=1 HEAD) && (cd "$CVSWORK" && - git cvsexportcommit -c $id + git cvsexportcommit -c $id && check_entries "G g" "with spaces.png/1.2/-kb|with spaces.txt/1.2/" )' @@ -245,7 +245,7 @@ test_expect_success FILEMODE \ git add G/off && git commit -a -m "Execute test" && (cd "$CVSWORK" && - git cvsexportcommit -c HEAD + git cvsexportcommit -c HEAD && test -x G/on && ! test -x G/off )' @@ -303,7 +303,7 @@ test_expect_success 're-commit a removed filename which remains in CVS attic' ' git add attic_gremlin && git commit -m "Added attic_gremlin" && git cvsexportcommit -w "$CVSWORK" -c HEAD && - (cd "$CVSWORK"; cvs -Q update -d) && + (cd "$CVSWORK" && cvs -Q update -d) && test -f "$CVSWORK/attic_gremlin" ' diff --git a/t/t9302-fast-import-unpack-limit.sh b/t/t9302-fast-import-unpack-limit.sh index a04de14677..bb1c39cfcc 100755 --- a/t/t9302-fast-import-unpack-limit.sh +++ b/t/t9302-fast-import-unpack-limit.sh @@ -80,7 +80,7 @@ test_expect_success 'lookups after checkpoint works' ' do if test $n -gt 30 then - echo >&2 "checkpoint did not update branch" + echo >&2 "checkpoint did not update branch" && exit 1 else n=$(($n + 1)) diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 06742748e9..a5e5dca753 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -328,7 +328,7 @@ test_expect_success 'cvs update (subdirectories)' \ '(for dir in A A/B A/B/C A/D E; do mkdir $dir && echo "test file in $dir" >"$dir/file_in_$(echo $dir|sed -e "s#/# #g")" && - git add $dir; + git add $dir done) && git commit -q -m "deep sub directory structure" && git push gitcvs.git >/dev/null && @@ -371,7 +371,7 @@ test_expect_success 'cvs update (merge)' \ 'echo Line 0 >expected && for i in 1 2 3 4 5 6 7 do - echo Line $i >>merge + echo Line $i >>merge && echo Line $i >>expected done && echo Line 8 >>expected && @@ -382,7 +382,7 @@ test_expect_success 'cvs update (merge)' \ GIT_CONFIG="$git_config" cvs -Q update && test "$(echo $(grep merge CVS/Entries|cut -d/ -f2,3,5))" = "merge/1.1/" && test_cmp merge ../merge && - ( echo Line 0; cat merge ) >merge.tmp && + ( echo Line 0 && cat merge ) >merge.tmp && mv merge.tmp merge && cd "$WORKDIR" && echo Line 8 >>merge && @@ -410,7 +410,7 @@ do done test_expect_success 'cvs update (conflict merge)' \ - '( echo LINE 0; cat merge ) >merge.tmp && + '( echo LINE 0 && cat merge ) >merge.tmp && mv merge.tmp merge && git add merge && git commit -q -m "Merge test (conflict)" && diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh index 804ce3850f..5dfee07d9a 100755 --- a/t/t9600-cvsimport.sh +++ b/t/t9600-cvsimport.sh @@ -135,7 +135,7 @@ test_expect_success PERL 'second update has correct .git/cvs-revisions' ' (cd module-git && git log --format="o_fortuna 1.1 %H" -1 HEAD^^ && - git log --format="o_fortuna 1.2 %H" -1 HEAD^ + git log --format="o_fortuna 1.2 %H" -1 HEAD^ && git log --format="tick 1.1 %H" -1 HEAD) > expected && test_cmp expected module-git/.git/cvs-revisions ' diff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh index 1ab76c4246..3f5291b857 100755 --- a/t/t9806-git-p4-options.sh +++ b/t/t9806-git-p4-options.sh @@ -134,7 +134,7 @@ test_expect_success 'clone --changesfile' ' ( cd "$git" && git log --oneline p4/master >lines && - test_line_count = 2 lines + test_line_count = 2 lines && test_path_is_file file1 && test_path_is_missing file2 && test_path_is_file file3 diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh index 8134ab439b..cc53debe19 100755 --- a/t/t9810-git-p4-rcs.sh +++ b/t/t9810-git-p4-rcs.sh @@ -161,7 +161,7 @@ test_expect_success 'cleanup after failure' ' test_expect_success 'ktext expansion should not expand multi-line $File::' ' ( cd "$cli" && - cat >lv.pm <<-\EOF + cat >lv.pm <<-\EOF && my $wanted = sub { my $f = $File::Find::name; if ( -f && $f =~ /foo/ ) { EOF diff --git a/t/t9811-git-p4-label-import.sh b/t/t9811-git-p4-label-import.sh index decb66ba30..602b0a5d5c 100755 --- a/t/t9811-git-p4-label-import.sh +++ b/t/t9811-git-p4-label-import.sh @@ -133,7 +133,7 @@ test_expect_success 'export git tags to p4' ' p4 labels ... | grep LIGHTWEIGHT_TAG && p4 label -o GIT_TAG_1 | grep "tag created in git:xyzzy" && p4 sync ...@GIT_TAG_1 && - ! test -f main/f10 + ! test -f main/f10 && p4 sync ...@GIT_TAG_2 && test -f main/f10 ) diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh index e7e0268e98..60baa06e27 100755 --- a/t/t9814-git-p4-rename.sh +++ b/t/t9814-git-p4-rename.sh @@ -9,23 +9,11 @@ test_expect_success 'start p4d' ' ' # We rely on this behavior to detect for p4 move availability. -test_expect_success 'p4 help unknown returns 1' ' +test_expect_success '"p4 help unknown" errors out' ' ( cd "$cli" && - ( - p4 help client >errs 2>&1 - echo $? >retval - ) - echo 0 >expected && - test_cmp expected retval && - rm retval && - ( - p4 help nosuchcommand >errs 2>&1 - echo $? >retval - ) - echo 1 >expected && - test_cmp expected retval && - rm retval + p4 help client && + ! p4 help nosuchcommand ) ' diff --git a/t/t9815-git-p4-submit-fail.sh b/t/t9815-git-p4-submit-fail.sh index 37b42d03a2..eaf03a6563 100755 --- a/t/t9815-git-p4-submit-fail.sh +++ b/t/t9815-git-p4-submit-fail.sh @@ -394,7 +394,7 @@ test_expect_success 'cleanup rename after submit cancel' ' ( cd "$cli" && test_path_is_missing text2 && - p4 fstat -T action text2 2>&1 | grep "no such file" + p4 fstat -T action text2 2>&1 | grep "no such file" && test_path_is_file text && ! p4 fstat -T action text ) diff --git a/t/t9830-git-p4-symlink-dir.sh b/t/t9830-git-p4-symlink-dir.sh index 3dc528bb1e..2ad1b0810d 100755 --- a/t/t9830-git-p4-symlink-dir.sh +++ b/t/t9830-git-p4-symlink-dir.sh @@ -30,7 +30,7 @@ test_expect_success 'symlinked directory' ' ( cd "$cli" && p4 sync && - test -L some/sub/directory/subdir2 + test -L some/sub/directory/subdir2 && test_path_is_file some/sub/directory/subdir2/file.t ) diff --git a/t/t9831-git-p4-triggers.sh b/t/t9831-git-p4-triggers.sh index bbcf14c664..be44c9751a 100755 --- a/t/t9831-git-p4-triggers.sh +++ b/t/t9831-git-p4-triggers.sh @@ -13,7 +13,7 @@ test_expect_success 'init depot' ' cd "$cli" && echo file1 >file1 && p4 add file1 && - p4 submit -d "change 1" + p4 submit -d "change 1" && echo file2 >file2 && p4 add file2 && p4 submit -d "change 2" diff --git a/t/t9833-errors.sh b/t/t9833-errors.sh index 9ba892de7a..277d347012 100755 --- a/t/t9833-errors.sh +++ b/t/t9833-errors.sh @@ -26,7 +26,9 @@ test_expect_success 'error handling' ' ) && p4 passwd -P newpassword && ( - P4PASSWD=badpassword test_must_fail git p4 clone //depot/foo 2>errmsg && + P4PASSWD=badpassword && + export P4PASSWD && + test_must_fail git p4 clone //depot/foo 2>errmsg && grep -q "failure accessing depot.*P4PASSWD" errmsg ) ' diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index a28640ce1a..5ff43b9cbb 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -501,6 +501,42 @@ test_expect_success '__gitcomp - suffix' ' EOF ' +test_expect_success '__gitcomp - ignore optional negative options' ' + test_gitcomp "--" "--abc --def --no-one -- --no-two" <<-\EOF + --abc Z + --def Z + --no-one Z + --no-... Z + EOF +' + +test_expect_success '__gitcomp - ignore/narrow optional negative options' ' + test_gitcomp "--a" "--abc --abcdef --no-one -- --no-two" <<-\EOF + --abc Z + --abcdef Z + EOF +' + +test_expect_success '__gitcomp - ignore/narrow optional negative options' ' + test_gitcomp "--n" "--abc --def --no-one -- --no-two" <<-\EOF + --no-one Z + --no-... Z + EOF +' + +test_expect_success '__gitcomp - expand all negative options' ' + test_gitcomp "--no-" "--abc --def --no-one -- --no-two" <<-\EOF + --no-one Z + --no-two Z + EOF +' + +test_expect_success '__gitcomp - expand/narrow all negative options' ' + test_gitcomp "--no-o" "--abc --def --no-one -- --no-two" <<-\EOF + --no-one Z + EOF +' + test_expect_success '__gitcomp - doesnt fail because of invalid variable name' ' __gitcomp "$invalid_variable_name" ' @@ -1067,7 +1103,7 @@ test_expect_success '__git_complete_refs - remote' ' master-in-other Z EOF ( - cur= + cur= && __git_complete_refs --remote=other && print_comp ) && @@ -1086,7 +1122,7 @@ test_expect_success '__git_complete_refs - track' ' master-in-other Z EOF ( - cur= + cur= && __git_complete_refs --track && print_comp ) && @@ -1398,8 +1434,8 @@ test_expect_success 'double dash "git checkout"' ' --ignore-other-worktrees Z --recurse-submodules Z --progress Z - --no-track Z - --no-recurse-submodules Z + --no-quiet Z + --no-... Z EOF ' @@ -1607,6 +1643,7 @@ test_expect_success 'completion used <cmd> completion for alias: !f() { : git <c test_expect_success 'completion without explicit _git_xxx function' ' test_completion "git version --" <<-\EOF --build-options Z + --no-build-options Z EOF ' diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index c3b89ae783..04440685a6 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -529,7 +529,7 @@ test_expect_success 'prompt - bash color pc mode - branch name' ' printf "BEFORE: (${c_green}\${__git_ps1_branch_name}${c_clear}):AFTER\\nmaster" >expected && ( GIT_PS1_SHOWCOLORHINTS=y && - __git_ps1 "BEFORE:" ":AFTER" >"$actual" + __git_ps1 "BEFORE:" ":AFTER" >"$actual" && printf "%s\\n%s" "$PS1" "${__git_ps1_branch_name}" >"$actual" ) && test_cmp expected "$actual" |