diff options
Diffstat (limited to 't')
137 files changed, 7112 insertions, 890 deletions
diff --git a/t/Makefile b/t/Makefile index bd09390d32..25c559bb49 100644 --- a/t/Makefile +++ b/t/Makefile @@ -27,6 +27,8 @@ pre-clean: clean: $(RM) -r 'trash directory'.* test-results + $(RM) t????/cvsroot/CVSROOT/?* + $(RM) -r valgrind/bin aggregate-results-and-cleanup: $(T) $(MAKE) aggregate-results @@ -75,6 +75,15 @@ appropriately before running "make". As the names depend on the tests' file names, it is safe to run the tests with this option in parallel. +--with-dashes:: + By default tests are run without dashed forms of + commands (like git-commit) in the PATH (it only uses + wrappers from ../bin-wrappers). Use this option to include + the build directory (..) in the PATH, which contains all + the dashed forms of commands. This option is currently + implied by other options like --valgrind and + GIT_TEST_INSTALLED. + You can also set the GIT_TEST_INSTALLED environment variable to the bindir of an existing git installation to test that installation. You still need to have built this git sandbox, from which various diff --git a/t/diff-lib.sh b/t/diff-lib.sh index 4bddeb591e..75a35fcd06 100644 --- a/t/diff-lib.sh +++ b/t/diff-lib.sh @@ -1,7 +1,5 @@ : -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" sanitize_diff_raw='/^:/s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]* / X X \1# /' compare_diff_raw () { # When heuristics are improved, the score numbers would change. diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh index 76d8b7b803..5a734b1b7b 100644 --- a/t/gitweb-lib.sh +++ b/t/gitweb-lib.sh @@ -25,6 +25,7 @@ our \$favicon = 'file:///$TEST_DIRECTORY/../gitweb/git-favicon.png'; our \$projects_list = ''; our \$export_ok = ''; our \$strict_export = ''; +our \$maxload = undef; EOF diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 6765b08065..28aff887b5 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -12,16 +12,29 @@ fi HTTPD_PARA="" +for DEFAULT_HTTPD_PATH in '/usr/sbin/httpd' '/usr/sbin/apache2' +do + if test -x "$DEFAULT_HTTPD_PATH" + then + break + fi +done + +for DEFAULT_HTTPD_MODULE_PATH in '/usr/libexec/apache2' \ + '/usr/lib/apache2/modules' \ + '/usr/lib64/httpd/modules' \ + '/usr/lib/httpd/modules' +do + if test -d "$DEFAULT_HTTPD_MODULE_PATH" + then + break + fi +done + case $(uname) in Darwin) - DEFAULT_HTTPD_PATH='/usr/sbin/httpd' - DEFAULT_HTTPD_MODULE_PATH='/usr/libexec/apache2' HTTPD_PARA="$HTTPD_PARA -DDarwin" ;; - *) - DEFAULT_HTTPD_PATH='/usr/sbin/apache2' - DEFAULT_HTTPD_MODULE_PATH='/usr/lib/apache2/modules' - ;; esac LIB_HTTPD_PATH=${LIB_HTTPD_PATH-"$DEFAULT_HTTPD_PATH"} @@ -49,6 +62,11 @@ then say "skipping test, at least Apache version 2 is required" test_done fi + if ! test -d "$DEFAULT_HTTPD_MODULE_PATH" + then + say "Apache module directory not found. Skipping tests." + test_done + fi LIB_HTTPD_MODULE_PATH="$DEFAULT_HTTPD_MODULE_PATH" fi diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 0fe3fd0d01..4961505d1d 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -22,8 +22,13 @@ Alias /dumb/ www/ <Location /smart/> SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} + SetEnv GIT_HTTP_EXPORT_ALL +</Location> +<Location /smart_noexport/> + SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} </Location> ScriptAlias /smart/ ${GIT_EXEC_PATH}/git-http-backend/ +ScriptAlias /smart_noexport/ ${GIT_EXEC_PATH}/git-http-backend/ <Directory ${GIT_EXEC_PATH}> Options None </Directory> diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 62f452c8ea..6aefe27593 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -2,21 +2,33 @@ # After setting the fake editor with this function, you can # -# - override the commit message with $FAKE_COMMIT_MESSAGE, +# - override the commit message with $FAKE_COMMIT_MESSAGE # - amend the commit message with $FAKE_COMMIT_AMEND # - check that non-commit messages have a certain line count with $EXPECT_COUNT -# - rewrite a rebase -i script with $FAKE_LINES in the form +# - check the commit count in the commit message header with $EXPECT_HEADER_COUNT +# - rewrite a rebase -i script as directed by $FAKE_LINES. +# $FAKE_LINES consists of a sequence of words separated by spaces. +# The following word combinations are possible: # -# "[<lineno1>] [<lineno2>]..." +# "<lineno>" -- add a "pick" line with the SHA1 taken from the +# specified line. # -# If a line number is prefixed with "squash", "edit", or "reword", the -# respective line's command will be replaced with the specified one. +# "<cmd> <lineno>" -- add a line with the specified command +# ("squash", "fixup", "edit", or "reword") and the SHA1 taken +# from the specified line. +# +# "#" -- Add a comment line. +# +# ">" -- Add a blank line. set_fake_editor () { echo "#!$SHELL_PATH" >fake-editor.sh cat >> fake-editor.sh <<\EOF case "$1" in */COMMIT_EDITMSG) + test -z "$EXPECT_HEADER_COUNT" || + test "$EXPECT_HEADER_COUNT" = "$(sed -n '1s/^# This is a combination of \(.*\) commits\./\1/p' < "$1")" || + exit test -z "$FAKE_COMMIT_MESSAGE" || echo "$FAKE_COMMIT_MESSAGE" > "$1" test -z "$FAKE_COMMIT_AMEND" || echo "$FAKE_COMMIT_AMEND" >> "$1" exit @@ -28,19 +40,24 @@ test -z "$EXPECT_COUNT" || test -z "$FAKE_LINES" && exit grep -v '^#' < "$1" > "$1".tmp rm -f "$1" +echo 'rebase -i script before editing:' cat "$1".tmp action=pick for line in $FAKE_LINES; do case $line in - squash|edit|reword) + squash|fixup|edit|reword) action="$line";; + "#") + echo '# comment' >> "$1";; + ">") + echo >> "$1";; *) - echo sed -n "${line}s/^pick/$action/p" - sed -n "${line}p" < "$1".tmp sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1" action=pick;; esac done +echo 'rebase -i script after editing:' +cat "$1" EOF test_set_editor "$(pwd)/fake-editor.sh" diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 4e72b53140..c3e7e322a8 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -4,21 +4,8 @@ test_description='CRLF conversion' . ./test-lib.sh -q_to_nul () { - perl -pe 'y/Q/\000/' -} - -q_to_cr () { - tr Q '\015' -} - -append_cr () { - sed -e 's/$/Q/' | tr Q '\015' -} - -remove_cr () { - tr '\015' Q <"$1" | grep Q >/dev/null && - tr '\015' Q <"$1" | sed -ne 's/Q$//p' +has_cr() { + tr '\015' Q <"$1" | grep Q >/dev/null } test_expect_success setup ' @@ -156,7 +143,7 @@ test_expect_success 'checkout with autocrlf=true' ' for f in one dir/two do - remove_cr "$f" >tmp && mv -f tmp $f && + remove_cr <"$f" >tmp && mv -f tmp $f && git update-index -- $f || { echo "Eh? $f" false @@ -180,7 +167,7 @@ test_expect_success 'checkout with autocrlf=input' ' for f in one dir/two do - if remove_cr "$f" >/dev/null + if has_cr "$f" then echo "Eh? $f" false @@ -245,7 +232,7 @@ test_expect_success 'apply patch (autocrlf=true)' ' git read-tree --reset -u HEAD && git apply patch.file && - test "$patched" = "`remove_cr one | git hash-object --stdin`" || { + test "$patched" = "`remove_cr <one | git hash-object --stdin`" || { echo "Eh? apply without index" false } @@ -272,7 +259,7 @@ test_expect_success 'apply patch --index (autocrlf=true)' ' git apply --index patch.file && test "$patched" = `git rev-parse :one` && - test "$patched" = "`remove_cr one | git hash-object --stdin`" || { + test "$patched" = "`remove_cr <one | git hash-object --stdin`" || { echo "Eh? apply with --index" false } @@ -285,7 +272,7 @@ test_expect_success '.gitattributes says two is binary' ' git config core.autocrlf true && git read-tree --reset -u HEAD && - if remove_cr dir/two >/dev/null + if has_cr dir/two then echo "Huh?" false @@ -293,7 +280,7 @@ test_expect_success '.gitattributes says two is binary' ' : happy fi && - if remove_cr one >/dev/null + if has_cr one then : happy else @@ -301,7 +288,7 @@ test_expect_success '.gitattributes says two is binary' ' false fi && - if remove_cr three >/dev/null + if has_cr three then echo "Huh?" false @@ -316,7 +303,7 @@ test_expect_success '.gitattributes says two is input' ' echo "two crlf=input" >.gitattributes && git read-tree --reset -u HEAD && - if remove_cr dir/two >/dev/null + if has_cr dir/two then echo "Huh?" false @@ -331,7 +318,7 @@ test_expect_success '.gitattributes says two and three are text' ' echo "t* crlf" >.gitattributes && git read-tree --reset -u HEAD && - if remove_cr dir/two >/dev/null + if has_cr dir/two then : happy else @@ -339,7 +326,7 @@ test_expect_success '.gitattributes says two and three are text' ' false fi && - if remove_cr three >/dev/null + if has_cr three then : happy else @@ -357,14 +344,14 @@ test_expect_success 'in-tree .gitattributes (1)' ' rm -rf tmp one dir .gitattributes patch.file three && git read-tree --reset -u HEAD && - if remove_cr one >/dev/null + if has_cr one then echo "Eh? one should not have CRLF" false else : happy fi && - remove_cr three >/dev/null || { + has_cr three || { echo "Eh? three should still have CRLF" false } @@ -376,14 +363,14 @@ test_expect_success 'in-tree .gitattributes (2)' ' git read-tree --reset HEAD && git checkout-index -f -q -u -a && - if remove_cr one >/dev/null + if has_cr one then echo "Eh? one should not have CRLF" false else : happy fi && - remove_cr three >/dev/null || { + has_cr three || { echo "Eh? three should still have CRLF" false } @@ -396,14 +383,14 @@ test_expect_success 'in-tree .gitattributes (3)' ' git checkout-index -u .gitattributes && git checkout-index -u one dir/two three && - if remove_cr one >/dev/null + if has_cr one then echo "Eh? one should not have CRLF" false else : happy fi && - remove_cr three >/dev/null || { + has_cr three || { echo "Eh? three should still have CRLF" false } @@ -416,14 +403,14 @@ test_expect_success 'in-tree .gitattributes (4)' ' git checkout-index -u one dir/two three && git checkout-index -u .gitattributes && - if remove_cr one >/dev/null + if has_cr one then echo "Eh? one should not have CRLF" false else : happy fi && - remove_cr three >/dev/null || { + has_cr three || { echo "Eh? three should still have CRLF" false } @@ -456,7 +443,7 @@ test_expect_success 'checkout when deleting .gitattributes' ' git checkout master~1 && git checkout master && - remove_cr .file2 >/dev/null + has_cr .file2 ' diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index 8fc39d77ce..6cb8d60ea2 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -4,7 +4,8 @@ test_description='blob conversion via gitattributes' . ./test-lib.sh -cat <<\EOF >rot13.sh +cat <<EOF >rot13.sh +#!$SHELL_PATH tr \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' \ 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM' diff --git a/t/t0022-crlf-rename.sh b/t/t0022-crlf-rename.sh index f1e1d48869..7af3fbcc7b 100755 --- a/t/t0022-crlf-rename.sh +++ b/t/t0022-crlf-rename.sh @@ -12,7 +12,7 @@ test_expect_success setup ' test_tick && git commit -m Initial && - sed -e "s/\$/
/" "$TEST_DIRECTORY"/t0022-crlf-rename.sh >elpmas && + append_cr <"$TEST_DIRECTORY"/t0022-crlf-rename.sh >elpmas && git add elpmas && rm -f sample && diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh index 89282ccf7a..41df6bcf27 100755 --- a/t/t0050-filesystem.sh +++ b/t/t0050-filesystem.sh @@ -108,13 +108,17 @@ $test_case 'merge (case change)' ' ' -$test_case 'add (with different case)' ' + + +test_expect_failure 'add (with different case)' ' git reset --hard initial && rm camelcase && echo 1 >CamelCase && git add CamelCase && - test $(git ls-files | grep -i camelcase | wc -l) = 1 + camel=$(git ls-files | grep -i camelcase) && + test $(echo "$camel" | wc -l) = 1 && + test "z$(git cat-file blob :$camel)" = z1 ' diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh new file mode 100755 index 0000000000..10b26e4d8e --- /dev/null +++ b/t/t0061-run-command.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Copyright (c) 2009 Ilari Liusvaara +# + +test_description='Test run command' + +. ./test-lib.sh + +test_expect_success 'start_command reports ENOENT' ' + test-run-command start-command-ENOENT ./does-not-exist +' + +test_done diff --git a/t/t0101-at-syntax.sh b/t/t0101-at-syntax.sh index 5e298c5102..a1998b558f 100755 --- a/t/t0101-at-syntax.sh +++ b/t/t0101-at-syntax.sh @@ -31,7 +31,7 @@ test_expect_success '@{2001-09-17} (before the first commit) shows old' ' ' test_expect_success 'silly approxidates work' ' - check_at @{3.hot.dogs.and.30.years.ago} one + check_at @{3.hot.dogs.on.2001-09-17} one ' test_expect_success 'notice misspelled upstream' ' diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh index 22ba7a5442..4f171722d9 100755 --- a/t/t1000-read-tree-m-3way.sh +++ b/t/t1000-read-tree-m-3way.sh @@ -126,9 +126,6 @@ cat >expected <<\EOF 100644 X 0 Z/NN EOF -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" - check_result () { git ls-files --stage | sed -e 's/ '"$_x40"' / X /' >current && test_cmp expected current diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index c2d408b461..6327d205cb 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -26,8 +26,6 @@ read_tree_twoway () { git read-tree -m "$1" "$2" && git ls-files --stage } -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" compare_change () { sed -n >current \ -e '/^--- /d; /^+++ /d; /^@@ /d;' \ diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh index 5e40cec530..0241329a08 100755 --- a/t/t1002-read-tree-m-u-2way.sh +++ b/t/t1002-read-tree-m-u-2way.sh @@ -10,8 +10,6 @@ This is identical to t1001, but uses -u to update the work tree as well. ' . ./test-lib.sh -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" compare_change () { sed >current \ -e '1{/^diff --git /d;}' \ diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh index 9956e3ad62..b946f87686 100755 --- a/t/t1010-mktree.sh +++ b/t/t1010-mktree.sh @@ -58,14 +58,12 @@ test_expect_success 'allow missing object with --missing' ' test_cmp tree.missing actual ' -test_expect_failure 'mktree reads ls-tree -r output (1)' ' - git mktree <all >actual && - test_cmp tree actual +test_expect_success 'mktree refuses to read ls-tree -r output (1)' ' + test_must_fail git mktree <all >actual ' -test_expect_failure 'mktree reads ls-tree -r output (2)' ' - git mktree <all.withsub >actual && - test_cmp tree.withsub actual +test_expect_success 'mktree refuses to read ls-tree -r output (2)' ' + test_must_fail git mktree <all.withsub >actual ' test_done diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh new file mode 100755 index 0000000000..62246dbf95 --- /dev/null +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -0,0 +1,150 @@ +#!/bin/sh + +test_description='sparse checkout tests' + +. ./test-lib.sh + +cat >expected <<EOF +100644 77f0ba1734ed79d12881f81b36ee134de6a3327b 0 init.t +100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 sub/added +EOF +test_expect_success 'setup' ' + test_commit init && + echo modified >> init.t && + mkdir sub && + touch sub/added && + git add init.t sub/added && + git commit -m "modified and added" && + git tag top && + git rm sub/added && + git commit -m removed && + git tag removed && + git checkout top && + git ls-files --stage > result && + test_cmp expected result +' + +cat >expected.swt <<EOF +H init.t +H sub/added +EOF +test_expect_success 'read-tree without .git/info/sparse-checkout' ' + git read-tree -m -u HEAD && + git ls-files --stage > result && + test_cmp expected result && + git ls-files -t > result && + test_cmp expected.swt result +' + +test_expect_success 'read-tree with .git/info/sparse-checkout but disabled' ' + echo > .git/info/sparse-checkout + git read-tree -m -u HEAD && + git ls-files -t > result && + test_cmp expected.swt result && + test -f init.t && + test -f sub/added +' + +test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-checkout and enabled' ' + git config core.sparsecheckout true && + echo > .git/info/sparse-checkout && + git read-tree --no-sparse-checkout -m -u HEAD && + git ls-files -t > result && + test_cmp expected.swt result && + test -f init.t && + test -f sub/added +' + +test_expect_success 'read-tree with empty .git/info/sparse-checkout' ' + git config core.sparsecheckout true && + echo > .git/info/sparse-checkout && + test_must_fail git read-tree -m -u HEAD && + git ls-files --stage > result && + test_cmp expected result && + git ls-files -t > result && + test_cmp expected.swt result && + test -f init.t && + test -f sub/added +' + +cat >expected.swt <<EOF +S init.t +H sub/added +EOF +test_expect_success 'match directories with trailing slash' ' + echo sub/ > .git/info/sparse-checkout && + git read-tree -m -u HEAD && + git ls-files -t > result && + test_cmp expected.swt result && + test ! -f init.t && + test -f sub/added +' + +cat >expected.swt <<EOF +H init.t +H sub/added +EOF +test_expect_failure 'match directories without trailing slash' ' + echo init.t > .git/info/sparse-checkout && + echo sub >> .git/info/sparse-checkout && + git read-tree -m -u HEAD && + git ls-files -t > result && + test_cmp expected.swt result && + test ! -f init.t && + test -f sub/added +' + +cat >expected.swt <<EOF +H init.t +S sub/added +EOF +test_expect_success 'checkout area changes' ' + echo init.t > .git/info/sparse-checkout && + git read-tree -m -u HEAD && + git ls-files -t > result && + test_cmp expected.swt result && + test -f init.t && + test ! -f sub/added +' + +test_expect_success 'read-tree updates worktree, absent case' ' + echo sub/added > .git/info/sparse-checkout && + git checkout -f top && + git read-tree -m -u HEAD^ && + test ! -f init.t +' + +test_expect_success 'read-tree updates worktree, dirty case' ' + echo sub/added > .git/info/sparse-checkout && + git checkout -f top && + echo dirty > init.t && + git read-tree -m -u HEAD^ && + grep -q dirty init.t && + rm init.t +' + +test_expect_success 'read-tree removes worktree, dirty case' ' + echo init.t > .git/info/sparse-checkout && + git checkout -f top && + echo dirty > added && + git read-tree -m -u HEAD^ && + grep -q dirty added +' + +test_expect_success 'read-tree adds to worktree, absent case' ' + echo init.t > .git/info/sparse-checkout && + git checkout -f removed && + git read-tree -u -m HEAD^ && + test ! -f sub/added +' + +test_expect_success 'read-tree adds to worktree, dirty case' ' + echo init.t > .git/info/sparse-checkout && + git checkout -f removed && + mkdir sub && + echo dirty > sub/added && + git read-tree -u -m HEAD^ && + grep -q dirty sub/added +' + +test_done diff --git a/t/t1012-read-tree-df.sh b/t/t1012-read-tree-df.sh new file mode 100755 index 0000000000..9811d467da --- /dev/null +++ b/t/t1012-read-tree-df.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +test_description='read-tree D/F conflict corner cases' + +. ./test-lib.sh + +maketree () { + ( + rm -f .git/index .git/index.lock && + git clean -d -f -f -q -x && + name="$1" && + shift && + for it + do + path=$(expr "$it" : '\([^:]*\)') && + mkdir -p $(dirname "$path") && + echo "$it" >"$path" && + git update-index --add "$path" || exit + done && + git tag "$name" $(git write-tree) + ) +} + +settree () { + rm -f .git/index .git/index.lock && + git clean -d -f -f -q -x && + git read-tree "$1" && + git checkout-index -f -q -u -a && + git update-index --refresh +} + +checkindex () { + git ls-files -s | + sed "s|^[0-7][0-7]* $_x40 \([0-3]\) |\1 |" >current && + cat >expect && + test_cmp expect current +} + +test_expect_success setup ' + maketree O-000 a/b-2/c/d a/b/c/d a/x && + maketree A-000 a/b-2/c/d a/b/c/d a/x && + maketree A-001 a/b-2/c/d a/b/c/d a/b/c/e a/x && + maketree B-000 a/b-2/c/d a/b a/x && + + maketree O-010 t-0 t/1 t/2 t=3 && + maketree A-010 t-0 t t=3 && + maketree B-010 t/1: t=3: && + + maketree O-020 ds/dma/ioat.c ds/dma/ioat_dca.c && + maketree A-020 ds/dma/ioat/Makefile ds/dma/ioat/registers.h && + : +' + +test_expect_success '3-way (1)' ' + settree A-000 && + git read-tree -m -u O-000 A-000 B-000 && + checkindex <<-EOF + 3 a/b + 0 a/b-2/c/d + 1 a/b/c/d + 2 a/b/c/d + 0 a/x + EOF +' + +test_expect_success '3-way (2)' ' + settree A-001 && + git read-tree -m -u O-000 A-001 B-000 && + checkindex <<-EOF + 3 a/b + 0 a/b-2/c/d + 1 a/b/c/d + 2 a/b/c/d + 2 a/b/c/e + 0 a/x + EOF +' + +test_expect_success '3-way (3)' ' + settree A-010 && + git read-tree -m -u O-010 A-010 B-010 && + checkindex <<-EOF + 2 t + 1 t-0 + 2 t-0 + 1 t/1 + 3 t/1 + 1 t/2 + 0 t=3 + EOF +' + +test_expect_success '2-way (1)' ' + settree O-020 && + git read-tree -m -u O-020 A-020 && + checkindex <<-EOF + 0 ds/dma/ioat/Makefile + 0 ds/dma/ioat/registers.h + EOF +' + +test_done diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 9e74b1f141..f11f98c3ce 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -694,6 +694,34 @@ test_expect_success 'set --bool-or-int' ' rm .git/config +cat >expect <<\EOF +[path] + home = ~/ + normal = /dev/null + trailingtilde = foo~ +EOF + +test_expect_success 'set --path' ' + git config --path path.home "~/" && + git config --path path.normal "/dev/null" && + git config --path path.trailingtilde "foo~" && + test_cmp expect .git/config' + +cat >expect <<EOF +$HOME/ +/dev/null +foo~ +EOF + +test_expect_success 'get --path' ' + git config --get --path path.home > result && + git config --get --path path.normal >> result && + git config --get --path path.trailingtilde >> result && + test_cmp expect result +' + +rm .git/config + git config quote.leading " test" git config quote.ending "test " git config quote.semicolon "test;test" diff --git a/t/t1304-default-acl.sh b/t/t1304-default-acl.sh new file mode 100755 index 0000000000..cc30be4a65 --- /dev/null +++ b/t/t1304-default-acl.sh @@ -0,0 +1,67 @@ +#!/bin/sh +# +# Copyright (c) 2010 Matthieu Moy +# + +test_description='Test repository with default ACL' + +# Create the test repo with restrictive umask +# => this must come before . ./test-lib.sh +umask 077 + +. ./test-lib.sh + +# We need an arbitrary other user give permission to using ACLs. root +# is a good candidate: exists on all unices, and it has permission +# anyway, so we don't create a security hole running the testsuite. + +if ! setfacl -m u:root:rwx .; then + say "Skipping ACL tests: unable to use setfacl" + test_done +fi + +modebits () { + ls -l "$1" | sed -e 's|^\(..........\).*|\1|' +} + +check_perms_and_acl () { + actual=$(modebits "$1") && + case "$actual" in + -r--r-----*) + : happy + ;; + *) + echo "Got permission '$actual', expected '-r--r-----'" + false + ;; + esac && + getfacl "$1" > actual && + grep -q "user:root:rwx" actual && + grep -q "user:${LOGNAME}:rwx" actual && + grep -q "mask::r--" actual && + grep -q "group::---" actual || false +} + +dirs_to_set="./ .git/ .git/objects/ .git/objects/pack/" + +test_expect_success 'Setup test repo' ' + setfacl -m u:root:rwx $dirs_to_set && + setfacl -d -m u:"$LOGNAME":rwx $dirs_to_set && + setfacl -d -m u:root:rwx $dirs_to_set && + + touch file.txt && + git add file.txt && + git commit -m "init" +' + +test_expect_success 'Objects creation does not break ACLs with restrictive umask' ' + # SHA1 for empty blob + check_perms_and_acl .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +' + +test_expect_success 'git gc does not break ACLs with restrictive umask' ' + git gc && + check_perms_and_acl .git/objects/pack/*.pack +' + +test_done diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 80af6b9b7e..25046c4208 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -214,4 +214,45 @@ test_expect_success 'delete' ' ' +test_expect_success 'rewind2' ' + + test_tick && git reset --hard HEAD~2 && + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 4 + +' + +test_expect_success '--expire=never' ' + + git reflog expire --verbose \ + --expire=never \ + --expire-unreachable=never \ + --all && + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 4 + +' + +test_expect_success 'gc.reflogexpire=never' ' + + git config gc.reflogexpire never && + git config gc.reflogexpireunreachable never && + git reflog expire --verbose --all && + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 4 +' + +test_expect_success 'gc.reflogexpire=false' ' + + git config gc.reflogexpire false && + git config gc.reflogexpireunreachable false && + git reflog expire --verbose --all && + loglen=$(wc -l <.git/logs/refs/heads/master) && + test $loglen = 4 && + + git config --unset gc.reflogexpire && + git config --unset gc.reflogexpireunreachable + +' + test_done diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh index c18ed8edf9..ba25ff354d 100755 --- a/t/t1411-reflog-show.sh +++ b/t/t1411-reflog-show.sh @@ -64,4 +64,13 @@ test_expect_success 'using --date= shows reflog date (oneline)' ' test_cmp expect actual ' +: >expect +test_expect_success 'empty reflog file' ' + git branch empty && + : >.git/logs/refs/heads/empty && + + git log -g empty >actual && + test_cmp expect actual +' + test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index a22632f483..49cae3ed52 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -66,12 +66,12 @@ tagger T A Gger <tagger@example.com> 1234567890 -0000 This is an invalid tag. EOF -test_expect_failure 'tag pointing to nonexistent' ' - tag=$(git hash-object -w --stdin < invalid-tag) && +test_expect_success 'tag pointing to nonexistent' ' + tag=$(git hash-object -t tag -w --stdin < invalid-tag) && echo $tag > .git/refs/tags/invalid && - git fsck --tags 2>out && + test_must_fail git fsck --tags >out && cat out && - grep "could not load tagged object" out && + grep "broken link" out && rm .git/refs/tags/invalid ' @@ -84,12 +84,12 @@ tagger T A Gger <tagger@example.com> 1234567890 -0000 This is an invalid tag. EOF -test_expect_failure 'tag pointing to something else than its type' ' - tag=$(git hash-object -w --stdin < wrong-tag) && +test_expect_success 'tag pointing to something else than its type' ' + tag=$(git hash-object -t tag -w --stdin < wrong-tag) && echo $tag > .git/refs/tags/wrong && - git fsck --tags 2>out && + test_must_fail git fsck --tags 2>out && cat out && - grep "some sane error message" out && + grep "error in tag.*broken links" out && rm .git/refs/tags/wrong ' diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh new file mode 100755 index 0000000000..af721f9719 --- /dev/null +++ b/t/t1506-rev-parse-diagnosis.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +test_description='test git rev-parse diagnosis for invalid argument' + +exec </dev/null + +. ./test-lib.sh + +HASH_file= + +test_expect_success 'set up basic repo' ' + echo one > file.txt && + mkdir subdir && + echo two > subdir/file.txt && + echo three > subdir/file2.txt && + git add . && + git commit -m init && + echo four > index-only.txt && + git add index-only.txt && + echo five > disk-only.txt +' + +test_expect_success 'correct file objects' ' + HASH_file=$(git rev-parse HEAD:file.txt) && + git rev-parse HEAD:subdir/file.txt && + git rev-parse :index-only.txt && + (cd subdir && + git rev-parse HEAD:subdir/file2.txt && + test $HASH_file = $(git rev-parse HEAD:file.txt) && + test $HASH_file = $(git rev-parse :file.txt) && + test $HASH_file = $(git rev-parse :0:file.txt) ) +' + +test_expect_success 'incorrect revision id' ' + test_must_fail git rev-parse foobar:file.txt 2>error && + grep "Invalid object name '"'"'foobar'"'"'." error && + test_must_fail git rev-parse foobar 2> error && + grep "unknown revision or path not in the working tree." error +' + +test_expect_success 'incorrect file in sha1:path' ' + test_must_fail git rev-parse HEAD:nothing.txt 2> error && + grep "fatal: Path '"'"'nothing.txt'"'"' does not exist in '"'"'HEAD'"'"'" error && + test_must_fail git rev-parse HEAD:index-only.txt 2> error && + grep "fatal: Path '"'"'index-only.txt'"'"' exists on disk, but not in '"'"'HEAD'"'"'." error && + (cd subdir && + test_must_fail git rev-parse HEAD:file2.txt 2> error && + grep "Did you mean '"'"'HEAD:subdir/file2.txt'"'"'?" error ) +' + +test_expect_success 'incorrect file in :path and :N:path' ' + test_must_fail git rev-parse :nothing.txt 2> error && + grep "fatal: Path '"'"'nothing.txt'"'"' does not exist (neither on disk nor in the index)." error && + test_must_fail git rev-parse :1:nothing.txt 2> error && + grep "Path '"'"'nothing.txt'"'"' does not exist (neither on disk nor in the index)." error && + test_must_fail git rev-parse :1:file.txt 2> error && + grep "Did you mean '"'"':0:file.txt'"'"'?" error && + (cd subdir && + test_must_fail git rev-parse :1:file.txt 2> error && + grep "Did you mean '"'"':0:file.txt'"'"'?" error && + test_must_fail git rev-parse :file2.txt 2> error && + grep "Did you mean '"'"':0:subdir/file2.txt'"'"'?" error && + test_must_fail git rev-parse :2:file2.txt 2> error && + grep "Did you mean '"'"':0:subdir/file2.txt'"'"'?" error) && + test_must_fail git rev-parse :disk-only.txt 2> error && + grep "fatal: Path '"'"'disk-only.txt'"'"' exists on disk, but not in the index." error +' + +test_done diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh new file mode 100755 index 0000000000..8c8dfdaf9f --- /dev/null +++ b/t/t1507-rev-parse-upstream.sh @@ -0,0 +1,139 @@ +#!/bin/sh + +test_description='test <branch>@{upstream} syntax' + +. ./test-lib.sh + + +test_expect_success 'setup' ' + + test_commit 1 && + git checkout -b side && + test_commit 2 && + git checkout master && + git clone . clone && + test_commit 3 && + (cd clone && + test_commit 4 && + git branch --track my-side origin/side) + +' + +full_name () { + (cd clone && + git rev-parse --symbolic-full-name "$@") +} + +commit_subject () { + (cd clone && + git show -s --pretty=format:%s "$@") +} + +test_expect_success '@{upstream} resolves to correct full name' ' + test refs/remotes/origin/master = "$(full_name @{upstream})" +' + +test_expect_success '@{u} resolves to correct full name' ' + test refs/remotes/origin/master = "$(full_name @{u})" +' + +test_expect_success 'my-side@{upstream} resolves to correct full name' ' + test refs/remotes/origin/side = "$(full_name my-side@{u})" +' + +test_expect_success 'my-side@{u} resolves to correct commit' ' + git checkout side && + test_commit 5 && + (cd clone && git fetch) && + test 2 = "$(commit_subject my-side)" && + test 5 = "$(commit_subject my-side@{u})" +' + +test_expect_success 'not-tracking@{u} fails' ' + test_must_fail full_name non-tracking@{u} && + (cd clone && git checkout --no-track -b non-tracking) && + test_must_fail full_name non-tracking@{u} +' + +test_expect_success '<branch>@{u}@{1} resolves correctly' ' + test_commit 6 && + (cd clone && git fetch) && + test 5 = $(commit_subject my-side@{u}@{1}) +' + +test_expect_success '@{u} without specifying branch fails on a detached HEAD' ' + git checkout HEAD^0 && + test_must_fail git rev-parse @{u} +' + +test_expect_success 'checkout -b new my-side@{u} forks from the same' ' +( + cd clone && + git checkout -b new my-side@{u} && + git rev-parse --symbolic-full-name my-side@{u} >expect && + git rev-parse --symbolic-full-name new@{u} >actual && + test_cmp expect actual +) +' + +test_expect_success 'merge my-side@{u} records the correct name' ' +( + sq="'\''" && + cd clone || exit + git checkout master || exit + git branch -D new ;# can fail but is ok + git branch -t new my-side@{u} && + git merge -s ours new@{u} && + git show -s --pretty=format:%s >actual && + echo "Merge remote branch ${sq}origin/side${sq}" >expect && + test_cmp expect actual +) +' + +test_expect_success 'branch -d other@{u}' ' + git checkout -t -b other master && + git branch -d @{u} && + git for-each-ref refs/heads/master >actual && + >expect && + test_cmp expect actual +' + +test_expect_success 'checkout other@{u}' ' + git branch -f master HEAD && + git checkout -t -b another master && + git checkout @{u} && + git symbolic-ref HEAD >actual && + echo refs/heads/master >expect && + test_cmp expect actual +' + +cat >expect <<EOF +commit 8f489d01d0cc65c3b0f09504ec50b5ed02a70bd5 +Reflog: master@{0} (C O Mitter <committer@example.com>) +Reflog message: branch: Created from HEAD +Author: A U Thor <author@example.com> +Date: Thu Apr 7 15:15:13 2005 -0700 + + 3 +EOF +test_expect_success 'log -g other@{u}' ' + git log -1 -g other@{u} >actual && + test_cmp expect actual +' + +cat >expect <<EOF +commit 8f489d01d0cc65c3b0f09504ec50b5ed02a70bd5 +Reflog: master@{Thu Apr 7 15:17:13 2005 -0700} (C O Mitter <committer@example.com>) +Reflog message: branch: Created from HEAD +Author: A U Thor <author@example.com> +Date: Thu Apr 7 15:15:13 2005 -0700 + + 3 +EOF + +test_expect_success 'log -g other@{u}@{now}' ' + git log -1 -g other@{u}@{now} >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t1508-at-combinations.sh b/t/t1508-at-combinations.sh new file mode 100755 index 0000000000..d5d6244178 --- /dev/null +++ b/t/t1508-at-combinations.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +test_description='test various @{X} syntax combinations together' +. ./test-lib.sh + +check() { +test_expect_${3:-success} "$1 = $2" " + echo '$2' >expect && + git log -1 --format=%s '$1' >actual && + test_cmp expect actual +" +} +nonsense() { +test_expect_${2:-success} "$1 is nonsensical" " + test_must_fail git log -1 '$1' +" +} +fail() { + "$@" failure +} + +test_expect_success 'setup' ' + test_commit master-one && + test_commit master-two && + git checkout -b upstream-branch && + test_commit upstream-one && + test_commit upstream-two && + git checkout -b old-branch && + test_commit old-one && + test_commit old-two && + git checkout -b new-branch && + test_commit new-one && + test_commit new-two && + git config branch.old-branch.remote . && + git config branch.old-branch.merge refs/heads/master && + git config branch.new-branch.remote . && + git config branch.new-branch.merge refs/heads/upstream-branch +' + +check HEAD new-two +check "@{1}" new-one +check "@{-1}" old-two +check "@{-1}@{1}" old-one +check "@{u}" upstream-two +check "@{u}@{1}" upstream-one +check "@{-1}@{u}" master-two +check "@{-1}@{u}@{1}" master-one +nonsense "@{u}@{-1}" +nonsense "@{1}@{u}" + +test_done diff --git a/t/t2012-checkout-last.sh b/t/t2012-checkout-last.sh index 87b30a268c..b44de9dc62 100755 --- a/t/t2012-checkout-last.sh +++ b/t/t2012-checkout-last.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='checkout can switch to last branch' +test_description='checkout can switch to last branch and merge base' . ./test-lib.sh @@ -91,4 +91,29 @@ test_expect_success 'switch to twelfth from the last' ' test "z$(git symbolic-ref HEAD)" = "zrefs/heads/branch13" ' +test_expect_success 'merge base test setup' ' + git checkout -b another other && + echo "hello again" >>world && + git add world && + git commit -m third +' + +test_expect_success 'another...master' ' + git checkout another && + git checkout another...master && + test "z$(git rev-parse --verify HEAD)" = "z$(git rev-parse --verify master^)" +' + +test_expect_success '...master' ' + git checkout another && + git checkout ...master && + test "z$(git rev-parse --verify HEAD)" = "z$(git rev-parse --verify master^)" +' + +test_expect_success 'master...' ' + git checkout another && + git checkout master... && + test "z$(git rev-parse --verify HEAD)" = "z$(git rev-parse --verify master^)" +' + test_done diff --git a/t/t2016-checkout-patch.sh b/t/t2016-checkout-patch.sh index 4d1c2e9e09..2144184d79 100755 --- a/t/t2016-checkout-patch.sh +++ b/t/t2016-checkout-patch.sh @@ -66,6 +66,14 @@ test_expect_success 'git checkout -p HEAD^' ' verify_state dir/foo parent parent ' +test_expect_success 'git checkout -p handles deletion' ' + set_state dir/foo work index && + rm dir/foo && + (echo n; echo y) | git checkout -p && + verify_saved_state bar && + verify_state dir/foo index index +' + # The idea in the rest is that bar sorts first, so we always say 'y' # first and if the path limiter fails it'll apply to bar instead of # dir/foo. There's always an extra 'n' to reject edits to dir/foo in diff --git a/t/t2030-unresolve-info.sh b/t/t2030-unresolve-info.sh new file mode 100755 index 0000000000..cb7effe0a3 --- /dev/null +++ b/t/t2030-unresolve-info.sh @@ -0,0 +1,170 @@ +#!/bin/sh + +test_description='undoing resolution' + +. ./test-lib.sh + +check_resolve_undo () { + msg=$1 + shift + while case $# in + 0) break ;; + 1|2|3) die "Bug in check-resolve-undo test" ;; + esac + do + path=$1 + shift + for stage in 1 2 3 + do + sha1=$1 + shift + case "$sha1" in + '') continue ;; + esac + sha1=$(git rev-parse --verify "$sha1") + printf "100644 %s %s\t%s\n" $sha1 $stage $path + done + done >"$msg.expect" && + git ls-files --resolve-undo >"$msg.actual" && + test_cmp "$msg.expect" "$msg.actual" +} + +prime_resolve_undo () { + git reset --hard && + git checkout second^0 && + test_tick && + test_must_fail git merge third^0 && + echo merge does not leave anything && + check_resolve_undo empty && + echo different >fi/le && + git add fi/le && + echo resolving records && + check_resolve_undo recorded fi/le initial:fi/le second:fi/le third:fi/le +} + +test_expect_success setup ' + mkdir fi && + test_commit initial fi/le first && + git branch side && + git branch another && + test_commit second fi/le second && + git checkout side && + test_commit third fi/le third && + git checkout another && + test_commit fourth fi/le fourth && + git checkout master +' + +test_expect_success 'add records switch clears' ' + prime_resolve_undo && + test_tick && + git commit -m merged && + echo committing keeps && + check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && + git checkout second^0 && + echo switching clears && + check_resolve_undo cleared +' + +test_expect_success 'rm records reset clears' ' + prime_resolve_undo && + test_tick && + git commit -m merged && + echo committing keeps && + check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && + + echo merge clears upfront && + test_must_fail git merge fourth^0 && + check_resolve_undo nuked && + + git rm -f fi/le && + echo resolving records && + check_resolve_undo recorded fi/le initial:fi/le HEAD:fi/le fourth:fi/le && + + git reset --hard && + echo resetting discards && + check_resolve_undo discarded +' + +test_expect_success 'plumbing clears' ' + prime_resolve_undo && + test_tick && + git commit -m merged && + echo committing keeps && + check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && + + echo plumbing clear && + git update-index --clear-resolve-undo && + check_resolve_undo cleared +' + +test_expect_success 'add records checkout -m undoes' ' + prime_resolve_undo && + git diff HEAD && + git checkout --conflict=merge fi/le && + echo checkout used the record and removed it && + check_resolve_undo removed && + echo the index and the work tree is unmerged again && + git diff >actual && + grep "^++<<<<<<<" actual +' + +test_expect_success 'unmerge with plumbing' ' + prime_resolve_undo && + git update-index --unresolve fi/le && + git ls-files -u >actual && + test $(wc -l <actual) = 3 +' + +test_expect_success 'rerere and rerere forget' ' + mkdir .git/rr-cache && + prime_resolve_undo && + echo record the resolution && + git rerere && + rerere_id=$(cd .git/rr-cache && echo */postimage) && + rerere_id=${rerere_id%/postimage} && + test -f .git/rr-cache/$rerere_id/postimage && + git checkout -m fi/le && + echo resurrect the conflict && + grep "^=======" fi/le && + echo reresolve the conflict && + git rerere && + test "z$(cat fi/le)" = zdifferent && + echo register the resolution again && + git add fi/le && + check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && + test -z "$(git ls-files -u)" && + git rerere forget fi/le && + ! test -f .git/rr-cache/$rerere_id/postimage && + tr "\0" "\n" <.git/MERGE_RR >actual && + echo "$rerere_id fi/le" >expect && + test_cmp expect actual +' + +test_expect_success 'rerere and rerere forget (subdirectory)' ' + rm -fr .git/rr-cache && + mkdir .git/rr-cache && + prime_resolve_undo && + echo record the resolution && + (cd fi && git rerere) && + rerere_id=$(cd .git/rr-cache && echo */postimage) && + rerere_id=${rerere_id%/postimage} && + test -f .git/rr-cache/$rerere_id/postimage && + (cd fi && git checkout -m le) && + echo resurrect the conflict && + grep "^=======" fi/le && + echo reresolve the conflict && + (cd fi && git rerere) && + test "z$(cat fi/le)" = zdifferent && + echo register the resolution again && + (cd fi && git add le) && + check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && + test -z "$(git ls-files -u)" && + (cd fi && git rerere forget le) && + ! test -f .git/rr-cache/$rerere_id/postimage && + tr "\0" "\n" <.git/MERGE_RR >actual && + echo "$rerere_id fi/le" >expect && + test_cmp expect actual +' + +test_done diff --git a/t/t2104-update-index-skip-worktree.sh b/t/t2104-update-index-skip-worktree.sh new file mode 100755 index 0000000000..1d0879be06 --- /dev/null +++ b/t/t2104-update-index-skip-worktree.sh @@ -0,0 +1,57 @@ +#!/bin/sh +# +# Copyright (c) 2008 Nguyễn Thái Ngọc Duy +# + +test_description='skip-worktree bit test' + +. ./test-lib.sh + +cat >expect.full <<EOF +H 1 +H 2 +H sub/1 +H sub/2 +EOF + +cat >expect.skip <<EOF +S 1 +H 2 +S sub/1 +H sub/2 +EOF + +test_expect_success 'setup' ' + mkdir sub && + touch ./1 ./2 sub/1 sub/2 && + git add 1 2 sub/1 sub/2 && + git ls-files -t | test_cmp expect.full - +' + +test_expect_success 'index is at version 2' ' + test "$(test-index-version < .git/index)" = 2 +' + +test_expect_success 'update-index --skip-worktree' ' + git update-index --skip-worktree 1 sub/1 && + git ls-files -t | test_cmp expect.skip - +' + +test_expect_success 'index is at version 3 after having some skip-worktree entries' ' + test "$(test-index-version < .git/index)" = 3 +' + +test_expect_success 'ls-files -t' ' + git ls-files -t | test_cmp expect.skip - +' + +test_expect_success 'update-index --no-skip-worktree' ' + git update-index --no-skip-worktree 1 sub/1 && + git ls-files -t | test_cmp expect.full - +' + +test_expect_success 'index version is back to 2 when there is no skip-worktree entry' ' + test "$(test-index-version < .git/index)" = 2 +' + +test_done diff --git a/t/t2105-update-index-gitfile.sh b/t/t2105-update-index-gitfile.sh new file mode 100755 index 0000000000..641607d89a --- /dev/null +++ b/t/t2105-update-index-gitfile.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Copyright (c) 2010 Brad King +# + +test_description='git update-index for gitlink to .git file. +' + +. ./test-lib.sh + +test_expect_success 'submodule with absolute .git file' ' + mkdir sub1 && + (cd sub1 && + git init && + REAL="$(pwd)/.real" && + mv .git "$REAL" + echo "gitdir: $REAL" >.git && + test_commit first) +' + +test_expect_success 'add gitlink to absolute .git file' ' + git update-index --add -- sub1 +' + +test_expect_success 'submodule with relative .git file' ' + mkdir sub2 && + (cd sub2 && + git init && + mv .git .real && + echo "gitdir: .real" >.git && + test_commit first) +' + +test_expect_success 'add gitlink to relative .git file' ' + git update-index --add -- sub2 +' + +test_done diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index 912075063b..2ad2819a34 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -176,4 +176,9 @@ test_expect_success 'add -u resolves unmerged paths' ' ' +test_expect_success '"add -u non-existent" should fail' ' + test_must_fail git add -u non-existent && + ! (git ls-files | grep "non-existent") +' + test_done diff --git a/t/t2204-add-ignored.sh b/t/t2204-add-ignored.sh new file mode 100755 index 0000000000..24afdabab7 --- /dev/null +++ b/t/t2204-add-ignored.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +test_description='giving ignored paths to git add' + +. ./test-lib.sh + +test_expect_success setup ' + mkdir sub dir dir/sub && + echo sub >.gitignore && + echo ign >>.gitignore && + for p in . sub dir dir/sub + do + >"$p/ign" && + >"$p/file" || exit 1 + done +' + +for i in file dir/file dir 'd*' +do + test_expect_success "no complaints for unignored $i" ' + rm -f .git/index && + git add "$i" && + git ls-files "$i" >out && + test -s out + ' +done + +for i in ign dir/ign dir/sub dir/sub/*ign sub/file sub sub/* +do + test_expect_success "complaints for ignored $i" ' + rm -f .git/index && + test_must_fail git add "$i" 2>err && + git ls-files "$i" >out && + ! test -s out && + grep -e "Use -f if" err && + cat err + ' + + test_expect_success "complaints for ignored $i with unignored file" ' + rm -f .git/index && + test_must_fail git add "$i" file 2>err && + git ls-files "$i" >out && + ! test -s out && + grep -e "Use -f if" err && + cat err + ' +done + +for i in sub sub/* +do + test_expect_success "complaints for ignored $i in dir" ' + rm -f .git/index && + ( + cd dir && + test_must_fail git add "$i" 2>err && + git ls-files "$i" >out && + ! test -s out && + grep -e "Use -f if" err && + cat err + ) + ' +done + +for i in ign file +do + test_expect_success "complaints for ignored $i in sub" ' + rm -f .git/index && + ( + cd sub && + test_must_fail git add "$i" 2>err && + git ls-files "$i" >out && + ! test -s out && + grep -e "Use -f if" err && + cat err + ) + ' +done + +test_done diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index c65bca8388..6d2f2b67ee 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -64,6 +64,8 @@ two/*.4 echo '!*.2 !*.8' >one/two/.gitignore +allignores='.gitignore one/.gitignore one/two/.gitignore' + test_expect_success \ 'git ls-files --others with various exclude options.' \ 'git ls-files --others \ @@ -85,6 +87,26 @@ test_expect_success \ >output && test_cmp expect output' +test_expect_success 'setup skip-worktree gitignore' ' + git add $allignores && + git update-index --skip-worktree $allignores && + rm $allignores +' + +test_expect_success \ + 'git ls-files --others with various exclude options.' \ + 'git ls-files --others \ + --exclude=\*.6 \ + --exclude-per-directory=.gitignore \ + --exclude-from=.git/ignore \ + >output && + test_cmp expect output' + +test_expect_success 'restore gitignore' ' + git checkout $allignores && + rm .git/index +' + cat > excludes-file <<\EOF *.[1-8] e* @@ -153,4 +175,43 @@ test_expect_success 'negated exclude matches can override previous ones' ' grep "^a.1" output ' +test_expect_success 'subdirectory ignore (setup)' ' + mkdir -p top/l1/l2 && + ( + cd top && + git init && + echo /.gitignore >.gitignore && + echo l1 >>.gitignore && + echo l2 >l1/.gitignore && + >l1/l2/l1 + ) +' + +test_expect_success 'subdirectory ignore (toplevel)' ' + ( + cd top && + git ls-files -o --exclude-standard + ) >actual && + >expect && + test_cmp expect actual +' + +test_expect_success 'subdirectory ignore (l1/l2)' ' + ( + cd top/l1/l2 && + git ls-files -o --exclude-standard + ) >actual && + >expect && + test_cmp expect actual +' + +test_expect_success 'subdirectory ignore (l1)' ' + ( + cd top/l1 && + git ls-files -o --exclude-standard + ) >actual && + >expect && + test_cmp expect actual +' + test_done diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index 9b3fa2bdcd..9929f82021 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -276,11 +276,13 @@ test_expect_success 'fail if the index has unresolved entries' ' test_must_fail git merge "$c5" && test_must_fail git merge "$c5" 2> out && + grep "not possible because you have unmerged files" out && + git add -u && + test_must_fail git merge "$c5" 2> out && grep "You have not concluded your merge" out && rm -f .git/MERGE_HEAD && test_must_fail git merge "$c5" 2> out && - grep "You are in the middle of a conflicted merge" out - + grep "Your local changes to .* would be overwritten by merge." out ' test_expect_success 'merge-recursive remove conflict' ' diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh index ee60d03fe8..eee0d344d2 100755 --- a/t/t3100-ls-tree-restrict.sh +++ b/t/t3100-ls-tree-restrict.sh @@ -43,8 +43,6 @@ test_expect_success \ tree=`git write-tree` && echo $tree' -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" test_output () { sed -e "s/ $_x40 / X /" <current >check test_cmp expected check diff --git a/t/t3101-ls-tree-dirname.sh b/t/t3101-ls-tree-dirname.sh index 8be9fb4112..06654c6f82 100755 --- a/t/t3101-ls-tree-dirname.sh +++ b/t/t3101-ls-tree-dirname.sh @@ -39,8 +39,6 @@ test_expect_success \ tree=`git write-tree` && echo $tree' -_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05" test_output () { sed -e "s/ $_x40 / X /" <current >check test_cmp expected check diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index d59a9b4aef..e0b760513c 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -468,4 +468,30 @@ test_expect_success 'detect misconfigured autosetuprebase (no value)' ' git config --unset branch.autosetuprebase ' +test_expect_success 'attempt to delete a branch without base and unmerged to HEAD' ' + git checkout my9 && + git config --unset branch.my8.merge && + test_must_fail git branch -d my8 +' + +test_expect_success 'attempt to delete a branch merged to its base' ' + # we are on my9 which is the initial commit; traditionally + # we would not have allowed deleting my8 that is not merged + # to my9, but it is set to track master that already has my8 + git config branch.my8.merge refs/heads/master && + git branch -d my8 +' + +test_expect_success 'attempt to delete a branch merged to its base' ' + git checkout master && + echo Third >>A && + git commit -m "Third commit" A && + git branch -t my10 my9 && + git branch -f my10 HEAD^ && + # we are on master which is at the third commit, and my10 + # is behind us, so traditionally we would have allowed deleting + # it; but my10 is set to track my9 that is further behind. + test_must_fail git branch -d my10 +' + test_done diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 4e6a44b623..4314ad2d66 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -134,10 +134,6 @@ test_expect_success 'rebase -q is quiet' ' test ! -s output.out ' -q_to_cr () { - tr Q '\015' -} - test_expect_success 'Rebase a commit that sprinkles CRs in' ' ( echo "One" diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 3a37793c0d..4e3513709e 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -14,58 +14,47 @@ that the result still makes sense. set_fake_editor -# set up two branches like this: +# Set up the repository like this: # -# A - B - C - D - E +# one - two - three - four (conflict-branch) +# / +# A - B - C - D - E (master) +# | \ +# | F - G - H (branch1) +# | \ +# \ I (branch2) # \ -# F - G - H -# \ -# I +# J - K - L - M (no-conflict-branch) # -# where B, D and G touch the same file. +# where A, B, D and G all touch file1, and one, two, three, four all +# touch file "conflict". test_expect_success 'setup' ' - : > file1 && - git add file1 && - test_tick && - git commit -m A && - git tag A && - echo 1 > file1 && - test_tick && - git commit -m B file1 && - : > file2 && - git add file2 && - test_tick && - git commit -m C && - echo 2 > file1 && - test_tick && - git commit -m D file1 && - : > file3 && - git add file3 && - test_tick && - git commit -m E && + test_commit A file1 && + test_commit B file1 && + test_commit C file2 && + test_commit D file1 && + test_commit E file3 && git checkout -b branch1 A && - : > file4 && - git add file4 && - test_tick && - git commit -m F && - git tag F && - echo 3 > file1 && - test_tick && - git commit -m G file1 && - : > file5 && - git add file5 && - test_tick && - git commit -m H && + test_commit F file4 && + test_commit G file1 && + test_commit H file5 && git checkout -b branch2 F && - : > file6 && - git add file6 && - test_tick && - git commit -m I && - git tag I + test_commit I file6 + git checkout -b conflict-branch A && + for n in one two three four + do + test_commit $n conflict + done && + git checkout -b no-conflict-branch A && + for n in J K L M + do + test_commit $n file$n + done ' test_expect_success 'no changes are a nop' ' + git checkout branch2 && git rebase -i F && test "$(git symbolic-ref -q HEAD)" = "refs/heads/branch2" && test $(git rev-parse I) = $(git rev-parse HEAD) @@ -111,19 +100,20 @@ test_expect_success 'exchange two commits' ' cat > expect << EOF diff --git a/file1 b/file1 -index e69de29..00750ed 100644 +index f70f10e..fd79235 100644 --- a/file1 +++ b/file1 -@@ -0,0 +1 @@ -+3 +@@ -1 +1 @@ +-A ++G EOF cat > expect2 << EOF <<<<<<< HEAD -2 +D ======= -3 ->>>>>>> b7ca976... G +G +>>>>>>> 51047de... G EOF test_expect_success 'stop on conflicting pick' ' @@ -161,7 +151,8 @@ test_expect_success 'squash' ' test_tick && GIT_AUTHOR_NAME="Nitfol" git commit -m "nitfol" file7 && echo "******************************" && - FAKE_LINES="1 squash 2" git rebase -i --onto master HEAD~2 && + FAKE_LINES="1 squash 2" EXPECT_HEADER_COUNT=2 \ + git rebase -i --onto master HEAD~2 && test B = $(cat file7) && test $(git rev-parse HEAD^) = $(git rev-parse master) ' @@ -256,30 +247,113 @@ test_expect_success 'verbose flag is heeded, even after --continue' ' test_expect_success 'multi-squash only fires up editor once' ' base=$(git rev-parse HEAD~4) && FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 squash 2 squash 3 squash 4" \ + EXPECT_HEADER_COUNT=4 \ git rebase -i $base && test $base = $(git rev-parse HEAD^) && test 1 = $(git show | grep ONCE | wc -l) ' +test_expect_success 'multi-fixup does not fire up editor' ' + git checkout -b multi-fixup E && + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="NEVER" FAKE_LINES="1 fixup 2 fixup 3 fixup 4" \ + git rebase -i $base && + test $base = $(git rev-parse HEAD^) && + test 0 = $(git show | grep NEVER | wc -l) && + git checkout to-be-rebased && + git branch -D multi-fixup +' + +test_expect_success 'commit message used after conflict' ' + git checkout -b conflict-fixup conflict-branch && + base=$(git rev-parse HEAD~4) && + ( + FAKE_LINES="1 fixup 3 fixup 4" && + export FAKE_LINES && + test_must_fail git rebase -i $base + ) && + echo three > conflict && + git add conflict && + FAKE_COMMIT_AMEND="ONCE" EXPECT_HEADER_COUNT=2 \ + git rebase --continue && + test $base = $(git rev-parse HEAD^) && + test 1 = $(git show | grep ONCE | wc -l) && + git checkout to-be-rebased && + git branch -D conflict-fixup +' + +test_expect_success 'commit message retained after conflict' ' + git checkout -b conflict-squash conflict-branch && + base=$(git rev-parse HEAD~4) && + ( + FAKE_LINES="1 fixup 3 squash 4" && + export FAKE_LINES && + test_must_fail git rebase -i $base + ) && + echo three > conflict && + git add conflict && + FAKE_COMMIT_AMEND="TWICE" EXPECT_HEADER_COUNT=2 \ + git rebase --continue && + test $base = $(git rev-parse HEAD^) && + test 2 = $(git show | grep TWICE | wc -l) && + git checkout to-be-rebased && + git branch -D conflict-squash +' + +cat > expect-squash-fixup << EOF +B + +D + +ONCE +EOF + +test_expect_success 'squash and fixup generate correct log messages' ' + git checkout -b squash-fixup E && + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="1 fixup 2 squash 3 fixup 4" \ + EXPECT_HEADER_COUNT=4 \ + git rebase -i $base && + git cat-file commit HEAD | sed -e 1,/^\$/d > actual-squash-fixup && + test_cmp expect-squash-fixup actual-squash-fixup && + git checkout to-be-rebased && + git branch -D squash-fixup +' + +test_expect_success 'squash ignores comments' ' + git checkout -b skip-comments E && + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="# 1 # squash 2 # squash 3 # squash 4 #" \ + EXPECT_HEADER_COUNT=4 \ + git rebase -i $base && + test $base = $(git rev-parse HEAD^) && + test 1 = $(git show | grep ONCE | wc -l) && + git checkout to-be-rebased && + git branch -D skip-comments +' + +test_expect_success 'squash ignores blank lines' ' + git checkout -b skip-blank-lines E && + base=$(git rev-parse HEAD~4) && + FAKE_COMMIT_AMEND="ONCE" FAKE_LINES="> 1 > squash 2 > squash 3 > squash 4 >" \ + EXPECT_HEADER_COUNT=4 \ + git rebase -i $base && + test $base = $(git rev-parse HEAD^) && + test 1 = $(git show | grep ONCE | wc -l) && + git checkout to-be-rebased && + git branch -D skip-blank-lines +' + test_expect_success 'squash works as expected' ' - for n in one two three four - do - echo $n >> file$n && - git add file$n && - git commit -m $n - done && + git checkout -b squash-works no-conflict-branch && one=$(git rev-parse HEAD~3) && - FAKE_LINES="1 squash 3 2" git rebase -i HEAD~3 && + FAKE_LINES="1 squash 3 2" EXPECT_HEADER_COUNT=2 \ + git rebase -i HEAD~3 && test $one = $(git rev-parse HEAD~2) ' test_expect_success 'interrupted squash works as expected' ' - for n in one two three four - do - echo $n >> conflict && - git add conflict && - git commit -m $n - done && + git checkout -b interrupted-squash conflict-branch && one=$(git rev-parse HEAD~3) && ( FAKE_LINES="1 squash 3 2" && @@ -296,12 +370,7 @@ test_expect_success 'interrupted squash works as expected' ' ' test_expect_success 'interrupted squash works as expected (case 2)' ' - for n in one two three four - do - echo $n >> conflict && - git add conflict && - git commit -m $n - done && + git checkout -b interrupted-squash2 conflict-branch && one=$(git rev-parse HEAD~3) && ( FAKE_LINES="3 squash 1 2" && diff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh index e12cd578e8..2062b858bb 100755 --- a/t/t3408-rebase-multi-line.sh +++ b/t/t3408-rebase-multi-line.sh @@ -32,8 +32,8 @@ test_expect_success rebase ' git checkout side && git rebase master && - git cat-file commit HEAD | sed -e "1,/^$/d" >actual && - git cat-file commit side@{1} | sed -e "1,/^$/d" >expect && + git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && + git cat-file commit side@{1} | sed -e "1,/^\$/d" >expect && test_cmp expect actual ' diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh new file mode 100755 index 0000000000..b63f4e2d67 --- /dev/null +++ b/t/t3415-rebase-autosquash.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +test_description='auto squash' + +. ./test-lib.sh + +test_expect_success setup ' + echo 0 >file0 && + git add . && + test_tick && + git commit -m "initial commit" && + echo 0 >file1 && + echo 2 >file2 && + git add . && + test_tick && + git commit -m "first commit" && + echo 3 >file3 && + git add . && + test_tick && + git commit -m "second commit" && + git tag base +' + +test_expect_success 'auto fixup' ' + git reset --hard base && + echo 1 >file1 && + git add -u && + test_tick && + git commit -m "fixup! first" + + git tag final-fixup && + test_tick && + git rebase --autosquash -i HEAD^^^ && + git log --oneline >actual && + test 3 = $(wc -l <actual) && + git diff --exit-code final-fixup && + test 1 = "$(git cat-file blob HEAD^:file1)" && + test 1 = $(git cat-file commit HEAD^ | grep first | wc -l) +' + +test_expect_success 'auto squash' ' + git reset --hard base && + echo 1 >file1 && + git add -u && + test_tick && + git commit -m "squash! first" + + git tag final-squash && + test_tick && + git rebase --autosquash -i HEAD^^^ && + git log --oneline >actual && + test 3 = $(wc -l <actual) && + git diff --exit-code final-squash && + test 1 = "$(git cat-file blob HEAD^:file1)" && + test 2 = $(git cat-file commit HEAD^ | grep first | wc -l) +' + +test_expect_success 'misspelled auto squash' ' + git reset --hard base && + echo 1 >file1 && + git add -u && + test_tick && + git commit -m "squash! forst" + git tag final-missquash && + test_tick && + git rebase --autosquash -i HEAD^^^ && + git log --oneline >actual && + test 4 = $(wc -l <actual) && + git diff --exit-code final-missquash && + test 0 = $(git rev-list final-missquash...HEAD | wc -l) +' + +test_done diff --git a/t/t3416-rebase-onto-threedots.sh b/t/t3416-rebase-onto-threedots.sh new file mode 100755 index 0000000000..ddf2f64853 --- /dev/null +++ b/t/t3416-rebase-onto-threedots.sh @@ -0,0 +1,105 @@ +#!/bin/sh + +test_description='git rebase --onto A...B' + +. ./test-lib.sh +. "$TEST_DIRECTORY/lib-rebase.sh" + +# Rebase only the tip commit of "topic" on merge base between "master" +# and "topic". Cannot do this for "side" with "master" because there +# is no single merge base. +# +# +# F---G topic G' +# / / +# A---B---C---D---E master --> A---B---C---D---E +# \ \ / +# \ x +# \ / \ +# H---I---J---K side + +test_expect_success setup ' + test_commit A && + test_commit B && + git branch side && + test_commit C && + git branch topic && + git checkout side && + test_commit H && + git checkout master && + test_tick && + git merge H && + git tag D && + test_commit E && + git checkout topic && + test_commit F && + test_commit G && + git checkout side && + test_tick && + git merge C && + git tag I && + test_commit J && + test_commit K +' + +test_expect_success 'rebase --onto master...topic' ' + git reset --hard && + git checkout topic && + git reset --hard G && + + git rebase --onto master...topic F && + git rev-parse HEAD^1 >actual && + git rev-parse C^0 >expect && + test_cmp expect actual +' + +test_expect_success 'rebase --onto master...' ' + git reset --hard && + git checkout topic && + git reset --hard G && + + git rebase --onto master... F && + git rev-parse HEAD^1 >actual && + git rev-parse C^0 >expect && + test_cmp expect actual +' + +test_expect_success 'rebase --onto master...side' ' + git reset --hard && + git checkout side && + git reset --hard K && + + test_must_fail git rebase --onto master...side J +' + +test_expect_success 'rebase -i --onto master...topic' ' + git reset --hard && + git checkout topic && + git reset --hard G && + set_fake_editor && + EXPECT_COUNT=1 git rebase -i --onto master...topic F && + git rev-parse HEAD^1 >actual && + git rev-parse C^0 >expect && + test_cmp expect actual +' + +test_expect_success 'rebase -i --onto master...' ' + git reset --hard && + git checkout topic && + git reset --hard G && + set_fake_editor && + EXPECT_COUNT=1 git rebase -i --onto master... F && + git rev-parse HEAD^1 >actual && + git rev-parse C^0 >expect && + test_cmp expect actual +' + +test_expect_success 'rebase -i --onto master...side' ' + git reset --hard && + git checkout side && + git reset --hard K && + + test_must_fail git rebase -i --onto master...side J +' + +test_done diff --git a/t/t3417-rebase-whitespace-fix.sh b/t/t3417-rebase-whitespace-fix.sh new file mode 100755 index 0000000000..220a740ee8 --- /dev/null +++ b/t/t3417-rebase-whitespace-fix.sh @@ -0,0 +1,126 @@ +#!/bin/sh + +test_description='git rebase --whitespace=fix + +This test runs git rebase --whitespace=fix and make sure that it works. +' + +. ./test-lib.sh + +# prepare initial revision of "file" with a blank line at the end +cat >file <<EOF +a +b +c + +EOF + +# expected contents in "file" after rebase +cat >expect-first <<EOF +a +b +c +EOF + +# prepare second revision of "file" +cat >second <<EOF +a +b +c + +d +e +f + + + + +EOF + +# expected contents in second revision after rebase +cat >expect-second <<EOF +a +b +c + +d +e +f +EOF + +test_expect_success 'blank line at end of file; extend at end of file' ' + git commit --allow-empty -m "Initial empty commit" && + git add file && git commit -m first && + mv second file && + git add file && git commit -m second && + git rebase --whitespace=fix HEAD^^ && + git diff --exit-code HEAD^:file expect-first && + test_cmp file expect-second +' + +# prepare third revision of "file" +sed -e's/Z//' >third <<EOF +a +b +c + +d +e +f + Z + Z +h +i +j +k +l +EOF + +sed -e's/ //g' <third >expect-third + +test_expect_success 'two blanks line at end of file; extend at end of file' ' + cp third file && git add file && git commit -m third && + git rebase --whitespace=fix HEAD^^ && + git diff --exit-code HEAD^:file expect-second && + test_cmp file expect-third +' + +test_expect_success 'same, but do not remove trailing spaces' ' + git config core.whitespace "-blank-at-eol" && + git reset --hard HEAD^ && + cp third file && git add file && git commit -m third && + git rebase --whitespace=fix HEAD^^ + git diff --exit-code HEAD^:file expect-second && + test_cmp file third +' + +sed -e's/Z//' >beginning <<EOF +a + Z + Z +EOF + +cat >expect-beginning <<EOF +a + + +1 +2 +3 +4 +5 +EOF + +test_expect_success 'at beginning of file' ' + git config core.whitespace "blank-at-eol" && + cp beginning file && + git commit -m beginning file && + for i in 1 2 3 4 5; do + echo $i + done >> file && + git commit -m more file && + git rebase --whitespace=fix HEAD^^ && + test_cmp file expect-beginning +' + +test_done diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index bb4cf00d78..7f858151d4 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -66,7 +66,7 @@ test_expect_success 'revert forbidden on dirty working tree' ' echo content >extra_file && git add extra_file && test_must_fail git revert HEAD 2>errors && - grep "Dirty index" errors + grep "Your local changes would be overwritten by " errors ' diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 85eb0fbf96..525c9a8fdf 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -255,4 +255,9 @@ test_expect_success 'git add to resolve conflicts on otherwise ignored path' ' git add track-this ' +test_expect_success '"add non-existent" should fail' ' + test_must_fail git add non-existent && + ! (git ls-files | grep "non-existent") +' + test_done diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh index 5868052425..29103f65dc 100755 --- a/t/t3902-quoted.sh +++ b/t/t3902-quoted.sh @@ -25,7 +25,7 @@ for_each_name () { for name in \ Name "Name and a${LF}LF" "Name and an${HT}HT" "Name${DQ}" \ "$FN$HT$GN" "$FN$LF$GN" "$FN $GN" "$FN$GN" "$FN$DQ$GN" \ - "With SP in it" + "With SP in it" "$FN/file" do eval "$1" done @@ -33,6 +33,7 @@ for_each_name () { test_expect_success setup ' + mkdir "$FN" && for_each_name "echo initial >\"\$name\"" git add . && git commit -q -m Initial && @@ -54,6 +55,7 @@ With SP in it "\346\277\261\351\207\216\n\347\264\224" "\346\277\261\351\207\216 \347\264\224" "\346\277\261\351\207\216\"\347\264\224" +"\346\277\261\351\207\216/file" "\346\277\261\351\207\216\347\264\224" EOF @@ -67,6 +69,7 @@ With SP in it "濱野\n純" 濱野 純 "濱野\"純" +濱野/file 濱野純 EOF @@ -97,6 +100,13 @@ test_expect_success 'check fully quoted output from diff-tree' ' ' +test_expect_success 'check fully quoted output from ls-tree' ' + + git ls-tree --name-only -r HEAD >current && + test_cmp expect.quoted current + +' + test_expect_success 'setting core.quotepath' ' git config --bool core.quotepath false @@ -130,4 +140,11 @@ test_expect_success 'check fully quoted output from diff-tree' ' ' +test_expect_success 'check fully quoted output from ls-tree' ' + + git ls-tree --name-only -r HEAD >current && + test_cmp expect.raw current + +' + test_done diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh index 8c1b81e248..ff8c2f7532 100755 --- a/t/t4006-diff-mode.sh +++ b/t/t4006-diff-mode.sh @@ -20,8 +20,6 @@ test_expect_success \ 'test_chmod +x rezrov && git diff-index $tree >current' -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" sed -e 's/\(:100644 100755\) \('"$_x40"'\) \2 /\1 X X /' <current >check echo ":100644 100755 X X M rezrov" >expected diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh index f64aa48d24..bc46563afc 100755 --- a/t/t4012-diff-binary.sh +++ b/t/t4012-diff-binary.sh @@ -77,10 +77,6 @@ test_expect_success 'apply binary patch' \ tree1=`git write-tree` && test "$tree1" = "$tree0"' -q_to_nul() { - perl -pe 'y/Q/\000/' -} - nul_to_q() { perl -pe 'y/\000/Q/' } diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 3bc1cccf88..843ef7f88c 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -93,9 +93,9 @@ test_expect_success 'extra headers' ' git config --add format.headers "Cc: S. E. Cipient <scipient@example.com> " && git format-patch --stdout master..side > patch2 && - sed -e "/^$/q" patch2 > hdrs2 && - grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs2 && - grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs2 + sed -e "/^\$/q" patch2 > hdrs2 && + grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs2 && + grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs2 ' @@ -104,9 +104,9 @@ test_expect_success 'extra headers without newlines' ' git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" && git config --add format.headers "Cc: S. E. Cipient <scipient@example.com>" && git format-patch --stdout master..side >patch3 && - sed -e "/^$/q" patch3 > hdrs3 && - grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs3 && - grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs3 + sed -e "/^\$/q" patch3 > hdrs3 && + grep "^To: R. E. Cipient <rcipient@example.com>\$" hdrs3 && + grep "^Cc: S. E. Cipient <scipient@example.com>\$" hdrs3 ' @@ -115,32 +115,32 @@ test_expect_success 'extra headers with multiple To:s' ' git config --replace-all format.headers "To: R. E. Cipient <rcipient@example.com>" && git config --add format.headers "To: S. E. Cipient <scipient@example.com>" && git format-patch --stdout master..side > patch4 && - sed -e "/^$/q" patch4 > hdrs4 && - grep "^To: R. E. Cipient <rcipient@example.com>,$" hdrs4 && - grep "^ *S. E. Cipient <scipient@example.com>$" hdrs4 + sed -e "/^\$/q" patch4 > hdrs4 && + grep "^To: R. E. Cipient <rcipient@example.com>,\$" hdrs4 && + grep "^ *S. E. Cipient <scipient@example.com>\$" hdrs4 ' test_expect_success 'additional command line cc' ' git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" && - git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^$/q" >patch5 && - grep "^Cc: R. E. Cipient <rcipient@example.com>,$" patch5 && - grep "^ *S. E. Cipient <scipient@example.com>$" patch5 + git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 && + grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch5 && + grep "^ *S. E. Cipient <scipient@example.com>\$" patch5 ' test_expect_success 'command line headers' ' git config --unset-all format.headers && - git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^$/q" >patch6 && - grep "^Cc: R. E. Cipient <rcipient@example.com>$" patch6 + git format-patch --add-header="Cc: R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch6 && + grep "^Cc: R. E. Cipient <rcipient@example.com>\$" patch6 ' test_expect_success 'configuration headers and command line headers' ' git config --replace-all format.headers "Cc: R. E. Cipient <rcipient@example.com>" && - git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^$/q" >patch7 && - grep "^Cc: R. E. Cipient <rcipient@example.com>,$" patch7 && - grep "^ *S. E. Cipient <scipient@example.com>$" patch7 + git format-patch --add-header="Cc: S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch7 && + grep "^Cc: R. E. Cipient <rcipient@example.com>,\$" patch7 && + grep "^ *S. E. Cipient <scipient@example.com>\$" patch7 ' test_expect_success 'multiple files' ' @@ -406,9 +406,9 @@ test_expect_success 'cover-letter inherits diff options' ' git mv file foo && git commit -m foo && git format-patch --cover-letter -1 && - ! grep "file => foo .* 0 *$" 0000-cover-letter.patch && + ! grep "file => foo .* 0 *\$" 0000-cover-letter.patch && git format-patch --cover-letter -1 -M && - grep "file => foo .* 0 *$" 0000-cover-letter.patch + grep "file => foo .* 0 *\$" 0000-cover-letter.patch ' @@ -425,7 +425,7 @@ EOF test_expect_success 'shortlog of cover-letter wraps overly-long onelines' ' git format-patch --cover-letter -2 && - sed -e "1,/A U Thor/d" -e "/^$/q" < 0000-cover-letter.patch > output && + sed -e "1,/A U Thor/d" -e "/^\$/q" < 0000-cover-letter.patch > output && test_cmp expect output ' @@ -450,7 +450,7 @@ EOF test_expect_success 'format-patch respects -U' ' git format-patch -U4 -2 && - sed -e "1,/^$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output && + sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output && test_cmp expect output ' @@ -471,7 +471,7 @@ EOF test_expect_success 'format-patch -p suppresses stat' ' git format-patch -p -2 && - sed -e "1,/^$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output && + sed -e "1,/^\$/d" -e "/^+5/q" < 0001-This-is-an-excessively-long-subject-line-for-a-messa.patch > output && test_cmp expect output ' @@ -557,4 +557,8 @@ test_expect_success 'format-patch -- <path>' ' ! grep "Use .--" error ' +test_expect_success 'format-patch --ignore-if-in-upstream HEAD' ' + git format-patch --ignore-if-in-upstream HEAD +' + test_done diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 8dd147d78f..90f3342373 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -93,8 +93,6 @@ git diff > out test_expect_success 'another test, without options' 'test_cmp expect out' cat << EOF > expect -diff --git a/x b/x -index d99af23..8b32fb5 100644 EOF git diff -w > out test_expect_success 'another test, with -w' 'test_cmp expect out' @@ -386,6 +384,18 @@ test_expect_success 'checkdiff allows new blank lines' ' git diff --check ' +cat <<EOF >expect +EOF +test_expect_success 'whitespace-only changes not reported' ' + git reset --hard && + echo >x "hello world" && + git add x && + git commit -m "hello 1" && + echo >x "hello world" && + git diff -b >actual && + test_cmp expect actual +' + test_expect_success 'combined diff with autocrlf conversion' ' git reset --hard && diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh index 60dd2014d5..61589853df 100755 --- a/t/t4017-diff-retval.sh +++ b/t/t4017-diff-retval.sh @@ -5,6 +5,9 @@ test_description='Return value of diffs' . ./test-lib.sh test_expect_success 'setup' ' + echo "1 " >a && + git add . && + git commit -m zeroth && echo 1 >a && git add . && git commit -m first && @@ -13,6 +16,18 @@ test_expect_success 'setup' ' git commit -a -m second ' +test_expect_success 'git diff --quiet -w HEAD^^ HEAD^' ' + git diff --quiet -w HEAD^^ HEAD^ +' + +test_expect_success 'git diff --quiet HEAD^^ HEAD^' ' + test_must_fail git diff --quiet HEAD^^ HEAD^ +' + +test_expect_success 'git diff --quiet -w HEAD^ HEAD' ' + test_must_fail git diff --quiet -w HEAD^ HEAD +' + test_expect_success 'git diff-tree HEAD^ HEAD' ' git diff-tree --exit-code HEAD^ HEAD test $? = 1 @@ -105,7 +120,6 @@ test_expect_success '--check with --no-pager returns 2 for dirty difference' ' ' - test_expect_success 'check should test not just the last line' ' echo "" >>a && git --no-pager diff --check @@ -127,4 +141,26 @@ test_expect_success 'check detects leftover conflict markers' ' git reset --hard ' +test_expect_success 'check honors conflict marker length' ' + git reset --hard && + echo ">>>>>>> boo" >>b && + echo "======" >>a && + git diff --check a && + ( + git diff --check b + test $? = 2 + ) && + git reset --hard && + echo ">>>>>>>> boo" >>b && + echo "========" >>a && + git diff --check && + echo "b conflict-marker-size=8" >.gitattributes && + ( + git diff --check b + test $? = 2 + ) && + git diff --check a && + git reset --hard +' + test_done diff --git a/t/t4026-color.sh b/t/t4026-color.sh index 5ade44c043..d5ccdd0cf8 100755 --- a/t/t4026-color.sh +++ b/t/t4026-color.sh @@ -8,14 +8,13 @@ test_description='Test diff/status color escape codes' color() { - git config diff.color.new "$1" && - test "`git config --get-color diff.color.new`" = "$2" + actual=$(git config --get-color no.such.slot "$1") && + test "$actual" = "$2" } invalid_color() { - git config diff.color.new "$1" && - test -z "`git config --get-color diff.color.new 2>/dev/null`" + test_must_fail git config --get-color no.such.slot "$1" } test_expect_success 'reset' ' @@ -42,6 +41,14 @@ test_expect_success 'fg bg attr' ' color "blue red ul" "[4;34;41m" ' +test_expect_success 'fg bg attr...' ' + color "blue bold dim ul blink reverse" "[1;2;4;5;7;34m" +' + +test_expect_success 'long color specification' ' + color "254 255 bold dim ul blink reverse" "[1;2;4;5;7;38;5;254;48;5;255m" +' + test_expect_success '256 colors' ' color "254 bold 255" "[1;38;5;254;48;5;255m" ' diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 5cf8924b21..83c1914771 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -32,7 +32,8 @@ test_expect_success setup ' cd sub && git rev-list HEAD ) && - echo ":160000 160000 $3 $_z40 M sub" >expect + echo ":160000 160000 $3 $_z40 M sub" >expect && + subtip=$3 subprev=$2 ' test_expect_success 'git diff --raw HEAD' ' @@ -50,6 +51,87 @@ test_expect_success 'git diff-files --raw' ' test_cmp expect actual.files ' +expect_from_to () { + printf "%sSubproject commit %s\n+Subproject commit %s\n" \ + "-" "$1" "$2" +} + +test_expect_success 'git diff HEAD' ' + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev && + test_cmp expect.body actual.body +' + +test_expect_success 'git diff HEAD with dirty submodule (work tree)' ' + echo >>sub/world && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev-dirty && + test_cmp expect.body actual.body +' + +test_expect_success 'git diff HEAD with dirty submodule (index)' ' + ( + cd sub && + git reset --hard && + echo >>world && + git add world + ) && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev-dirty && + test_cmp expect.body actual.body +' + +test_expect_success 'git diff HEAD with dirty submodule (untracked)' ' + ( + cd sub && + git reset --hard && + git clean -qfdx && + >cruft + ) && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subtip $subprev-dirty && + test_cmp expect.body actual.body +' + +test_expect_success 'git diff HEAD with dirty submodule (work tree, refs match)' ' + git commit -m "x" sub && + echo >>sub/world && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body +' + +test_expect_success 'git diff HEAD with dirty submodule (index, refs match)' ' + ( + cd sub && + git reset --hard && + echo >>world && + git add world + ) && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body +' + +test_expect_success 'git diff HEAD with dirty submodule (untracked, refs match)' ' + ( + cd sub && + git reset --hard && + git clean -qfdx && + >cruft + ) && + git diff HEAD >actual && + sed -e "1,/^@@/d" actual >actual.body && + expect_from_to >expect.body $subprev $subprev-dirty && + test_cmp expect.body actual.body +' + test_expect_success 'git diff (empty submodule dir)' ' : >empty && rm -rf sub/* sub/.git && diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh index a3f0897a52..88c5619ae7 100755 --- a/t/t4030-diff-textconv.sh +++ b/t/t4030-diff-textconv.sh @@ -48,7 +48,7 @@ test_expect_success 'file is considered binary by plumbing' ' test_expect_success 'setup textconv filters' ' echo file diff=foo >.gitattributes && - git config diff.foo.textconv "$PWD"/hexdump && + git config diff.foo.textconv "\"$(pwd)\""/hexdump && git config diff.fail.textconv false ' diff --git a/t/t4031-diff-rewrite-binary.sh b/t/t4031-diff-rewrite-binary.sh index a894c60622..7e7b307a24 100755 --- a/t/t4031-diff-rewrite-binary.sh +++ b/t/t4031-diff-rewrite-binary.sh @@ -54,7 +54,7 @@ chmod +x dump test_expect_success 'setup textconv' ' echo file diff=foo >.gitattributes && - git config diff.foo.textconv "$PWD"/dump + git config diff.foo.textconv "\"$(pwd)\""/dump ' test_expect_success 'rewrite diff respects textconv' ' diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 1c21276c55..2e2e103b31 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -12,19 +12,9 @@ test_expect_success setup ' ' -decrypt_color () { - sed \ - -e 's/.\[1m/<WHITE>/g' \ - -e 's/.\[31m/<RED>/g' \ - -e 's/.\[32m/<GREEN>/g' \ - -e 's/.\[35m/<MAGENTA>/g' \ - -e 's/.\[36m/<BROWN>/g' \ - -e 's/.\[m/<RESET>/g' -} - word_diff () { test_must_fail git diff --no-index "$@" pre post > output && - decrypt_color < output > output.decrypted && + test_decode_color <output >output.decrypted && test_cmp expect output.decrypted } @@ -49,7 +39,7 @@ cat > expect <<\EOF <WHITE>index 330b04f..5ed8eff 100644<RESET> <WHITE>--- a/pre<RESET> <WHITE>+++ b/post<RESET> -<BROWN>@@ -1,3 +1,7 @@<RESET> +<CYAN>@@ -1,3 +1,7 @@<RESET> <RED>h(4)<RESET><GREEN>h(4),hh[44]<RESET> a = b + c<RESET> @@ -70,9 +60,9 @@ cat > expect <<\EOF <WHITE>index 330b04f..5ed8eff 100644<RESET> <WHITE>--- a/pre<RESET> <WHITE>+++ b/post<RESET> -<BROWN>@@ -1 +1 @@<RESET> +<CYAN>@@ -1 +1 @@<RESET> <RED>h(4)<RESET><GREEN>h(4),hh[44]<RESET> -<BROWN>@@ -3,0 +4,4 @@<RESET> <RESET><MAGENTA>a = b + c<RESET> +<CYAN>@@ -3,0 +4,4 @@<RESET> <RESET><MAGENTA>a = b + c<RESET> <GREEN>aa = a<RESET> @@ -90,7 +80,7 @@ cat > expect <<\EOF <WHITE>index 330b04f..5ed8eff 100644<RESET> <WHITE>--- a/pre<RESET> <WHITE>+++ b/post<RESET> -<BROWN>@@ -1,3 +1,7 @@<RESET> +<CYAN>@@ -1,3 +1,7 @@<RESET> h(4),<GREEN>hh<RESET>[44] a = b + c<RESET> @@ -126,7 +116,7 @@ cat > expect <<\EOF <WHITE>index 330b04f..5ed8eff 100644<RESET> <WHITE>--- a/pre<RESET> <WHITE>+++ b/post<RESET> -<BROWN>@@ -1,3 +1,7 @@<RESET> +<CYAN>@@ -1,3 +1,7 @@<RESET> h(4)<GREEN>,hh[44]<RESET> a = b + c<RESET> @@ -168,7 +158,7 @@ cat > expect <<\EOF <WHITE>index 330b04f..5ed8eff 100644<RESET> <WHITE>--- a/pre<RESET> <WHITE>+++ b/post<RESET> -<BROWN>@@ -1,3 +1,7 @@<RESET> +<CYAN>@@ -1,3 +1,7 @@<RESET> h(4),<GREEN>hh[44<RESET>] a = b + c<RESET> @@ -190,7 +180,7 @@ cat > expect <<\EOF <WHITE>index c29453b..be22f37 100644<RESET> <WHITE>--- a/pre<RESET> <WHITE>+++ b/post<RESET> -<BROWN>@@ -1 +1 @@<RESET> +<CYAN>@@ -1 +1 @@<RESET> aaa (aaa) <GREEN>aaa<RESET> EOF @@ -209,7 +199,7 @@ cat > expect <<\EOF <WHITE>index 289cb9d..2d06f37 100644<RESET> <WHITE>--- a/pre<RESET> <WHITE>+++ b/post<RESET> -<BROWN>@@ -1 +1 @@<RESET> +<CYAN>@@ -1 +1 @@<RESET> (<RED>:<RESET> EOF diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh index 2cf7e01ac2..40277c77aa 100755 --- a/t/t4038-diff-combined.sh +++ b/t/t4038-diff-combined.sh @@ -76,9 +76,17 @@ test_expect_success 'check combined output (1)' ' verify_helper sidewithone ' -test_expect_failure 'check combined output (2)' ' +test_expect_success 'check combined output (2)' ' git show sidesansone -- >sidesansone && verify_helper sidesansone ' +test_expect_success 'diagnose truncated file' ' + >file && + git add file && + git commit --amend -C HEAD && + git show >out && + grep "diff --cc file" out +' + test_done diff --git a/t/t4040-whitespace-status.sh b/t/t4040-whitespace-status.sh new file mode 100755 index 0000000000..a30b03bcf2 --- /dev/null +++ b/t/t4040-whitespace-status.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +test_description='diff --exit-code with whitespace' +. ./test-lib.sh + +test_expect_success setup ' + mkdir a b && + echo >c && + echo >a/d && + echo >b/e && + git add . && + test_tick && + git commit -m initial && + echo " " >a/d && + test_tick && + git commit -a -m second && + echo " " >a/d && + echo " " >b/e && + git add a/d +' + +test_expect_success 'diff-tree --exit-code' ' + test_must_fail git diff --exit-code HEAD^ HEAD && + test_must_fail git diff-tree --exit-code HEAD^ HEAD +' + +test_expect_success 'diff-tree -b --exit-code' ' + git diff -b --exit-code HEAD^ HEAD && + git diff-tree -b -p --exit-code HEAD^ HEAD && + git diff-tree -b --exit-code HEAD^ HEAD +' + +test_expect_success 'diff-index --cached --exit-code' ' + test_must_fail git diff --cached --exit-code HEAD && + test_must_fail git diff-index --cached --exit-code HEAD +' + +test_expect_success 'diff-index -b -p --cached --exit-code' ' + git diff -b --cached --exit-code HEAD && + git diff-index -b -p --cached --exit-code HEAD +' + +test_expect_success 'diff-index --exit-code' ' + test_must_fail git diff --exit-code HEAD && + test_must_fail git diff-index --exit-code HEAD +' + +test_expect_success 'diff-index -b -p --exit-code' ' + git diff -b --exit-code HEAD && + git diff-index -b -p --exit-code HEAD +' + +test_expect_success 'diff-files --exit-code' ' + test_must_fail git diff --exit-code && + test_must_fail git diff-files --exit-code +' + +test_expect_success 'diff-files -b -p --exit-code' ' + git diff -b --exit-code && + git diff-files -b -p --exit-code +' + +test_done diff --git a/t/t4041-diff-submodule.sh b/t/t4041-diff-submodule.sh index 5bb4fed3f5..464305405a 100755 --- a/t/t4041-diff-submodule.sh +++ b/t/t4041-diff-submodule.sh @@ -191,6 +191,73 @@ EOF " commit_file sm1 && +test_expect_success 'submodule is up to date' " + git diff-index -p --submodule=log HEAD >actual && + diff actual - <<-EOF +EOF +" + +test_expect_success 'submodule contains untracked content' " + echo new > sm1/new-file && + git diff-index -p --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head6-dirty: +EOF +" + +test_expect_success 'submodule contains untracked and modifed content' " + echo new > sm1/foo6 && + git diff-index -p --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head6-dirty: +EOF +" + +test_expect_success 'submodule contains modifed content' " + rm -f sm1/new-file && + git diff-index -p --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head6-dirty: +EOF +" + +(cd sm1; git commit -mchange foo6 >/dev/null) && +head8=$(cd sm1; git rev-parse --verify HEAD | cut -c1-7) && +test_expect_success 'submodule is modified' " + git diff-index -p --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head8: + > change +EOF +" + +test_expect_success 'modified submodule contains untracked content' " + echo new > sm1/new-file && + git diff-index -p --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head8-dirty: + > change +EOF +" + +test_expect_success 'modified submodule contains untracked and modifed content' " + echo modification >> sm1/foo6 && + git diff-index -p --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head8-dirty: + > change +EOF +" + +test_expect_success 'modified submodule contains modifed content' " + rm -f sm1/new-file && + git diff-index -p --submodule=log HEAD >actual && + diff actual - <<-EOF +Submodule sm1 $head6..$head8-dirty: + > change +EOF +" + rm -rf sm1 test_expect_success 'deleted submodule' " git diff-index -p --submodule=log HEAD >actual && diff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh index 0e3ce3611d..c617c2a33d 100755 --- a/t/t4104-apply-boundary.sh +++ b/t/t4104-apply-boundary.sh @@ -134,4 +134,13 @@ test_expect_success 'two lines' ' ' +test_expect_success 'apply patch with 3 context lines matching at end' ' + { echo a; echo b; echo c; echo d; } >file && + git add file && + echo e >>file && + git diff >patch && + >file && + test_must_fail git apply patch +' + test_done diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh index 83d4ba6798..b463b4f05c 100755 --- a/t/t4120-apply-popt.sh +++ b/t/t4120-apply-popt.sh @@ -22,4 +22,9 @@ test_expect_success 'apply git diff with -p2' ' git apply -p2 patch.file ' +test_expect_success 'apply with too large -p' ' + test_must_fail git apply --stat -p3 patch.file 2>err && + grep "removing 3 leading" err +' + test_done diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index ca26397590..fb9ad247bf 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -261,4 +261,174 @@ test_expect_success 'blank but not empty at EOF' ' grep "new blank line at EOF" error ' +test_expect_success 'applying beyond EOF requires one non-blank context line' ' + { echo; echo; echo; echo; } >one && + git add one && + { echo b; } >>one && + git diff -- one >patch && + + git checkout one && + { echo a; echo; } >one && + cp one expect && + test_must_fail git apply --whitespace=fix patch && + test_cmp one expect && + test_must_fail git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'tons of blanks at EOF should not apply' ' + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do + echo; echo; echo; echo; + done >one && + git add one && + echo a >>one && + git diff -- one >patch && + + >one && + test_must_fail git apply --whitespace=fix patch && + test_must_fail git apply --ignore-space-change --whitespace=fix patch +' + +test_expect_success 'missing blank line at end with --whitespace=fix' ' + echo a >one && + echo >>one && + git add one && + echo b >>one && + cp one expect && + git diff -- one >patch && + echo a >one && + cp one saved-one && + test_must_fail git apply patch && + git apply --whitespace=fix patch && + test_cmp one expect && + mv saved-one one && + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'two missing blank lines at end with --whitespace=fix' ' + { echo a; echo; echo b; echo c; } >one && + cp one no-blank-lines && + { echo; echo; } >>one && + git add one && + echo d >>one && + cp one expect && + echo >>one && + git diff -- one >patch && + cp no-blank-lines one && + test_must_fail git apply patch && + git apply --whitespace=fix patch && + test_cmp one expect && + mv no-blank-lines one && + test_must_fail git apply patch && + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'shrink file with tons of missing blanks at end of file' ' + { echo a; echo b; echo c; } >one && + cp one no-blank-lines && + for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do + echo; echo; echo; echo; + done >>one && + git add one && + echo a >one && + cp one expect && + git diff -- one >patch && + cp no-blank-lines one && + test_must_fail git apply patch && + git apply --whitespace=fix patch && + test_cmp one expect && + mv no-blank-lines one && + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'missing blanks at EOF must only match blank lines' ' + { echo a; echo b; } >one && + git add one && + { echo c; echo d; } >>one && + git diff -- one >patch && + + echo a >one && + test_must_fail git apply patch + test_must_fail git apply --whitespace=fix patch && + test_must_fail git apply --ignore-space-change --whitespace=fix patch +' + +sed -e's/Z//' >one <<EOF +a +b +c + Z +EOF + +test_expect_success 'missing blank line should match context line with spaces' ' + git add one && + echo d >>one && + git diff -- one >patch && + { echo a; echo b; echo c; } >one && + cp one expect && + { echo; echo d; } >>expect && + git add one && + + git apply --whitespace=fix patch && + test_cmp one expect +' + +sed -e's/Z//' >one <<EOF +a +b +c + Z +EOF + +test_expect_success 'same, but with the --ignore-space-option' ' + git add one && + echo d >>one && + cp one expect && + git diff -- one >patch && + { echo a; echo b; echo c; } >one && + git add one && + + git checkout-index -f one && + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' ' + git config core.whitespace cr-at-eol && + printf "a\r\n" >one && + printf "b\r\n" >>one && + printf "c\r\n" >>one && + cp one save-one && + printf " \r\n" >>one + git add one && + printf "d\r\n" >>one && + cp one expect && + git diff -- one >patch && + mv save-one one && + + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + +test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' ' + git config --unset core.whitespace && + printf "a\r\n" >one && + printf "b\r\n" >>one && + printf "c\r\n" >>one && + cp one save-one && + printf " \r\n" >>one + git add one && + cp one expect && + printf "d\r\n" >>one && + git diff -- one >patch && + mv save-one one && + echo d >>expect && + + git apply --ignore-space-change --whitespace=fix patch && + test_cmp one expect +' + test_done diff --git a/t/t4125-apply-ws-fuzz.sh b/t/t4125-apply-ws-fuzz.sh index 3b471b641b..9671de7999 100755 --- a/t/t4125-apply-ws-fuzz.sh +++ b/t/t4125-apply-ws-fuzz.sh @@ -37,11 +37,11 @@ test_expect_success setup ' # patch-2 is the same as patch-1 but is based # on a version that already has whitespace fixed, # and does not introduce whitespace breakages. - sed -e "s/ $//" patch-1 >patch-2 && + sed -e "s/ \$//" patch-1 >patch-2 && # If all whitespace breakages are fixed the contents # should look like file-fixed - sed -e "s/ $//" file-1 >file-fixed + sed -e "s/ \$//" file-1 >file-fixed ' diff --git a/t/t4133-apply-filenames.sh b/t/t4133-apply-filenames.sh new file mode 100755 index 0000000000..34218071b6 --- /dev/null +++ b/t/t4133-apply-filenames.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Copyright (c) 2010 Andreas Gruenbacher +# + +test_description='git apply filename consistency check' + +. ./test-lib.sh + +test_expect_success setup ' + cat > bad1.patch <<EOF +diff --git a/f b/f +new file mode 100644 +index 0000000..d00491f +--- /dev/null ++++ b/f-blah +@@ -0,0 +1 @@ ++1 +EOF + cat > bad2.patch <<EOF +diff --git a/f b/f +deleted file mode 100644 +index d00491f..0000000 +--- b/f-blah ++++ /dev/null +@@ -1 +0,0 @@ +-1 +EOF +' + +test_expect_success 'apply diff with inconsistent filenames in headers' ' + test_must_fail git apply bad1.patch 2>err + grep "inconsistent new filename" err + test_must_fail git apply bad2.patch 2>err + grep "inconsistent old filename" err +' + +test_done diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 8296605234..810b04b817 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -83,6 +83,12 @@ test_expect_success setup ' echo "X-Fake-Field: Line Three" && git format-patch --stdout first | sed -e "1d" } > patch1.eml && + { + echo "X-Fake-Field: Line One" && + echo "X-Fake-Field: Line Two" && + echo "X-Fake-Field: Line Three" && + git format-patch --stdout first | sed -e "1d" + } | append_cr >patch1-crlf.eml && sed -n -e "3,\$p" msg >file && git add file && test_tick && @@ -123,6 +129,15 @@ test_expect_success 'am applies patch e-mail not in a mbox' ' test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" ' +test_expect_success 'am applies patch e-mail not in a mbox with CRLF' ' + git checkout first && + git am patch1-crlf.eml && + ! test -d .git/rebase-apply && + test -z "$(git diff second)" && + test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && + test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" +' + GIT_AUTHOR_NAME="Another Thor" GIT_AUTHOR_EMAIL="a.thor@example.com" GIT_COMMITTER_NAME="Co M Miter" @@ -287,7 +302,7 @@ test_expect_success 'am --committer-date-is-author-date' ' git checkout first && test_tick && git am --committer-date-is-author-date patch1 && - git cat-file commit HEAD | sed -e "/^$/q" >head1 && + git cat-file commit HEAD | sed -e "/^\$/q" >head1 && at=$(sed -ne "/^author /s/.*> //p" head1) && ct=$(sed -ne "/^committer /s/.*> //p" head1) && test "$at" = "$ct" @@ -297,7 +312,7 @@ test_expect_success 'am without --committer-date-is-author-date' ' git checkout first && test_tick && git am patch1 && - git cat-file commit HEAD | sed -e "/^$/q" >head1 && + git cat-file commit HEAD | sed -e "/^\$/q" >head1 && at=$(sed -ne "/^author /s/.*> //p" head1) && ct=$(sed -ne "/^committer /s/.*> //p" head1) && test "$at" != "$ct" @@ -311,7 +326,7 @@ test_expect_success 'am --ignore-date' ' git checkout first && test_tick && git am --ignore-date patch1 && - git cat-file commit HEAD | sed -e "/^$/q" >head1 && + git cat-file commit HEAD | sed -e "/^\$/q" >head1 && at=$(sed -ne "/^author /s/.*> //p" head1) && echo "$at" | grep "+0000" ' diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index a6bc028a57..bb402c3780 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -217,7 +217,22 @@ test_expect_success 'rerere.autoupdate' ' git checkout version2 && test_must_fail git merge fifth && test 0 = $(git ls-files -u | wc -l) +' +test_expect_success 'merge --rerere-autoupdate' ' + git config --unset rerere.autoupdate + git reset --hard && + git checkout version2 && + test_must_fail git merge --rerere-autoupdate fifth && + test 0 = $(git ls-files -u | wc -l) +' + +test_expect_success 'merge --no-rerere-autoupdate' ' + git config rerere.autoupdate true + git reset --hard && + git checkout version2 && + test_must_fail git merge --no-rerere-autoupdate fifth && + test 2 = $(git ls-files -u | wc -l) ' test_done diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 779a5adf55..1dc224f6fb 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -255,7 +255,7 @@ EOF test_expect_success 'log --graph with merge' ' git log --graph --date-order --pretty=tformat:%s | - sed "s/ *$//" >actual && + sed "s/ *\$//" >actual && test_cmp expect actual ' @@ -315,7 +315,7 @@ EOF test_expect_success 'log --graph with full output' ' git log --graph --date-order --pretty=short | git name-rev --name-only --stdin | - sed "s/Merge:.*/Merge: A B/;s/ *$//" >actual && + sed "s/Merge:.*/Merge: A B/;s/ *\$//" >actual && test_cmp expect actual ' @@ -383,7 +383,7 @@ EOF test_expect_success 'log --graph with merge' ' git log --graph --date-order --pretty=tformat:%s | - sed "s/ *$//" >actual && + sed "s/ *\$//" >actual && test_cmp expect actual ' diff --git a/t/t5100/msg0015 b/t/t5100/msg0015 index 9577238685..4abb3d5c6c 100644 --- a/t/t5100/msg0015 +++ b/t/t5100/msg0015 @@ -1,2 +1,2 @@ -- a list + - a list - of stuff diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index e2aa254eae..7649b810b1 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -16,7 +16,9 @@ test_expect_success \ perl -e "print \"a\" x 4096;" > a && perl -e "print \"b\" x 4096;" > b && perl -e "print \"c\" x 4096;" > c && - git update-index --add a b c && + test-genrandom "seed a" 2097152 > a_big && + test-genrandom "seed b" 2097152 > b_big && + git update-index --add a a_big b b_big c && cat c >d && echo foo >>d && git update-index --add d && tree=`git write-tree` && commit=`git commit-tree $tree </dev/null` && { @@ -280,26 +282,8 @@ test_expect_success \ :' -test_expect_success \ - 'fake a SHA1 hash collision' \ - 'test -f .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67 && - cp -f .git/objects/9d/235ed07cd19811a6ceb342de82f190e49c9f68 \ - .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67' - -test_expect_success \ - 'make sure index-pack detects the SHA1 collision' \ - 'test_must_fail git index-pack -o bad.idx test-3.pack 2>msg && - grep "SHA1 COLLISION FOUND" msg' - -test_expect_success \ - 'honor pack.packSizeLimit' \ - 'git config pack.packSizeLimit 200 && - packname_4=$(git pack-objects test-4 <obj-list) && - test 3 = $(ls test-4-*.pack | wc -l)' - test_expect_success 'unpacking with --strict' ' - git config --unset pack.packsizelimit && for j in a b c d e f g do for i in 0 1 2 3 4 5 6 7 8 9 @@ -392,10 +376,42 @@ test_expect_success 'index-pack with --strict' ' ) ' -test_expect_success 'tolerate absurdly small packsizelimit' ' - git config pack.packSizeLimit 2 && - packname_9=$(git pack-objects test-9 <obj-list) && - test $(wc -l <obj-list) = $(ls test-9-*.pack | wc -l) +test_expect_success 'honor pack.packSizeLimit' ' + git config pack.packSizeLimit 3m && + packname_10=$(git pack-objects test-10 <obj-list) && + test 2 = $(ls test-10-*.pack | wc -l) +' + +test_expect_success 'verify resulting packs' ' + git verify-pack test-10-*.pack +' + +test_expect_success 'tolerate packsizelimit smaller than biggest object' ' + git config pack.packSizeLimit 1 && + packname_11=$(git pack-objects test-11 <obj-list) && + test 5 = $(ls test-11-*.pack | wc -l) ' +test_expect_success 'verify resulting packs' ' + git verify-pack test-11-*.pack +' + +# +# WARNING! +# +# The following test is destructive. Please keep the next +# two tests at the end of this file. +# + +test_expect_success \ + 'fake a SHA1 hash collision' \ + 'test -f .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67 && + cp -f .git/objects/9d/235ed07cd19811a6ceb342de82f190e49c9f68 \ + .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67' + +test_expect_success \ + 'make sure index-pack detects the SHA1 collision' \ + 'test_must_fail git index-pack -o bad.idx test-3.pack 2>msg && + grep "SHA1 COLLISION FOUND" msg' + test_done diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index 3c6687abec..e2ed13dba2 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -148,6 +148,38 @@ test_expect_success 'gc --prune=<date>' ' ' +test_expect_success 'gc --prune=never' ' + + add_blob && + git gc --prune=never && + test -f $BLOB_FILE && + git gc --prune=now && + test ! -f $BLOB_FILE + +' + +test_expect_success 'gc respects gc.pruneExpire=never' ' + + git config gc.pruneExpire never && + add_blob && + git gc && + test -f $BLOB_FILE && + git config gc.pruneExpire now && + git gc && + test ! -f $BLOB_FILE + +' + +test_expect_success 'prune --expire=never' ' + + add_blob && + git prune --expire=never && + test -f $BLOB_FILE && + git prune && + test ! -f $BLOB_FILE + +' + test_expect_success 'gc: prune old objects after local clone' ' add_blob && test-chmtime =-$((2*$week+1)) $BLOB_FILE && diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index f2d5581b12..c718253673 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -32,7 +32,7 @@ test_expect_success setup ' done && git update-ref HEAD "$commit" && git clone ./. victim && - ( cd victim && git log ) && + ( cd victim && git config receive.denyCurrentBranch warn && git log ) && git update-ref HEAD "$zero" && parent=$zero && i=0 && @@ -129,6 +129,7 @@ rewound_push_setup() { cd parent && git init && echo one >file && git add file && git commit -m one && + git config receive.denyCurrentBranch warn && echo two >file && git commit -a -m two ) && git clone parent child && @@ -190,16 +191,11 @@ test_expect_success 'pushing wildcard refspecs respects forcing' ' test "$parent_head" = "$child_head" ' -test_expect_success 'warn pushing to delete current branch' ' +test_expect_success 'deny pushing to delete current branch' ' rewound_push_setup && ( cd child && - git send-pack ../parent :refs/heads/master 2>errs - ) && - grep "warning: to refuse deleting" child/errs && - ( - cd parent && - test_must_fail git rev-parse --verify master + test_must_fail git send-pack ../parent :refs/heads/master 2>errs ) ' diff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh index cb9aacc7bc..4bda18a662 100755 --- a/t/t5405-send-pack-rewind.sh +++ b/t/t5405-send-pack-rewind.sh @@ -8,6 +8,7 @@ test_expect_success setup ' >file1 && git add file1 && test_tick && git commit -m Initial && + git config receive.denyCurrentBranch warn && mkdir another && ( cd another && diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 936fe0a1a6..2692050209 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -507,15 +507,15 @@ test_expect_success 'remote prune to cause a dangling symref' ' ( cd seven && git remote prune origin - ) 2>err && + ) >err 2>&1 && grep "has become dangling" err && - : And the dangling symref will not cause other annoying errors + : And the dangling symref will not cause other annoying errors && ( cd seven && git branch -a ) 2>err && - ! grep "points nowhere" err + ! grep "points nowhere" err && ( cd seven && test_must_fail git branch nomore origin @@ -533,5 +533,219 @@ test_expect_success 'show empty remote' ' ) ' -test_done +test_expect_success 'new remote' ' +( + git remote add someremote foo && + echo foo >expect && + git config --get-all remote.someremote.url >actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url bar' ' +( + git remote set-url someremote bar && + echo bar >expect && + git config --get-all remote.someremote.url >actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url baz bar' ' +( + git remote set-url someremote baz bar && + echo baz >expect && + git config --get-all remote.someremote.url >actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url zot bar' ' +( + test_must_fail git remote set-url someremote zot bar && + echo baz >expect && + git config --get-all remote.someremote.url >actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --push zot baz' ' +( + test_must_fail git remote set-url --push someremote zot baz && + echo "YYY" >expect && + echo baz >>expect && + test_must_fail git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --push zot' ' +( + git remote set-url --push someremote zot && + echo zot >expect && + echo "YYY" >>expect && + echo baz >>expect && + git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --push qux zot' ' +( + git remote set-url --push someremote qux zot && + echo qux >expect && + echo "YYY" >>expect && + echo baz >>expect && + git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --push foo qu+x' ' +( + git remote set-url --push someremote foo qu+x && + echo foo >expect && + echo "YYY" >>expect && + echo baz >>expect && + git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --push --add aaa' ' +( + git remote set-url --push --add someremote aaa && + echo foo >expect && + echo aaa >>expect && + echo "YYY" >>expect && + echo baz >>expect && + git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' +test_expect_success 'remote set-url --push bar aaa' ' +( + git remote set-url --push someremote bar aaa && + echo foo >expect && + echo bar >>expect && + echo "YYY" >>expect && + echo baz >>expect && + git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --push --delete bar' ' +( + git remote set-url --push --delete someremote bar && + echo foo >expect && + echo "YYY" >>expect && + echo baz >>expect && + git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --push --delete foo' ' +( + git remote set-url --push --delete someremote foo && + echo "YYY" >expect && + echo baz >>expect && + test_must_fail git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --add bbb' ' +( + git remote set-url --add someremote bbb && + echo "YYY" >expect && + echo baz >>expect && + echo bbb >>expect && + test_must_fail git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --delete .*' ' +( + test_must_fail git remote set-url --delete someremote .* && + echo "YYY" >expect && + echo baz >>expect && + echo bbb >>expect && + test_must_fail git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --delete bbb' ' +( + git remote set-url --delete someremote bbb && + echo "YYY" >expect && + echo baz >>expect && + test_must_fail git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --delete baz' ' +( + test_must_fail git remote set-url --delete someremote baz && + echo "YYY" >expect && + echo baz >>expect && + test_must_fail git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --add ccc' ' +( + git remote set-url --add someremote ccc && + echo "YYY" >expect && + echo baz >>expect && + echo ccc >>expect && + test_must_fail git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_expect_success 'remote set-url --delete baz' ' +( + git remote set-url --delete someremote baz && + echo "YYY" >expect && + echo ccc >>expect && + test_must_fail git config --get-all remote.someremote.pushurl >actual && + echo "YYY" >>actual && + git config --get-all remote.someremote.url >>actual && + cmp expect actual +) +' + +test_done diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 6889a53cf9..0f04b2e894 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -12,6 +12,7 @@ mk_empty () { ( cd testrepo && git init && + git config receive.denyCurrentBranch warn && mv .git/hooks .git/hooks-disabled ) } @@ -546,6 +547,32 @@ test_expect_success 'allow deleting an invalid remote ref' ' ' +test_expect_success 'allow deleting a ref using --delete' ' + mk_test heads/master && + (cd testrepo && git config receive.denyDeleteCurrent warn) && + git push testrepo --delete master && + (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master) +' + +test_expect_success 'allow deleting a tag using --delete' ' + mk_test heads/master && + git tag -a -m dummy_message deltag heads/master && + git push testrepo --tags && + (cd testrepo && git rev-parse --verify -q refs/tags/deltag) && + git push testrepo --delete tag deltag && + (cd testrepo && test_must_fail git rev-parse --verify refs/tags/deltag) +' + +test_expect_success 'push --delete without args aborts' ' + mk_test heads/master && + test_must_fail git push testrepo --delete +' + +test_expect_success 'push --delete refuses src:dest refspecs' ' + mk_test heads/master && + test_must_fail git push testrepo --delete master:foo +' + test_expect_success 'warn on push to HEAD of non-bare repository' ' mk_test heads/master (cd testrepo && diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh index ea49dedbf8..e2ad260508 100755 --- a/t/t5517-push-mirror.sh +++ b/t/t5517-push-mirror.sh @@ -19,7 +19,8 @@ mk_repo_pair () { mkdir mirror && ( cd mirror && - git init + git init && + git config receive.denyCurrentBranch warn ) && mkdir master && ( diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 83e2e8ab80..1b06691bb4 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -4,8 +4,6 @@ test_description='pull options' . ./test-lib.sh -D=`pwd` - test_expect_success 'setup' ' mkdir parent && (cd parent && git init && @@ -13,48 +11,83 @@ test_expect_success 'setup' ' git commit -m one) ' -cd "$D" - test_expect_success 'git pull -q' ' mkdir clonedq && - cd clonedq && - git pull -q "$D/parent" >out 2>err && - test ! -s out + (cd clonedq && git init && + git pull -q "../parent" >out 2>err && + test ! -s err && + test ! -s out) ' -cd "$D" - test_expect_success 'git pull' ' mkdir cloned && - cd cloned && - git pull "$D/parent" >out 2>err && - test -s out + (cd cloned && git init && + git pull "../parent" >out 2>err && + test -s err && + test ! -s out) ' -cd "$D" test_expect_success 'git pull -v' ' mkdir clonedv && - cd clonedv && - git pull -v "$D/parent" >out 2>err && - test -s out + (cd clonedv && git init && + git pull -v "../parent" >out 2>err && + test -s err && + test ! -s out) ' -cd "$D" - test_expect_success 'git pull -v -q' ' mkdir clonedvq && - cd clonedvq && - git pull -v -q "$D/parent" >out 2>err && - test ! -s out + (cd clonedvq && git init && + git pull -v -q "../parent" >out 2>err && + test ! -s out && + test ! -s err) ' -cd "$D" - test_expect_success 'git pull -q -v' ' mkdir clonedqv && - cd clonedqv && - git pull -q -v "$D/parent" >out 2>err && - test -s out + (cd clonedqv && git init && + git pull -q -v "../parent" >out 2>err && + test ! -s out && + test -s err) +' + +test_expect_success 'git pull --force' ' + mkdir clonedoldstyle && + (cd clonedoldstyle && git init && + cat >>.git/config <<-\EOF && + [remote "one"] + url = ../parent + fetch = refs/heads/master:refs/heads/mirror + [remote "two"] + url = ../parent + fetch = refs/heads/master:refs/heads/origin + [branch "master"] + remote = two + merge = refs/heads/master + EOF + git pull two && + test_commit A && + git branch -f origin && + git pull --all --force + ) +' + +test_expect_success 'git pull --all' ' + mkdir clonedmulti && + (cd clonedmulti && git init && + cat >>.git/config <<-\EOF && + [remote "one"] + url = ../parent + fetch = refs/heads/*:refs/remotes/one/* + [remote "two"] + url = ../parent + fetch = refs/heads/*:refs/remotes/two/* + [branch "master"] + remote = one + merge = refs/heads/master + EOF + git pull --all + ) ' test_done diff --git a/t/t5522-pull-symlink.sh b/t/t5522-pull-symlink.sh index 86bbd7d024..7206817ca1 100755 --- a/t/t5522-pull-symlink.sh +++ b/t/t5522-pull-symlink.sh @@ -20,13 +20,19 @@ fi # # The working directory is subdir-link. -mkdir subdir -echo file >subdir/file -git add subdir/file -git commit -q -m file -git clone -q . clone-repo -ln -s clone-repo/subdir/ subdir-link - +test_expect_success setup ' + mkdir subdir && + echo file >subdir/file && + git add subdir/file && + git commit -q -m file && + git clone -q . clone-repo && + ln -s clone-repo/subdir/ subdir-link && + ( + cd clone-repo && + git config receive.denyCurrentBranch warn + ) && + git config receive.denyCurrentBranch warn +' # Demonstrate that things work if we just avoid the symlink # diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh new file mode 100755 index 0000000000..00da70763b --- /dev/null +++ b/t/t5523-push-upstream.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +test_description='push with --set-upstream' +. ./test-lib.sh + +test_expect_success 'setup bare parent' ' + git init --bare parent && + git remote add upstream parent +' + +test_expect_success 'setup local commit' ' + echo content >file && + git add file && + git commit -m one +' + +check_config() { + (echo $2; echo $3) >expect.$1 + (git config branch.$1.remote + git config branch.$1.merge) >actual.$1 + test_cmp expect.$1 actual.$1 +} + +test_expect_success 'push -u master:master' ' + git push -u upstream master:master && + check_config master upstream refs/heads/master +' + +test_expect_success 'push -u master:other' ' + git push -u upstream master:other && + check_config master upstream refs/heads/other +' + +test_expect_success 'push -u --dry-run master:otherX' ' + git push -u --dry-run upstream master:otherX && + check_config master upstream refs/heads/other +' + +test_expect_success 'push -u master2:master2' ' + git branch master2 && + git push -u upstream master2:master2 && + check_config master2 upstream refs/heads/master2 +' + +test_expect_success 'push -u master2:other2' ' + git push -u upstream master2:other2 && + check_config master2 upstream refs/heads/other2 +' + +test_expect_success 'push -u :master2' ' + git push -u upstream :master2 && + check_config master2 upstream refs/heads/other2 +' + +test_expect_success 'push -u --all' ' + git branch all1 && + git branch all2 && + git push -u --all && + check_config all1 upstream refs/heads/all1 && + check_config all2 upstream refs/heads/all2 +' + +test_expect_success 'push -u HEAD' ' + git checkout -b headbranch && + git push -u upstream HEAD && + check_config headbranch upstream refs/heads/headbranch +' + +test_done diff --git a/t/t5524-pull-msg.sh b/t/t5524-pull-msg.sh new file mode 100755 index 0000000000..8cccecc2fc --- /dev/null +++ b/t/t5524-pull-msg.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +test_description='git pull message generation' + +. ./test-lib.sh + +dollar='$Dollar' + +test_expect_success setup ' + test_commit initial afile original && + git clone . cloned && + ( + cd cloned && + echo added >bfile && + git add bfile && + test_tick && + git commit -m "add bfile" + ) && + test_tick && test_tick && + echo "original $dollar" >afile && + git add afile && + git commit -m "do not clobber $dollar signs" +' + +test_expect_success pull ' +( + cd cloned && + git pull --log && + git log -2 && + git cat-file commit HEAD >result && + grep Dollar result +) +' + +test_done diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh index 2a58d0cc9c..53f54a2789 100755 --- a/t/t5541-http-push.sh +++ b/t/t5541-http-push.sh @@ -88,5 +88,45 @@ test_expect_success 'used receive-pack service' ' test_cmp exp act ' +test_expect_success 'non-fast-forward push fails' ' + cd "$ROOT_PATH"/test_repo_clone && + git checkout master && + echo "changed" > path2 && + git commit -a -m path2 --amend && + + HEAD=$(git rev-parse --verify HEAD) && + !(git push -v origin >output 2>&1) && + (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git && + test $HEAD != $(git rev-parse --verify HEAD)) +' + +test_expect_success 'non-fast-forward push show ref status' ' + grep "^ ! \[rejected\][ ]*master -> master (non-fast-forward)$" output +' + +test_expect_success 'non-fast-forward push shows help message' ' + grep "To prevent you from losing history, non-fast-forward updates were rejected" \ + output +' + +test_expect_success 'push fails for non-fast-forward refs unmatched by remote helper' ' + # create a dissimilarly-named remote ref so that git is unable to match the + # two refs (viz. local, remote) unless an explicit refspec is provided. + git push origin master:retsam + + echo "change changed" > path2 && + git commit -a -m path2 --amend && + + # push master too; this ensures there is at least one '"'push'"' command to + # the remote helper and triggers interaction with the helper. + !(git push -v origin +master master:retsam >output 2>&1) && + + grep "^ + [a-f0-9]*\.\.\.[a-f0-9]* *master -> master (forced update)$" output && + grep "^ ! \[rejected\] *master -> retsam (non-fast-forward)$" output && + + grep "To prevent you from losing history, non-fast-forward updates were rejected" \ + output +' + stop_httpd test_done diff --git a/t/t5560-http-backend-noserver.sh b/t/t5560-http-backend-noserver.sh new file mode 100755 index 0000000000..44885b850c --- /dev/null +++ b/t/t5560-http-backend-noserver.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +test_description='test git-http-backend-noserver' +. ./test-lib.sh + +HTTPD_DOCUMENT_ROOT_PATH="$TRASH_DIRECTORY" + +run_backend() { + echo "$2" | + QUERY_STRING="${1#*\?}" \ + GIT_PROJECT_ROOT="$HTTPD_DOCUMENT_ROOT_PATH" \ + PATH_INFO="${1%%\?*}" \ + git http-backend >act.out 2>act.err +} + +GET() { + export REQUEST_METHOD="GET" && + run_backend "/repo.git/$1" && + unset REQUEST_METHOD && + if ! grep "Status" act.out >act + then + printf "Status: 200 OK\r\n" >act + fi + printf "Status: $2\r\n" >exp && + test_cmp exp act +} + +POST() { + export REQUEST_METHOD="POST" && + export CONTENT_TYPE="application/x-$1-request" && + run_backend "/repo.git/$1" "$2" && + unset REQUEST_METHOD && + unset CONTENT_TYPE && + if ! grep "Status" act.out >act + then + printf "Status: 200 OK\r\n" >act + fi + printf "Status: $3\r\n" >exp && + test_cmp exp act +} + +log_div() { + return 0 +} + +. "$TEST_DIRECTORY"/t556x_common + +expect_aliased() { + export REQUEST_METHOD="GET" && + if test $1 = 0; then + run_backend "$2" + else + run_backend "$2" && + echo "fatal: '$2': aliased" >exp.err && + test_cmp exp.err act.err + fi + unset REQUEST_METHOD +} + +test_expect_success 'http-backend blocks bad PATH_INFO' ' + config http.getanyfile true && + + expect_aliased 0 /repo.git/HEAD && + + expect_aliased 1 /repo.git/../HEAD && + expect_aliased 1 /../etc/passwd && + expect_aliased 1 ../etc/passwd && + expect_aliased 1 /etc//passwd && + expect_aliased 1 /etc/./passwd && + expect_aliased 1 //domain/data.txt +' + +test_done diff --git a/t/t5560-http-backend.sh b/t/t5560-http-backend.sh deleted file mode 100755 index ed034bc980..0000000000 --- a/t/t5560-http-backend.sh +++ /dev/null @@ -1,260 +0,0 @@ -#!/bin/sh - -test_description='test git-http-backend' -. ./test-lib.sh - -if test -n "$NO_CURL"; then - say 'skipping test, git built without http support' - test_done -fi - -LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5560'} -. "$TEST_DIRECTORY"/lib-httpd.sh -start_httpd - -find_file() { - cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && - find $1 -type f | - sed -e 1q -} - -config() { - git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" config $1 $2 -} - -GET() { - curl --include "$HTTPD_URL/smart/repo.git/$1" >out 2>/dev/null && - tr '\015' Q <out | - sed ' - s/Q$// - 1q - ' >act && - echo "HTTP/1.1 $2" >exp && - test_cmp exp act -} - -POST() { - curl --include --data "$2" \ - --header "Content-Type: application/x-$1-request" \ - "$HTTPD_URL/smart/repo.git/$1" >out 2>/dev/null && - tr '\015' Q <out | - sed ' - s/Q$// - 1q - ' >act && - echo "HTTP/1.1 $3" >exp && - test_cmp exp act -} - -log_div() { - echo >>"$HTTPD_ROOT_PATH"/access.log - echo "### $1" >>"$HTTPD_ROOT_PATH"/access.log - echo "###" >>"$HTTPD_ROOT_PATH"/access.log -} - -test_expect_success 'setup repository' ' - echo content >file && - git add file && - git commit -m one && - - mkdir "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && - (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && - git --bare init && - : >objects/info/alternates && - : >objects/info/http-alternates - ) && - git remote add public "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && - git push public master:master && - - (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && - git repack -a -d - ) && - - echo other >file && - git add file && - git commit -m two && - git push public master:master && - - LOOSE_URL=$(find_file objects/??) && - PACK_URL=$(find_file objects/pack/*.pack) && - IDX_URL=$(find_file objects/pack/*.idx) -' - -get_static_files() { - GET HEAD "$1" && - GET info/refs "$1" && - GET objects/info/packs "$1" && - GET objects/info/alternates "$1" && - GET objects/info/http-alternates "$1" && - GET $LOOSE_URL "$1" && - GET $PACK_URL "$1" && - GET $IDX_URL "$1" -} - -test_expect_success 'direct refs/heads/master not found' ' - log_div "refs/heads/master" - GET refs/heads/master "404 Not Found" -' -test_expect_success 'static file is ok' ' - log_div "getanyfile default" - get_static_files "200 OK" -' -test_expect_success 'static file if http.getanyfile true is ok' ' - log_div "getanyfile true" - config http.getanyfile true && - get_static_files "200 OK" -' -test_expect_success 'static file if http.getanyfile false fails' ' - log_div "getanyfile false" - config http.getanyfile false && - get_static_files "403 Forbidden" -' - -test_expect_success 'http.uploadpack default enabled' ' - log_div "uploadpack default" - GET info/refs?service=git-upload-pack "200 OK" && - POST git-upload-pack 0000 "200 OK" -' -test_expect_success 'http.uploadpack true' ' - log_div "uploadpack true" - config http.uploadpack true && - GET info/refs?service=git-upload-pack "200 OK" && - POST git-upload-pack 0000 "200 OK" -' -test_expect_success 'http.uploadpack false' ' - log_div "uploadpack false" - config http.uploadpack false && - GET info/refs?service=git-upload-pack "403 Forbidden" && - POST git-upload-pack 0000 "403 Forbidden" -' - -test_expect_success 'http.receivepack default disabled' ' - log_div "receivepack default" - GET info/refs?service=git-receive-pack "403 Forbidden" && - POST git-receive-pack 0000 "403 Forbidden" -' -test_expect_success 'http.receivepack true' ' - log_div "receivepack true" - config http.receivepack true && - GET info/refs?service=git-receive-pack "200 OK" && - POST git-receive-pack 0000 "200 OK" -' -test_expect_success 'http.receivepack false' ' - log_div "receivepack false" - config http.receivepack false && - GET info/refs?service=git-receive-pack "403 Forbidden" && - POST git-receive-pack 0000 "403 Forbidden" -' - -run_backend() { - REQUEST_METHOD=GET \ - GIT_PROJECT_ROOT="$HTTPD_DOCUMENT_ROOT_PATH" \ - PATH_INFO="$2" \ - git http-backend >act.out 2>act.err -} - -path_info() { - if test $1 = 0; then - run_backend "$2" - else - test_must_fail run_backend "$2" && - echo "fatal: '$2': aliased" >exp.err && - test_cmp exp.err act.err - fi -} - -test_expect_success 'http-backend blocks bad PATH_INFO' ' - config http.getanyfile true && - - run_backend 0 /repo.git/HEAD && - - run_backend 1 /repo.git/../HEAD && - run_backend 1 /../etc/passwd && - run_backend 1 ../etc/passwd && - run_backend 1 /etc//passwd && - run_backend 1 /etc/./passwd && - run_backend 1 /etc/.../passwd && - run_backend 1 //domain/data.txt -' - -cat >exp <<EOF - -### refs/heads/master -### -GET /smart/repo.git/refs/heads/master HTTP/1.1 404 - - -### getanyfile default -### -GET /smart/repo.git/HEAD HTTP/1.1 200 -GET /smart/repo.git/info/refs HTTP/1.1 200 -GET /smart/repo.git/objects/info/packs HTTP/1.1 200 -GET /smart/repo.git/objects/info/alternates HTTP/1.1 200 - -GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 200 - -GET /smart/repo.git/$LOOSE_URL HTTP/1.1 200 -GET /smart/repo.git/$PACK_URL HTTP/1.1 200 -GET /smart/repo.git/$IDX_URL HTTP/1.1 200 - -### getanyfile true -### -GET /smart/repo.git/HEAD HTTP/1.1 200 -GET /smart/repo.git/info/refs HTTP/1.1 200 -GET /smart/repo.git/objects/info/packs HTTP/1.1 200 -GET /smart/repo.git/objects/info/alternates HTTP/1.1 200 - -GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 200 - -GET /smart/repo.git/$LOOSE_URL HTTP/1.1 200 -GET /smart/repo.git/$PACK_URL HTTP/1.1 200 -GET /smart/repo.git/$IDX_URL HTTP/1.1 200 - -### getanyfile false -### -GET /smart/repo.git/HEAD HTTP/1.1 403 - -GET /smart/repo.git/info/refs HTTP/1.1 403 - -GET /smart/repo.git/objects/info/packs HTTP/1.1 403 - -GET /smart/repo.git/objects/info/alternates HTTP/1.1 403 - -GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 403 - -GET /smart/repo.git/$LOOSE_URL HTTP/1.1 403 - -GET /smart/repo.git/$PACK_URL HTTP/1.1 403 - -GET /smart/repo.git/$IDX_URL HTTP/1.1 403 - - -### uploadpack default -### -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 - - -### uploadpack true -### -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 - - -### uploadpack false -### -GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 403 - -POST /smart/repo.git/git-upload-pack HTTP/1.1 403 - - -### receivepack default -### -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 - - -### receivepack true -### -GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 200 -POST /smart/repo.git/git-receive-pack HTTP/1.1 200 - - -### receivepack false -### -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 -' - -stop_httpd -test_done diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh new file mode 100755 index 0000000000..8c6d0b2f20 --- /dev/null +++ b/t/t5561-http-backend.sh @@ -0,0 +1,149 @@ +#!/bin/sh + +test_description='test git-http-backend' +. ./test-lib.sh + +if test -n "$NO_CURL"; then + say 'skipping test, git built without http support' + test_done +fi + +LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5561'} +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +GET() { + curl --include "$HTTPD_URL/$SMART/repo.git/$1" >out 2>/dev/null && + tr '\015' Q <out | + sed ' + s/Q$// + 1q + ' >act && + echo "HTTP/1.1 $2" >exp && + test_cmp exp act +} + +POST() { + curl --include --data "$2" \ + --header "Content-Type: application/x-$1-request" \ + "$HTTPD_URL/smart/repo.git/$1" >out 2>/dev/null && + tr '\015' Q <out | + sed ' + s/Q$// + 1q + ' >act && + echo "HTTP/1.1 $3" >exp && + test_cmp exp act +} + +log_div() { + echo >>"$HTTPD_ROOT_PATH"/access.log + echo "### $1" >>"$HTTPD_ROOT_PATH"/access.log + echo "###" >>"$HTTPD_ROOT_PATH"/access.log +} + +. "$TEST_DIRECTORY"/t556x_common + +cat >exp <<EOF + +### refs/heads/master +### +GET /smart/repo.git/refs/heads/master HTTP/1.1 404 - + +### getanyfile default +### +GET /smart/repo.git/HEAD HTTP/1.1 200 +GET /smart/repo.git/info/refs HTTP/1.1 200 +GET /smart/repo.git/objects/info/packs HTTP/1.1 200 +GET /smart/repo.git/objects/info/alternates HTTP/1.1 200 - +GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 200 - +GET /smart/repo.git/$LOOSE_URL HTTP/1.1 200 +GET /smart/repo.git/$PACK_URL HTTP/1.1 200 +GET /smart/repo.git/$IDX_URL HTTP/1.1 200 + +### no git-daemon-export-ok +### +GET /smart_noexport/repo.git/HEAD HTTP/1.1 404 - +GET /smart_noexport/repo.git/info/refs HTTP/1.1 404 - +GET /smart_noexport/repo.git/objects/info/packs HTTP/1.1 404 - +GET /smart_noexport/repo.git/objects/info/alternates HTTP/1.1 404 - +GET /smart_noexport/repo.git/objects/info/http-alternates HTTP/1.1 404 - +GET /smart_noexport/repo.git/$LOOSE_URL HTTP/1.1 404 - +GET /smart_noexport/repo.git/$PACK_URL HTTP/1.1 404 - +GET /smart_noexport/repo.git/$IDX_URL HTTP/1.1 404 - + +### git-daemon-export-ok +### +GET /smart_noexport/repo.git/HEAD HTTP/1.1 200 +GET /smart_noexport/repo.git/info/refs HTTP/1.1 200 +GET /smart_noexport/repo.git/objects/info/packs HTTP/1.1 200 +GET /smart_noexport/repo.git/objects/info/alternates HTTP/1.1 200 - +GET /smart_noexport/repo.git/objects/info/http-alternates HTTP/1.1 200 - +GET /smart_noexport/repo.git/$LOOSE_URL HTTP/1.1 200 +GET /smart_noexport/repo.git/$PACK_URL HTTP/1.1 200 +GET /smart_noexport/repo.git/$IDX_URL HTTP/1.1 200 + +### getanyfile true +### +GET /smart/repo.git/HEAD HTTP/1.1 200 +GET /smart/repo.git/info/refs HTTP/1.1 200 +GET /smart/repo.git/objects/info/packs HTTP/1.1 200 +GET /smart/repo.git/objects/info/alternates HTTP/1.1 200 - +GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 200 - +GET /smart/repo.git/$LOOSE_URL HTTP/1.1 200 +GET /smart/repo.git/$PACK_URL HTTP/1.1 200 +GET /smart/repo.git/$IDX_URL HTTP/1.1 200 + +### getanyfile false +### +GET /smart/repo.git/HEAD HTTP/1.1 403 - +GET /smart/repo.git/info/refs HTTP/1.1 403 - +GET /smart/repo.git/objects/info/packs HTTP/1.1 403 - +GET /smart/repo.git/objects/info/alternates HTTP/1.1 403 - +GET /smart/repo.git/objects/info/http-alternates HTTP/1.1 403 - +GET /smart/repo.git/$LOOSE_URL HTTP/1.1 403 - +GET /smart/repo.git/$PACK_URL HTTP/1.1 403 - +GET /smart/repo.git/$IDX_URL HTTP/1.1 403 - + +### uploadpack default +### +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 - + +### uploadpack true +### +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 - + +### uploadpack false +### +GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1 403 - +POST /smart/repo.git/git-upload-pack HTTP/1.1 403 - + +### receivepack default +### +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 - + +### receivepack true +### +GET /smart/repo.git/info/refs?service=git-receive-pack HTTP/1.1 200 +POST /smart/repo.git/git-receive-pack HTTP/1.1 200 - + +### receivepack false +### +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 +' + +stop_httpd +test_done diff --git a/t/t556x_common b/t/t556x_common new file mode 100755 index 0000000000..be024e551c --- /dev/null +++ b/t/t556x_common @@ -0,0 +1,122 @@ +#!/bin/sh + +find_file() { + cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + find $1 -type f | + sed -e 1q +} + +config() { + git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" config $1 $2 +} + +test_expect_success 'setup repository' ' + echo content >file && + git add file && + git commit -m one && + + mkdir "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git --bare init && + : >objects/info/alternates && + : >objects/info/http-alternates + ) && + git remote add public "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git push public master:master && + + (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git repack -a -d + ) && + + echo other >file && + git add file && + git commit -m two && + git push public master:master && + + LOOSE_URL=$(find_file objects/??) && + PACK_URL=$(find_file objects/pack/*.pack) && + IDX_URL=$(find_file objects/pack/*.idx) +' + +get_static_files() { + GET HEAD "$1" && + GET info/refs "$1" && + GET objects/info/packs "$1" && + GET objects/info/alternates "$1" && + GET objects/info/http-alternates "$1" && + GET $LOOSE_URL "$1" && + GET $PACK_URL "$1" && + GET $IDX_URL "$1" +} + +SMART=smart +export GIT_HTTP_EXPORT_ALL=1 +test_expect_success 'direct refs/heads/master not found' ' + log_div "refs/heads/master" + GET refs/heads/master "404 Not Found" +' +test_expect_success 'static file is ok' ' + log_div "getanyfile default" + get_static_files "200 OK" +' +SMART=smart_noexport +unset GIT_HTTP_EXPORT_ALL +test_expect_success 'no export by default' ' + log_div "no git-daemon-export-ok" + get_static_files "404 Not Found" +' +test_expect_success 'export if git-daemon-export-ok' ' + log_div "git-daemon-export-ok" + (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + touch git-daemon-export-ok + ) && + get_static_files "200 OK" +' +SMART=smart +export GIT_HTTP_EXPORT_ALL=1 +test_expect_success 'static file if http.getanyfile true is ok' ' + log_div "getanyfile true" + config http.getanyfile true && + get_static_files "200 OK" +' +test_expect_success 'static file if http.getanyfile false fails' ' + log_div "getanyfile false" + config http.getanyfile false && + get_static_files "403 Forbidden" +' + +test_expect_success 'http.uploadpack default enabled' ' + log_div "uploadpack default" + GET info/refs?service=git-upload-pack "200 OK" && + POST git-upload-pack 0000 "200 OK" +' +test_expect_success 'http.uploadpack true' ' + log_div "uploadpack true" + config http.uploadpack true && + GET info/refs?service=git-upload-pack "200 OK" && + POST git-upload-pack 0000 "200 OK" +' +test_expect_success 'http.uploadpack false' ' + log_div "uploadpack false" + config http.uploadpack false && + GET info/refs?service=git-upload-pack "403 Forbidden" && + POST git-upload-pack 0000 "403 Forbidden" +' + +test_expect_success 'http.receivepack default disabled' ' + log_div "receivepack default" + GET info/refs?service=git-receive-pack "403 Forbidden" && + POST git-receive-pack 0000 "403 Forbidden" +' +test_expect_success 'http.receivepack true' ' + log_div "receivepack true" + config http.receivepack true && + GET info/refs?service=git-receive-pack "200 OK" && + POST git-receive-pack 0000 "200 OK" +' +test_expect_success 'http.receivepack false' ' + log_div "receivepack false" + config http.receivepack false && + GET info/refs?service=git-receive-pack "403 Forbidden" && + POST git-receive-pack 0000 "403 Forbidden" +' diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh index 19b5c0d552..8b4c356cd2 100755 --- a/t/t5701-clone-local.sh +++ b/t/t5701-clone-local.sh @@ -119,7 +119,9 @@ test_expect_success 'bundle clone with nonexistent HEAD' ' test_expect_success 'clone empty repository' ' cd "$D" && mkdir empty && - (cd empty && git init) && + (cd empty && + git init && + git config receive.denyCurrentBranch warn) && git clone empty empty-clone && test_tick && (cd empty-clone diff --git a/t/t5702-clone-options.sh b/t/t5702-clone-options.sh index 27825f5f31..02cb024723 100755 --- a/t/t5702-clone-options.sh +++ b/t/t5702-clone-options.sh @@ -27,7 +27,8 @@ test_expect_success 'redirected clone' ' ' test_expect_success 'redirected clone -v' ' - git clone -v "file://$(pwd)/parent" clone-redirected-v >out 2>err && + git clone --progress "file://$(pwd)/parent" clone-redirected-progress \ + >out 2>err && test -s err ' diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 571931588e..d24ca5c077 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -19,6 +19,13 @@ test_cmp expect.$1 output.$1 " } +test_format percent %%h <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +%h +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +%h +EOF + test_format hash %H%n%h <<'EOF' commit 131a310eb913d107dd3c09a65d1651175898735d 131a310eb913d107dd3c09a65d1651175898735d @@ -202,4 +209,13 @@ test_expect_success '%gd shortens ref name' ' test_cmp expect.gd-short actual.gd-short ' +test_expect_success 'oneline with empty message' ' + git commit -m "dummy" --allow-empty && + git commit -m "dummy" --allow-empty && + git filter-branch --msg-filter "sed -e s/dummy//" HEAD^^.. && + git rev-list --oneline HEAD > /tmp/test.txt && + test $(git rev-list --oneline HEAD | wc -l) -eq 5 && + test $(git rev-list --oneline --graph HEAD | wc -l) -eq 5 +' + test_done diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh index 510bb9679f..af34a1e817 100755 --- a/t/t6012-rev-list-simplify.sh +++ b/t/t6012-rev-list-simplify.sh @@ -8,9 +8,6 @@ note () { git tag "$1" } -_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' -_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" - unnote () { git name-rev --tags --stdin | sed -e "s|$_x40 (tags/\([^)]*\)) |\1 |g" } diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh new file mode 100755 index 0000000000..8d3fa7d014 --- /dev/null +++ b/t/t6018-rev-list-glob.sh @@ -0,0 +1,195 @@ +#!/bin/sh + +test_description='rev-list/rev-parse --glob' + +. ./test-lib.sh + +commit () { + test_tick && + echo $1 > foo && + git add foo && + git commit -m "$1" +} + +compare () { + # Split arguments on whitespace. + git $1 $2 >expected && + git $1 $3 >actual && + test_cmp expected actual +} + +test_expect_success 'setup' ' + + commit master && + git checkout -b subspace/one master && + commit one && + git checkout -b subspace/two master && + commit two && + git checkout -b subspace-x master && + commit subspace-x && + git checkout -b other/three master && + commit three && + git checkout -b someref master && + commit some && + git checkout master && + commit master2 && + git tag foo/bar master && + git update-ref refs/remotes/foo/baz master +' + +test_expect_success 'rev-parse --glob=refs/heads/subspace/*' ' + + compare rev-parse "subspace/one subspace/two" "--glob=refs/heads/subspace/*" + +' + +test_expect_success 'rev-parse --glob=heads/subspace/*' ' + + compare rev-parse "subspace/one subspace/two" "--glob=heads/subspace/*" + +' + +test_expect_success 'rev-parse --glob=refs/heads/subspace/' ' + + compare rev-parse "subspace/one subspace/two" "--glob=refs/heads/subspace/" + +' + +test_expect_success 'rev-parse --glob=heads/subspace/' ' + + compare rev-parse "subspace/one subspace/two" "--glob=heads/subspace/" + +' + +test_expect_success 'rev-parse --glob=heads/subspace' ' + + compare rev-parse "subspace/one subspace/two" "--glob=heads/subspace" + +' + +test_expect_success 'rev-parse --branches=subspace/*' ' + + compare rev-parse "subspace/one subspace/two" "--branches=subspace/*" + +' + +test_expect_success 'rev-parse --branches=subspace/' ' + + compare rev-parse "subspace/one subspace/two" "--branches=subspace/" + +' + +test_expect_success 'rev-parse --branches=subspace' ' + + compare rev-parse "subspace/one subspace/two" "--branches=subspace" + +' + +test_expect_success 'rev-parse --glob=heads/subspace/* --glob=heads/other/*' ' + + compare rev-parse "subspace/one subspace/two other/three" "--glob=heads/subspace/* --glob=heads/other/*" + +' + +test_expect_success 'rev-parse --glob=heads/someref/* master' ' + + compare rev-parse "master" "--glob=heads/someref/* master" + +' + +test_expect_success 'rev-parse --glob=heads/*' ' + + compare rev-parse "master other/three someref subspace-x subspace/one subspace/two" "--glob=heads/*" + +' + +test_expect_success 'rev-parse --tags=foo' ' + + compare rev-parse "foo/bar" "--tags=foo" + +' + +test_expect_success 'rev-parse --remotes=foo' ' + + compare rev-parse "foo/baz" "--remotes=foo" + +' + +test_expect_success 'rev-list --glob=refs/heads/subspace/*' ' + + compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*" + +' + +test_expect_success 'rev-list --glob=heads/subspace/*' ' + + compare rev-list "subspace/one subspace/two" "--glob=heads/subspace/*" + +' + +test_expect_success 'rev-list --glob=refs/heads/subspace/' ' + + compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/" + +' + +test_expect_success 'rev-list --glob=heads/subspace/' ' + + compare rev-list "subspace/one subspace/two" "--glob=heads/subspace/" + +' + +test_expect_success 'rev-list --glob=heads/subspace' ' + + compare rev-list "subspace/one subspace/two" "--glob=heads/subspace" + +' + +test_expect_success 'rev-list --branches=subspace/*' ' + + compare rev-list "subspace/one subspace/two" "--branches=subspace/*" + +' + +test_expect_success 'rev-list --branches=subspace/' ' + + compare rev-list "subspace/one subspace/two" "--branches=subspace/" + +' + +test_expect_success 'rev-list --branches=subspace' ' + + compare rev-list "subspace/one subspace/two" "--branches=subspace" + +' +test_expect_success 'rev-list --glob=heads/someref/* master' ' + + compare rev-list "master" "--glob=heads/someref/* master" + +' + +test_expect_success 'rev-list --glob=heads/subspace/* --glob=heads/other/*' ' + + compare rev-list "subspace/one subspace/two other/three" "--glob=heads/subspace/* --glob=heads/other/*" + +' + +test_expect_success 'rev-list --glob=heads/*' ' + + compare rev-list "master other/three someref subspace-x subspace/one subspace/two" "--glob=heads/*" + +' + +test_expect_success 'rev-list --tags=foo' ' + + compare rev-list "foo/bar" "--tags=foo" + +' + +test_expect_success 'rev-list --remotes=foo' ' + + compare rev-list "foo/baz" "--remotes=foo" + +' + +test_done diff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh index 7dcf391914..6291307cd0 100755 --- a/t/t6023-merge-file.sh +++ b/t/t6023-merge-file.sh @@ -146,8 +146,8 @@ test_expect_success 'binary files cannot be merged' ' grep "Cannot merge binary files" merge.err ' -sed -e "s/deerit.$/deerit;/" -e "s/me;$/me./" < new5.txt > new6.txt -sed -e "s/deerit.$/deerit,/" -e "s/me;$/me,/" < new5.txt > new7.txt +sed -e "s/deerit.\$/deerit;/" -e "s/me;\$/me./" < new5.txt > new6.txt +sed -e "s/deerit.\$/deerit,/" -e "s/me;\$/me,/" < new5.txt > new7.txt test_expect_success 'MERGE_ZEALOUS simplifies non-conflicts' ' diff --git a/t/t6026-merge-attr.sh b/t/t6026-merge-attr.sh index 1ba0a25223..5e439972be 100755 --- a/t/t6026-merge-attr.sh +++ b/t/t6026-merge-attr.sh @@ -70,6 +70,18 @@ test_expect_success 'check merge result in working tree' ' ' +test_expect_success 'retry the merge with longer context' ' + echo text conflict-marker-size=32 >>.gitattributes && + git checkout -m text && + sed -ne "/^\([<=>]\)\1\1\1*/{ + s/ .*$// + p + }" >actual text && + grep ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" actual && + grep "================================" actual && + grep "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" actual +' + cat >./custom-merge <<\EOF #!/bin/sh diff --git a/t/t6029-merge-subtree.sh b/t/t6029-merge-subtree.sh index 5bbfa44e8d..3900d9f61f 100755 --- a/t/t6029-merge-subtree.sh +++ b/t/t6029-merge-subtree.sh @@ -52,6 +52,7 @@ test_expect_success 'initial merge' ' git merge -s ours --no-commit gui/master && git read-tree --prefix=git-gui/ -u gui/master && git commit -m "Merge git-gui as our subdirectory" && + git checkout -b work && git ls-files -s >actual && ( echo "100644 $o1 0 git-gui/git-gui.sh" @@ -65,9 +66,10 @@ test_expect_success 'merge update' ' echo git-gui2 > git-gui.sh && o3=$(git hash-object git-gui.sh) && git add git-gui.sh && + git checkout -b master2 && git commit -m "update git-gui" && cd ../git && - git pull -s subtree gui master && + git pull -s subtree gui master2 && git ls-files -s >actual && ( echo "100644 $o3 0 git-gui/git-gui.sh" @@ -76,4 +78,47 @@ test_expect_success 'merge update' ' test_cmp expected actual ' +test_expect_success 'initial ambiguous subtree' ' + cd ../git && + git reset --hard master && + git checkout -b master2 && + git merge -s ours --no-commit gui/master && + git read-tree --prefix=git-gui2/ -u gui/master && + git commit -m "Merge git-gui2 as our subdirectory" && + 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 $o2 0 git.c" + ) >expected && + test_cmp expected actual +' + +test_expect_success 'merge using explicit' ' + cd ../git && + git reset --hard master2 && + 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 $o2 0 git.c" + ) >expected && + test_cmp expected actual +' + +test_expect_success 'merge2 using explicit' ' + cd ../git && + git reset --hard master2 && + 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 $o2 0 git.c" + ) >expected && + test_cmp expected actual +' + test_done diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index dc9e8d030a..3b042aacd6 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -423,7 +423,7 @@ test_expect_success 'skipped merge base when good and bad are siblings' ' grep "merge base must be tested" my_bisect_log.txt && grep $HASH4 my_bisect_log.txt && git bisect skip > my_bisect_log.txt 2>&1 && - grep "Warning" my_bisect_log.txt && + grep "warning" my_bisect_log.txt && grep $SIDE_HASH6 my_bisect_log.txt && git bisect reset ' diff --git a/t/t6033-merge-crlf.sh b/t/t6033-merge-crlf.sh index 75d9602de4..e8d65eefb5 100755 --- a/t/t6033-merge-crlf.sh +++ b/t/t6033-merge-crlf.sh @@ -1,13 +1,5 @@ #!/bin/sh -append_cr () { - sed -e 's/$/Q/' | tr Q '\015' -} - -remove_cr () { - tr '\015' Q | sed -e 's/Q$//' -} - test_description='merge conflict in crlf repo b---M diff --git a/t/t6035-merge-dir-to-symlink.sh b/t/t6035-merge-dir-to-symlink.sh index 5b96fb0b37..3202e1de6d 100755 --- a/t/t6035-merge-dir-to-symlink.sh +++ b/t/t6035-merge-dir-to-symlink.sh @@ -74,7 +74,7 @@ test_expect_success 'setup a merge where dir a/b-2 changed to symlink' ' git tag test2 ' -test_expect_failure 'merge should not have conflicts (resolve)' ' +test_expect_success 'merge should not have conflicts (resolve)' ' git reset --hard && git checkout baseline^0 && git merge -s resolve test2 && diff --git a/t/t6037-merge-ours-theirs.sh b/t/t6037-merge-ours-theirs.sh new file mode 100755 index 0000000000..8ab3d61f44 --- /dev/null +++ b/t/t6037-merge-ours-theirs.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +test_description='Merge-recursive ours and theirs variants' +. ./test-lib.sh + +test_expect_success setup ' + for i in 1 2 3 4 5 6 7 8 9 + do + echo "$i" + done >file && + git add file && + cp file elif && + git commit -m initial && + + sed -e "s/1/one/" -e "s/9/nine/" >file <elif && + git commit -a -m ours && + + git checkout -b side HEAD^ && + + sed -e "s/9/nueve/" >file <elif && + git commit -a -m theirs && + + git checkout master^0 +' + +test_expect_success 'plain recursive - should conflict' ' + git reset --hard master && + test_must_fail git merge -s recursive side && + grep nine file && + grep nueve file && + ! grep 9 file && + grep one file && + ! grep 1 file +' + +test_expect_success 'recursive favouring theirs' ' + git reset --hard master && + git merge -s recursive -Xtheirs side && + ! grep nine file && + grep nueve file && + ! grep 9 file && + grep one file && + ! grep 1 file +' + +test_expect_success 'recursive favouring ours' ' + git reset --hard master && + git merge -s recursive -X ours side && + grep nine file && + ! grep nueve file && + ! grep 9 file && + grep one file && + ! grep 1 file +' + +test_expect_success 'pull with -X' ' + git reset --hard master && git pull -s recursive -Xours . side && + git reset --hard master && git pull -s recursive -X ours . side && + git reset --hard master && git pull -s recursive -Xtheirs . side && + git reset --hard master && git pull -s recursive -X theirs . side && + git reset --hard master && ! git pull -s recursive -X bork . side +' + +test_done diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh index 00e1de9627..1785e178a4 100755 --- a/t/t6040-tracking-info.sh +++ b/t/t6040-tracking-info.sh @@ -69,7 +69,7 @@ test_expect_success 'status' ' cd test && git checkout b1 >/dev/null && # reports nothing to commit - test_must_fail git status + test_must_fail git commit --dry-run ) >actual && grep "have 1 and 1 different" actual ' @@ -89,4 +89,25 @@ test_expect_success 'status when tracking annotated tags' ' grep "set up to track" actual && git checkout heavytrack ' + +test_expect_success 'setup tracking with branch --set-upstream on existing branch' ' + git branch from-master master && + test_must_fail git config branch.from-master.merge > actual && + git branch --set-upstream from-master master && + git config branch.from-master.merge > actual && + grep -q "^refs/heads/master$" actual +' + +test_expect_success '--set-upstream does not change branch' ' + git branch from-master2 master && + test_must_fail git config branch.from-master2.merge > actual && + git rev-list from-master2 && + git update-ref refs/heads/from-master2 from-master2^ && + git rev-parse from-master2 >expect2 && + git branch --set-upstream from-master2 master && + git config branch.from-master.merge > actual && + git rev-parse from-master2 >actual2 && + grep -q "^refs/heads/master$" actual && + cmp expect2 actual2 +' test_done diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 10b8f8c44b..65a35d94a0 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -189,6 +189,18 @@ test_expect_success 'absolute pathname outside should fail' '( )' +test_expect_success 'git mv to move multiple sources into a directory' ' + rm -fr .git && git init && + mkdir dir other && + >dir/a.txt && + >dir/b.txt && + git add dir/?.txt && + git mv dir/a.txt dir/b.txt other && + git ls-files >actual && + { echo other/a.txt; echo other/b.txt; } >expect && + test_cmp expect actual +' + test_expect_success 'git mv should not change sha1 of moved cache entry' ' rm -fr .git && diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh index abd14bf819..af63d6ec6d 100755 --- a/t/t7002-grep.sh +++ b/t/t7002-grep.sh @@ -291,6 +291,14 @@ y:y yy z:zzz EOF +test_expect_success 'grep -q, silently report matches' ' + >empty && + git grep -q mmap >actual && + test_cmp empty actual && + test_must_fail git grep -q qfwfq >actual && + test_cmp empty actual +' + # Create 1024 file names that sort between "y" and "z" to make sure # the two files are handled by different calls to an external grep. # This depends on MAXARGS in builtin-grep.c being 1024 or less. @@ -302,8 +310,8 @@ test_expect_success 'grep -C1, hunk mark between files' ' test_cmp expected actual ' -test_expect_success 'grep -C1 --no-ext-grep, hunk mark between files' ' - git grep -C1 --no-ext-grep "^[yz]" >actual && +test_expect_success 'grep -C1 hunk mark between files' ' + git grep -C1 "^[yz]" >actual && test_cmp expected actual ' @@ -345,7 +353,7 @@ test_expect_success 'log grep (4)' ' ' test_expect_success 'log grep (5)' ' - git log --author=Thor -F --grep=Thu --pretty=tformat:%s >actual && + git log --author=Thor -F --pretty=tformat:%s >actual && ( echo third ; echo initial ) >expect && test_cmp expect actual ' @@ -356,10 +364,18 @@ test_expect_success 'log grep (6)' ' test_cmp expect actual ' +test_expect_success 'log --grep --author implicitly uses all-match' ' + # grep matches initial and second but not third + # author matches only initial and third + git log --author="A U Thor" --grep=s --grep=l --format=%s >actual && + echo initial >expect && + test_cmp expect actual +' + test_expect_success 'grep with CE_VALID file' ' git update-index --assume-unchanged t/t && rm t/t && - test "$(git grep --no-ext-grep test)" = "t/t:test" && + test "$(git grep test)" = "t/t:test" && git update-index --no-assume-unchanged t/t && git checkout t/t ' @@ -426,4 +442,37 @@ test_expect_success 'grep -Fi' ' test_cmp expected actual ' +test_expect_success 'setup double-dash tests' ' +cat >double-dash <<EOF && +-- +-> +other +EOF +git add double-dash +' + +cat >expected <<EOF +double-dash:-> +EOF +test_expect_success 'grep -- pattern' ' + git grep -- "->" >actual && + test_cmp expected actual +' +test_expect_success 'grep -- pattern -- pathspec' ' + git grep -- "->" -- double-dash >actual && + test_cmp expected actual +' +test_expect_success 'grep -e pattern -- path' ' + git grep -e "->" -- double-dash >actual && + test_cmp expected actual +' + +cat >expected <<EOF +double-dash:-- +EOF +test_expect_success 'grep -e -- -- path' ' + git grep -e -- -- double-dash >actual && + test_cmp expected actual +' + test_done diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 9503875e97..0da13a8d6b 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -306,4 +306,43 @@ test_expect_success '--remap-to-ancestor with filename filters' ' test $orig_invariant = $(git rev-parse invariant) ' +test_expect_success 'setup submodule' ' + rm -fr ?* .git && + git init && + test_commit file && + mkdir submod && + submodurl="$PWD/submod" && + ( cd submod && + git init && + test_commit file-in-submod ) && + git submodule add "$submodurl" && + git commit -m "added submodule" && + test_commit add-file && + ( cd submod && test_commit add-in-submodule ) && + git add submod && + git commit -m "changed submodule" && + git branch original HEAD +' + +orig_head=`git show-ref --hash --head HEAD` + +test_expect_success 'rewrite submodule with another content' ' + git filter-branch --tree-filter "test -d submod && { + rm -rf submod && + git rm -rf --quiet submod && + mkdir submod && + : > submod/file + } || :" HEAD && + test $orig_head != `git show-ref --hash --head HEAD` +' + +test_expect_success 'replace submodule revision' ' + git reset --hard original && + git filter-branch -f --tree-filter \ + "if git ls-files --error-unmatch -- submod > /dev/null 2>&1 + then git update-index --cacheinfo 160000 0123456789012345678901234567890123456789 submod + fi" HEAD && + test $orig_head != `git show-ref --hash --head HEAD` +' + test_done diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh new file mode 100755 index 0000000000..d9202d5af5 --- /dev/null +++ b/t/t7006-pager.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +test_description='Test automatic use of a pager.' + +. ./test-lib.sh + +rm -f stdout_is_tty +test_expect_success 'set up terminal for tests' ' + if test -t 1 + then + : > stdout_is_tty + elif + test_have_prereq PERL && + "$PERL_PATH" "$TEST_DIRECTORY"/t7006/test-terminal.perl \ + sh -c "test -t 1" + then + : > test_terminal_works + fi +' + +if test -e stdout_is_tty +then + test_terminal() { "$@"; } + test_set_prereq TTY +elif test -e test_terminal_works +then + test_terminal() { + "$PERL_PATH" "$TEST_DIRECTORY"/t7006/test-terminal.perl "$@" + } + test_set_prereq TTY +else + say no usable terminal, so skipping some tests +fi + +unset GIT_PAGER GIT_PAGER_IN_USE +git config --unset core.pager +PAGER='cat > paginated.out' +export PAGER + +test_expect_success 'setup' ' + test_commit initial +' + +rm -f paginated.out +test_expect_success TTY 'some commands use a pager' ' + test_terminal git log && + test -e paginated.out +' + +rm -f paginated.out +test_expect_success TTY 'some commands do not use a pager' ' + test_terminal git rev-list HEAD && + ! test -e paginated.out +' + +rm -f paginated.out +test_expect_success 'no pager when stdout is a pipe' ' + git log | cat && + ! test -e paginated.out +' + +rm -f paginated.out +test_expect_success 'no pager when stdout is a regular file' ' + git log > file && + ! test -e paginated.out +' + +rm -f paginated.out +test_expect_success TTY 'git --paginate rev-list uses a pager' ' + test_terminal git --paginate rev-list HEAD && + test -e paginated.out +' + +rm -f file paginated.out +test_expect_success 'no pager even with --paginate when stdout is a pipe' ' + git --paginate log | cat && + ! test -e paginated.out +' + +rm -f paginated.out +test_expect_success TTY 'no pager with --no-pager' ' + test_terminal git --no-pager log && + ! test -e paginated.out +' + +# A colored commit log will begin with an appropriate ANSI escape +# for the first color; the text "commit" comes later. +colorful() { + read firstline < $1 + ! expr "$firstline" : "^[a-zA-Z]" >/dev/null +} + +rm -f colorful.log colorless.log +test_expect_success 'tests can detect color' ' + git log --no-color > colorless.log && + git log --color > colorful.log && + ! colorful colorless.log && + colorful colorful.log +' + +rm -f colorless.log +git config color.ui auto +test_expect_success 'no color when stdout is a regular file' ' + git log > colorless.log && + ! colorful colorless.log +' + +rm -f paginated.out +git config color.ui auto +test_expect_success TTY 'color when writing to a pager' ' + TERM=vt100 test_terminal git log && + colorful paginated.out +' + +rm -f colorful.log +git config color.ui auto +test_expect_success 'color when writing to a file intended for a pager' ' + TERM=vt100 GIT_PAGER_IN_USE=true git log > colorful.log && + colorful colorful.log +' + +unset PAGER GIT_PAGER +git config --unset core.pager +test_expect_success 'determine default pager' ' + less=$(git var GIT_PAGER) && + test -n "$less" +' + +if expr "$less" : '^[a-z]*$' > /dev/null && test_have_prereq TTY +then + test_set_prereq SIMPLEPAGER +fi + +unset PAGER GIT_PAGER +git config --unset core.pager +rm -f default_pager_used +test_expect_success SIMPLEPAGER 'default pager is used by default' ' + cat > $less <<-EOF && + #!$SHELL_PATH + wc > default_pager_used + EOF + chmod +x $less && + PATH=.:$PATH test_terminal git log && + test -e default_pager_used +' + +unset GIT_PAGER +git config --unset core.pager +rm -f PAGER_used +test_expect_success TTY 'PAGER overrides default pager' ' + PAGER="wc > PAGER_used" && + export PAGER && + test_terminal git log && + test -e PAGER_used +' + +unset GIT_PAGER +rm -f core.pager_used +test_expect_success TTY 'core.pager overrides PAGER' ' + PAGER=wc && + export PAGER && + git config core.pager "wc > core.pager_used" && + test_terminal git log && + test -e core.pager_used +' + +rm -f GIT_PAGER_used +test_expect_success TTY 'GIT_PAGER overrides core.pager' ' + git config core.pager wc && + GIT_PAGER="wc > GIT_PAGER_used" && + export GIT_PAGER && + test_terminal git log && + test -e GIT_PAGER_used +' + +test_done diff --git a/t/t7006/test-terminal.perl b/t/t7006/test-terminal.perl new file mode 100755 index 0000000000..73ff809371 --- /dev/null +++ b/t/t7006/test-terminal.perl @@ -0,0 +1,58 @@ +#!/usr/bin/perl +use strict; +use warnings; +use IO::Pty; +use File::Copy; + +# Run @$argv in the background with stdout redirected to $out. +sub start_child { + my ($argv, $out) = @_; + my $pid = fork; + if (not defined $pid) { + die "fork failed: $!" + } elsif ($pid == 0) { + open STDOUT, ">&", $out; + close $out; + exec(@$argv) or die "cannot exec '$argv->[0]': $!" + } + return $pid; +} + +# Wait for $pid to finish. +sub finish_child { + # Simplified from wait_or_whine() in run-command.c. + my ($pid) = @_; + + my $waiting = waitpid($pid, 0); + if ($waiting < 0) { + die "waitpid failed: $!"; + } elsif ($? & 127) { + my $code = $? & 127; + warn "died of signal $code"; + return $code - 128; + } else { + return $? >> 8; + } +} + +sub xsendfile { + my ($out, $in) = @_; + + # Note: the real sendfile() cannot read from a terminal. + + # It is unspecified by POSIX whether reads + # from a disconnected terminal will return + # EIO (as in AIX 4.x, IRIX, and Linux) or + # end-of-file. Either is fine. + copy($in, $out, 4096) or $!{EIO} or die "cannot copy from child: $!"; +} + +if ($#ARGV < 1) { + die "usage: test-terminal program args"; +} +my $master = new IO::Pty; +my $slave = $master->slave; +my $pid = start_child(\@ARGV, $slave); +close $slave; +xsendfile(\*STDOUT, $master); +exit(finish_child($pid)); diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh new file mode 100755 index 0000000000..bb4066f767 --- /dev/null +++ b/t/t7011-skip-worktree-reading.sh @@ -0,0 +1,163 @@ +#!/bin/sh +# +# Copyright (c) 2008 Nguyễn Thái Ngọc Duy +# + +test_description='skip-worktree bit test' + +. ./test-lib.sh + +cat >expect.full <<EOF +H 1 +H 2 +H init.t +H sub/1 +H sub/2 +EOF + +cat >expect.skip <<EOF +S 1 +H 2 +H init.t +S sub/1 +H sub/2 +EOF + +NULL_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 +ZERO_SHA0=0000000000000000000000000000000000000000 +setup_absent() { + test -f 1 && rm 1 + git update-index --remove 1 && + git update-index --add --cacheinfo 100644 $NULL_SHA1 1 && + git update-index --skip-worktree 1 +} + +test_absent() { + echo "100644 $NULL_SHA1 0 1" > expected && + git ls-files --stage 1 > result && + test_cmp expected result && + test ! -f 1 +} + +setup_dirty() { + git update-index --force-remove 1 && + echo dirty > 1 && + git update-index --add --cacheinfo 100644 $NULL_SHA1 1 && + git update-index --skip-worktree 1 +} + +test_dirty() { + echo "100644 $NULL_SHA1 0 1" > expected && + git ls-files --stage 1 > result && + test_cmp expected result && + echo dirty > expected + test_cmp expected 1 +} + +test_expect_success 'setup' ' + test_commit init && + mkdir sub && + touch ./1 ./2 sub/1 sub/2 && + git add 1 2 sub/1 sub/2 && + git update-index --skip-worktree 1 sub/1 && + git ls-files -t > result && + test_cmp expect.skip result +' + +test_expect_success 'update-index' ' + setup_absent && + git update-index 1 && + test_absent +' + +test_expect_success 'update-index' ' + setup_dirty && + git update-index 1 && + test_dirty +' + +test_expect_success 'update-index --remove' ' + setup_absent && + git update-index --remove 1 && + test -z "$(git ls-files 1)" && + test ! -f 1 +' + +test_expect_success 'update-index --remove' ' + setup_dirty && + git update-index --remove 1 && + test -z "$(git ls-files 1)" && + echo dirty > expected && + test_cmp expected 1 +' + +test_expect_success 'ls-files --delete' ' + setup_absent && + test -z "$(git ls-files -d)" +' + +test_expect_success 'ls-files --delete' ' + setup_dirty && + test -z "$(git ls-files -d)" +' + +test_expect_success 'ls-files --modified' ' + setup_absent && + test -z "$(git ls-files -m)" +' + +test_expect_success 'ls-files --modified' ' + setup_dirty && + test -z "$(git ls-files -m)" +' + +test_expect_success 'grep with skip-worktree file' ' + git update-index --no-skip-worktree 1 && + echo test > 1 && + git update-index 1 && + git update-index --skip-worktree 1 && + rm 1 && + test "$(git grep --no-ext-grep test)" = "1:test" +' + +echo ":000000 100644 $ZERO_SHA0 $NULL_SHA1 A 1" > expected +test_expect_success 'diff-index does not examine skip-worktree absent entries' ' + setup_absent && + git diff-index HEAD -- 1 > result && + test_cmp expected result +' + +test_expect_success 'diff-index does not examine skip-worktree dirty entries' ' + setup_dirty && + git diff-index HEAD -- 1 > result && + test_cmp expected result +' + +test_expect_success 'diff-files does not examine skip-worktree absent entries' ' + setup_absent && + test -z "$(git diff-files -- one)" +' + +test_expect_success 'diff-files does not examine skip-worktree dirty entries' ' + setup_dirty && + test -z "$(git diff-files -- one)" +' + +test_expect_success 'git-rm succeeds on skip-worktree absent entries' ' + setup_absent && + git rm 1 +' + +test_expect_success 'commit on skip-worktree absent entries' ' + git reset && + setup_absent && + test_must_fail git commit -m null 1 +' + +test_expect_success 'commit on skip-worktree dirty entries' ' + git reset && + setup_dirty && + test_must_fail git commit -m null 1 +' + +test_done diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh new file mode 100755 index 0000000000..8d8b1c0e25 --- /dev/null +++ b/t/t7012-skip-worktree-writing.sh @@ -0,0 +1,146 @@ +#!/bin/sh +# +# Copyright (c) 2008 Nguyễn Thái Ngọc Duy +# + +test_description='test worktree writing operations when skip-worktree is used' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit init && + echo modified >> init.t && + touch added && + git add init.t added && + git commit -m "modified and added" && + git tag top +' + +test_expect_success 'read-tree updates worktree, absent case' ' + git checkout -f top && + git update-index --skip-worktree init.t && + rm init.t && + git read-tree -m -u HEAD^ && + echo init > expected && + test_cmp expected init.t +' + +test_expect_success 'read-tree updates worktree, dirty case' ' + git checkout -f top && + git update-index --skip-worktree init.t && + echo dirty >> init.t && + test_must_fail git read-tree -m -u HEAD^ && + grep -q dirty init.t && + test "$(git ls-files -t init.t)" = "S init.t" && + git update-index --no-skip-worktree init.t +' + +test_expect_success 'read-tree removes worktree, absent case' ' + git checkout -f top && + git update-index --skip-worktree added && + rm added && + git read-tree -m -u HEAD^ && + test ! -f added +' + +test_expect_success 'read-tree removes worktree, dirty case' ' + git checkout -f top && + git update-index --skip-worktree added && + echo dirty >> added && + test_must_fail git read-tree -m -u HEAD^ && + grep -q dirty added && + test "$(git ls-files -t added)" = "S added" && + git update-index --no-skip-worktree added +' + +NULL_SHA1=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 +ZERO_SHA0=0000000000000000000000000000000000000000 +setup_absent() { + test -f 1 && rm 1 + git update-index --remove 1 && + git update-index --add --cacheinfo 100644 $NULL_SHA1 1 && + git update-index --skip-worktree 1 +} + +test_absent() { + echo "100644 $NULL_SHA1 0 1" > expected && + git ls-files --stage 1 > result && + test_cmp expected result && + test ! -f 1 +} + +setup_dirty() { + git update-index --force-remove 1 && + echo dirty > 1 && + git update-index --add --cacheinfo 100644 $NULL_SHA1 1 && + git update-index --skip-worktree 1 +} + +test_dirty() { + echo "100644 $NULL_SHA1 0 1" > expected && + git ls-files --stage 1 > result && + test_cmp expected result && + echo dirty > expected + test_cmp expected 1 +} + +cat >expected <<EOF +S 1 +H 2 +H init.t +S sub/1 +H sub/2 +EOF + +test_expect_success 'index setup' ' + git checkout -f init && + mkdir sub && + touch ./1 ./2 sub/1 sub/2 && + git add 1 2 sub/1 sub/2 && + git update-index --skip-worktree 1 sub/1 && + git ls-files -t > result && + test_cmp expected result +' + +test_expect_success 'git-add ignores worktree content' ' + setup_absent && + git add 1 && + test_absent +' + +test_expect_success 'git-add ignores worktree content' ' + setup_dirty && + git add 1 && + test_dirty +' + +test_expect_success 'git-rm fails if worktree is dirty' ' + setup_dirty && + test_must_fail git rm 1 && + test_dirty +' + +cat >expected <<EOF +Would remove expected +Would remove result +EOF +test_expect_success 'git-clean, absent case' ' + setup_absent && + git clean -n > result && + test_cmp expected result +' + +test_expect_success 'git-clean, dirty case' ' + setup_dirty && + git clean -n > result && + test_cmp expected result +' + +test_expect_failure 'git-apply adds file' false +test_expect_failure 'git-apply updates file' false +test_expect_failure 'git-apply removes file' false +test_expect_failure 'git-mv to skip-worktree' false +test_expect_failure 'git-mv from skip-worktree' false +test_expect_failure 'git-checkout' false + +test_done diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh index 1044aa6549..fcac472598 100755 --- a/t/t7060-wtstatus.sh +++ b/t/t7060-wtstatus.sh @@ -31,8 +31,7 @@ test_expect_success 'Report new path with conflict' ' cat >expect <<EOF # On branch side # Unmerged paths: -# (use "git reset HEAD <file>..." to unstage) -# (use "git add <file>..." to mark resolution) +# (use "git add/rm <file>..." as appropriate to mark resolution) # # deleted by us: foo # @@ -50,9 +49,11 @@ test_expect_success 'M/D conflict does not segfault' ' git rm foo && git commit -m delete && test_must_fail git merge master && - test_must_fail git status > ../actual - ) && - test_cmp expect actual + test_must_fail git commit --dry-run >../actual && + test_cmp ../expect ../actual && + git status >../actual && + test_cmp ../expect ../actual + ) ' test_done diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh new file mode 100755 index 0000000000..8704d00196 --- /dev/null +++ b/t/t7110-reset-merge.sh @@ -0,0 +1,183 @@ +#!/bin/sh +# +# Copyright (c) 2009 Christian Couder +# + +test_description='Tests for "git reset --merge"' + +. ./test-lib.sh + +test_expect_success setup ' + for i in 1 2 3; do echo line $i; done >file1 && + cat file1 >file2 && + git add file1 file2 && + test_tick && + git commit -m "Initial commit" && + git tag initial && + echo line 4 >>file1 && + cat file1 >file2 && + test_tick && + git commit -m "add line 4 to file1" file1 && + git tag second +' + +# The next test will test the following: +# +# working index HEAD target working index HEAD +# ---------------------------------------------------- +# file1: C C C D --merge D D D +# file2: C D D D --merge C D D +test_expect_success 'reset --merge is ok with changes in file it does not touch' ' + git reset --merge HEAD^ && + ! grep 4 file1 && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && + test -z "$(git diff --cached)" +' + +test_expect_success 'reset --merge is ok when switching back' ' + git reset --merge second && + grep 4 file1 && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" +' + +# The next test will test the following: +# +# working index HEAD target working index HEAD +# ---------------------------------------------------- +# file1: B B C D --merge D D D +# file2: C D D D --merge C D D +test_expect_success 'reset --merge discards changes added to index (1)' ' + git reset --hard second && + cat file1 >file2 && + echo "line 5" >> file1 && + git add file1 && + git reset --merge HEAD^ && + ! grep 4 file1 && + ! grep 5 file1 && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && + test -z "$(git diff --cached)" +' + +test_expect_success 'reset --merge is ok again when switching back (1)' ' + git reset --hard initial && + echo "line 5" >> file2 && + git add file2 && + git reset --merge second && + ! grep 4 file2 && + ! grep 5 file1 && + grep 4 file1 && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" +' + +# The next test will test the following: +# +# working index HEAD target working index HEAD +# ---------------------------------------------------- +# file1: C C C D --merge D D D +# file2: C C D D --merge D D D +test_expect_success 'reset --merge discards changes added to index (2)' ' + git reset --hard second && + echo "line 4" >> file2 && + git add file2 && + git reset --merge HEAD^ && + ! grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && + test -z "$(git diff)" && + test -z "$(git diff --cached)" +' + +test_expect_success 'reset --merge is ok again when switching back (2)' ' + git reset --hard initial && + git reset --merge second && + ! grep 4 file2 && + grep 4 file1 && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" +' + +# The next test will test the following: +# +# working index HEAD target working index HEAD +# ---------------------------------------------------- +# file1: A B B C --merge (disallowed) +test_expect_success 'reset --merge fails with changes in file it touches' ' + git reset --hard second && + echo "line 5" >> file1 && + test_tick && + git commit -m "add line 5" file1 && + sed -e "s/line 1/changed line 1/" <file1 >file3 && + mv file3 file1 && + test_must_fail git reset --merge HEAD^ 2>err.log && + grep file1 err.log | grep "not uptodate" +' + +test_expect_success 'setup 3 different branches' ' + git reset --hard second && + git branch branch1 && + git branch branch2 && + git branch branch3 && + git checkout branch1 && + echo "line 5 in branch1" >> file1 && + test_tick && + git commit -a -m "change in branch1" && + git checkout branch2 && + echo "line 5 in branch2" >> file1 && + test_tick && + git commit -a -m "change in branch2" && + git tag third && + git checkout branch3 && + echo a new file >file3 && + rm -f file1 && + git add file3 && + test_tick && + git commit -a -m "change in branch3" +' + +# The next test will test the following: +# +# working index HEAD target working index HEAD +# ---------------------------------------------------- +# file1: X U B C --merge C C C +test_expect_success '"reset --merge HEAD^" is ok with pending merge' ' + git checkout third && + test_must_fail git merge branch1 && + git reset --merge HEAD^ && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" && + test -z "$(git diff)" +' + +# The next test will test the following: +# +# working index HEAD target working index HEAD +# ---------------------------------------------------- +# file1: X U B B --merge B B B +test_expect_success '"reset --merge HEAD" is ok with pending merge' ' + git reset --hard third && + test_must_fail git merge branch1 && + git reset --merge HEAD && + test "$(git rev-parse HEAD)" = "$(git rev-parse third)" && + test -z "$(git diff --cached)" && + test -z "$(git diff)" +' + +test_expect_success '--merge with added/deleted' ' + git reset --hard third && + rm -f file2 && + test_must_fail git merge branch3 && + ! test -f file2 && + test -f file3 && + git diff --exit-code file3 && + git diff --exit-code branch3 file3 && + git reset --merge HEAD && + ! test -f file3 && + ! test -f file2 && + git diff --exit-code --cached +' + +test_done diff --git a/t/t7111-reset-table.sh b/t/t7111-reset-table.sh new file mode 100755 index 0000000000..de896c948d --- /dev/null +++ b/t/t7111-reset-table.sh @@ -0,0 +1,113 @@ +#!/bin/sh +# +# Copyright (c) 2010 Christian Couder +# + +test_description='Tests to check that "reset" options follow a known table' + +. ./test-lib.sh + + +test_expect_success 'creating initial commits' ' + test_commit E file1 && + test_commit D file1 && + test_commit C file1 +' + +while read W1 I1 H1 T opt W2 I2 H2 +do + test_expect_success "check: $W1 $I1 $H1 $T --$opt $W2 $I2 $H2" ' + git reset --hard C && + if test "$I1" != "$H1" + then + echo "$I1" >file1 && + git add file1 + fi && + if test "$W1" != "$I1" + then + echo "$W1" >file1 + fi && + if test "$W2" != "XXXXX" + then + git reset --$opt $T && + test "$(cat file1)" = "$W2" && + git checkout-index -f -- file1 && + test "$(cat file1)" = "$I2" && + git checkout -f HEAD -- file1 && + test "$(cat file1)" = "$H2" + else + test_must_fail git reset --$opt $T + fi + ' +done <<\EOF +A B C D soft A B D +A B C D mixed A D D +A B C D hard D D D +A B C D merge XXXXX +A B C C soft A B C +A B C C mixed A C C +A B C C hard C C C +A B C C merge XXXXX +B B C D soft B B D +B B C D mixed B D D +B B C D hard D D D +B B C D merge D D D +B B C C soft B B C +B B C C mixed B C C +B B C C hard C C C +B B C C merge C C C +B C C D soft B C D +B C C D mixed B D D +B C C D hard D D D +B C C D merge XXXXX +B C C C soft B C C +B C C C mixed B C C +B C C C hard C C C +B C C C merge B C C +EOF + +test_expect_success 'setting up branches to test with unmerged entries' ' + git reset --hard C && + git branch branch1 && + git branch branch2 && + git checkout branch1 && + test_commit B1 file1 && + git checkout branch2 && + test_commit B file1 +' + +while read W1 I1 H1 T opt W2 I2 H2 +do + test_expect_success "check: $W1 $I1 $H1 $T --$opt $W2 $I2 $H2" ' + git reset --hard B && + test_must_fail git merge branch1 && + cat file1 >X_file1 && + if test "$W2" != "XXXXX" + then + git reset --$opt $T && + if test "$W2" = "X" + then + test_cmp file1 X_file1 + else + test "$(cat file1)" = "$W2" + fi && + git checkout-index -f -- file1 && + test "$(cat file1)" = "$I2" && + git checkout -f HEAD -- file1 && + test "$(cat file1)" = "$H2" + else + test_must_fail git reset --$opt $T + fi + ' +done <<\EOF +X U B C soft XXXXX +X U B C mixed X C C +X U B C hard C C C +X U B C merge C C C +X U B B soft XXXXX +X U B B mixed X B B +X U B B hard B B B +X U B B merge B B B +EOF + +test_done diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 6442f710be..d20ed61b48 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -166,19 +166,31 @@ test_expect_success 'checkout -m with merge conflict' ' ! test -s current ' -test_expect_success 'checkout to detach HEAD' ' +test_expect_success 'checkout to detach HEAD (with advice declined)' ' + git config advice.detachedHead false && git checkout -f renamer && git clean -f && git checkout renamer^ 2>messages && - (cat >messages.expect <<EOF -Note: moving to '\''renamer^'\'' which isn'\''t a local branch -If you want to create a new branch from this checkout, you may do so -(now or later) by using -b with the checkout command again. Example: - git checkout -b <new_branch_name> -HEAD is now at 7329388... Initial A one, A two -EOF -) && - test_cmp messages.expect messages && + grep "HEAD is now at 7329388" messages && + test 1 -eq $(wc -l <messages) && + H=$(git rev-parse --verify HEAD) && + M=$(git show-ref -s --verify refs/heads/master) && + test "z$H" = "z$M" && + if git symbolic-ref HEAD >/dev/null 2>&1 + then + echo "OOPS, HEAD is still symbolic???" + false + else + : happy + fi +' + +test_expect_success 'checkout to detach HEAD' ' + git config advice.detachedHead true && + git checkout -f renamer && git clean -f && + git checkout renamer^ 2>messages && + grep "HEAD is now at 7329388" messages && + test 1 -lt $(wc -l <messages) && H=$(git rev-parse --verify HEAD) && M=$(git show-ref -s --verify refs/heads/master) && test "z$H" = "z$M" && diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 118c6ebb18..7d8ed68bef 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -22,6 +22,25 @@ test_expect_success 'setup' ' ' +test_expect_success 'git clean with skip-worktree .gitignore' ' + git update-index --skip-worktree .gitignore && + rm .gitignore && + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git clean && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.out && + test ! -f src/part3.c && + test -f docs/manual.txt && + test -f obj.o && + test -f build/lib.so && + git update-index --no-skip-worktree .gitignore && + git checkout .gitignore +' + test_expect_success 'git clean' ' mkdir -p build docs && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index a0cc99ab9f..1a4dc5f893 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -299,6 +299,15 @@ test_expect_success 'ls-files gracefully handles trailing slash' ' ' +test_expect_success 'moving to a commit without submodule does not leave empty dir' ' + rm -rf init && + mkdir init && + git reset --hard && + git checkout initial && + test ! -d init && + git checkout second +' + test_expect_success 'submodule <invalid-path> warns' ' git submodule no-such-submodule 2> output.err && diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index 6cc16c39fe..d3c039f724 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -213,7 +213,7 @@ EOF test_expect_success '--for-status' " git submodule summary --for-status HEAD^ >actual && test_cmp actual - <<EOF -# Modified submodules: +# Submodule changes to be committed: # # * sm1 $head6...0000000: # diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 8e2449d244..1382a8e58a 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -28,6 +28,8 @@ test_expect_success 'setup a submodule tree' ' git commit -m upstream git clone . super && git clone super submodule && + git clone super rebasing && + git clone super merging && (cd super && git submodule add ../submodule submodule && test_tick && @@ -45,6 +47,16 @@ test_expect_success 'setup a submodule tree' ' ) && git add submodule && git commit -m "submodule update" + ) && + (cd super && + git submodule add ../rebasing rebasing && + test_tick && + git commit -m "rebasing" + ) && + (cd super && + git submodule add ../merging merging && + test_tick && + git commit -m "rebasing" ) ' @@ -177,21 +189,17 @@ test_expect_success 'submodule update - checkout in .git/config' ' test_expect_success 'submodule init picks up rebase' ' (cd super && - git config submodule.rebasing.url git://non-existing/git && - git config submodule.rebasing.path does-not-matter && - git config submodule.rebasing.update rebase && + git config -f .gitmodules submodule.rebasing.update rebase && git submodule init rebasing && - test "rebase" = $(git config submodule.rebasing.update) + test "rebase" = "$(git config submodule.rebasing.update)" ) ' test_expect_success 'submodule init picks up merge' ' (cd super && - git config submodule.merging.url git://non-existing/git && - git config submodule.merging.path does-not-matter && - git config submodule.merging.update merge && + git config -f .gitmodules submodule.merging.update merge && git submodule init merging && - test "merge" = $(git config submodule.merging.update) + test "merge" = "$(git config submodule.merging.update)" ) ' diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index 8eec0fa9bc..9f5c3edb03 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -150,7 +150,7 @@ EOF test_expect_success '--signoff' ' echo "yet another content *narf*" >> foo && echo "zort" | git commit -s -F - foo && - git cat-file commit HEAD | sed "1,/^$/d" > output && + git cat-file commit HEAD | sed "1,/^\$/d" > output && test_cmp expect output ' diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index a603f6d21a..7940901d47 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -117,7 +117,11 @@ test_expect_success \ test_expect_success \ "overriding author from command line" \ "echo 'gak' >file && \ - git commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a" + git commit -m 'author' --author 'Rubber Duck <rduck@convoy.org>' -a >output 2>&1" + +test_expect_success \ + "commit --author output mentions author" \ + "grep Rubber.Duck output" test_expect_success PERL \ "interactive add" \ @@ -211,6 +215,21 @@ test_expect_success 'amend commit to fix author' ' ' +test_expect_success 'amend commit to fix date' ' + + test_tick && + newtick=$GIT_AUTHOR_DATE && + git reset --hard && + git cat-file -p HEAD | + sed -e "s/author.*/author $author $newtick/" \ + -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \ + expected && + git commit --amend --date="$newtick" && + git cat-file -p HEAD > current && + test_cmp expected current + +' + test_expect_success 'sign off (1)' ' echo 1 >positive && diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index fe94552296..844fb43c6d 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -267,4 +267,113 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo ' +cat >.git/FAKE_EDITOR <<EOF +#!$SHELL_PATH +mv "\$1" "\$1.orig" +( + echo message + cat "\$1.orig" +) >"\$1" +EOF + +echo '## Custom template' >template + +clear_config () { + ( + git config --unset-all "$1" + case $? in + 0|5) exit 0 ;; + *) exit 1 ;; + esac + ) +} + +try_commit () { + git reset --hard && + echo >>negative && + GIT_EDITOR=.git/FAKE_EDITOR git commit -a $* $use_template && + case "$use_template" in + '') + ! grep "^## Custom template" .git/COMMIT_EDITMSG ;; + *) + grep "^## Custom template" .git/COMMIT_EDITMSG ;; + esac +} + +try_commit_status_combo () { + + test_expect_success 'commit' ' + clear_config commit.status && + try_commit "" && + grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit' ' + clear_config commit.status && + try_commit "" && + grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit --status' ' + clear_config commit.status && + try_commit --status && + grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit --no-status' ' + clear_config commit.status && + try_commit --no-status + ! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit with commit.status = yes' ' + clear_config commit.status && + git config commit.status yes && + try_commit "" && + grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit with commit.status = no' ' + clear_config commit.status && + git config commit.status no && + try_commit "" && + ! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit --status with commit.status = yes' ' + clear_config commit.status && + git config commit.status yes && + try_commit --status && + grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit --no-status with commit.status = yes' ' + clear_config commit.status && + git config commit.status yes && + try_commit --no-status && + ! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit --status with commit.status = no' ' + clear_config commit.status && + git config commit.status no && + try_commit --status && + grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + + test_expect_success 'commit --no-status with commit.status = no' ' + clear_config commit.status && + git config commit.status no && + try_commit --no-status && + ! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG + ' + +} + +try_commit_status_combo + +use_template="-t template" + +try_commit_status_combo + test_done diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh index d9a08aac56..253c334319 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -5,34 +5,87 @@ test_description='git status for submodule' . ./test-lib.sh test_expect_success 'setup' ' - test_create_repo sub - cd sub && - : >bar && - git add bar && - git commit -m " Add bar" && - cd .. && - git add sub && + test_create_repo sub && + ( + cd sub && + : >bar && + git add bar && + git commit -m " Add bar" && + : >foo && + git add foo && + git commit -m " Add foo" + ) && + echo output > .gitignore && + git add sub .gitignore && git commit -m "Add submodule sub" ' test_expect_success 'status clean' ' - git status | - grep "nothing to commit" + git status >output && + grep "nothing to commit" output ' -test_expect_success 'status -a clean' ' - git status -a | - grep "nothing to commit" + +test_expect_success 'commit --dry-run -a clean' ' + test_must_fail git commit --dry-run -a >output && + grep "nothing to commit" output +' + +test_expect_success 'status with modified file in submodule' ' + (cd sub && git reset --hard) && + echo "changed" >sub/foo && + git status >output && + grep "modified: sub" output +' + +test_expect_success 'status with modified file in submodule (porcelain)' ' + (cd sub && git reset --hard) && + echo "changed" >sub/foo && + git status --porcelain >output && + diff output - <<-\EOF + M sub + EOF +' + +test_expect_success 'status with added file in submodule' ' + (cd sub && git reset --hard && echo >foo && git add foo) && + git status >output && + grep "modified: sub" output +' + +test_expect_success 'status with added file in submodule (porcelain)' ' + (cd sub && git reset --hard && echo >foo && git add foo) && + git status --porcelain >output && + diff output - <<-\EOF + M sub + EOF +' + +test_expect_success 'status with untracked file in submodule' ' + (cd sub && git reset --hard) && + echo "content" >sub/new-file && + git status >output && + grep "modified: sub" output +' + +test_expect_success 'status with untracked file in submodule (porcelain)' ' + git status --porcelain >output && + diff output - <<-\EOF + M sub + EOF ' + test_expect_success 'rm submodule contents' ' rm -rf sub/* sub/.git ' + test_expect_success 'status clean (empty submodule dir)' ' - git status | - grep "nothing to commit" + git status >output && + grep "nothing to commit" output ' + test_expect_success 'status -a clean (empty submodule dir)' ' - git status -a | - grep "nothing to commit" + test_must_fail git commit --dry-run -a >output && + grep "nothing to commit" output ' test_done diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 93f875f500..556d0faa77 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -8,26 +8,26 @@ test_description='git status' . ./test-lib.sh test_expect_success 'setup' ' - : > tracked && - : > modified && + : >tracked && + : >modified && mkdir dir1 && - : > dir1/tracked && - : > dir1/modified && + : >dir1/tracked && + : >dir1/modified && mkdir dir2 && - : > dir1/tracked && - : > dir1/modified && + : >dir1/tracked && + : >dir1/modified && git add . && git status >output && test_tick && git commit -m initial && - : > untracked && - : > dir1/untracked && - : > dir2/untracked && - echo 1 > dir1/modified && - echo 2 > dir2/modified && - echo 3 > dir2/added && + : >untracked && + : >dir1/untracked && + : >dir2/untracked && + echo 1 >dir1/modified && + echo 2 >dir2/modified && + echo 3 >dir2/added && git add dir2/added ' @@ -37,7 +37,7 @@ test_expect_success 'status (1)' ' ' -cat > expect << \EOF +cat >expect <<\EOF # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) @@ -63,7 +63,25 @@ EOF test_expect_success 'status (2)' ' - git status > output && + git status >output && + test_cmp expect output + +' + +cat >expect <<\EOF + M dir1/modified +A dir2/added +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF + +test_expect_success 'status -s (2)' ' + + git status -s >output && test_cmp expect output ' @@ -85,8 +103,8 @@ cat >expect <<EOF EOF test_expect_success 'status -uno' ' mkdir dir3 && - : > dir3/untracked1 && - : > dir3/untracked2 && + : >dir3/untracked1 && + : >dir3/untracked2 && git status -uno >output && test_cmp expect output ' @@ -97,6 +115,22 @@ test_expect_success 'status (status.showUntrackedFiles no)' ' test_cmp expect output ' +cat >expect << EOF + M dir1/modified +A dir2/added +EOF +test_expect_success 'status -s -uno' ' + git config --unset status.showuntrackedfiles + git status -s -uno >output && + test_cmp expect output +' + +test_expect_success 'status -s (status.showUntrackedFiles no)' ' + git config status.showuntrackedfiles no + git status -s >output && + test_cmp expect output +' + cat >expect <<EOF # On branch master # Changes to be committed: @@ -133,6 +167,29 @@ test_expect_success 'status (status.showUntrackedFiles normal)' ' ' cat >expect <<EOF + M dir1/modified +A dir2/added +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? dir3/ +?? expect +?? output +?? untracked +EOF +test_expect_success 'status -s -unormal' ' + git config --unset status.showuntrackedfiles + git status -s -unormal >output && + test_cmp expect output +' + +test_expect_success 'status -s (status.showUntrackedFiles normal)' ' + git config status.showuntrackedfiles normal + git status -s >output && + test_cmp expect output +' + +cat >expect <<EOF # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) @@ -169,7 +226,30 @@ test_expect_success 'status (status.showUntrackedFiles all)' ' test_cmp expect output ' -cat > expect << \EOF +cat >expect <<EOF + M dir1/modified +A dir2/added +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF +test_expect_success 'status -s -uall' ' + git config --unset status.showuntrackedfiles + git status -s -uall >output && + test_cmp expect output +' +test_expect_success 'status -s (status.showUntrackedFiles all)' ' + git config status.showuntrackedfiles all + git status -s >output && + rm -rf dir3 && + git config --unset status.showuntrackedfiles && + test_cmp expect output +' + +cat >expect <<\EOF # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) @@ -195,12 +275,156 @@ EOF test_expect_success 'status with relative paths' ' - (cd dir1 && git status) > output && + (cd dir1 && git status) >output && + test_cmp expect output + +' + +cat >expect <<\EOF + M modified +A ../dir2/added +?? untracked +?? ../dir2/modified +?? ../dir2/untracked +?? ../expect +?? ../output +?? ../untracked +EOF +test_expect_success 'status -s with relative paths' ' + + (cd dir1 && git status -s) >output && test_cmp expect output ' -cat > expect << \EOF +cat >expect <<\EOF + M dir1/modified +A dir2/added +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF + +test_expect_success 'status --porcelain ignores relative paths setting' ' + + (cd dir1 && git status --porcelain) >output && + test_cmp expect output + +' + +test_expect_success 'setup unique colors' ' + + git config status.color.untracked blue + +' + +cat >expect <<\EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# <GREEN>new file: dir2/added<RESET> +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# (use "git checkout -- <file>..." to discard changes in working directory) +# +# <RED>modified: dir1/modified<RESET> +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# <BLUE>dir1/untracked<RESET> +# <BLUE>dir2/modified<RESET> +# <BLUE>dir2/untracked<RESET> +# <BLUE>expect<RESET> +# <BLUE>output<RESET> +# <BLUE>untracked<RESET> +EOF + +test_expect_success 'status with color.ui' ' + + git config color.ui always && + git status | test_decode_color >output && + test_cmp expect output + +' + +test_expect_success 'status with color.status' ' + + git config --unset color.ui && + git config color.status always && + git status | test_decode_color >output && + test_cmp expect output + +' + +cat >expect <<\EOF + <RED>M<RESET> dir1/modified +<GREEN>A<RESET> dir2/added +<BLUE>??<RESET> dir1/untracked +<BLUE>??<RESET> dir2/modified +<BLUE>??<RESET> dir2/untracked +<BLUE>??<RESET> expect +<BLUE>??<RESET> output +<BLUE>??<RESET> untracked +EOF + +test_expect_success 'status -s with color.ui' ' + + git config --unset color.status && + git config color.ui always && + git status -s | test_decode_color >output && + test_cmp expect output + +' + +test_expect_success 'status -s with color.status' ' + + git config --unset color.ui && + git config color.status always && + git status -s | test_decode_color >output && + test_cmp expect output + +' + +cat >expect <<\EOF + M dir1/modified +A dir2/added +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF + +test_expect_success 'status --porcelain ignores color.ui' ' + + git config --unset color.status && + git config color.ui always && + git status --porcelain | test_decode_color >output && + test_cmp expect output + +' + +test_expect_success 'status --porcelain ignores color.status' ' + + git config --unset color.ui && + git config color.status always && + git status --porcelain | test_decode_color >output && + test_cmp expect output + +' + +# recover unconditionally from color tests +git config --unset color.status +git config --unset color.ui + +cat >expect <<\EOF # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) @@ -224,10 +448,29 @@ cat > expect << \EOF # untracked EOF + test_expect_success 'status without relative paths' ' git config status.relativePaths false - (cd dir1 && git status) > output && + (cd dir1 && git status) >output && + test_cmp expect output + +' + +cat >expect <<\EOF + M dir1/modified +A dir2/added +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF + +test_expect_success 'status -s without relative paths' ' + + (cd dir1 && git status -s) >output && test_cmp expect output ' @@ -248,8 +491,8 @@ cat <<EOF >expect # output # untracked EOF -test_expect_success 'status of partial commit excluding new file in index' ' - git status dir1/modified >output && +test_expect_success 'dry-run of partial commit excluding new file in index' ' + git commit --dry-run dir1/modified >output && test_cmp expect output ' @@ -298,6 +541,28 @@ test_expect_success 'status --untracked-files=all does not show submodule' ' test_cmp expect output ' +cat >expect <<EOF + M dir1/modified +A dir2/added +A sm +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF +test_expect_success 'status -s submodule summary is disabled by default' ' + git status -s >output && + test_cmp expect output +' + +# we expect the same as the previous test +test_expect_success 'status -s --untracked-files=all does not show submodule' ' + git status -s --untracked-files=all >output && + test_cmp expect output +' + head=$(cd sm && git rev-parse --short=7 --verify HEAD) cat >expect <<EOF @@ -314,7 +579,7 @@ cat >expect <<EOF # # modified: dir1/modified # -# Modified submodules: +# Submodule changes to be committed: # # * sm 0000000...$head (1): # > Add foo @@ -335,6 +600,21 @@ test_expect_success 'status submodule summary' ' test_cmp expect output ' +cat >expect <<EOF + M dir1/modified +A dir2/added +A sm +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF +test_expect_success 'status -s submodule summary' ' + git status -s >output && + test_cmp expect output +' cat >expect <<EOF # On branch master @@ -358,7 +638,23 @@ EOF test_expect_success 'status submodule summary (clean submodule)' ' git commit -m "commit submodule" && git config status.submodulesummary 10 && - test_must_fail git status >output && + test_must_fail git commit --dry-run >output && + test_cmp expect output && + git status >output && + test_cmp expect output +' + +cat >expect <<EOF + M dir1/modified +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF +test_expect_success 'status -s submodule summary (clean submodule)' ' + git status -s >output && test_cmp expect output ' @@ -376,7 +672,7 @@ cat >expect <<EOF # # modified: dir1/modified # -# Modified submodules: +# Submodule changes to be committed: # # * sm 0000000...$head (1): # > Add foo @@ -391,9 +687,9 @@ cat >expect <<EOF # output # untracked EOF -test_expect_success 'status submodule summary (--amend)' ' +test_expect_success 'commit --dry-run submodule summary (--amend)' ' git config status.submodulesummary 10 && - git status --amend >output && + git commit --dry-run --amend >output && test_cmp expect output ' diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index fff6a6d0ea..1de83ef98f 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2009 David Aguilar +# Copyright (c) 2009, 2010 David Aguilar # test_description='git-difftool @@ -15,14 +15,19 @@ if ! test_have_prereq PERL; then test_done fi +LF=' +' + remove_config_vars() { # Unset all config variables used by git-difftool git config --unset diff.tool + git config --unset diff.guitool git config --unset difftool.test-tool.cmd git config --unset difftool.prompt git config --unset merge.tool git config --unset mergetool.test-tool.cmd + git config --unset mergetool.prompt return 0 } @@ -31,11 +36,11 @@ restore_test_defaults() # Restores the test defaults used by several tests remove_config_vars unset GIT_DIFF_TOOL - unset GIT_MERGE_TOOL unset GIT_DIFFTOOL_PROMPT unset GIT_DIFFTOOL_NO_PROMPT git config diff.tool test-tool && git config difftool.test-tool.cmd 'cat $LOCAL' + git config difftool.bogus-tool.cmd false } prompt_given() @@ -71,11 +76,31 @@ test_expect_success 'custom commands' ' # Ensures that git-difftool ignores bogus --tool values test_expect_success 'difftool ignores bad --tool values' ' - diff=$(git difftool --no-prompt --tool=bogus-tool branch) + diff=$(git difftool --no-prompt --tool=bad-tool branch) test "$?" = 1 && test "$diff" = "" ' +test_expect_success 'difftool honors --gui' ' + git config merge.tool bogus-tool && + git config diff.tool bogus-tool && + git config diff.guitool test-tool && + + diff=$(git difftool --no-prompt --gui branch) && + test "$diff" = "branch" && + + restore_test_defaults +' + +test_expect_success 'difftool --gui works without configured diff.guitool' ' + git config diff.tool test-tool && + + diff=$(git difftool --no-prompt --gui branch) && + test "$diff" = "branch" && + + restore_test_defaults +' + # Specify the diff tool using $GIT_DIFF_TOOL test_expect_success 'GIT_DIFF_TOOL variable' ' git config --unset diff.tool @@ -94,15 +119,7 @@ test_expect_success 'GIT_DIFF_TOOL overrides' ' git config diff.tool bogus-tool && git config merge.tool bogus-tool && - GIT_MERGE_TOOL=test-tool && - export GIT_MERGE_TOOL && - diff=$(git difftool --no-prompt branch) && - test "$diff" = "branch" && - unset GIT_MERGE_TOOL && - - GIT_MERGE_TOOL=bogus-tool && GIT_DIFF_TOOL=test-tool && - export GIT_MERGE_TOOL && export GIT_DIFF_TOOL && diff=$(git difftool --no-prompt branch) && @@ -152,6 +169,17 @@ test_expect_success 'difftool.prompt config variable is false' ' restore_test_defaults ' +# Test that we don't have to pass --no-prompt when mergetool.prompt is false +test_expect_success 'difftool merge.prompt = false' ' + git config --unset difftool.prompt + git config mergetool.prompt false && + + diff=$(git difftool branch) && + test "$diff" = "branch" && + + restore_test_defaults +' + # Test that the -y flag can override difftool.prompt = true test_expect_success 'difftool.prompt can overridden with -y' ' git config difftool.prompt true && @@ -210,7 +238,39 @@ test_expect_success 'difftool.<tool>.path' ' diff=$(git difftool --tool=tkdiff --no-prompt branch) && git config --unset difftool.tkdiff.path && lines=$(echo "$diff" | grep file | wc -l) && - test "$lines" -eq 1 + test "$lines" -eq 1 && + + restore_test_defaults +' + +test_expect_success 'difftool --extcmd=cat' ' + diff=$(git difftool --no-prompt --extcmd=cat branch) && + test "$diff" = branch"$LF"master +' + +test_expect_success 'difftool --extcmd cat' ' + diff=$(git difftool --no-prompt --extcmd cat branch) && + test "$diff" = branch"$LF"master +' + +test_expect_success 'difftool -x cat' ' + diff=$(git difftool --no-prompt -x cat branch) && + test "$diff" = branch"$LF"master +' + +test_expect_success 'difftool --extcmd echo arg1' ' + diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"echo\ \$1\" branch) + test "$diff" = file +' + +test_expect_success 'difftool --extcmd cat arg1' ' + diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$1\" branch) + test "$diff" = master +' + +test_expect_success 'difftool --extcmd cat arg2' ' + diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$2\" branch) + test "$diff" = branch ' test_done diff --git a/t/t8003-blame.sh b/t/t8003-blame.sh index 3bbddd03cb..230143cf31 100755 --- a/t/t8003-blame.sh +++ b/t/t8003-blame.sh @@ -11,7 +11,15 @@ test_expect_success setup ' echo B B B B B >two && echo C C C C C >tres && echo ABC >mouse && - git add one two tres mouse && + for i in 1 2 3 4 5 6 7 8 9 + do + echo $i + done >nine_lines && + for i in 1 2 3 4 5 6 7 8 9 a + do + echo $i + done >ten_lines && + git add one two tres mouse nine_lines ten_lines && test_tick && GIT_AUTHOR_NAME=Initial git commit -m Initial && @@ -167,4 +175,14 @@ test_expect_success 'blame -L with invalid end' ' grep "has only 2 lines" errors ' +test_expect_success 'indent of line numbers, nine lines' ' + git blame nine_lines >actual && + test $(grep -c " " actual) = 0 +' + +test_expect_success 'indent of line numbers, ten lines' ' + git blame ten_lines >actual && + test $(grep -c " " actual) = 9 +' + test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 752adaac85..c09f375288 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -186,8 +186,8 @@ test_expect_success 'Prompting works' ' --smtp-server="$(pwd)/fake.sendmail" \ $patches \ 2>errors && - grep "^From: Example <from@example.com>$" msgtxt1 && - grep "^To: to@example.com$" msgtxt1 + grep "^From: Example <from@example.com>\$" msgtxt1 && + grep "^To: to@example.com\$" msgtxt1 ' test_expect_success 'cccmd works' ' @@ -236,7 +236,7 @@ test_expect_success 'Author From: in message body' ' --to=nobody@example.com \ --smtp-server="$(pwd)/fake.sendmail" \ $patches && - sed "1,/^$/d" < msgtxt1 > msgbody1 + sed "1,/^\$/d" < msgtxt1 > msgbody1 grep "From: A <author@example.com>" msgbody1 ' @@ -247,7 +247,7 @@ test_expect_success 'Author From: not in message body' ' --to=nobody@example.com \ --smtp-server="$(pwd)/fake.sendmail" \ $patches && - sed "1,/^$/d" < msgtxt1 > msgbody1 + sed "1,/^\$/d" < msgtxt1 > msgbody1 ! grep "From: A <author@example.com>" msgbody1 ' diff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh index 359eeaa738..3569c62096 100755 --- a/t/t9151-svn-mergeinfo.sh +++ b/t/t9151-svn-mergeinfo.sh @@ -33,7 +33,7 @@ test_expect_success 'svn non-merge merge commits did not become git merge commit [ -z "$bad_non_merges" ] ' -test_expect_success 'everything got merged in the end' ' +test_expect_failure 'everything got merged in the end' ' unmerged=$(git rev-list --all --not master) [ -z "$unmerged" ] ' diff --git a/t/t9151/make-svnmerge-dump b/t/t9151/make-svnmerge-dump index d917717cf3..3d73f140f8 100644 --- a/t/t9151/make-svnmerge-dump +++ b/t/t9151/make-svnmerge-dump @@ -26,8 +26,9 @@ i=0 cd foo mkdir trunk mkdir branches -svn add trunk branches -i=$(commit $i "Setup trunk and branches") +mkdir tags +svn add trunk branches tags +i=$(commit $i "Setup trunk, branches, and tags") git cat-file blob 6683463e:Makefile > trunk/Makefile svn add trunk/Makefile @@ -155,6 +156,66 @@ svn merge ../branches/right --accept postpone i=$(commit $i "non-merge right to trunk 2") cd .. +say "Adding subdirectory to LEFT" +svn update +cd branches/left +mkdir subdir +echo "Yeehaw" > subdir/cowboy +svn add subdir +i=$(commit $i "add subdirectory to left branch") +cd ../../ + +say "Merging LEFT to TRUNK" +svn update +cd trunk +svn merge ../branches/left --accept postpone +i=$(commit $i "merge left to trunk") +cd .. + +say "Make PARTIAL branch" +svn update +i=$(commit $i "make partial branch") +svn cp trunk/subdir branches/partial + +say "Make a commit to PARTIAL" +svn update +cd branches/partial +echo "racecar" > palindromes +svn add palindromes +i=$(commit $i "partial update") +cd ../../ + +say "Merge PARTIAL to TRUNK" +svn update +cd trunk/subdir +svn merge ../../branches/partial --accept postpone +i=$(commit $i "merge partial to trunk") +cd ../../ + +say "Tagging trunk" +svn update +i=$(commit $i "tagging v1.0") +svn cp trunk tags/v1.0 + +say "Branching BUGFIX from v1.0" +svn update +i=$(commit $i "make bugfix branch from tag") +svn cp tags/v1.0 branches/bugfix + +say "Make a commit to BUGFIX" +svn update +cd branches/bugfix/ +echo "kayak" >> subdir/palindromes +i=$(commit $i "commit to bugfix") +cd ../../ + +say "Merge BUGFIX to TRUNK" +svn update +cd trunk +svn merge ../branches/bugfix/ --accept postpone +i=$(commit $i "Merge BUGFIX to TRUNK") +cd .. + cd .. svnadmin dump foo.svn > svn-mergeinfo.dump diff --git a/t/t9151/svn-mergeinfo.dump b/t/t9151/svn-mergeinfo.dump index 9543e31c96..ebf386ebd5 100644 --- a/t/t9151/svn-mergeinfo.dump +++ b/t/t9151/svn-mergeinfo.dump @@ -1,6 +1,6 @@ SVN-fs-dump-format-version: 2 -UUID: 64142547-0943-4db2-836a-d1e1eb2f9924 +UUID: d6191530-2693-4a8e-98e7-b194d4c3edd8 Revision-number: 0 Prop-content-length: 56 @@ -9,25 +9,25 @@ Content-length: 56 K 8 svn:date V 27 -2009-12-19T16:17:51.232640Z +2010-01-19T04:14:02.832406Z PROPS-END Revision-number: 1 -Prop-content-length: 128 -Content-length: 128 +Prop-content-length: 134 +Content-length: 134 K 7 svn:log -V 29 -(r1) Setup trunk and branches +V 36 +(r1) Setup trunk, branches, and tags K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:51.831965Z +2010-01-19T04:14:03.055172Z PROPS-END Node-path: branches @@ -39,6 +39,15 @@ Content-length: 10 PROPS-END +Node-path: tags +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + Node-path: trunk Node-kind: dir Node-action: add @@ -49,8 +58,8 @@ PROPS-END Revision-number: 2 -Prop-content-length: 112 -Content-length: 112 +Prop-content-length: 111 +Content-length: 111 K 7 svn:log @@ -58,12 +67,12 @@ V 13 (r2) ancestor K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:52.300075Z +2010-01-19T04:14:04.064506Z PROPS-END Node-path: trunk/Makefile @@ -156,8 +165,8 @@ backup: clean Revision-number: 3 -Prop-content-length: 120 -Content-length: 120 +Prop-content-length: 119 +Content-length: 119 K 7 svn:log @@ -165,12 +174,12 @@ V 21 (r3) make left branch K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:52.768800Z +2010-01-19T04:14:06.040389Z PROPS-END Node-path: branches/left @@ -190,8 +199,8 @@ Text-copy-source-sha1: 103205ce331f7d64086dba497574734f78439590 Revision-number: 4 -Prop-content-length: 121 -Content-length: 121 +Prop-content-length: 120 +Content-length: 120 K 7 svn:log @@ -199,12 +208,12 @@ V 22 (r4) make right branch K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:53.177879Z +2010-01-19T04:14:08.040905Z PROPS-END Node-path: branches/right @@ -224,8 +233,8 @@ Text-copy-source-sha1: 103205ce331f7d64086dba497574734f78439590 Revision-number: 5 -Prop-content-length: 117 -Content-length: 117 +Prop-content-length: 116 +Content-length: 116 K 7 svn:log @@ -233,12 +242,12 @@ V 18 (r5) left update 1 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:53.604691Z +2010-01-19T04:14:09.049169Z PROPS-END Node-path: branches/left/Makefile @@ -329,8 +338,8 @@ backup: clean Revision-number: 6 -Prop-content-length: 118 -Content-length: 118 +Prop-content-length: 117 +Content-length: 117 K 7 svn:log @@ -338,12 +347,12 @@ V 19 (r6) right update 1 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:54.063555Z +2010-01-19T04:14:10.049350Z PROPS-END Node-path: branches/right/Makefile @@ -437,8 +446,8 @@ backup: clean Revision-number: 7 -Prop-content-length: 117 -Content-length: 117 +Prop-content-length: 116 +Content-length: 116 K 7 svn:log @@ -446,12 +455,12 @@ V 18 (r7) left update 2 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:54.523904Z +2010-01-19T04:14:11.049209Z PROPS-END Node-path: branches/left/Makefile @@ -542,8 +551,8 @@ backup: clean Revision-number: 8 -Prop-content-length: 117 -Content-length: 117 +Prop-content-length: 116 +Content-length: 116 K 7 svn:log @@ -551,12 +560,12 @@ V 18 (r8) left update 3 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:54.975970Z +2010-01-19T04:14:12.049234Z PROPS-END Node-path: branches/left/Makefile @@ -647,8 +656,8 @@ backup: clean Revision-number: 9 -Prop-content-length: 124 -Content-length: 124 +Prop-content-length: 123 +Content-length: 123 K 7 svn:log @@ -656,12 +665,12 @@ V 25 (r9) make left sub-branch K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:55.459904Z +2010-01-19T04:14:14.040894Z PROPS-END Node-path: branches/left-sub @@ -687,8 +696,8 @@ Text-copy-source-sha1: a13de8e23f1483efca3e57b2b64b0ae6f740ce10 Revision-number: 10 -Prop-content-length: 129 -Content-length: 129 +Prop-content-length: 128 +Content-length: 128 K 7 svn:log @@ -696,12 +705,12 @@ V 30 (r10) left sub-branch update 1 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:55.862113Z +2010-01-19T04:14:15.049935Z PROPS-END Node-path: branches/left-sub/README @@ -718,8 +727,8 @@ crunch Revision-number: 11 -Prop-content-length: 126 -Content-length: 126 +Prop-content-length: 125 +Content-length: 125 K 7 svn:log @@ -727,12 +736,12 @@ V 27 (r11) Merge left to trunk 1 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:56.413416Z +2010-01-19T04:14:18.056594Z PROPS-END Node-path: trunk @@ -836,8 +845,8 @@ backup: clean Revision-number: 12 -Prop-content-length: 118 -Content-length: 118 +Prop-content-length: 117 +Content-length: 117 K 7 svn:log @@ -845,12 +854,12 @@ V 19 (r12) left update 4 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:56.831014Z +2010-01-19T04:14:19.049620Z PROPS-END Node-path: branches/left/zlonk @@ -867,8 +876,8 @@ touche Revision-number: 13 -Prop-content-length: 119 -Content-length: 119 +Prop-content-length: 118 +Content-length: 118 K 7 svn:log @@ -876,12 +885,12 @@ V 20 (r13) right update 2 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:57.341143Z +2010-01-19T04:14:20.049659Z PROPS-END Node-path: branches/right/bang @@ -898,8 +907,8 @@ thwacke Revision-number: 14 -Prop-content-length: 141 -Content-length: 141 +Prop-content-length: 140 +Content-length: 140 K 7 svn:log @@ -907,12 +916,12 @@ V 42 (r14) Cherry-pick right 2 commits to trunk K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:57.841851Z +2010-01-19T04:14:23.041991Z PROPS-END Node-path: trunk @@ -1029,8 +1038,8 @@ Text-copy-source-sha1: 0bc5bb345c0e71d28f784f12e0bd2d384c283062 Revision-number: 15 -Prop-content-length: 127 -Content-length: 127 +Prop-content-length: 126 +Content-length: 126 K 7 svn:log @@ -1038,12 +1047,12 @@ V 28 (r15) Merge right to trunk 1 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:58.368520Z +2010-01-19T04:14:26.054456Z PROPS-END Node-path: trunk @@ -1061,8 +1070,8 @@ PROPS-END Revision-number: 16 -Prop-content-length: 119 -Content-length: 119 +Prop-content-length: 118 +Content-length: 118 K 7 svn:log @@ -1070,12 +1079,12 @@ V 20 (r16) right update 3 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:58.779056Z +2010-01-19T04:14:27.049955Z PROPS-END Node-path: branches/right/urkkk @@ -1092,8 +1101,8 @@ whamm Revision-number: 17 -Prop-content-length: 119 -Content-length: 119 +Prop-content-length: 118 +Content-length: 118 K 7 svn:log @@ -1101,12 +1110,12 @@ V 20 (r17) trunk update 1 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:59.221851Z +2010-01-19T04:14:28.049615Z PROPS-END Node-path: trunk/vronk @@ -1123,8 +1132,8 @@ pow Revision-number: 18 -Prop-content-length: 135 -Content-length: 135 +Prop-content-length: 134 +Content-length: 134 K 7 svn:log @@ -1132,12 +1141,12 @@ V 36 (r18) Merge right to left sub-branch K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:17:59.781666Z +2010-01-19T04:14:31.061460Z PROPS-END Node-path: branches/left-sub @@ -1262,8 +1271,8 @@ Text-copy-source-sha1: 3934264d277a0cf886b6b1c7f2b9e56da2525302 Revision-number: 19 -Prop-content-length: 129 -Content-length: 129 +Prop-content-length: 128 +Content-length: 128 K 7 svn:log @@ -1271,12 +1280,12 @@ V 30 (r19) left sub-branch update 2 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:18:00.200531Z +2010-01-19T04:14:32.049244Z PROPS-END Node-path: branches/left-sub/wham_eth @@ -1293,8 +1302,8 @@ zowie Revision-number: 20 -Prop-content-length: 118 -Content-length: 118 +Prop-content-length: 117 +Content-length: 117 K 7 svn:log @@ -1302,12 +1311,12 @@ V 19 (r20) left update 5 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:18:00.659636Z +2010-01-19T04:14:33.049332Z PROPS-END Node-path: branches/left/glurpp @@ -1324,8 +1333,8 @@ eee_yow Revision-number: 21 -Prop-content-length: 147 -Content-length: 147 +Prop-content-length: 146 +Content-length: 146 K 7 svn:log @@ -1333,12 +1342,12 @@ V 48 (r21) Cherry-pick left sub-branch commit to left K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:18:01.194402Z +2010-01-19T04:14:36.041839Z PROPS-END Node-path: branches/left @@ -1364,8 +1373,8 @@ Text-copy-source-sha1: b165019b005c199237ba822c4404e771e93b654a Revision-number: 22 -Prop-content-length: 134 -Content-length: 134 +Prop-content-length: 133 +Content-length: 133 K 7 svn:log @@ -1373,12 +1382,12 @@ V 35 (r22) Merge left sub-branch to left K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:18:01.679218Z +2010-01-19T04:14:39.045014Z PROPS-END Node-path: branches/left @@ -1513,8 +1522,8 @@ Text-copy-source-sha1: 3934264d277a0cf886b6b1c7f2b9e56da2525302 Revision-number: 23 -Prop-content-length: 126 -Content-length: 126 +Prop-content-length: 125 +Content-length: 125 K 7 svn:log @@ -1522,12 +1531,12 @@ V 27 (r23) Merge left to trunk 2 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:18:02.212349Z +2010-01-19T04:14:42.052798Z PROPS-END Node-path: trunk @@ -1591,8 +1600,8 @@ Text-copy-source-sha1: 9716527ebd70a75c27625cacbeb2d897c6e86178 Revision-number: 24 -Prop-content-length: 131 -Content-length: 131 +Prop-content-length: 130 +Content-length: 130 K 7 svn:log @@ -1600,12 +1609,12 @@ V 32 (r24) non-merge right to trunk 2 K 10 svn:author -V 4 -samv +V 3 +adm K 8 svn:date V 27 -2009-12-19T16:18:02.672148Z +2010-01-19T04:14:44.038434Z PROPS-END Node-path: trunk @@ -1623,3 +1632,291 @@ V 64 PROPS-END +Revision-number: 25 +Prop-content-length: 135 +Content-length: 135 + +K 7 +svn:log +V 37 +(r25) add subdirectory to left branch +K 10 +svn:author +V 3 +adm +K 8 +svn:date +V 27 +2010-01-19T04:14:46.052649Z +PROPS-END + +Node-path: branches/left/subdir +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: branches/left/subdir/cowboy +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 7 +Text-content-md5: f1d6530278ad409e68cc675476ad995f +Text-content-sha1: 732d9e3e5c391ffd767a98b45ddcc848de778cea +Content-length: 17 + +PROPS-END +Yeehaw + + +Revision-number: 26 +Prop-content-length: 123 +Content-length: 123 + +K 7 +svn:log +V 25 +(r26) merge left to trunk +K 10 +svn:author +V 3 +adm +K 8 +svn:date +V 27 +2010-01-19T04:14:49.040783Z +PROPS-END + +Node-path: trunk +Node-kind: dir +Node-action: change +Prop-content-length: 99 +Content-length: 99 + +K 13 +svn:mergeinfo +V 64 +/branches/left:2-25 +/branches/left-sub:4-19 +/branches/right:2-22 +PROPS-END + + +Node-path: trunk/subdir +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 25 +Node-copyfrom-path: branches/left/subdir + + +Revision-number: 27 +Prop-content-length: 118 +Content-length: 118 + +K 7 +svn:log +V 20 +(r28) partial update +K 10 +svn:author +V 3 +adm +K 8 +svn:date +V 27 +2010-01-19T04:14:53.049037Z +PROPS-END + +Node-path: branches/partial +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 26 +Node-copyfrom-path: trunk/subdir + + +Node-path: branches/partial/palindromes +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 8 +Text-content-md5: 5d1c2024fb5efc4eef812856df1b080c +Text-content-sha1: 5f8509ddd14c91a52864dd1447344e706f9bbc69 +Content-length: 18 + +PROPS-END +racecar + + +Revision-number: 28 +Prop-content-length: 126 +Content-length: 126 + +K 7 +svn:log +V 28 +(r29) merge partial to trunk +K 10 +svn:author +V 3 +adm +K 8 +svn:date +V 27 +2010-01-19T04:14:56.041526Z +PROPS-END + +Node-path: trunk/subdir +Node-kind: dir +Node-action: change +Prop-content-length: 142 +Content-length: 142 + +K 13 +svn:mergeinfo +V 106 +/branches/left/subdir:2-25 +/branches/left-sub/subdir:4-19 +/branches/partial:27 +/branches/right/subdir:2-22 +PROPS-END + + +Node-path: trunk/subdir/palindromes +Node-kind: file +Node-action: add +Node-copyfrom-rev: 27 +Node-copyfrom-path: branches/partial/palindromes +Text-copy-source-md5: 5d1c2024fb5efc4eef812856df1b080c +Text-copy-source-sha1: 5f8509ddd14c91a52864dd1447344e706f9bbc69 + + +Revision-number: 29 +Prop-content-length: 131 +Content-length: 131 + +K 7 +svn:log +V 33 +(r31) make bugfix branch from tag +K 10 +svn:author +V 3 +adm +K 8 +svn:date +V 27 +2010-01-19T04:15:00.039761Z +PROPS-END + +Node-path: tags/v1.0 +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 28 +Node-copyfrom-path: trunk + + +Revision-number: 30 +Prop-content-length: 120 +Content-length: 120 + +K 7 +svn:log +V 22 +(r32) commit to bugfix +K 10 +svn:author +V 3 +adm +K 8 +svn:date +V 27 +2010-01-19T04:15:03.043218Z +PROPS-END + +Node-path: branches/bugfix +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 29 +Node-copyfrom-path: tags/v1.0 + + +Node-path: branches/bugfix/subdir/palindromes +Node-kind: file +Node-action: change +Text-content-length: 14 +Text-content-md5: 3b12d98578a3f4320ba97e66da54fe5f +Text-content-sha1: 672931c9e8ac2c408209efab2f015638b6d64042 +Content-length: 14 + +racecar +kayak + + +Revision-number: 31 +Prop-content-length: 125 +Content-length: 125 + +K 7 +svn:log +V 27 +(r33) Merge BUGFIX to TRUNK +K 10 +svn:author +V 3 +adm +K 8 +svn:date +V 27 +2010-01-19T04:15:06.043723Z +PROPS-END + +Node-path: trunk +Node-kind: dir +Node-action: change +Prop-content-length: 133 +Content-length: 133 + +K 13 +svn:mergeinfo +V 98 +/branches/bugfix:30 +/branches/left:2-25 +/branches/left-sub:4-19 +/branches/right:2-22 +/tags/v1.0:29 +PROPS-END + + +Node-path: trunk/subdir +Node-kind: dir +Node-action: change +Prop-content-length: 190 +Content-length: 190 + +K 13 +svn:mergeinfo +V 154 +/branches/bugfix/subdir:30 +/branches/left/subdir:2-25 +/branches/left-sub/subdir:4-19 +/branches/partial:27 +/branches/right/subdir:2-22 +/tags/v1.0/subdir:29 +PROPS-END + + +Node-path: trunk/subdir/palindromes +Node-kind: file +Node-action: change +Text-content-length: 14 +Text-content-md5: 3b12d98578a3f4320ba97e66da54fe5f +Text-content-sha1: 672931c9e8ac2c408209efab2f015638b6d64042 +Content-length: 14 + +racecar +kayak + + diff --git a/t/t9153-git-svn-rewrite-uuid.sh b/t/t9153-git-svn-rewrite-uuid.sh new file mode 100755 index 0000000000..88a2cfa233 --- /dev/null +++ b/t/t9153-git-svn-rewrite-uuid.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# +# Copyright (c) 2010 Jay Soffian +# + +test_description='git svn --rewrite-uuid test' + +. ./lib-git-svn.sh + +uuid=6cc8ada4-5932-4b4a-8242-3534ed8a3232 + +test_expect_success 'load svn repo' " + svnadmin load -q '$rawsvnrepo' < '$TEST_DIRECTORY/t9153/svn.dump' && + git svn init --minimize-url --rewrite-uuid='$uuid' '$svnrepo' && + git svn fetch + " + +test_expect_success 'verify uuid' " + git cat-file commit refs/remotes/git-svn~0 | \ + grep '^${git_svn_id}: .*@2 $uuid$' && + git cat-file commit refs/remotes/git-svn~1 | \ + grep '^${git_svn_id}: .*@1 $uuid$' + " + +test_done diff --git a/t/t9153/svn.dump b/t/t9153/svn.dump new file mode 100644 index 0000000000..0ddfe7025d --- /dev/null +++ b/t/t9153/svn.dump @@ -0,0 +1,75 @@ +SVN-fs-dump-format-version: 2 + +UUID: b4885626-c94f-4a6c-b179-00c030fc68e8 + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2010-01-23T06:41:03.908576Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 109 +Content-length: 109 + +K 7 +svn:log +V 11 +initial foo +K 10 +svn:author +V 3 +jay +K 8 +svn:date +V 27 +2010-01-23T06:41:48.353776Z +PROPS-END + +Node-path: foo +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: d3b07384d113edec49eaa6238ad5ff00 +Text-content-sha1: f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 +Content-length: 14 + +PROPS-END +foo + + +Revision-number: 2 +Prop-content-length: 110 +Content-length: 110 + +K 7 +svn:log +V 12 +now with bar +K 10 +svn:author +V 3 +jay +K 8 +svn:date +V 27 +2010-01-23T06:42:14.214640Z +PROPS-END + +Node-path: foo +Node-kind: file +Node-action: change +Text-content-length: 8 +Text-content-md5: f47c75614087a8dd938ba4acff252494 +Text-content-sha1: 4e48e2c9a3d2ca8a708cb0cc545700544efb5021 +Content-length: 8 + +foo +bar + + diff --git a/t/t9154-git-svn-fancy-glob.sh b/t/t9154-git-svn-fancy-glob.sh new file mode 100755 index 0000000000..a6a56a6cb9 --- /dev/null +++ b/t/t9154-git-svn-fancy-glob.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Copyright (c) 2010 Jay Soffian +# + +test_description='git svn fancy glob test' + +. ./lib-git-svn.sh + +test_expect_success 'load svn repo' " + svnadmin load -q '$rawsvnrepo' < '$TEST_DIRECTORY/t9154/svn.dump' && + git svn init --minimize-url -T trunk '$svnrepo' && + git svn fetch + " + +test_expect_success 'add red branch' " + git config svn-remote.svn.branches 'branches/{red}:refs/remotes/*' && + git svn fetch && + git rev-parse refs/remotes/red && + test_must_fail git rev-parse refs/remotes/green && + test_must_fail git rev-parse refs/remotes/blue + " + +test_expect_success 'add green branch' " + GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev && + git config svn-remote.svn.branches 'branches/{red,green}:refs/remotes/*' && + git svn fetch && + git rev-parse refs/remotes/red && + git rev-parse refs/remotes/green && + test_must_fail git rev-parse refs/remotes/blue + " + +test_expect_success 'add all branches' " + GIT_CONFIG=.git/svn/.metadata git config --unset svn-remote.svn.branches-maxRev && + git config svn-remote.svn.branches 'branches/*:refs/remotes/*' && + git svn fetch && + git rev-parse refs/remotes/red && + git rev-parse refs/remotes/green && + git rev-parse refs/remotes/blue + " + +test_done diff --git a/t/t9154/svn.dump b/t/t9154/svn.dump new file mode 100644 index 0000000000..3dfabb67db --- /dev/null +++ b/t/t9154/svn.dump @@ -0,0 +1,222 @@ +SVN-fs-dump-format-version: 2 + +UUID: a18093a0-5f0b-44e0-8d88-8911ac7078db + +Revision-number: 0 +Prop-content-length: 56 +Content-length: 56 + +K 8 +svn:date +V 27 +2010-01-23T07:40:25.660053Z +PROPS-END + +Revision-number: 1 +Prop-content-length: 104 +Content-length: 104 + +K 7 +svn:log +V 7 +initial +K 10 +svn:author +V 3 +jay +K 8 +svn:date +V 27 +2010-01-23T07:41:33.636365Z +PROPS-END + +Node-path: trunk +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: trunk/foo +Node-kind: file +Node-action: add +Prop-content-length: 10 +Text-content-length: 4 +Text-content-md5: d3b07384d113edec49eaa6238ad5ff00 +Text-content-sha1: f1d2d2f924e986ac86fdf7b36c94bcdf32beec15 +Content-length: 14 + +PROPS-END +foo + + +Revision-number: 2 +Prop-content-length: 110 +Content-length: 110 + +K 7 +svn:log +V 12 +add branches +K 10 +svn:author +V 3 +jay +K 8 +svn:date +V 27 +2010-01-23T07:42:37.290694Z +PROPS-END + +Node-path: branches +Node-kind: dir +Node-action: add +Prop-content-length: 10 +Content-length: 10 + +PROPS-END + + +Node-path: branches/blue +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 1 +Node-copyfrom-path: trunk + + +Node-path: branches/green +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 1 +Node-copyfrom-path: trunk + + +Node-path: branches/red +Node-kind: dir +Node-action: add +Node-copyfrom-rev: 1 +Node-copyfrom-path: trunk + + +Revision-number: 3 +Prop-content-length: 108 +Content-length: 108 + +K 7 +svn:log +V 10 +red change +K 10 +svn:author +V 3 +jay +K 8 +svn:date +V 27 +2010-01-23T07:43:02.208918Z +PROPS-END + +Node-path: branches/red/foo +Node-kind: file +Node-action: change +Text-content-length: 8 +Text-content-md5: 64c3c8cf7d0233ab7627623a68888bd1 +Text-content-sha1: 95a0492027876adfd3891ec71ee37b79ee44d640 +Content-length: 8 + +foo +red + + +Revision-number: 4 +Prop-content-length: 110 +Content-length: 110 + +K 7 +svn:log +V 12 +green change +K 10 +svn:author +V 3 +jay +K 8 +svn:date +V 27 +2010-01-23T07:43:15.746586Z +PROPS-END + +Node-path: branches/green/foo +Node-kind: file +Node-action: change +Text-content-length: 10 +Text-content-md5: 0209b6450891abc033d5eaaa9d3a8023 +Text-content-sha1: 87fc3bef9faeec48c0cd61dfc9851db377fdccf7 +Content-length: 10 + +foo +green + + +Revision-number: 5 +Prop-content-length: 109 +Content-length: 109 + +K 7 +svn:log +V 11 +blue change +K 10 +svn:author +V 3 +jay +K 8 +svn:date +V 27 +2010-01-23T07:43:29.364811Z +PROPS-END + +Node-path: branches/blue/foo +Node-kind: file +Node-action: change +Text-content-length: 9 +Text-content-md5: 9fbe4c13d0bae86386ae5209b2e6b275 +Text-content-sha1: cc4575083459a16f9aaef796c4a2456d64691ba0 +Content-length: 9 + +foo +blue + + +Revision-number: 6 +Prop-content-length: 110 +Content-length: 110 + +K 7 +svn:log +V 12 +trunk change +K 10 +svn:author +V 3 +jay +K 8 +svn:date +V 27 +2010-01-23T07:44:01.313130Z +PROPS-END + +Node-path: trunk/foo +Node-kind: file +Node-action: change +Text-content-length: 10 +Text-content-md5: 1c4db977d7a57c3bae582aab87948516 +Text-content-sha1: 469c08df449e702cf2a1fe746244a9ef3f837fad +Content-length: 10 + +foo +trunk + + diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 513db86ad2..131f032988 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -1092,9 +1092,12 @@ test_expect_success 'P: fail on blob mark in gitlink' ' ### series Q (notes) ### -note1_data="Note for the first commit" -note2_data="Note for the second commit" -note3_data="Note for the third commit" +note1_data="The first note for the first commit" +note2_data="The first note for the second commit" +note3_data="The first note for the third commit" +note1b_data="The second note for the first commit" +note1c_data="The third note for the first commit" +note2b_data="The second note for the second commit" test_tick cat >input <<INPUT_END @@ -1169,7 +1172,45 @@ data <<EOF $note3_data EOF +commit refs/notes/foobar +mark :10 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +notes (:10) +COMMIT + +N inline :3 +data <<EOF +$note1b_data +EOF + +commit refs/notes/foobar2 +mark :11 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +notes (:11) +COMMIT + +N inline :3 +data <<EOF +$note1c_data +EOF + +commit refs/notes/foobar +mark :12 +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +notes (:12) +COMMIT + +deleteall +N inline :5 +data <<EOF +$note2b_data +EOF + INPUT_END + test_expect_success \ 'Q: commit notes' \ 'git fast-import <input && @@ -1224,8 +1265,8 @@ committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE notes (:9) EOF test_expect_success \ - 'Q: verify notes commit' \ - 'git cat-file commit refs/notes/foobar | sed 1d >actual && + 'Q: verify first notes commit' \ + 'git cat-file commit refs/notes/foobar~2 | sed 1d >actual && test_cmp expect actual' cat >expect.unsorted <<EOF @@ -1235,24 +1276,265 @@ cat >expect.unsorted <<EOF EOF cat expect.unsorted | sort >expect test_expect_success \ - 'Q: verify notes tree' \ - 'git cat-file -p refs/notes/foobar^{tree} | sed "s/ [0-9a-f]* / /" >actual && + 'Q: verify first notes tree' \ + 'git cat-file -p refs/notes/foobar~2^{tree} | sed "s/ [0-9a-f]* / /" >actual && test_cmp expect actual' echo "$note1_data" >expect test_expect_success \ - 'Q: verify note for first commit' \ - 'git cat-file blob refs/notes/foobar:$commit1 >actual && test_cmp expect actual' + 'Q: verify first note for first commit' \ + 'git cat-file blob refs/notes/foobar~2:$commit1 >actual && test_cmp expect actual' echo "$note2_data" >expect test_expect_success \ - 'Q: verify note for second commit' \ - 'git cat-file blob refs/notes/foobar:$commit2 >actual && test_cmp expect actual' + 'Q: verify first note for second commit' \ + 'git cat-file blob refs/notes/foobar~2:$commit2 >actual && test_cmp expect actual' echo "$note3_data" >expect test_expect_success \ - 'Q: verify note for third commit' \ - 'git cat-file blob refs/notes/foobar:$commit3 >actual && test_cmp expect actual' + 'Q: verify first note for third commit' \ + 'git cat-file blob refs/notes/foobar~2:$commit3 >actual && test_cmp expect actual' + +cat >expect <<EOF +parent `git rev-parse --verify refs/notes/foobar~2` +author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + +notes (:10) +EOF +test_expect_success \ + 'Q: verify second notes commit' \ + 'git cat-file commit refs/notes/foobar^ | sed 1d >actual && + test_cmp expect actual' + +cat >expect.unsorted <<EOF +100644 blob $commit1 +100644 blob $commit2 +100644 blob $commit3 +EOF +cat expect.unsorted | sort >expect +test_expect_success \ + 'Q: verify second notes tree' \ + 'git cat-file -p refs/notes/foobar^^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual' + +echo "$note1b_data" >expect +test_expect_success \ + 'Q: verify second note for first commit' \ + 'git cat-file blob refs/notes/foobar^:$commit1 >actual && test_cmp expect actual' + +echo "$note2_data" >expect +test_expect_success \ + 'Q: verify first note for second commit' \ + 'git cat-file blob refs/notes/foobar^:$commit2 >actual && test_cmp expect actual' + +echo "$note3_data" >expect +test_expect_success \ + 'Q: verify first note for third commit' \ + 'git cat-file blob refs/notes/foobar^:$commit3 >actual && test_cmp expect actual' + +cat >expect <<EOF +author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + +notes (:11) +EOF +test_expect_success \ + 'Q: verify third notes commit' \ + 'git cat-file commit refs/notes/foobar2 | sed 1d >actual && + test_cmp expect actual' + +cat >expect.unsorted <<EOF +100644 blob $commit1 +EOF +cat expect.unsorted | sort >expect +test_expect_success \ + 'Q: verify third notes tree' \ + 'git cat-file -p refs/notes/foobar2^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual' + +echo "$note1c_data" >expect +test_expect_success \ + 'Q: verify third note for first commit' \ + 'git cat-file blob refs/notes/foobar2:$commit1 >actual && test_cmp expect actual' + +cat >expect <<EOF +parent `git rev-parse --verify refs/notes/foobar^` +author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + +notes (:12) +EOF +test_expect_success \ + 'Q: verify fourth notes commit' \ + 'git cat-file commit refs/notes/foobar | sed 1d >actual && + test_cmp expect actual' + +cat >expect.unsorted <<EOF +100644 blob $commit2 +EOF +cat expect.unsorted | sort >expect +test_expect_success \ + 'Q: verify fourth notes tree' \ + 'git cat-file -p refs/notes/foobar^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual' + +echo "$note2b_data" >expect +test_expect_success \ + 'Q: verify second note for second commit' \ + 'git cat-file blob refs/notes/foobar:$commit2 >actual && test_cmp expect actual' + +### +### series R (feature and option) +### + +cat >input <<EOF +feature no-such-feature-exists +EOF + +test_expect_success 'R: abort on unsupported feature' ' + test_must_fail git fast-import <input +' + +cat >input <<EOF +feature date-format=now +EOF + +test_expect_success 'R: supported feature is accepted' ' + git fast-import <input +' + +cat >input << EOF +blob +data 3 +hi +feature date-format=now +EOF + +test_expect_success 'R: abort on receiving feature after data command' ' + test_must_fail git fast-import <input +' + +cat >input << EOF +feature import-marks=git.marks +feature import-marks=git2.marks +EOF + +test_expect_success 'R: only one import-marks feature allowed per stream' ' + test_must_fail git fast-import <input +' + +cat >input << EOF +feature export-marks=git.marks +blob +mark :1 +data 3 +hi + +EOF + +test_expect_success \ + 'R: export-marks feature results in a marks file being created' \ + 'cat input | git fast-import && + grep :1 git.marks' + +test_expect_success \ + 'R: export-marks options can be overriden by commandline options' \ + 'cat input | git fast-import --export-marks=other.marks && + grep :1 other.marks' + +cat >input << EOF +feature import-marks=marks.out +feature export-marks=marks.new +EOF + +test_expect_success \ + 'R: import to output marks works without any content' \ + 'cat input | git fast-import && + test_cmp marks.out marks.new' + +cat >input <<EOF +feature import-marks=nonexistant.marks +feature export-marks=marks.new +EOF + +test_expect_success \ + 'R: import marks prefers commandline marks file over the stream' \ + 'cat input | git fast-import --import-marks=marks.out && + test_cmp marks.out marks.new' + + +cat >input <<EOF +feature import-marks=nonexistant.marks +feature export-marks=combined.marks +EOF + +test_expect_success 'R: multiple --import-marks= should be honoured' ' + head -n2 marks.out > one.marks && + tail -n +3 marks.out > two.marks && + git fast-import --import-marks=one.marks --import-marks=two.marks <input && + test_cmp marks.out combined.marks +' + +cat >input <<EOF +feature relative-marks +feature import-marks=relative.in +feature export-marks=relative.out +EOF + +test_expect_success 'R: feature relative-marks should be honoured' ' + mkdir -p .git/info/fast-import/ && + cp marks.new .git/info/fast-import/relative.in && + git fast-import <input && + test_cmp marks.new .git/info/fast-import/relative.out +' + +cat >input <<EOF +feature relative-marks +feature import-marks=relative.in +feature no-relative-marks +feature export-marks=non-relative.out +EOF + +test_expect_success 'R: feature no-relative-marks should be honoured' ' + git fast-import <input && + test_cmp marks.new non-relative.out +' + +cat >input << EOF +option git quiet +blob +data 3 +hi + +EOF + +touch empty + +test_expect_success 'R: quiet option results in no stats being output' ' + cat input | git fast-import 2> output && + test_cmp empty output +' + +cat >input <<EOF +option git non-existing-option +EOF + +test_expect_success 'R: die on unknown option' ' + test_must_fail git fast-import <input +' + +test_expect_success 'R: unknown commandline options are rejected' '\ + test_must_fail git fast-import --non-existing-option < /dev/null +' + +cat >input <<EOF +option non-existing-vcs non-existing-option +EOF + +test_expect_success 'R: ignore non-git options' ' + git fast-import <input +' ## ## R: very large blobs diff --git a/t/t9301-fast-import-notes.sh b/t/t9301-fast-import-notes.sh new file mode 100755 index 0000000000..a5c99d8507 --- /dev/null +++ b/t/t9301-fast-import-notes.sh @@ -0,0 +1,623 @@ +#!/bin/sh +# +# Copyright (c) 2009 Johan Herland +# + +test_description='test git fast-import of notes objects' +. ./test-lib.sh + + +test_tick +cat >input <<INPUT_END +commit refs/heads/master +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +first commit +COMMIT + +M 644 inline foo +data <<EOF +file foo in first commit +EOF + +M 755 inline bar +data <<EOF +file bar in first commit +EOF + +M 644 inline baz/xyzzy +data <<EOF +file baz/xyzzy in first commit +EOF + +commit refs/heads/master +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +second commit +COMMIT + +M 644 inline foo +data <<EOF +file foo in second commit +EOF + +M 755 inline baz/xyzzy +data <<EOF +file baz/xyzzy in second commit +EOF + +commit refs/heads/master +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +third commit +COMMIT + +M 644 inline foo +data <<EOF +file foo in third commit +EOF + +commit refs/heads/master +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +fourth commit +COMMIT + +M 755 inline bar +data <<EOF +file bar in fourth commit +EOF + +INPUT_END + +test_expect_success 'set up master branch' ' + + git fast-import <input && + git whatchanged master +' + +commit4=$(git rev-parse refs/heads/master) +commit3=$(git rev-parse "$commit4^") +commit2=$(git rev-parse "$commit4~2") +commit1=$(git rev-parse "$commit4~3") + +test_tick +cat >input <<INPUT_END +commit refs/notes/test +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +first notes commit +COMMIT + +M 644 inline $commit1 +data <<EOF +first note for first commit +EOF + +M 755 inline $commit2 +data <<EOF +first note for second commit +EOF + +INPUT_END + +cat >expect <<EXPECT_END + fourth commit + third commit + second commit + first note for second commit + first commit + first note for first commit +EXPECT_END + +test_expect_success 'add notes with simple M command' ' + + git fast-import <input && + GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual && + test_cmp expect actual + +' + +test_tick +cat >input <<INPUT_END +commit refs/notes/test +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +second notes commit +COMMIT + +from refs/notes/test^0 +N inline $commit3 +data <<EOF +first note for third commit +EOF + +N inline $commit4 +data <<EOF +first note for fourth commit +EOF + +INPUT_END + +cat >expect <<EXPECT_END + fourth commit + first note for fourth commit + third commit + first note for third commit + second commit + first note for second commit + first commit + first note for first commit +EXPECT_END + +test_expect_success 'add notes with simple N command' ' + + git fast-import <input && + GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual && + test_cmp expect actual + +' + +test_tick +cat >input <<INPUT_END +commit refs/notes/test +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +third notes commit +COMMIT + +from refs/notes/test^0 +N inline $commit1 +data <<EOF +second note for first commit +EOF + +N inline $commit2 +data <<EOF +second note for second commit +EOF + +N inline $commit3 +data <<EOF +second note for third commit +EOF + +N inline $commit4 +data <<EOF +second note for fourth commit +EOF + +INPUT_END + +cat >expect <<EXPECT_END + fourth commit + second note for fourth commit + third commit + second note for third commit + second commit + second note for second commit + first commit + second note for first commit +EXPECT_END + +test_expect_success 'update existing notes with N command' ' + + git fast-import <input && + GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual && + test_cmp expect actual + +' + +test_tick +cat >input <<INPUT_END +commit refs/notes/test +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +fourth notes commit +COMMIT + +from refs/notes/test^0 +M 644 inline $(echo "$commit3" | sed "s|^..|&/|") +data <<EOF +prefix of note for third commit +EOF + +M 644 inline $(echo "$commit4" | sed "s|^..|&/|") +data <<EOF +prefix of note for fourth commit +EOF + +M 644 inline $(echo "$commit4" | sed "s|^\(..\)\(..\)|\1/\2/|") +data <<EOF +pre-prefix of note for fourth commit +EOF + +N inline $commit1 +data <<EOF +third note for first commit +EOF + +N inline $commit2 +data <<EOF +third note for second commit +EOF + +N inline $commit3 +data <<EOF +third note for third commit +EOF + +N inline $commit4 +data <<EOF +third note for fourth commit +EOF + + +INPUT_END + +cat >expect <<EXPECT_END + fourth commit + pre-prefix of note for fourth commit + prefix of note for fourth commit + third note for fourth commit + third commit + prefix of note for third commit + third note for third commit + second commit + third note for second commit + first commit + third note for first commit +EXPECT_END + +test_expect_success 'add concatentation notes with M command' ' + + git fast-import <input && + GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual && + test_cmp expect actual + +' + +test_tick +cat >input <<INPUT_END +commit refs/notes/test +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +fifth notes commit +COMMIT + +from refs/notes/test^0 +deleteall + +INPUT_END + +cat >expect <<EXPECT_END + fourth commit + third commit + second commit + first commit +EXPECT_END + +test_expect_success 'verify that deleteall also removes notes' ' + + git fast-import <input && + GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual && + test_cmp expect actual + +' + +test_tick +cat >input <<INPUT_END +commit refs/notes/test +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +sixth notes commit +COMMIT + +from refs/notes/test^0 +M 644 inline $commit1 +data <<EOF +third note for first commit +EOF + +M 644 inline $commit3 +data <<EOF +third note for third commit +EOF + +N inline $commit1 +data <<EOF +fourth note for first commit +EOF + +N inline $commit3 +data <<EOF +fourth note for third commit +EOF + +INPUT_END + +cat >expect <<EXPECT_END + fourth commit + third commit + fourth note for third commit + second commit + first commit + fourth note for first commit +EXPECT_END + +test_expect_success 'verify that later N commands override earlier M commands' ' + + git fast-import <input && + GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual && + test_cmp expect actual + +' + +# Write fast-import commands to create the given number of commits +fast_import_commits () { + my_ref=$1 + my_num_commits=$2 + my_append_to_file=$3 + my_i=0 + while test $my_i -lt $my_num_commits + do + my_i=$(($my_i + 1)) + test_tick + cat >>"$my_append_to_file" <<INPUT_END +commit $my_ref +mark :$my_i +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +commit #$my_i +COMMIT + +M 644 inline file +data <<EOF +file contents in commit #$my_i +EOF + +INPUT_END + done +} + +# Write fast-import commands to create the given number of notes annotating +# the commits created by fast_import_commits() +fast_import_notes () { + my_notes_ref=$1 + my_num_commits=$2 + my_append_to_file=$3 + my_note_append=$4 + test_tick + cat >>"$my_append_to_file" <<INPUT_END +commit $my_notes_ref +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +committing $my_num_commits notes +COMMIT + +INPUT_END + + my_i=0 + while test $my_i -lt $my_num_commits + do + my_i=$(($my_i + 1)) + cat >>"$my_append_to_file" <<INPUT_END +N inline :$my_i +data <<EOF +note for commit #$my_i$my_note_append +EOF + +INPUT_END + done +} + + +rm input expect +num_commits=400 +# Create lots of commits +fast_import_commits "refs/heads/many_commits" $num_commits input +# Create one note per above commit +fast_import_notes "refs/notes/many_notes" $num_commits input +# Add a couple of non-notes as well +test_tick +cat >>input <<INPUT_END +commit refs/notes/many_notes +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +committing some non-notes to the notes tree +COMMIT + +M 755 inline foobar/non-note.txt +data <<EOF +This is not a note, but rather a regular file residing in a notes tree +EOF + +M 644 inline deadbeef +data <<EOF +Non-note file +EOF + +M 644 inline de/adbeef +data <<EOF +Another non-note file +EOF + +INPUT_END +# Finally create the expected output from all these notes and commits +i=$num_commits +while test $i -gt 0 +do + cat >>expect <<EXPECT_END + commit #$i + note for commit #$i +EXPECT_END + i=$(($i - 1)) +done + +test_expect_success 'add lots of commits and notes' ' + + git fast-import <input && + GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits | + grep "^ " > actual && + test_cmp expect actual + +' + +test_expect_success 'verify that lots of notes trigger a fanout scheme' ' + + # None of the entries in the top-level notes tree should be a full SHA1 + git ls-tree --name-only refs/notes/many_notes | + while read path + do + if test $(expr length "$path") -ge 40 + then + return 1 + fi + done + +' + +cat >>expect_non-note1 << EOF +This is not a note, but rather a regular file residing in a notes tree +EOF + +cat >>expect_non-note2 << EOF +Non-note file +EOF + +cat >>expect_non-note3 << EOF +Another non-note file +EOF + +test_expect_success 'verify that non-notes are untouched by a fanout change' ' + + git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual && + test_cmp expect_non-note1 actual && + git cat-file -p refs/notes/many_notes:deadbeef > actual && + test_cmp expect_non-note2 actual && + git cat-file -p refs/notes/many_notes:de/adbeef > actual && + test_cmp expect_non-note3 actual + +' +remaining_notes=10 +test_tick +cat >>input <<INPUT_END +commit refs/notes/many_notes +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +data <<COMMIT +removing all notes but $remaining_notes +COMMIT +from refs/notes/many_notes^0 +INPUT_END + +i=$remaining_notes +while test $i -lt $num_commits +do + i=$(($i + 1)) + cat >>input <<INPUT_END +N 0000000000000000000000000000000000000000 :$i +INPUT_END +done + +i=$num_commits +rm expect +while test $i -gt 0 +do + cat >>expect <<EXPECT_END + commit #$i +EXPECT_END + if test $i -le $remaining_notes + then + cat >>expect <<EXPECT_END + note for commit #$i +EXPECT_END + fi + i=$(($i - 1)) +done + +test_expect_success 'remove lots of notes' ' + + git fast-import <input && + GIT_NOTES_REF=refs/notes/many_notes git log refs/heads/many_commits | + grep "^ " > actual && + test_cmp expect actual + +' + +test_expect_success 'verify that removing notes trigger fanout consolidation' ' + + # All entries in the top-level notes tree should be a full SHA1 + git ls-tree --name-only -r refs/notes/many_notes | + while read path + do + # Explicitly ignore the non-note paths + test "$path" = "foobar/non-note.txt" && continue + test "$path" = "deadbeef" && continue + test "$path" = "de/adbeef" && continue + + if test $(expr length "$path") -ne 40 + then + return 1 + fi + done + +' + +test_expect_success 'verify that non-notes are untouched by a fanout change' ' + + git cat-file -p refs/notes/many_notes:foobar/non-note.txt > actual && + test_cmp expect_non-note1 actual && + git cat-file -p refs/notes/many_notes:deadbeef > actual && + test_cmp expect_non-note2 actual && + git cat-file -p refs/notes/many_notes:de/adbeef > actual && + test_cmp expect_non-note3 actual + +' + + +rm input expect +num_notes_refs=10 +num_commits=16 +some_commits=8 +# Create commits +fast_import_commits "refs/heads/more_commits" $num_commits input +# Create one note per above commit per notes ref +i=0 +while test $i -lt $num_notes_refs +do + i=$(($i + 1)) + fast_import_notes "refs/notes/more_notes_$i" $num_commits input +done +# Trigger branch reloading in git-fast-import by repeating the note creation +i=0 +while test $i -lt $num_notes_refs +do + i=$(($i + 1)) + fast_import_notes "refs/notes/more_notes_$i" $some_commits input " (2)" +done +# Finally create the expected output from the notes in refs/notes/more_notes_1 +i=$num_commits +while test $i -gt 0 +do + note_data="note for commit #$i" + if test $i -le $some_commits + then + note_data="$note_data (2)" + fi + cat >>expect <<EXPECT_END + commit #$i + $note_data +EXPECT_END + i=$(($i - 1)) +done + +test_expect_success "add notes to $num_commits commits in each of $num_notes_refs refs" ' + + git fast-import --active-branches=5 <input && + GIT_NOTES_REF=refs/notes/more_notes_1 git log refs/heads/more_commits | + grep "^ " > actual && + test_cmp expect actual + +' + +test_done diff --git a/t/t9301-fast-export.sh b/t/t9350-fast-export.sh index 356964e53a..d43f37ccaf 100755 --- a/t/t9301-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -150,20 +150,22 @@ test_expect_success 'setup submodule' ' git checkout -f master && mkdir sub && - cd sub && - git init && - echo test file > file && - git add file && - git commit -m sub_initial && - cd .. && + ( + cd sub && + git init && + echo test file > file && + git add file && + git commit -m sub_initial + ) && git submodule add "`pwd`/sub" sub && git commit -m initial && test_tick && - cd sub && - echo more data >> file && - git add file && - git commit -m sub_second && - cd .. && + ( + cd sub && + echo more data >> file && + git add file && + git commit -m sub_second + ) && git add sub && git commit -m second @@ -264,19 +266,20 @@ test_expect_success 'cope with tagger-less tags' ' test_expect_success 'setup for limiting exports by PATH' ' mkdir limit-by-paths && - cd limit-by-paths && - git init && - echo hi > there && - git add there && - git commit -m "First file" && - echo foo > bar && - git add bar && - git commit -m "Second file" && - git tag -a -m msg mytag && - echo morefoo >> bar && - git add bar && - git commit -m "Change to second file" && - cd .. + ( + cd limit-by-paths && + git init && + echo hi > there && + git add there && + git commit -m "First file" && + echo foo > bar && + git add bar && + git commit -m "Second file" && + git tag -a -m msg mytag && + echo morefoo >> bar && + git add bar && + git commit -m "Change to second file" + ) ' cat > limit-by-paths/expected << EOF @@ -297,10 +300,11 @@ M 100644 :1 there EOF test_expect_success 'dropping tag of filtered out object' ' +( cd limit-by-paths && git fast-export --tag-of-filtered-object=drop mytag -- there > output && - test_cmp output expected && - cd .. + test_cmp output expected +) ' cat >> limit-by-paths/expected << EOF @@ -313,10 +317,11 @@ msg EOF test_expect_success 'rewriting tag of filtered out object' ' +( cd limit-by-paths && git fast-export --tag-of-filtered-object=rewrite mytag -- there > output && - test_cmp output expected && - cd .. + test_cmp output expected +) ' cat > limit-by-paths/expected << EOF @@ -343,13 +348,13 @@ M 100644 :2 there EOF test_expect_failure 'no exact-ref revisions included' ' - cd limit-by-paths && - git fast-export master~2..master~1 > output && - test_cmp output expected && - cd .. + ( + cd limit-by-paths && + git fast-export master~2..master~1 > output && + test_cmp output expected + ) ' - test_expect_success 'set-up a few more tags for tag export tests' ' git checkout -f master && HEAD_TREE=`git show -s --pretty=raw HEAD | grep tree | sed "s/tree //"` && diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index c2ec3cb4bd..daef2d6c23 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -96,7 +96,7 @@ EOF test_expect_success 'pserver authentication' \ 'cat request-anonymous | git-cvsserver pserver >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU$"' + sed -ne \$p log | grep "^I LOVE YOU\$"' test_expect_success 'pserver authentication failure (non-anonymous user)' \ 'if cat request-git | git-cvsserver pserver >log 2>&1 @@ -105,11 +105,11 @@ test_expect_success 'pserver authentication failure (non-anonymous user)' \ else true fi && - sed -ne \$p log | grep "^I HATE YOU$"' + sed -ne \$p log | grep "^I HATE YOU\$"' test_expect_success 'pserver authentication (login)' \ 'cat login-anonymous | git-cvsserver pserver >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU$"' + sed -ne \$p log | grep "^I LOVE YOU\$"' test_expect_success 'pserver authentication failure (login/non-anonymous user)' \ 'if cat login-git | git-cvsserver pserver >log 2>&1 @@ -118,7 +118,7 @@ test_expect_success 'pserver authentication failure (login/non-anonymous user)' else true fi && - sed -ne \$p log | grep "^I HATE YOU$"' + sed -ne \$p log | grep "^I HATE YOU\$"' # misuse pserver authentication for testing of req_Root @@ -156,7 +156,7 @@ test_expect_success 'req_Root failure (conflicting roots)' \ test_expect_success 'req_Root (strict paths)' \ 'cat request-anonymous | git-cvsserver --strict-paths pserver "$SERVERDIR" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU$"' + sed -ne \$p log | grep "^I LOVE YOU\$"' test_expect_success 'req_Root failure (strict-paths)' ' ! cat request-anonymous | @@ -165,7 +165,7 @@ test_expect_success 'req_Root failure (strict-paths)' ' test_expect_success 'req_Root (w/o strict-paths)' \ 'cat request-anonymous | git-cvsserver pserver "$WORKDIR/" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU$"' + sed -ne \$p log | grep "^I LOVE YOU\$"' test_expect_success 'req_Root failure (w/o strict-paths)' ' ! cat request-anonymous | @@ -183,7 +183,7 @@ EOF test_expect_success 'req_Root (base-path)' \ 'cat request-base | git-cvsserver --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU$"' + sed -ne \$p log | grep "^I LOVE YOU\$"' test_expect_success 'req_Root failure (base-path)' ' ! cat request-anonymous | @@ -194,14 +194,14 @@ GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false || exit 1 test_expect_success 'req_Root (export-all)' \ 'cat request-anonymous | git-cvsserver --export-all pserver "$WORKDIR" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU$"' + sed -ne \$p log | grep "^I LOVE YOU\$"' test_expect_success 'req_Root failure (export-all w/o whitelist)' \ '! (cat request-anonymous | git-cvsserver --export-all pserver >log 2>&1 || false)' test_expect_success 'req_Root (everything together)' \ 'cat request-base | git-cvsserver --export-all --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU$"' + sed -ne \$p log | grep "^I LOVE YOU\$"' GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true || exit 1 @@ -226,7 +226,7 @@ test_expect_success 'gitcvs.ext.enabled = true' \ 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false && GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 && - diff -q cvswork cvswork2' + test_cmp cvswork cvswork2' rm -fr cvswork2 test_expect_success 'gitcvs.ext.enabled = false' \ @@ -247,7 +247,7 @@ test_expect_success 'gitcvs.dbname' \ 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs.%a.%m.sqlite && GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 && - diff -q cvswork cvswork2 && + test_cmp cvswork cvswork2 && test -f "$SERVERDIR/gitcvs.ext.master.sqlite" && cmp "$SERVERDIR/gitcvs.master.sqlite" "$SERVERDIR/gitcvs.ext.master.sqlite"' @@ -257,7 +257,7 @@ test_expect_success 'gitcvs.ext.dbname' \ GIT_DIR="$SERVERDIR" git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite && GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 master >cvs.log 2>&1 && - diff -q cvswork cvswork2 && + test_cmp cvswork cvswork2 && test -f "$SERVERDIR/gitcvs1.ext.master.sqlite" && test ! -f "$SERVERDIR/gitcvs2.ext.master.sqlite" && cmp "$SERVERDIR/gitcvs.master.sqlite" "$SERVERDIR/gitcvs1.ext.master.sqlite"' @@ -282,7 +282,7 @@ test_expect_success 'cvs update (create new file)' \ cd cvswork && GIT_CONFIG="$git_config" cvs -Q update && test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.1/" && - diff -q testfile1 ../testfile1' + test_cmp testfile1 ../testfile1' cd "$WORKDIR" test_expect_success 'cvs update (update existing file)' \ @@ -293,7 +293,7 @@ test_expect_success 'cvs update (update existing file)' \ cd cvswork && GIT_CONFIG="$git_config" cvs -Q update && test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.2/" && - diff -q testfile1 ../testfile1' + test_cmp testfile1 ../testfile1' cd "$WORKDIR" #TODO: cvsserver doesn't support update w/o -d @@ -322,7 +322,7 @@ test_expect_success 'cvs update (subdirectories)' \ (for dir in A A/B A/B/C A/D E; do filename="file_in_$(echo $dir|sed -e "s#/# #g")" && if test "$(echo $(grep -v ^D $dir/CVS/Entries|cut -d/ -f2,3,5))" = "$filename/1.1/" && - diff -q "$dir/$filename" "../$dir/$filename"; then + test_cmp "$dir/$filename" "../$dir/$filename"; then : else echo >failure @@ -349,7 +349,7 @@ test_expect_success 'cvs update (re-add deleted file)' \ cd cvswork && GIT_CONFIG="$git_config" cvs -Q update && test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.4/" && - diff -q testfile1 ../testfile1' + test_cmp testfile1 ../testfile1' cd "$WORKDIR" test_expect_success 'cvs update (merge)' \ @@ -366,7 +366,7 @@ test_expect_success 'cvs update (merge)' \ cd cvswork && GIT_CONFIG="$git_config" cvs -Q update && test "$(echo $(grep merge CVS/Entries|cut -d/ -f2,3,5))" = "merge/1.1/" && - diff -q merge ../merge && + test_cmp merge ../merge && ( echo Line 0; cat merge ) >merge.tmp && mv merge.tmp merge && cd "$WORKDIR" && @@ -377,7 +377,7 @@ test_expect_success 'cvs update (merge)' \ cd cvswork && sleep 1 && touch merge && GIT_CONFIG="$git_config" cvs -Q update && - diff -q merge ../expected' + test_cmp merge ../expected' cd "$WORKDIR" @@ -402,13 +402,13 @@ test_expect_success 'cvs update (conflict merge)' \ git push gitcvs.git >/dev/null && cd cvswork && GIT_CONFIG="$git_config" cvs -Q update && - diff -q merge ../expected.C' + test_cmp merge ../expected.C' cd "$WORKDIR" test_expect_success 'cvs update (-C)' \ 'cd cvswork && GIT_CONFIG="$git_config" cvs -Q update -C && - diff -q merge ../merge' + test_cmp merge ../merge' cd "$WORKDIR" test_expect_success 'cvs update (merge no-op)' \ @@ -420,7 +420,7 @@ test_expect_success 'cvs update (merge no-op)' \ cd cvswork && sleep 1 && touch merge && GIT_CONFIG="$git_config" cvs -Q update && - diff -q merge ../merge' + test_cmp merge ../merge' cd "$WORKDIR" test_expect_success 'cvs update (-p)' ' diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index 40637d6782..ed7b513f3e 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -11,14 +11,6 @@ repository using cvs CLI client via git-cvsserver server' . ./test-lib.sh -q_to_nul () { - perl -pe 'y/Q/\000/' -} - -q_to_cr () { - tr Q '\015' -} - marked_as () { foundEntry="$(grep "^/$2/" "$1/CVS/Entries")" if [ x"$foundEntry" = x"" ] ; then diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 2fc7fdb124..63b6b060e6 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -591,14 +591,22 @@ test_debug 'cat gitweb.log' # ---------------------------------------------------------------------- # gitweb config and repo config -cat >>gitweb_config.perl <<EOF - -\$feature{'blame'}{'override'} = 1; -\$feature{'snapshot'}{'override'} = 1; -\$feature{'avatar'}{'override'} = 1; +cat >>gitweb_config.perl <<\EOF + +# turn on override for each overridable feature +foreach my $key (keys %feature) { + if ($feature{$key}{'sub'}) { + $feature{$key}{'override'} = 1; + } +} EOF test_expect_success \ + 'config override: projects list (implicit)' \ + 'gitweb_run' +test_debug 'cat gitweb.log' + +test_expect_success \ 'config override: tree view, features not overridden in repo config' \ 'gitweb_run "p=.git;a=tree"' test_debug 'cat gitweb.log' diff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh index 0688a57e1d..d196cc5ca9 100755 --- a/t/t9501-gitweb-standalone-http-status.sh +++ b/t/t9501-gitweb-standalone-http-status.sh @@ -33,7 +33,6 @@ test_expect_success \ grep "403 - Snapshot format not allowed" gitweb.output && gitweb_run "p=.git;a=snapshot;h=HEAD;sf=zip" && grep "403 - Unsupported snapshot format" gitweb.output' -test_debug 'cat gitweb.output' cat >>gitweb_config.perl <<\EOF @@ -50,7 +49,6 @@ test_expect_success \ grep "403 - Snapshot format not allowed" gitweb.output && gitweb_run "p=.git;a=snapshot;h=HEAD;sf=zip" && grep "Status: 200 OK" gitweb.output' -test_debug 'cat gitweb.output' cat >>gitweb_config.perl <<\EOF @@ -72,7 +70,7 @@ test_expect_success \ 'snapshots: tgz explicitly enabled' \ 'gitweb_run "p=.git;a=snapshot;h=HEAD;sf=tgz" && grep "Status: 200 OK" gitweb.output' -test_debug 'cat gitweb.output' +test_debug 'cat gitweb.headers' # ---------------------------------------------------------------------- @@ -82,7 +80,7 @@ test_expect_success 'snapshots: good tree-ish id' ' gitweb_run "p=.git;a=snapshot;h=master;sf=tgz" && grep "Status: 200 OK" gitweb.output ' -test_debug 'cat gitweb.output' +test_debug 'cat gitweb.headers' test_expect_success 'snapshots: bad tree-ish id' ' gitweb_run "p=.git;a=snapshot;h=frizzumFrazzum;sf=tgz" && @@ -105,7 +103,7 @@ test_expect_success 'snapshots: good object id' ' gitweb_run "p=.git;a=snapshot;h=$ID;sf=tgz" && grep "Status: 200 OK" gitweb.output ' -test_debug 'cat gitweb.output' +test_debug 'cat gitweb.headers' test_expect_success 'snapshots: bad object id' ' gitweb_run "p=.git;a=snapshot;h=abcdef01234;sf=tgz" && @@ -114,4 +112,26 @@ test_expect_success 'snapshots: bad object id' ' test_debug 'cat gitweb.output' +# ---------------------------------------------------------------------- +# load checking + +# always hit the load limit +cat >>gitweb_config.perl <<\EOF +our $maxload = -1; +EOF + +test_expect_success 'load checking: load too high (default action)' ' + gitweb_run "p=.git" && + grep "Status: 503 Service Unavailable" gitweb.headers && + grep "503 - The load average on the server is too high" gitweb.body +' +test_debug 'cat gitweb.log' # just in case +test_debug 'cat gitweb.headers' + +# turn off load checking +cat >>gitweb_config.perl <<\EOF +our $maxload = undef; +EOF + + test_done diff --git a/t/test-lib.sh b/t/test-lib.sh index ec3336aba5..a0e396a952 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -65,6 +65,8 @@ GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u} # CDPATH into the environment unset CDPATH +unset GREP_OPTIONS + case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in 1|2|true) echo "* warning: Some tests will not work if GIT_TRACE" \ @@ -74,6 +76,12 @@ case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in ;; esac +# Convenience +# +# A regexp to match 5 and 40 hexdigits +_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]' +_x40="$_x05$_x05$_x05$_x05$_x05$_x05$_x05$_x05" + # Each test should start with something like this, after copyright notices: # # test_description='Description of this test... @@ -105,6 +113,8 @@ do verbose=t; shift ;; -q|--q|--qu|--qui|--quie|--quiet) quiet=t; shift ;; + --with-dashes) + with_dashes=t; shift ;; --no-color) color=; shift ;; --no-python) @@ -211,6 +221,33 @@ test_set_editor () { export EDITOR } +test_decode_color () { + sed -e 's/.\[1m/<WHITE>/g' \ + -e 's/.\[31m/<RED>/g' \ + -e 's/.\[32m/<GREEN>/g' \ + -e 's/.\[33m/<YELLOW>/g' \ + -e 's/.\[34m/<BLUE>/g' \ + -e 's/.\[35m/<MAGENTA>/g' \ + -e 's/.\[36m/<CYAN>/g' \ + -e 's/.\[m/<RESET>/g' +} + +q_to_nul () { + perl -pe 'y/Q/\000/' +} + +q_to_cr () { + tr Q '\015' +} + +append_cr () { + sed -e 's/$/Q/' | tr Q '\015' +} + +remove_cr () { + tr '\015' Q | sed -e 's/Q$//' +} + test_tick () { if test -z "${test_tick+set}" then @@ -551,19 +588,8 @@ test_done () { # Test the binaries we have just built. The tests are kept in # t/ subdirectory and are run in 'trash directory' subdirectory. TEST_DIRECTORY=$(pwd) -if test -z "$valgrind" +if test -n "$valgrind" then - if test -z "$GIT_TEST_INSTALLED" - then - PATH=$TEST_DIRECTORY/..:$PATH - GIT_EXEC_PATH=$TEST_DIRECTORY/.. - else - GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path) || - error "Cannot run git from $GIT_TEST_INSTALLED." - PATH=$GIT_TEST_INSTALLED:$TEST_DIRECTORY/..:$PATH - GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH} - fi -else make_symlink () { test -h "$2" && test "$1" = "$(readlink "$2")" || { @@ -625,6 +651,24 @@ else PATH=$GIT_VALGRIND/bin:$PATH GIT_EXEC_PATH=$GIT_VALGRIND/bin export GIT_VALGRIND +elif test -n "$GIT_TEST_INSTALLED" ; then + GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path) || + error "Cannot run git from $GIT_TEST_INSTALLED." + PATH=$GIT_TEST_INSTALLED:$TEST_DIRECTORY/..:$PATH + GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH} +else # normal case, use ../bin-wrappers only unless $with_dashes: + git_bin_dir="$TEST_DIRECTORY/../bin-wrappers" + if ! test -x "$git_bin_dir/git" ; then + if test -z "$with_dashes" ; then + say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH" + fi + with_dashes=t + fi + PATH="$git_bin_dir:$PATH" + GIT_EXEC_PATH=$TEST_DIRECTORY/.. + if test -n "$with_dashes" ; then + PATH="$TEST_DIRECTORY/..:$PATH" + fi fi GIT_TEMPLATE_DIR=$(pwd)/../templates/blt unset GIT_CONFIG @@ -632,20 +676,29 @@ GIT_CONFIG_NOSYSTEM=1 GIT_CONFIG_NOGLOBAL=1 export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOBAL +. ../GIT-BUILD-OPTIONS + GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git export GITPERLLIB test -d ../templates/blt || { error "You haven't built things yet, have you?" } +if test -z "$GIT_TEST_INSTALLED" && test -z "$NO_PYTHON" +then + GITPYTHONLIB="$(pwd)/../git_remote_helpers/build/lib" + export GITPYTHONLIB + test -d ../git_remote_helpers/build || { + error "You haven't built git_remote_helpers yet, have you?" + } +fi + if ! test -x ../test-chmtime; then echo >&2 'You need to build test-chmtime:' echo >&2 'Run "make test-chmtime" in the source (toplevel) directory' exit 1 fi -. ../GIT-BUILD-OPTIONS - # Test repository test="trash directory.$(basename "$0" .sh)" test -n "$root" && test="$root/$test" @@ -729,6 +782,7 @@ case $(uname -s) in esac test -z "$NO_PERL" && test_set_prereq PERL +test -z "$NO_PYTHON" && test_set_prereq PYTHON # test whether the filesystem supports symbolic links ln -s x y 2>/dev/null && test -h y 2>/dev/null && test_set_prereq SYMLINKS |