diff options
Diffstat (limited to 't')
192 files changed, 4324 insertions, 786 deletions
diff --git a/t/Git-SVN/00compile.t b/t/Git-SVN/00compile.t index c92fee453f..c92fee453f 100644..100755 --- a/t/Git-SVN/00compile.t +++ b/t/Git-SVN/00compile.t diff --git a/t/Git-SVN/Utils/add_path_to_url.t b/t/Git-SVN/Utils/add_path_to_url.t index bfbd87845f..bfbd87845f 100644..100755 --- a/t/Git-SVN/Utils/add_path_to_url.t +++ b/t/Git-SVN/Utils/add_path_to_url.t diff --git a/t/Git-SVN/Utils/can_compress.t b/t/Git-SVN/Utils/can_compress.t index d7b49b8d54..d7b49b8d54 100644..100755 --- a/t/Git-SVN/Utils/can_compress.t +++ b/t/Git-SVN/Utils/can_compress.t diff --git a/t/Git-SVN/Utils/canonicalize_url.t b/t/Git-SVN/Utils/canonicalize_url.t index 05795ab636..05795ab636 100644..100755 --- a/t/Git-SVN/Utils/canonicalize_url.t +++ b/t/Git-SVN/Utils/canonicalize_url.t diff --git a/t/Git-SVN/Utils/collapse_dotdot.t b/t/Git-SVN/Utils/collapse_dotdot.t index 1da1cce156..1da1cce156 100644..100755 --- a/t/Git-SVN/Utils/collapse_dotdot.t +++ b/t/Git-SVN/Utils/collapse_dotdot.t diff --git a/t/Git-SVN/Utils/fatal.t b/t/Git-SVN/Utils/fatal.t index 49e1438295..49e1438295 100644..100755 --- a/t/Git-SVN/Utils/fatal.t +++ b/t/Git-SVN/Utils/fatal.t diff --git a/t/Git-SVN/Utils/join_paths.t b/t/Git-SVN/Utils/join_paths.t index d4488e7162..d4488e7162 100644..100755 --- a/t/Git-SVN/Utils/join_paths.t +++ b/t/Git-SVN/Utils/join_paths.t @@ -340,7 +340,11 @@ Don't: - use perl without spelling it as "$PERL_PATH". This is to help our friends on Windows where the platform Perl often adds CR before the end of line, and they bundle Git with a version of Perl that - does not do so, whose path is specified with $PERL_PATH. + does not do so, whose path is specified with $PERL_PATH. Note that we + provide a "perl" function which uses $PERL_PATH under the hood, so + you do not need to worry when simply running perl in the test scripts + (but you do, for example, on a shebang line or in a sub script + created via "write_script"). - use sh without spelling it as "$SHELL_PATH", when the script can be misinterpreted by broken platform shell (e.g. Solaris). @@ -387,7 +391,7 @@ of the test_* functions (see the "Test harness library" section below), e.g.: test_expect_success PERL 'I need Perl' ' - "$PERL_PATH" -e "hlagh() if unf_unf()" + perl -e "hlagh() if unf_unf()" ' The advantage of skipping tests like this is that platforms that don't @@ -520,7 +524,7 @@ library for your script to use. test_external \ 'GitwebCache::*FileCache*' \ - "$PERL_PATH" "$TEST_DIRECTORY"/t9503/test_cache_interface.pl + perl "$TEST_DIRECTORY"/t9503/test_cache_interface.pl If the test is outputting its own TAP you should set the test_external_has_tap variable somewhere before calling the first @@ -536,7 +540,7 @@ library for your script to use. test_external_without_stderr \ 'Perl API' \ - "$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl + perl "$TEST_DIRECTORY"/t9700/test.pl - test_expect_code <exit-code> <command> @@ -629,11 +633,18 @@ See the prereq argument to the test_* functions in the "Test harness library" section above and the "test_have_prereq" function for how to use these, and "test_set_prereq" for how to define your own. - - PERL & PYTHON + - PYTHON - Git wasn't compiled with NO_PERL=YesPlease or - NO_PYTHON=YesPlease. Wrap any tests that need Perl or Python in - these. + Git wasn't compiled with NO_PYTHON=YesPlease. Wrap any tests that + need Python with this. + + - PERL + + Git wasn't compiled with NO_PERL=YesPlease. + + Even without the PERL prerequisite, tests can assume there is a + usable perl interpreter at $PERL_PATH, though it need not be + particularly modern. - POSIXPERM diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index 99caa42f5c..304c7b7d87 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -92,7 +92,7 @@ test_expect_success 'blame 2 authors + 1 branch2 author' ' ' test_expect_success 'merge branch1 & branch2' ' - git pull . branch1 + git merge branch1 ' test_expect_success 'blame 2 authors + 2 merged-in authors' ' @@ -116,6 +116,27 @@ test_expect_success 'blame evil merge' ' check_count A 2 B 1 B1 2 B2 1 "A U Thor" 1 ' +test_expect_success 'blame huge graft' ' + test_when_finished "git checkout branch2" && + test_when_finished "rm -f .git/info/grafts" && + graft= && + for i in 0 1 2 + do + for j in 0 1 2 3 4 5 6 7 8 9 + do + git checkout --orphan "$i$j" && + printf "%s\n" "$i" "$j" >file && + test_tick && + GIT_AUTHOR_NAME=$i$j GIT_AUTHOR_EMAIL=$i$j@test.git \ + git commit -a -m "$i$j" && + commit=$(git rev-parse --verify HEAD) && + graft="$graft$commit " + done + done && + printf "%s " $graft >.git/info/grafts && + check_count -h 00 01 1 10 1 +' + test_expect_success 'setup incomplete line' ' echo "incomplete" | tr -d "\\012" >>file && GIT_AUTHOR_NAME="C" GIT_AUTHOR_EMAIL="C@test.git" \ diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh index 9e381e000f..d5dab5a94f 100644 --- a/t/gitweb-lib.sh +++ b/t/gitweb-lib.sh @@ -1,4 +1,5 @@ -#!/bin/sh +# Initialization and helpers for Gitweb tests, which source this +# shell library instead of test-lib.sh. # # Copyright (c) 2007 Jakub Narebski # @@ -69,7 +70,7 @@ gitweb_run () { # written to web server logs, so we are not interested in that: # we are interested only in properly formatted errors/warnings rm -f gitweb.log && - "$PERL_PATH" -- "$SCRIPT_NAME" \ + perl -- "$SCRIPT_NAME" \ >gitweb.output 2>gitweb.log && perl -w -e ' open O, ">gitweb.headers"; diff --git a/t/lib-bash.sh b/t/lib-bash.sh index 11397f747b..2be955fafb 100644 --- a/t/lib-bash.sh +++ b/t/lib-bash.sh @@ -1,7 +1,6 @@ -#!/bin/sh -# -# Ensures that tests are run under Bash; primarily intended for running tests -# of the completion script. +# Shell library sourced instead of ./test-lib.sh by tests that need +# to run under Bash; primarily intended for tests of the completion +# script. if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then # we are in full-on bash mode diff --git a/t/lib-credential.sh b/t/lib-credential.sh index 3c43ff11b3..957ae936e8 100755 --- a/t/lib-credential.sh +++ b/t/lib-credential.sh @@ -18,10 +18,6 @@ check() { cat stderr && false fi && - if test_have_prereq MINGW - then - dos2unix -q stderr - fi && test_cmp expect-stdout stdout && test_cmp expect-stderr stderr } diff --git a/t/lib-cvs.sh b/t/lib-cvs.sh index 44263ade25..5076718916 100644 --- a/t/lib-cvs.sh +++ b/t/lib-cvs.sh @@ -1,4 +1,4 @@ -#!/bin/sh +# Shell library sourced instead of ./test-lib.sh by cvsimport tests. . ./test-lib.sh diff --git a/t/lib-diff-alternative.sh b/t/lib-diff-alternative.sh index 75ffd9174f..8b4dbf22d2 100644 --- a/t/lib-diff-alternative.sh +++ b/t/lib-diff-alternative.sh @@ -1,4 +1,5 @@ -#!/bin/sh +# Helpers shared by the test scripts for diff algorithms (patience, +# histogram, etc). test_diff_frobnitz() { cat >file1 <<\EOF diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh index ae8883a075..eec757f104 100644 --- a/t/lib-gettext.sh +++ b/t/lib-gettext.sh @@ -1,4 +1,5 @@ -#!/bin/sh +# Initialization and Icelandic locale for basic git i18n tests, +# which source this scriptlet instead of ./test-lib.sh. # # Copyright (c) 2010 Ævar Arnfjörð Bjarmason # diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh index 87f0ad8f41..bc4b3412fb 100644 --- a/t/lib-git-daemon.sh +++ b/t/lib-git-daemon.sh @@ -1,12 +1,29 @@ -#!/bin/sh +# Shell library to run git-daemon in tests. Ends the test early if +# GIT_TEST_GIT_DAEMON is not set. +# +# Usage: +# +# . ./test-lib.sh +# . "$TEST_DIRECTORY"/lib-git-daemon.sh +# start_git_daemon +# +# test_expect_success '...' ' +# ... +# ' +# +# test_expect_success ... +# +# stop_git_daemon +# test_done -if test -z "$GIT_TEST_GIT_DAEMON" +test_tristate GIT_TEST_GIT_DAEMON +if test "$GIT_TEST_GIT_DAEMON" = false then - skip_all="git-daemon testing disabled (define GIT_TEST_GIT_DAEMON to enable)" + skip_all="git-daemon testing disabled (unset GIT_TEST_GIT_DAEMON to enable)" test_done fi -LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-'8121'} +LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-${this_test#t}} GIT_DAEMON_PID= GIT_DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo @@ -42,7 +59,8 @@ start_git_daemon() { kill "$GIT_DAEMON_PID" wait "$GIT_DAEMON_PID" trap 'die' EXIT - error "git daemon failed to start" + test_skip_or_die $GIT_TEST_GIT_DAEMON \ + "git daemon failed to start" fi } diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh index ccd918e79e..5aa8adcf9c 100644 --- a/t/lib-git-p4.sh +++ b/t/lib-git-p4.sh @@ -47,15 +47,22 @@ P4DPORT=$((10669 + ($testid - $git_p4_test_start))) P4PORT=localhost:$P4DPORT P4CLIENT=client -P4EDITOR=: +P4USER=author +P4EDITOR=true unset P4CHARSET -export P4PORT P4CLIENT P4EDITOR P4CHARSET +export P4PORT P4CLIENT P4USER P4EDITOR P4CHARSET db="$TRASH_DIRECTORY/db" cli="$TRASH_DIRECTORY/cli" git="$TRASH_DIRECTORY/git" pidfile="$TRASH_DIRECTORY/p4d.pid" +# git p4 submit generates a temp file, which will +# not get cleaned up if the submission fails. Don't +# clutter up /tmp on the test machine. +TMPDIR="$TRASH_DIRECTORY" +export TMPDIR + start_p4d() { mkdir -p "$db" "$cli" "$git" && rm -f "$pidfile" && @@ -96,12 +103,24 @@ start_p4d() { return 1 fi + # build a p4 user so author@example.com has an entry + p4_add_user author + # build a client client_view "//depot/... //client/..." && return 0 } +p4_add_user() { + name=$1 && + p4 user -f -i <<-EOF + User: $name + Email: $name@example.com + FullName: Dr. $name + EOF +} + kill_p4d() { pid=$(cat "$pidfile") # it had better exist for the first kill diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index c5e55b190b..b0ec12ff6c 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -29,7 +29,7 @@ export svnrepo svnconf=$PWD/svnconf export svnconf -"$PERL_PATH" -w -e " +perl -w -e " use SVN::Core; use SVN::Repos; \$SVN::Core::VERSION gt '1.1.0' or exit(42); @@ -146,7 +146,7 @@ stop_httpd () { } convert_to_rev_db () { - "$PERL_PATH" -w -- - "$@" <<\EOF + perl -w -- - "$@" <<\EOF use strict; @ARGV == 2 or die "usage: convert_to_rev_db <input> <output>"; open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]"; diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 54dbbfe5ce..252cbf163b 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -1,11 +1,39 @@ -#!/bin/sh +# Shell library to run an HTTP server for use in tests. +# Ends the test early if httpd tests should not be run, +# for example because the user has not enabled them. +# +# Usage: +# +# . ./test-lib.sh +# . "$TEST_DIRECTORY"/lib-httpd.sh +# start_httpd +# +# test_expect_success '...' ' +# ... +# ' +# +# test_expect_success ... +# +# stop_httpd +# test_done +# +# Can be configured using the following variables. +# +# GIT_TEST_HTTPD enable HTTPD tests +# LIB_HTTPD_PATH web server path +# LIB_HTTPD_MODULE_PATH web server modules path +# LIB_HTTPD_PORT listening port +# LIB_HTTPD_DAV enable DAV +# LIB_HTTPD_SVN enable SVN +# LIB_HTTPD_SSL enable SSL # # Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at> # -if test -z "$GIT_TEST_HTTPD" +test_tristate GIT_TEST_HTTPD +if test "$GIT_TEST_HTTPD" = false then - skip_all="Network testing disabled (define GIT_TEST_HTTPD to enable)" + skip_all="Network testing disabled (unset GIT_TEST_HTTPD to enable)" test_done fi @@ -37,7 +65,7 @@ case $(uname) in esac LIB_HTTPD_PATH=${LIB_HTTPD_PATH-"$DEFAULT_HTTPD_PATH"} -LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'8111'} +LIB_HTTPD_PORT=${LIB_HTTPD_PORT-${this_test#t}} TEST_PATH="$TEST_DIRECTORY"/lib-httpd HTTPD_ROOT_PATH="$PWD"/httpd @@ -49,8 +77,7 @@ GIT_VALGRIND_OPTIONS=$GIT_VALGRIND_OPTIONS; export GIT_VALGRIND_OPTIONS if ! test -x "$LIB_HTTPD_PATH" then - skip_all="skipping test, no web server found at '$LIB_HTTPD_PATH'" - test_done + test_skip_or_die $GIT_TEST_HTTPD "no web server found at '$LIB_HTTPD_PATH'" fi HTTPD_VERSION=`$LIB_HTTPD_PATH -v | \ @@ -62,19 +89,20 @@ then then if ! test $HTTPD_VERSION -ge 2 then - skip_all="skipping test, at least Apache version 2 is required" - test_done + test_skip_or_die $GIT_TEST_HTTPD \ + "at least Apache version 2 is required" fi if ! test -d "$DEFAULT_HTTPD_MODULE_PATH" then - skip_all="Apache module directory not found. Skipping tests." - test_done + test_skip_or_die $GIT_TEST_HTTPD \ + "Apache module directory not found" fi LIB_HTTPD_MODULE_PATH="$DEFAULT_HTTPD_MODULE_PATH" fi else - error "Could not identify web server at '$LIB_HTTPD_PATH'" + test_skip_or_die $GIT_TEST_HTTPD \ + "Could not identify web server at '$LIB_HTTPD_PATH'" fi prepare_httpd() { @@ -102,7 +130,7 @@ prepare_httpd() { HTTPD_DEST=127.0.0.1:$LIB_HTTPD_PORT HTTPD_URL=$HTTPD_PROTO://$HTTPD_DEST HTTPD_URL_USER=$HTTPD_PROTO://user%40host@$HTTPD_DEST - HTTPD_URL_USER_PASS=$HTTPD_PROTO://user%40host:user%40host@$HTTPD_DEST + HTTPD_URL_USER_PASS=$HTTPD_PROTO://user%40host:pass%40host@$HTTPD_DEST if test -n "$LIB_HTTPD_DAV" -o -n "$LIB_HTTPD_SVN" then @@ -128,9 +156,8 @@ start_httpd() { >&3 2>&4 if test $? -ne 0 then - skip_all="skipping test, web server setup failed" trap 'die' EXIT - test_done + test_skip_or_die $GIT_TEST_HTTPD "web server setup failed" fi } @@ -190,7 +217,15 @@ setup_askpass_helper() { test_expect_success 'setup askpass helper' ' write_script "$TRASH_DIRECTORY/askpass" <<-\EOF && echo >>"$TRASH_DIRECTORY/askpass-query" "askpass: $*" && - cat "$TRASH_DIRECTORY/askpass-response" + case "$*" in + *Username*) + what=user + ;; + *Password*) + what=pass + ;; + esac && + cat "$TRASH_DIRECTORY/askpass-$what" EOF GIT_ASKPASS="$TRASH_DIRECTORY/askpass" && export GIT_ASKPASS && @@ -200,11 +235,13 @@ setup_askpass_helper() { set_askpass() { >"$TRASH_DIRECTORY/askpass-query" && - echo "$*" >"$TRASH_DIRECTORY/askpass-response" + echo "$1" >"$TRASH_DIRECTORY/askpass-user" && + echo "$2" >"$TRASH_DIRECTORY/askpass-pass" } expect_askpass() { - dest=$HTTPD_DEST + dest=$HTTPD_DEST${3+/$3} + { case "$1" in none) diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 397c480401..3a03e8263d 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -110,6 +110,8 @@ ScriptAlias /broken_smart/ broken-smart-http.sh/ RewriteEngine on RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301] RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302] +RewriteRule ^/smart-redir-auth/(.*)$ /auth/smart/$1 [R=301] +RewriteRule ^/smart-redir-limited/(.*)/info/refs$ /smart/$1/info/refs [R=301] <IfDefine SSL> LoadModule ssl_module modules/mod_ssl.so diff --git a/t/lib-httpd/passwd b/t/lib-httpd/passwd index f2fbcad33e..99a34d6487 100644 --- a/t/lib-httpd/passwd +++ b/t/lib-httpd/passwd @@ -1 +1 @@ -user@host:nKpa8pZUHx/ic +user@host:xb4E8pqD81KQs diff --git a/t/lib-pack.sh b/t/lib-pack.sh index 7e8685b44c..7509846571 100644 --- a/t/lib-pack.sh +++ b/t/lib-pack.sh @@ -1,5 +1,3 @@ -#!/bin/sh -# # Support routines for hand-crafting weird or malicious packs. # # You can make a complete pack like: @@ -12,10 +10,10 @@ # Print the big-endian 4-byte octal representation of $1 uint32_octal () { n=$1 - printf '\%o' $(($n / 16777216)); n=$((n % 16777216)) - printf '\%o' $(($n / 65536)); n=$((n % 65536)) - printf '\%o' $(($n / 256)); n=$((n % 256)) - printf '\%o' $(($n )); + printf '\\%o' $(($n / 16777216)); n=$((n % 16777216)) + printf '\\%o' $(($n / 65536)); n=$((n % 65536)) + printf '\\%o' $(($n / 256)); n=$((n % 256)) + printf '\\%o' $(($n )); } # Print the big-endian 4-byte binary representation of $1 diff --git a/t/lib-pager.sh b/t/lib-pager.sh index ba03eab14f..3aa7a3ffd8 100644 --- a/t/lib-pager.sh +++ b/t/lib-pager.sh @@ -1,4 +1,4 @@ -#!/bin/sh +# Helpers for tests of git's choice of pager. test_expect_success 'determine default pager' ' test_might_fail git config --unset core.pager && diff --git a/t/lib-prereq-FILEMODE.sh b/t/lib-prereq-FILEMODE.sh deleted file mode 100644 index bce5a4c8bd..0000000000 --- a/t/lib-prereq-FILEMODE.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2010 Ævar Arnfjörð Bjarmason -# - -if test "$(git config --bool core.filemode)" = false -then - say 'filemode disabled on the filesystem' -else - test_set_prereq FILEMODE -fi diff --git a/t/lib-read-tree.sh b/t/lib-read-tree.sh index abc2c6f57f..b95f485606 100644 --- a/t/lib-read-tree.sh +++ b/t/lib-read-tree.sh @@ -1,43 +1,41 @@ -#!/bin/sh -# # Helper functions to check if read-tree would succeed/fail as expected with # and without the dry-run option. They also test that the dry-run does not # write the index and that together with -u it doesn't touch the work tree. # read_tree_must_succeed () { - git ls-files -s >pre-dry-run && - git read-tree -n "$@" && - git ls-files -s >post-dry-run && - test_cmp pre-dry-run post-dry-run && - git read-tree "$@" + git ls-files -s >pre-dry-run && + git read-tree -n "$@" && + git ls-files -s >post-dry-run && + test_cmp pre-dry-run post-dry-run && + git read-tree "$@" } read_tree_must_fail () { - git ls-files -s >pre-dry-run && - test_must_fail git read-tree -n "$@" && - git ls-files -s >post-dry-run && - test_cmp pre-dry-run post-dry-run && - test_must_fail git read-tree "$@" + git ls-files -s >pre-dry-run && + test_must_fail git read-tree -n "$@" && + git ls-files -s >post-dry-run && + test_cmp pre-dry-run post-dry-run && + test_must_fail git read-tree "$@" } read_tree_u_must_succeed () { - git ls-files -s >pre-dry-run && - git diff-files -p >pre-dry-run-wt && - git read-tree -n "$@" && - git ls-files -s >post-dry-run && - git diff-files -p >post-dry-run-wt && - test_cmp pre-dry-run post-dry-run && - test_cmp pre-dry-run-wt post-dry-run-wt && - git read-tree "$@" + git ls-files -s >pre-dry-run && + git diff-files -p >pre-dry-run-wt && + git read-tree -n "$@" && + git ls-files -s >post-dry-run && + git diff-files -p >post-dry-run-wt && + test_cmp pre-dry-run post-dry-run && + test_cmp pre-dry-run-wt post-dry-run-wt && + git read-tree "$@" } read_tree_u_must_fail () { - git ls-files -s >pre-dry-run && - git diff-files -p >pre-dry-run-wt && - test_must_fail git read-tree -n "$@" && - git ls-files -s >post-dry-run && - git diff-files -p >post-dry-run-wt && - test_cmp pre-dry-run post-dry-run && - test_cmp pre-dry-run-wt post-dry-run-wt && - test_must_fail git read-tree "$@" + git ls-files -s >pre-dry-run && + git diff-files -p >pre-dry-run-wt && + test_must_fail git read-tree -n "$@" && + git ls-files -s >post-dry-run && + git diff-files -p >post-dry-run-wt && + test_cmp pre-dry-run post-dry-run && + test_cmp pre-dry-run-wt post-dry-run-wt && + test_must_fail git read-tree "$@" } diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 8ff87fb3f9..6bd252212a 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -1,4 +1,4 @@ -#!/bin/sh +# Helper functions used by interactive rebase tests. # After setting the fake editor with this function, you can # diff --git a/t/lib-terminal.sh b/t/lib-terminal.sh index 58d911d21b..51845491bb 100644 --- a/t/lib-terminal.sh +++ b/t/lib-terminal.sh @@ -1,6 +1,20 @@ -#!/bin/sh +# Helpers for terminal output tests. + +# Catch tests which should depend on TTY but forgot to. There's no need +# to aditionally check that the TTY prereq is set here. If the test declared +# it and we are running the test, then it must have been set. +test_terminal () { + if ! test_declared_prereq TTY + then + echo >&4 "test_terminal: need to declare TTY prerequisite" + return 127 + fi + perl "$TEST_DIRECTORY"/test-terminal.perl "$@" +} + +test_lazy_prereq TTY ' + test_have_prereq PERL && -test_expect_success PERL 'set up terminal for tests' ' # Reading from the pty master seems to get stuck _sometimes_ # on Mac OS X 10.5.0, using Perl 5.10.0 or 5.8.9. # @@ -15,21 +29,8 @@ test_expect_success PERL 'set up terminal for tests' ' # After 2000 iterations or so it hangs. # https://rt.cpan.org/Ticket/Display.html?id=65692 # - if test "$(uname -s)" = Darwin - then - : - elif - "$PERL_PATH" "$TEST_DIRECTORY"/test-terminal.perl \ - sh -c "test -t 1 && test -t 2" - then - test_set_prereq TTY && - test_terminal () { - if ! test_declared_prereq TTY - then - echo >&4 "test_terminal: need to declare TTY prerequisite" - return 127 - fi - "$PERL_PATH" "$TEST_DIRECTORY"/test-terminal.perl "$@" - } - fi + test "$(uname -s)" != Darwin && + + perl "$TEST_DIRECTORY"/test-terminal.perl \ + sh -c "test -t 1 && test -t 2" ' diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh index 4f71a63b0a..16359d51ae 100755 --- a/t/perf/p0001-rev-list.sh +++ b/t/perf/p0001-rev-list.sh @@ -14,4 +14,16 @@ test_perf 'rev-list --all --objects' ' git rev-list --all --objects >/dev/null ' +test_expect_success 'create new unreferenced commit' ' + commit=$(git commit-tree HEAD^{tree} -p HEAD) +' + +test_perf 'rev-list $commit --not --all' ' + git rev-list $commit --not --all >/dev/null +' + +test_perf 'rev-list --objects $commit --not --all' ' + git rev-list --objects $commit --not --all >/dev/null +' + test_done diff --git a/t/perf/p4001-diff-no-index.sh b/t/perf/p4001-diff-no-index.sh new file mode 100755 index 0000000000..683be6984f --- /dev/null +++ b/t/perf/p4001-diff-no-index.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +test_description="Test diff --no-index performance" + +. ./perf-lib.sh + +test_perf_large_repo +test_checkout_worktree + +file1=$(git ls-files | tail -n 2 | head -1) +file2=$(git ls-files | tail -n 1 | head -1) + +test_expect_success "empty files, so they take no time to diff" " + echo >$file1 && + echo >$file2 +" + +test_perf "diff --no-index" " + git diff --no-index $file1 $file2 >/dev/null +" + +test_done diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index f4eecaa171..a8c9574291 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -1,4 +1,6 @@ -#!/bin/sh +# Performance testing framework. Each perf script starts much like +# a normal test script, except it sources this library instead of +# test-lib.sh. See t/perf/README for documentation. # # Copyright (c) 2011 Thomas Rast # diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 10be52beed..a2bb63ce8e 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -41,20 +41,17 @@ test_expect_success '.git/objects should have 3 subdirectories' ' test_expect_success 'success is reported like this' ' : ' -test_expect_failure 'pretend we have a known breakage' ' - false -' run_sub_test_lib_test () { name="$1" descr="$2" # stdin is the body of the test code shift 2 mkdir "$name" && ( - # Pretend we're a test harness. This prevents - # test-lib from writing the counts to a file that will - # later be summarized, showing spurious "failed" tests - HARNESS_ACTIVE=t && - export HARNESS_ACTIVE && + # Pretend we're not running under a test harness, whether we + # are or not. The test-lib output depends on the setting of + # this variable, so we need a stable setting under which to run + # the sub-test. + sane_unset HARNESS_ACTIVE && cd "$name" && cat >"$name.sh" <<-EOF && #!$SHELL_PATH @@ -71,6 +68,8 @@ run_sub_test_lib_test () { cat >>"$name.sh" && chmod +x "$name.sh" && export TEST_DIRECTORY && + TEST_OUTPUT_DIRECTORY=$(pwd) && + export TEST_OUTPUT_DIRECTORY && ./"$name.sh" "$@" >out 2>err ) } @@ -233,16 +232,13 @@ test_expect_success 'test --verbose' ' grep -v "^Initialized empty" test-verbose/out+ >test-verbose/out && check_sub_test_lib_test test-verbose <<-\EOF > expecting success: true - > Z > ok 1 - passing test > Z > expecting success: echo foo > foo - > Z > ok 2 - test with output > Z > expecting success: false - > Z > not ok 3 - failing test > # false > Z @@ -265,7 +261,6 @@ test_expect_success 'test --verbose-only' ' > Z > expecting success: echo foo > foo - > Z > ok 2 - test with output > Z > not ok 3 - failing test diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index cb144258cc..37e9396e5d 100755 --- a/t/t0002-gitfile.sh +++ b/t/t0002-gitfile.sh @@ -7,7 +7,7 @@ Verify that plumbing commands work when .git is a file . ./test-lib.sh objpath() { - echo "$1" | sed -e 's|\(..\)|\1/|' + echo "$1" | sed -e 's|\(..\)|\1/|' } objck() { @@ -19,7 +19,6 @@ objck() { fi } - test_expect_success 'initial setup' ' REAL="$(pwd)/.real" && mv .git "$REAL" diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 0b98b6f8d0..f0fbb42554 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -13,7 +13,6 @@ attr_check () { test_line_count = 0 err } - test_expect_success 'setup' ' mkdir -p a/b/d a/c b && ( @@ -244,40 +243,58 @@ EOF test_line_count = 0 err ' +test_expect_success 'using --git-dir and --work-tree' ' + mkdir unreal real && + git init real && + echo "file test=in-real" >real/.gitattributes && + ( + cd unreal && + attr_check file in-real "--git-dir ../real/.git --work-tree ../real" + ) +' + test_expect_success 'setup bare' ' - git clone --bare . bare.git && - cd bare.git + git clone --bare . bare.git ' test_expect_success 'bare repository: check that .gitattribute is ignored' ' ( - echo "f test=f" - echo "a/i test=a/i" - ) >.gitattributes && - attr_check f unspecified && - attr_check a/f unspecified && - attr_check a/c/f unspecified && - attr_check a/i unspecified && - attr_check subdir/a/i unspecified + cd bare.git && + ( + echo "f test=f" + echo "a/i test=a/i" + ) >.gitattributes && + attr_check f unspecified && + attr_check a/f unspecified && + attr_check a/c/f unspecified && + attr_check a/i unspecified && + attr_check subdir/a/i unspecified + ) ' test_expect_success 'bare repository: check that --cached honors index' ' - GIT_INDEX_FILE=../.git/index \ - git check-attr --cached --stdin --all <../stdin-all | - sort >actual && - test_cmp ../specified-all actual + ( + cd bare.git && + GIT_INDEX_FILE=../.git/index \ + git check-attr --cached --stdin --all <../stdin-all | + sort >actual && + test_cmp ../specified-all actual + ) ' test_expect_success 'bare repository: test info/attributes' ' ( - echo "f test=f" - echo "a/i test=a/i" - ) >info/attributes && - attr_check f f && - attr_check a/f f && - attr_check a/c/f f && - attr_check a/i a/i && - attr_check subdir/a/i unspecified + cd bare.git && + ( + echo "f test=f" + echo "a/i test=a/i" + ) >info/attributes && + attr_check f f && + attr_check a/f f && + attr_check a/c/f f && + attr_check a/i a/i && + attr_check subdir/a/i unspecified + ) ' test_done diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index 181513ab4f..63beb99828 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -37,6 +37,14 @@ test_stderr () { test_cmp "$HOME/expected-stderr" "$HOME/stderr" } +broken_c_unquote () { + "$PERL_PATH" -pe 's/^"//; s/\\//; s/"$//; tr/\n/\0/' "$@" +} + +broken_c_unquote_verbose () { + "$PERL_PATH" -pe 's/ "/ /; s/\\//; s/"$//; tr/:\t\n/\0/' "$@" +} + stderr_contains () { regexp="$1" if grep "$regexp" "$HOME/stderr" @@ -606,12 +614,11 @@ cat <<-EOF >expected-verbose $global_excludes:2:!globaltwo b/globaltwo EOF -sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \ - tr "\n" "\0" >stdin0 -sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \ - tr "\n" "\0" >expected-default0 -sed -e 's/ "/ /' -e 's/\\//' -e 's/"$//' expected-verbose | \ - tr ":\t\n" "\0" >expected-verbose0 +broken_c_unquote stdin >stdin0 + +broken_c_unquote expected-default >expected-default0 + +broken_c_unquote_verbose expected-verbose >expected-verbose0 test_expect_success '--stdin' ' expect_from_stdin <expected-default && @@ -692,12 +699,11 @@ EOF grep -v '^:: ' expected-all >expected-verbose sed -e 's/.* //' expected-verbose >expected-default -sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \ - tr "\n" "\0" >stdin0 -sed -e 's/^"//' -e 's/\\//' -e 's/"$//' expected-default | \ - tr "\n" "\0" >expected-default0 -sed -e 's/ "/ /' -e 's/\\//' -e 's/"$//' expected-verbose | \ - tr ":\t\n" "\0" >expected-verbose0 +broken_c_unquote stdin >stdin0 + +broken_c_unquote expected-default >expected-default0 + +broken_c_unquote_verbose expected-verbose >expected-verbose0 test_expect_success '--stdin from subdirectory' ' expect_from_stdin <expected-default && @@ -769,4 +775,35 @@ test_expect_success PIPE 'streaming support for --stdin' ' echo "$response" | grep "^:: two" ' +############################################################################ +# +# test whitespace handling + +test_expect_success 'trailing whitespace is ignored' ' + mkdir whitespace && + >whitespace/trailing && + >whitespace/untracked && + echo "whitespace/trailing " >ignore && + cat >expect <<EOF && +whitespace/untracked +EOF + : >err.expect && + git ls-files -o -X ignore whitespace >actual 2>err && + test_cmp expect actual && + test_cmp err.expect err +' + +test_expect_success !MINGW 'quoting allows trailing whitespace' ' + rm -rf whitespace && + mkdir whitespace && + >"whitespace/trailing " && + >whitespace/untracked && + echo "whitespace/trailing\\ \\ " >ignore && + echo whitespace/untracked >expect && + : >err.expect && + git ls-files -o -X ignore whitespace >actual 2>err && + test_cmp expect actual && + test_cmp err.expect err +' + test_done diff --git a/t/t0011-hashmap.sh b/t/t0011-hashmap.sh new file mode 100755 index 0000000000..391e2b6492 --- /dev/null +++ b/t/t0011-hashmap.sh @@ -0,0 +1,240 @@ +#!/bin/sh + +test_description='test hashmap and string hash functions' +. ./test-lib.sh + +test_hashmap() { + echo "$1" | test-hashmap $3 > actual && + echo "$2" > expect && + test_cmp expect actual +} + +test_expect_success 'hash functions' ' + +test_hashmap "hash key1" "2215982743 2215982743 116372151 116372151" && +test_hashmap "hash key2" "2215982740 2215982740 116372148 116372148" && +test_hashmap "hash fooBarFrotz" "1383912807 1383912807 3189766727 3189766727" && +test_hashmap "hash foobarfrotz" "2862305959 2862305959 3189766727 3189766727" + +' + +test_expect_success 'put' ' + +test_hashmap "put key1 value1 +put key2 value2 +put fooBarFrotz value3 +put foobarfrotz value4 +size" "NULL +NULL +NULL +NULL +64 4" + +' + +test_expect_success 'put (case insensitive)' ' + +test_hashmap "put key1 value1 +put key2 value2 +put fooBarFrotz value3 +size" "NULL +NULL +NULL +64 3" ignorecase + +' + +test_expect_success 'replace' ' + +test_hashmap "put key1 value1 +put key1 value2 +put fooBarFrotz value3 +put fooBarFrotz value4 +size" "NULL +value1 +NULL +value3 +64 2" + +' + +test_expect_success 'replace (case insensitive)' ' + +test_hashmap "put key1 value1 +put Key1 value2 +put fooBarFrotz value3 +put foobarfrotz value4 +size" "NULL +value1 +NULL +value3 +64 2" ignorecase + +' + +test_expect_success 'get' ' + +test_hashmap "put key1 value1 +put key2 value2 +put fooBarFrotz value3 +put foobarfrotz value4 +get key1 +get key2 +get fooBarFrotz +get notInMap" "NULL +NULL +NULL +NULL +value1 +value2 +value3 +NULL" + +' + +test_expect_success 'get (case insensitive)' ' + +test_hashmap "put key1 value1 +put key2 value2 +put fooBarFrotz value3 +get Key1 +get keY2 +get foobarfrotz +get notInMap" "NULL +NULL +NULL +value1 +value2 +value3 +NULL" ignorecase + +' + +test_expect_success 'add' ' + +test_hashmap "add key1 value1 +add key1 value2 +add fooBarFrotz value3 +add fooBarFrotz value4 +get key1 +get fooBarFrotz +get notInMap" "value2 +value1 +value4 +value3 +NULL" + +' + +test_expect_success 'add (case insensitive)' ' + +test_hashmap "add key1 value1 +add Key1 value2 +add fooBarFrotz value3 +add foobarfrotz value4 +get key1 +get Foobarfrotz +get notInMap" "value2 +value1 +value4 +value3 +NULL" ignorecase + +' + +test_expect_success 'remove' ' + +test_hashmap "put key1 value1 +put key2 value2 +put fooBarFrotz value3 +remove key1 +remove key2 +remove notInMap +size" "NULL +NULL +NULL +value1 +value2 +NULL +64 1" + +' + +test_expect_success 'remove (case insensitive)' ' + +test_hashmap "put key1 value1 +put key2 value2 +put fooBarFrotz value3 +remove Key1 +remove keY2 +remove notInMap +size" "NULL +NULL +NULL +value1 +value2 +NULL +64 1" ignorecase + +' + +test_expect_success 'iterate' ' + +test_hashmap "put key1 value1 +put key2 value2 +put fooBarFrotz value3 +iterate" "NULL +NULL +NULL +key2 value2 +key1 value1 +fooBarFrotz value3" + +' + +test_expect_success 'iterate (case insensitive)' ' + +test_hashmap "put key1 value1 +put key2 value2 +put fooBarFrotz value3 +iterate" "NULL +NULL +NULL +fooBarFrotz value3 +key2 value2 +key1 value1" ignorecase + +' + +test_expect_success 'grow / shrink' ' + + rm -f in && + rm -f expect && + for n in $(test_seq 51) + do + echo put key$n value$n >> in && + echo NULL >> expect + done && + echo size >> in && + echo 64 51 >> expect && + echo put key52 value52 >> in && + echo NULL >> expect + echo size >> in && + echo 256 52 >> expect && + for n in $(test_seq 12) + do + echo remove key$n >> in && + echo value$n >> expect + done && + echo size >> in && + echo 256 40 >> expect && + echo remove key40 >> in && + echo value40 >> expect && + echo size >> in && + echo 64 39 >> expect && + cat in | test-hashmap > out && + test_cmp expect out + +' + +test_done diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 2bd5e32745..c0143a0a70 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -190,33 +190,58 @@ test_expect_success SYMLINKS 'real path works on symlinks' ' test "$sym" = "$(test-path-utils real_path "$dir2/syml")" ' -relative_path /a/b/c/ /a/b/ c/ -relative_path /a/b/c/ /a/b c/ -relative_path /a//b//c/ //a/b// c/ POSIX -relative_path /a/b /a/b ./ -relative_path /a/b/ /a/b ./ -relative_path /a /a/b ../ -relative_path / /a/b/ ../../ -relative_path /a/c /a/b/ ../c -relative_path /a/c /a/b ../c -relative_path /x/y /a/b/ ../../x/y -relative_path /a/b "<empty>" /a/b -relative_path /a/b "<null>" /a/b -relative_path a/b/c/ a/b/ c/ -relative_path a/b/c/ a/b c/ -relative_path a/b//c a//b c -relative_path a/b/ a/b/ ./ -relative_path a/b/ a/b ./ -relative_path a a/b ../ -relative_path x/y a/b ../../x/y -relative_path a/c a/b ../c -relative_path a/b "<empty>" a/b -relative_path a/b "<null>" a/b -relative_path "<empty>" /a/b ./ -relative_path "<empty>" "<empty>" ./ -relative_path "<empty>" "<null>" ./ -relative_path "<null>" "<empty>" ./ -relative_path "<null>" "<null>" ./ -relative_path "<null>" /a/b ./ +test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' ' + ln -s target symlink && + test "$(test-path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink" +' + +test_expect_success 'prefix_path works with only absolute path to work tree' ' + echo "" >expected && + test-path-utils prefix_path prefix "$(pwd)" >actual && + test_cmp expected actual +' + +test_expect_success 'prefix_path rejects absolute path to dir with same beginning as work tree' ' + test_must_fail test-path-utils prefix_path prefix "$(pwd)a" +' + +test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having same beginning as work tree' ' + git init repo && + ln -s repo repolink && + test "a" = "$(cd repo && test-path-utils prefix_path prefix "$(pwd)/../repolink/a")" +' + +relative_path /foo/a/b/c/ /foo/a/b/ c/ +relative_path /foo/a/b/c/ /foo/a/b c/ +relative_path /foo/a//b//c/ ///foo/a/b// c/ POSIX +relative_path /foo/a/b /foo/a/b ./ +relative_path /foo/a/b/ /foo/a/b ./ +relative_path /foo/a /foo/a/b ../ +relative_path / /foo/a/b/ ../../../ +relative_path /foo/a/c /foo/a/b/ ../c +relative_path /foo/a/c /foo/a/b ../c +relative_path /foo/x/y /foo/a/b/ ../../x/y +relative_path /foo/a/b "<empty>" /foo/a/b +relative_path /foo/a/b "<null>" /foo/a/b +relative_path foo/a/b/c/ foo/a/b/ c/ +relative_path foo/a/b/c/ foo/a/b c/ +relative_path foo/a/b//c foo/a//b c +relative_path foo/a/b/ foo/a/b/ ./ +relative_path foo/a/b/ foo/a/b ./ +relative_path foo/a foo/a/b ../ +relative_path foo/x/y foo/a/b ../../x/y +relative_path foo/a/c foo/a/b ../c +relative_path foo/a/b /foo/x/y foo/a/b +relative_path /foo/a/b foo/x/y /foo/a/b +relative_path d:/a/b D:/a/c ../b MINGW +relative_path C:/a/b D:/a/c C:/a/b MINGW +relative_path foo/a/b "<empty>" foo/a/b +relative_path foo/a/b "<null>" foo/a/b +relative_path "<empty>" /foo/a/b ./ +relative_path "<empty>" "<empty>" ./ +relative_path "<empty>" "<null>" ./ +relative_path "<null>" "<empty>" ./ +relative_path "<null>" "<null>" ./ +relative_path "<null>" /foo/a/b ./ test_done diff --git a/t/t0202-gettext-perl.sh b/t/t0202-gettext-perl.sh index 428ebb0080..a29d166e00 100755 --- a/t/t0202-gettext-perl.sh +++ b/t/t0202-gettext-perl.sh @@ -12,7 +12,7 @@ if ! test_have_prereq PERL; then test_done fi -"$PERL_PATH" -MTest::More -e 0 2>/dev/null || { +perl -MTest::More -e 0 2>/dev/null || { skip_all="Perl Test::More unavailable, skipping test" test_done } @@ -22,6 +22,6 @@ test_external_has_tap=1 test_external_without_stderr \ 'Perl Git::I18N API' \ - "$PERL_PATH" "$TEST_DIRECTORY"/t0202/test.pl + perl "$TEST_DIRECTORY"/t0202/test.pl test_done diff --git a/t/t0202/test.pl b/t/t0202/test.pl index 2c10cb4693..2c10cb4693 100644..100755 --- a/t/t0202/test.pl +++ b/t/t0202/test.pl diff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh index f53de79e56..074568500a 100755 --- a/t/t1005-read-tree-reset.sh +++ b/t/t1005-read-tree-reset.sh @@ -8,84 +8,99 @@ test_description='read-tree -u --reset' # two-tree test test_expect_success 'setup' ' - git init && - mkdir df && - echo content >df/file && - git add df/file && - git commit -m one && - git ls-files >expect && - rm -rf df && - echo content >df && - git add df && - echo content >new && - git add new && - git commit -m two + git init && + mkdir df && + echo content >df/file && + git add df/file && + git commit -m one && + git ls-files >expect && + rm -rf df && + echo content >df && + git add df && + echo content >new && + git add new && + git commit -m two ' test_expect_success 'reset should work' ' - read_tree_u_must_succeed -u --reset HEAD^ && - git ls-files >actual && - test_cmp expect actual + read_tree_u_must_succeed -u --reset HEAD^ && + git ls-files >actual && + test_cmp expect actual ' test_expect_success 'reset should remove remnants from a failed merge' ' - read_tree_u_must_succeed --reset -u HEAD && - git ls-files -s >expect && - sha1=$(git rev-parse :new) && - ( - echo "100644 $sha1 1 old" - echo "100644 $sha1 3 old" - ) | git update-index --index-info && - >old && - git ls-files -s && - read_tree_u_must_succeed --reset -u HEAD && - git ls-files -s >actual && - ! test -f old + read_tree_u_must_succeed --reset -u HEAD && + git ls-files -s >expect && + sha1=$(git rev-parse :new) && + ( + echo "100644 $sha1 1 old" + echo "100644 $sha1 3 old" + ) | git update-index --index-info && + >old && + git ls-files -s && + read_tree_u_must_succeed --reset -u HEAD && + git ls-files -s >actual && + ! test -f old +' + +test_expect_success 'two-way reset should remove remnants too' ' + read_tree_u_must_succeed --reset -u HEAD && + git ls-files -s >expect && + sha1=$(git rev-parse :new) && + ( + echo "100644 $sha1 1 old" + echo "100644 $sha1 3 old" + ) | git update-index --index-info && + >old && + git ls-files -s && + read_tree_u_must_succeed --reset -u HEAD HEAD && + git ls-files -s >actual && + ! test -f old ' test_expect_success 'Porcelain reset should remove remnants too' ' - read_tree_u_must_succeed --reset -u HEAD && - git ls-files -s >expect && - sha1=$(git rev-parse :new) && - ( - echo "100644 $sha1 1 old" - echo "100644 $sha1 3 old" - ) | git update-index --index-info && - >old && - git ls-files -s && - git reset --hard && - git ls-files -s >actual && - ! test -f old + read_tree_u_must_succeed --reset -u HEAD && + git ls-files -s >expect && + sha1=$(git rev-parse :new) && + ( + echo "100644 $sha1 1 old" + echo "100644 $sha1 3 old" + ) | git update-index --index-info && + >old && + git ls-files -s && + git reset --hard && + git ls-files -s >actual && + ! test -f old ' test_expect_success 'Porcelain checkout -f should remove remnants too' ' - read_tree_u_must_succeed --reset -u HEAD && - git ls-files -s >expect && - sha1=$(git rev-parse :new) && - ( - echo "100644 $sha1 1 old" - echo "100644 $sha1 3 old" - ) | git update-index --index-info && - >old && - git ls-files -s && - git checkout -f && - git ls-files -s >actual && - ! test -f old + read_tree_u_must_succeed --reset -u HEAD && + git ls-files -s >expect && + sha1=$(git rev-parse :new) && + ( + echo "100644 $sha1 1 old" + echo "100644 $sha1 3 old" + ) | git update-index --index-info && + >old && + git ls-files -s && + git checkout -f && + git ls-files -s >actual && + ! test -f old ' test_expect_success 'Porcelain checkout -f HEAD should remove remnants too' ' - read_tree_u_must_succeed --reset -u HEAD && - git ls-files -s >expect && - sha1=$(git rev-parse :new) && - ( - echo "100644 $sha1 1 old" - echo "100644 $sha1 3 old" - ) | git update-index --index-info && - >old && - git ls-files -s && - git checkout -f HEAD && - git ls-files -s >actual && - ! test -f old + read_tree_u_must_succeed --reset -u HEAD && + git ls-files -s >expect && + sha1=$(git rev-parse :new) && + ( + echo "100644 $sha1 1 old" + echo "100644 $sha1 3 old" + ) | git update-index --index-info && + >old && + git ls-files -s && + git checkout -f HEAD && + git ls-files -s >actual && + ! test -f old ' test_done diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index a420742494..a72e700ae4 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -85,6 +85,28 @@ $content" git cat-file --batch-check="%(objecttype) %(rest)" >actual && test_cmp expect actual ' + + test -z "$content" || + test_expect_success "--batch without type ($type)" ' + { + echo "$size" && + maybe_remove_timestamp "$content" $no_ts + } >expect && + echo $sha1 | git cat-file --batch="%(objectsize)" >actual.full && + maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual && + test_cmp expect actual + ' + + test -z "$content" || + test_expect_success "--batch without size ($type)" ' + { + echo "$type" && + maybe_remove_timestamp "$content" $no_ts + } >expect && + echo $sha1 | git cat-file --batch="%(objecttype)" >actual.full && + maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual && + test_cmp expect actual + ' } hello_content="Hello World" @@ -194,6 +216,12 @@ test_expect_success "--batch-check for an emtpy line" ' test " missing" = "$(echo | git cat-file --batch-check)" ' +test_expect_success 'empty --batch-check notices missing object' ' + echo "$_z40 missing" >expect && + echo "$_z40" | git cat-file --batch-check="" >actual && + test_cmp expect actual +' + batch_input="$hello_sha1 $commit_sha1 $tag_sha1 @@ -234,4 +262,38 @@ test_expect_success "--batch-check with multiple sha1s gives correct format" ' "$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)" ' +test_expect_success 'setup blobs which are likely to delta' ' + test-genrandom foo 10240 >foo && + { cat foo; echo plus; } >foo-plus && + git add foo foo-plus && + git commit -m foo && + cat >blobs <<-\EOF + HEAD:foo + HEAD:foo-plus + EOF +' + +test_expect_success 'confirm that neither loose blob is a delta' ' + cat >expect <<-EOF + $_z40 + $_z40 + EOF + git cat-file --batch-check="%(deltabase)" <blobs >actual && + test_cmp expect actual +' + +# To avoid relying too much on the current delta heuristics, +# we will check only that one of the two objects is a delta +# against the other, but not the order. We can do so by just +# asking for the base of both, and checking whether either +# sha1 appears in the output. +test_expect_success '%(deltabase) reports packed delta bases' ' + git repack -ad && + git cat-file --batch-check="%(deltabase)" <blobs >actual && + { + grep "$(git rev-parse HEAD:foo)" actual || + grep "$(git rev-parse HEAD:foo-plus)" actual + } +' + test_done diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh index df573c4978..b946f87686 100755 --- a/t/t1010-mktree.sh +++ b/t/t1010-mktree.sh @@ -42,13 +42,13 @@ test_expect_success 'ls-tree piped to mktree (2)' ' ' test_expect_success 'ls-tree output in wrong order given to mktree (1)' ' - "$PERL_PATH" -e "print reverse <>" <top | + perl -e "print reverse <>" <top | git mktree >actual && test_cmp tree actual ' test_expect_success 'ls-tree output in wrong order given to mktree (2)' ' - "$PERL_PATH" -e "print reverse <>" <top.withsub | + perl -e "print reverse <>" <top.withsub | git mktree >actual && test_cmp tree.withsub actual ' diff --git a/t/t1013-loose-object-format.sh b/t/t1013-loose-object-format.sh deleted file mode 100755 index fbf5f2fc00..0000000000 --- a/t/t1013-loose-object-format.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2011 Roberto Tyley -# - -test_description='Correctly identify and parse loose object headers - -There are two file formats for loose objects - the original standard -format, and the experimental format introduced with Git v1.4.3, later -deprecated with v1.5.3. Although Git no longer writes the -experimental format, objects in both formats must be read, with the -format for a given file being determined by the header. - -Detecting file format based on header is not entirely trivial, not -least because the first byte of a zlib-deflated stream will vary -depending on how much memory was allocated for the deflation window -buffer when the object was written out (for example 4KB on Android, -rather that 32KB on a normal PC). - -The loose objects used as test vectors have been generated with the -following Git versions: - -standard format: Git v1.7.4.1 -experimental format: Git v1.4.3 (legacyheaders=false) -standard format, deflated with 4KB window size: Agit/JGit on Android -' - -. ./test-lib.sh - -assert_blob_equals() { - printf "%s" "$2" >expected && - git cat-file -p "$1" >actual && - test_cmp expected actual -} - -test_expect_success setup ' - cp -R "$TEST_DIRECTORY/t1013/objects" .git/ && - git --version -' - -test_expect_success 'read standard-format loose objects' ' - git cat-file tag 8d4e360d6c70fbd72411991c02a09c442cf7a9fa && - git cat-file commit 6baee0540ea990d9761a3eb9ab183003a71c3696 && - git ls-tree 7a37b887a73791d12d26c0d3e39568a8fb0fa6e8 && - assert_blob_equals "257cc5642cb1a054f08cc83f2d943e56fd3ebe99" "foo$LF" -' - -test_expect_success 'read experimental-format loose objects' ' - git cat-file tag 76e7fa9941f4d5f97f64fea65a2cba436bc79cbb && - git cat-file commit 7875c6237d3fcdd0ac2f0decc7d3fa6a50b66c09 && - git ls-tree 95b1625de3ba8b2214d1e0d0591138aea733f64f && - assert_blob_equals "2e65efe2a145dda7ee51d1741299f848e5bf752e" "a" && - assert_blob_equals "9ae9e86b7bd6cb1472d9373702d8249973da0832" "ab" && - assert_blob_equals "85df50785d62d3b05ab03d9cbf7e4a0b49449730" "abcd" && - assert_blob_equals "1656f9233d999f61ef23ef390b9c71d75399f435" "abcdefgh" && - assert_blob_equals "1e72a6b2c4a577ab0338860fa9fe87f761fc9bbd" "abcdefghi" && - assert_blob_equals "70e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd" "abcdefghijklmnop" && - assert_blob_equals "bd15045f6ce8ff75747562173640456a394412c8" "abcdefghijklmnopqrstuvwx" -' - -test_expect_success 'read standard-format objects deflated with smaller window buffer' ' - git cat-file tag f816d5255855ac160652ee5253b06cd8ee14165a && - git cat-file tag 149cedb5c46929d18e0f118e9fa31927487af3b6 -' - -test_done diff --git a/t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6 b/t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6 Binary files differdeleted file mode 100644 index 472fd1458e..0000000000 --- a/t/t1013/objects/14/9cedb5c46929d18e0f118e9fa31927487af3b6 +++ /dev/null diff --git a/t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435 b/t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435 Binary files differdeleted file mode 100644 index c379d74ae2..0000000000 --- a/t/t1013/objects/16/56f9233d999f61ef23ef390b9c71d75399f435 +++ /dev/null diff --git a/t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd b/t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd Binary files differdeleted file mode 100644 index 93706305bc..0000000000 --- a/t/t1013/objects/1e/72a6b2c4a577ab0338860fa9fe87f761fc9bbd +++ /dev/null diff --git a/t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 b/t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 Binary files differdeleted file mode 100644 index bdcf704c9e..0000000000 --- a/t/t1013/objects/25/7cc5642cb1a054f08cc83f2d943e56fd3ebe99 +++ /dev/null diff --git a/t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e b/t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e Binary files differdeleted file mode 100644 index ad62c43e41..0000000000 --- a/t/t1013/objects/2e/65efe2a145dda7ee51d1741299f848e5bf752e +++ /dev/null diff --git a/t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696 b/t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696 Binary files differdeleted file mode 100644 index 3d2f0337db..0000000000 --- a/t/t1013/objects/6b/aee0540ea990d9761a3eb9ab183003a71c3696 +++ /dev/null diff --git a/t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd b/t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd Binary files differdeleted file mode 100644 index b3f71a6ee5..0000000000 --- a/t/t1013/objects/70/e6a83d8dcb26fc8bc0cf702e2ddeb6adca18fd +++ /dev/null diff --git a/t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb b/t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb deleted file mode 100644 index af4e9a7b0c..0000000000 --- a/t/t1013/objects/76/e7fa9941f4d5f97f64fea65a2cba436bc79cbb +++ /dev/null @@ -1,2 +0,0 @@ -Âxœ%ÌA‚0@Ñ}O1{cSZ(˜ãνáÃthª”’ZŒÜÞ Ëÿ?
¦m×6dµiÉ9…¤Gå˜h´Ø¨ÁZR'Q¶…RŒ¡ˆ‚ø³p‘ç‚ÓqL9âÏ=g¸§sIÐoopÎÿ”eÏ«_1»€³¤$×ç*Si«ëNwpP•RBôûÅÁú -³‡[(ð®d-øÁL9á
\ No newline at end of file diff --git a/t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09 b/t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09 Binary files differdeleted file mode 100644 index 3dd28be5c6..0000000000 --- a/t/t1013/objects/78/75c6237d3fcdd0ac2f0decc7d3fa6a50b66c09 +++ /dev/null diff --git a/t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8 b/t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8 Binary files differdeleted file mode 100644 index 2b97b264c3..0000000000 --- a/t/t1013/objects/7a/37b887a73791d12d26c0d3e39568a8fb0fa6e8 +++ /dev/null diff --git a/t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730 b/t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730 Binary files differdeleted file mode 100644 index 6dff746876..0000000000 --- a/t/t1013/objects/85/df50785d62d3b05ab03d9cbf7e4a0b49449730 +++ /dev/null diff --git a/t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa b/t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa Binary files differdeleted file mode 100644 index cb41e92d07..0000000000 --- a/t/t1013/objects/8d/4e360d6c70fbd72411991c02a09c442cf7a9fa +++ /dev/null diff --git a/t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f b/t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f Binary files differdeleted file mode 100644 index 7ac46b4f70..0000000000 --- a/t/t1013/objects/95/b1625de3ba8b2214d1e0d0591138aea733f64f +++ /dev/null diff --git a/t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832 b/t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832 Binary files differdeleted file mode 100644 index 9d8316d4e5..0000000000 --- a/t/t1013/objects/9a/e9e86b7bd6cb1472d9373702d8249973da0832 +++ /dev/null diff --git a/t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8 b/t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8 Binary files differdeleted file mode 100644 index eebf23956e..0000000000 --- a/t/t1013/objects/bd/15045f6ce8ff75747562173640456a394412c8 +++ /dev/null diff --git a/t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 Binary files differdeleted file mode 100644 index 134cf19379..0000000000 --- a/t/t1013/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +++ /dev/null diff --git a/t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a b/t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a deleted file mode 100644 index 26b75aec56..0000000000 --- a/t/t1013/objects/f8/16d5255855ac160652ee5253b06cd8ee14165a +++ /dev/null @@ -1 +0,0 @@ -H‰ÌÁ‚0€aÏ{ŠÞ
I»e&Æø*¥ˆG°ß^¸ýù¿ËDåÒ†wU‡Ò—¬S±4ªŠÆªž ,fÅ[ðßVAÛºÎüxÈÇö6[wtG§Lu¸?—¦²¼Ú×@‰"gì{†+by¾%M
\ No newline at end of file diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh index 1e2945ec7e..6902320e81 100755 --- a/t/t1020-subdirectory.sh +++ b/t/t1020-subdirectory.sh @@ -148,7 +148,7 @@ test_expect_success 'GIT_PREFIX for built-ins' ' ( cd dir && printf "change" >two && - env GIT_EXTERNAL_DIFF=./diff git diff >../actual + GIT_EXTERNAL_DIFF=./diff git diff >../actual git checkout -- two ) && test_cmp expect actual diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 967359344d..c9c426c273 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -475,15 +475,28 @@ ein.bahn=strasse EOF test_expect_success 'alternative GIT_CONFIG' ' - GIT_CONFIG=other-config git config -l >output && + GIT_CONFIG=other-config git config --list >output && test_cmp expect output ' test_expect_success 'alternative GIT_CONFIG (--file)' ' - git config --file other-config -l > output && + git config --file other-config --list >output && test_cmp expect output ' +test_expect_success 'alternative GIT_CONFIG (--file=-)' ' + git config --file - --list <other-config >output && + test_cmp expect output +' + +test_expect_success 'setting a value in stdin is an error' ' + test_must_fail git config --file - some.value foo +' + +test_expect_success 'editing stdin is an error' ' + test_must_fail git config --file - --edit +' + test_expect_success 'refer config from subdirectory' ' mkdir x && ( diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh index 46103a1591..3a2c81968c 100755 --- a/t/t1303-wacky-config.sh +++ b/t/t1303-wacky-config.sh @@ -3,17 +3,28 @@ test_description='Test wacky input to git config' . ./test-lib.sh +# Leaving off the newline is intentional! setup() { (printf "[section]\n" && printf " key = foo") >.git/config } +# 'check section.key value' verifies that the entry for section.key is +# 'value' check() { echo "$2" >expected git config --get "$1" >actual 2>&1 test_cmp actual expected } +# 'check section.key regex value' verifies that the entry for +# section.key *that matches 'regex'* is 'value' +check_regex() { + echo "$3" >expected + git config --get "$1" "$2" >actual 2>&1 + test_cmp actual expected +} + test_expect_success 'modify same key' ' setup && git config section.key bar && @@ -47,4 +58,57 @@ test_expect_success 'do not crash on special long config line' ' check section.key "$LONG_VALUE" ' +setup_many() { + setup && + # This time we want the newline so that we can tack on more + # entries. + echo >>.git/config && + # Semi-efficient way of concatenating 5^5 = 3125 lines. Note + # that because 'setup' already put one line, this means 3126 + # entries for section.key in the config file. + cat >5to1 <<-\EOF && + key = foo + key = foo + key = foo + key = foo + key = foo + EOF + cat 5to1 5to1 5to1 5to1 5to1 >5to2 && # 25 + cat 5to2 5to2 5to2 5to2 5to2 >5to3 && # 125 + cat 5to3 5to3 5to3 5to3 5to3 >5to4 && # 635 + cat 5to4 5to4 5to4 5to4 5to4 >>.git/config # 3125 +} + +test_expect_success 'get many entries' ' + setup_many && + git config --get-all section.key >actual && + test_line_count = 3126 actual +' + +test_expect_success 'get many entries by regex' ' + setup_many && + git config --get-regexp "sec.*ke." >actual && + test_line_count = 3126 actual +' + +test_expect_success 'add and replace one of many entries' ' + setup_many && + git config --add section.key bar && + check_regex section.key "b.*r" bar && + git config section.key beer "b.*r" && + check_regex section.key "b.*r" beer +' + +test_expect_success 'replace many entries' ' + setup_many && + git config --replace-all section.key bar && + check section.key bar +' + +test_expect_success 'unset many entries' ' + setup_many && + git config --unset-all section.key && + test_must_fail git config section.key +' + test_done diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh index a70707620f..9ba2ba11c3 100755 --- a/t/t1305-config-include.sh +++ b/t/t1305-config-include.sh @@ -113,7 +113,7 @@ test_expect_success 'missing include files are ignored' ' test_expect_success 'absolute includes from command line work' ' echo "[test]one = 1" >one && echo 1 >expect && - git -c include.path="$PWD/one" config test.one >actual && + git -c include.path="$(pwd)/one" config test.one >actual && test_cmp expect actual ' @@ -122,6 +122,36 @@ test_expect_success 'relative includes from command line fail' ' test_must_fail git -c include.path=one config test.one ' +test_expect_success 'absolute includes from blobs work' ' + echo "[test]one = 1" >one && + echo "[include]path=$(pwd)/one" >blob && + blob=$(git hash-object -w blob) && + echo 1 >expect && + git config --blob=$blob test.one >actual && + test_cmp expect actual +' + +test_expect_success 'relative includes from blobs fail' ' + echo "[test]one = 1" >one && + echo "[include]path=one" >blob && + blob=$(git hash-object -w blob) && + test_must_fail git config --blob=$blob test.one +' + +test_expect_success 'absolute includes from stdin work' ' + echo "[test]one = 1" >one && + echo 1 >expect && + echo "[include]path=\"$(pwd)/one\"" | + git config --file - test.one >actual && + test_cmp expect actual +' + +test_expect_success 'relative includes from stdin line fail' ' + echo "[test]one = 1" >one && + echo "[include]path=one" | + test_must_fail git config --file - test.one +' + test_expect_success 'include cycles are detected' ' cat >.gitconfig <<-\EOF && [test]value = gitconfig diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index d730734fde..8c739c9613 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -142,6 +142,20 @@ test_expect_success '> in name is reported' ' grep "error in commit $new" out ' +# date is 2^64 + 1 +test_expect_success 'integer overflow in timestamps is reported' ' + git cat-file commit HEAD >basis && + sed "s/^\\(author .*>\\) [0-9]*/\\1 18446744073709551617/" \ + <basis >bad-timestamp && + new=$(git hash-object -t commit -w --stdin <bad-timestamp) && + test_when_finished "remove_object $new" && + git update-ref refs/heads/bogus "$new" && + test_when_finished "git update-ref -d refs/heads/bogus" && + git fsck 2>out && + cat out && + grep "error in commit $new.*integer overflow" out +' + test_expect_success 'tag pointing to nonexistent' ' cat >invalid-tag <<-\EOF && object ffffffffffffffffffffffffffffffffffffffff diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index 13c88c9aae..83b1300cef 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -12,9 +12,11 @@ usage: some-command [options] <args>... -h, --help show the help --foo some nifty option --foo --bar ... some cool option --bar with an argument + -b, --baz a short and long option An option group Header -C[...] option C with an optional argument + -d, --data[=...] short and long option with an optional argument Extras --extra1 line above used to cause a segfault but no longer does @@ -31,9 +33,11 @@ h,help show the help foo some nifty option --foo bar= some cool option --bar with an argument +b,baz a short and long option An option group Header C? option C with an optional argument +d,data? short and long option with an optional argument Extras extra1 line above used to cause a segfault but no longer does @@ -45,16 +49,16 @@ test_expect_success 'test --parseopt help output' ' ' cat > expect <<EOF -set -- --foo --bar 'ham' -- 'arg' +set -- --foo --bar 'ham' -b -- 'arg' EOF test_expect_success 'test --parseopt' ' - git rev-parse --parseopt -- --foo --bar=ham arg < optionspec > output && + git rev-parse --parseopt -- --foo --bar=ham --baz arg < optionspec > output && test_cmp expect output ' test_expect_success 'test --parseopt with mixed options and arguments' ' - git rev-parse --parseopt -- --foo arg --bar=ham < optionspec > output && + git rev-parse --parseopt -- --foo arg --bar=ham --baz < optionspec > output && test_cmp expect output ' @@ -99,4 +103,36 @@ test_expect_success 'test --parseopt --keep-dashdash --stop-at-non-option withou test_cmp expect output ' +cat > expect <<EOF +set -- --foo --bar='z' --baz -C'Z' --data='A' -- 'arg' +EOF + +test_expect_success 'test --parseopt --stuck-long' ' + git rev-parse --parseopt --stuck-long -- --foo --bar=z -b arg -CZ -dA <optionspec >output && + test_cmp expect output +' + +cat > expect <<EOF +set -- --data='' -C --baz -- 'arg' +EOF + +test_expect_success 'test --parseopt --stuck-long and empty optional argument' ' + git rev-parse --parseopt --stuck-long -- --data= arg -C -b <optionspec >output && + test_cmp expect output +' + +cat > expect <<EOF +set -- --data --baz -- 'arg' +EOF + +test_expect_success 'test --parseopt --stuck-long and long option with unset optional argument' ' + git rev-parse --parseopt --stuck-long -- --data arg -b <optionspec >output && + test_cmp expect output +' + +test_expect_success 'test --parseopt --stuck-long and short option with unset optional argument' ' + git rev-parse --parseopt --stuck-long -- -d arg -b <optionspec >output && + test_cmp expect output +' + test_done diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index f950c10128..613d9bfe1b 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -196,4 +196,28 @@ test_expect_success 'dotdot is not an empty set' ' test_cmp expect actual ' +test_expect_success 'arg before dashdash must be a revision (missing)' ' + test_must_fail git rev-parse foobar -- 2>stderr && + test_i18ngrep "bad revision" stderr +' + +test_expect_success 'arg before dashdash must be a revision (file)' ' + >foobar && + test_must_fail git rev-parse foobar -- 2>stderr && + test_i18ngrep "bad revision" stderr +' + +test_expect_success 'arg before dashdash must be a revision (ambiguous)' ' + >foobar && + git update-ref refs/heads/foobar HEAD && + { + # we do not want to use rev-parse here, because + # we are testing it + cat .git/refs/heads/foobar && + printf "%s\n" -- + } >expect && + git rev-parse foobar -- >actual && + test_cmp expect actual +' + test_done diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index 2a19e797eb..178694ee63 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -17,6 +17,9 @@ test_expect_success 'setup' ' test_commit 4 && git branch --track my-side origin/side && git branch --track local-master master && + git branch --track fun@ny origin/side && + git branch --track @funny origin/side && + git branch --track funny@ origin/side && git remote add -t master master-only .. && git fetch master-only && git branch bad-upstream && @@ -54,6 +57,24 @@ test_expect_success 'my-side@{upstream} resolves to correct full name' ' test refs/remotes/origin/side = "$(full_name my-side@{u})" ' +test_expect_success 'upstream of branch with @ in middle' ' + full_name fun@ny@{u} >actual && + echo refs/remotes/origin/side >expect && + test_cmp expect actual +' + +test_expect_success 'upstream of branch with @ at start' ' + full_name @funny@{u} >actual && + echo refs/remotes/origin/side >expect && + test_cmp expect actual +' + +test_expect_success 'upstream of branch with @ at end' ' + full_name funny@@{u} >actual && + echo refs/remotes/origin/side >expect && + test_cmp expect actual +' + test_expect_success 'refs/heads/my-side@{upstream} does not resolve to my-side{upstream}' ' test_must_fail full_name refs/heads/my-side@{upstream} ' @@ -210,4 +231,20 @@ test_expect_success 'log -g other@{u}@{now}' ' test_cmp expect actual ' +test_expect_success '@{reflog}-parsing does not look beyond colon' ' + echo content >@{yesterday} && + git add @{yesterday} && + git commit -m "funny reflog file" && + git hash-object @{yesterday} >expect && + git rev-parse HEAD:@{yesterday} >actual +' + +test_expect_success '@{upstream}-parsing does not look beyond colon' ' + echo content >@{upstream} && + git add @{upstream} && + git commit -m "funny upstream file" && + git hash-object @{upstream} >expect && + git rev-parse HEAD:@{upstream} >actual +' + test_done diff --git a/t/t1508-at-combinations.sh b/t/t1508-at-combinations.sh index ceb844985f..078e1195df 100755 --- a/t/t1508-at-combinations.sh +++ b/t/t1508-at-combinations.sh @@ -9,8 +9,11 @@ check() { if test '$2' = 'commit' then git log -1 --format=%s '$1' >actual - else + elif test '$2' = 'ref' + then git rev-parse --symbolic-full-name '$1' >actual + else + git cat-file -p '$1' >actual fi && test_cmp expect actual " @@ -82,4 +85,14 @@ check HEAD ref refs/heads/old-branch check "HEAD@{1}" commit new-two check "@{1}" commit old-one +test_expect_success 'create path with @' ' + echo content >normal && + echo content >fun@ny && + git add normal fun@ny && + git commit -m "funny path" +' + +check "@:normal" blob content +check "@:fun@ny" blob content + test_done diff --git a/t/t1600-index.sh b/t/t1600-index.sh new file mode 100755 index 0000000000..079d241145 --- /dev/null +++ b/t/t1600-index.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +test_description='index file specific tests' + +. ./test-lib.sh + +test_expect_success 'setup' ' + echo 1 >a +' + +test_expect_success 'bogus GIT_INDEX_VERSION issues warning' ' + ( + rm -f .git/index && + GIT_INDEX_VERSION=2bogus && + export GIT_INDEX_VERSION && + git add a 2>&1 | sed "s/[0-9]//" >actual.err && + sed -e "s/ Z$/ /" <<-\EOF >expect.err && + warning: GIT_INDEX_VERSION set, but the value is invalid. + Using version Z + EOF + test_i18ncmp expect.err actual.err + ) +' + +test_expect_success 'out of bounds GIT_INDEX_VERSION issues warning' ' + ( + rm -f .git/index && + GIT_INDEX_VERSION=1 && + export GIT_INDEX_VERSION && + git add a 2>&1 | sed "s/[0-9]//" >actual.err && + sed -e "s/ Z$/ /" <<-\EOF >expect.err && + warning: GIT_INDEX_VERSION set, but the value is invalid. + Using version Z + EOF + test_i18ncmp expect.err actual.err + ) +' + +test_expect_success 'no warning with bogus GIT_INDEX_VERSION and existing index' ' + ( + GIT_INDEX_VERSION=1 && + export GIT_INDEX_VERSION && + git add a 2>actual.err && + >expect.err && + test_i18ncmp expect.err actual.err + ) +' + +test_expect_success 'out of bounds index.version issues warning' ' + ( + sane_unset GIT_INDEX_VERSION && + rm -f .git/index && + git config --add index.version 1 && + git add a 2>&1 | sed "s/[0-9]//" >actual.err && + sed -e "s/ Z$/ /" <<-\EOF >expect.err && + warning: index.version set, but the value is invalid. + Using version Z + EOF + test_i18ncmp expect.err actual.err + ) +' + +test_expect_success 'GIT_INDEX_VERSION takes precedence over config' ' + ( + rm -f .git/index && + GIT_INDEX_VERSION=4 && + export GIT_INDEX_VERSION && + git config --add index.version 2 && + git add a 2>&1 && + echo 4 >expect && + test-index-version <.git/index >actual && + test_cmp expect actual + ) +' + +test_done diff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh index 7cc0a3582e..87bdf9c96b 100755 --- a/t/t2010-checkout-ambiguous.sh +++ b/t/t2010-checkout-ambiguous.sh @@ -47,4 +47,10 @@ test_expect_success 'disambiguate checking out from a tree-ish' ' git diff --exit-code --quiet ' +test_expect_success 'accurate error message with more than one ref' ' + test_must_fail git checkout HEAD master -- 2>actual && + grep 2 actual && + test_i18ngrep "one reference expected, 2 given" actual +' + test_done diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh index 094b92ef48..6ecb559465 100755 --- a/t/t2024-checkout-dwim.sh +++ b/t/t2024-checkout-dwim.sh @@ -164,4 +164,25 @@ test_expect_success 'checkout of branch from a single remote succeeds #4' ' test_branch_upstream eggs repo_d eggs ' +test_expect_success 'checkout of branch with a file having the same name fails' ' + git checkout -B master && + test_might_fail git branch -D spam && + + >spam && + test_must_fail git checkout spam && + test_must_fail git rev-parse --verify refs/heads/spam && + test_branch master +' + +test_expect_success 'checkout <branch> -- succeeds, even if a file with the same name exists' ' + git checkout -B master && + test_might_fail git branch -D spam && + + >spam && + git checkout spam -- && + test_branch spam && + test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD && + test_branch_upstream spam repo_c spam +' + test_done diff --git a/t/t2104-update-index-skip-worktree.sh b/t/t2104-update-index-skip-worktree.sh index 1d0879be06..29c1fb10ca 100755 --- a/t/t2104-update-index-skip-worktree.sh +++ b/t/t2104-update-index-skip-worktree.sh @@ -7,6 +7,8 @@ test_description='skip-worktree bit test' . ./test-lib.sh +test_set_index_version 3 + cat >expect.full <<EOF H 1 H 2 diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index 9bf2bdffd2..e16b15d3e5 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -80,18 +80,13 @@ test_expect_success 'change gets noticed' ' ' -# Note that this is scheduled to change in Git 2.0, when -# "git add -u" will become full-tree by default. -test_expect_success 'non-limited update in subdir leaves root alone' ' +test_expect_success 'non-qualified update in subdir updates from the root' ' ( cd dir1 && echo even more >>sub2 && git add -u ) && - cat >expect <<-\EOF && - check - top - EOF + : >expect && git diff-files --name-only >actual && test_cmp expect actual ' diff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh index 8d9bc3c2af..9c7adbdbe1 100755 --- a/t/t3004-ls-files-basic.sh +++ b/t/t3004-ls-files-basic.sh @@ -36,4 +36,21 @@ test_expect_success 'ls-files -h in corrupt repository' ' test_i18ngrep "[Uu]sage: git ls-files " broken/usage ' +test_expect_success SYMLINKS 'ls-files with absolute paths to symlinks' ' + mkdir subs && + ln -s nosuch link && + ln -s ../nosuch subs/link && + git add link subs/link && + git ls-files -s link subs/link >expect && + git ls-files -s "$(pwd)/link" "$(pwd)/subs/link" >actual && + test_cmp expect actual && + + ( + cd subs && + git ls-files -s link >../expect && + git ls-files -s "$(pwd)/link" >../actual + ) && + test_cmp expect actual +' + test_done diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index 2f96100a5f..82e18548c3 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -257,6 +257,7 @@ test_expect_success 'setup 8' ' git add e && test_tick && git commit -m "rename a->e" && + c7=$(git rev-parse --verify HEAD) && git checkout rename-ln && git mv a e && test_ln_s_add e a && @@ -517,6 +518,52 @@ test_expect_success 'reset and bind merge' ' ' +test_expect_success 'merge-recursive w/ empty work tree - ours has rename' ' + ( + GIT_WORK_TREE="$PWD/ours-has-rename-work" && + export GIT_WORK_TREE && + GIT_INDEX_FILE="$PWD/ours-has-rename-index" && + export GIT_INDEX_FILE && + mkdir "$GIT_WORK_TREE" && + git read-tree -i -m $c7 && + git update-index --ignore-missing --refresh && + git merge-recursive $c0 -- $c7 $c3 && + git ls-files -s >actual-files + ) 2>actual-err && + >expected-err && + cat >expected-files <<-EOF && + 100644 $o3 0 b/c + 100644 $o0 0 c + 100644 $o0 0 d/e + 100644 $o0 0 e + EOF + test_cmp expected-files actual-files && + test_cmp expected-err actual-err +' + +test_expect_success 'merge-recursive w/ empty work tree - theirs has rename' ' + ( + GIT_WORK_TREE="$PWD/theirs-has-rename-work" && + export GIT_WORK_TREE && + GIT_INDEX_FILE="$PWD/theirs-has-rename-index" && + export GIT_INDEX_FILE && + mkdir "$GIT_WORK_TREE" && + git read-tree -i -m $c3 && + git update-index --ignore-missing --refresh && + git merge-recursive $c0 -- $c3 $c7 && + git ls-files -s >actual-files + ) 2>actual-err && + >expected-err && + cat >expected-files <<-EOF && + 100644 $o3 0 b/c + 100644 $o0 0 c + 100644 $o0 0 d/e + 100644 $o0 0 e + EOF + test_cmp expected-files actual-files && + test_cmp expected-err actual-err +' + test_expect_success 'merge removes empty directories' ' git reset --hard master && diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh index 38446a0e87..ef509df351 100755 --- a/t/t3070-wildmatch.sh +++ b/t/t3070-wildmatch.sh @@ -14,19 +14,6 @@ match() { ! test-wildmatch wildmatch '$3' '$4' " fi - if [ $2 = 1 ]; then - test_expect_success "fnmatch: match '$3' '$4'" " - test-wildmatch fnmatch '$3' '$4' - " - elif [ $2 = 0 ]; then - test_expect_success "fnmatch: no match '$3' '$4'" " - ! test-wildmatch fnmatch '$3' '$4' - " -# else -# test_expect_success BROKEN_FNMATCH "fnmatch: '$3' '$4'" " -# ! test-wildmatch fnmatch '$3' '$4' -# " - fi } imatch() { diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 0fe7647928..83037b1cd9 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -18,7 +18,7 @@ test_expect_success 'prepare a trivial repository' ' ' test_expect_success 'git branch --help should not have created a bogus branch' ' - test_might_fail git branch --help </dev/null >/dev/null 2>/dev/null && + test_might_fail git branch --man --help </dev/null >/dev/null 2>&1 && test_path_is_missing .git/refs/heads/--help ' @@ -507,6 +507,16 @@ EOF test_cmp expected actual ' +test_expect_success '--set-upstream-to notices an error to set branch as own upstream' ' + git branch --set-upstream-to refs/heads/my13 my13 2>actual && + cat >expected <<-\EOF && + warning: Not setting branch my13 as its own upstream. + EOF + test_expect_code 1 git config branch.my13.remote && + test_expect_code 1 git config branch.my13.merge && + test_i18ncmp expected actual +' + # Keep this test last, as it changes the current branch cat >expect <<EOF $_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh index 7480d6e7c2..9a146f1335 100755 --- a/t/t3300-funny-names.sh +++ b/t/t3300-funny-names.sh @@ -69,7 +69,7 @@ test_expect_success 'ls-files -z does not quote funny filename' ' tabs ," (dq) and spaces EOF git ls-files -z >ls-files.z && - "$PERL_PATH" -pe "y/\000/\012/" <ls-files.z >current && + perl -pe "y/\000/\012/" <ls-files.z >current && test_cmp expected current ' @@ -106,7 +106,7 @@ test_expect_success 'diff-index -z does not quote funny filename' ' tabs ," (dq) and spaces EOF git diff-index -z --name-status $t0 >diff-index.z && - "$PERL_PATH" -pe "y/\000/\012/" <diff-index.z >current && + perl -pe "y/\000/\012/" <diff-index.z >current && test_cmp expected current ' @@ -116,7 +116,7 @@ test_expect_success 'diff-tree -z does not quote funny filename' ' tabs ," (dq) and spaces EOF git diff-tree -z --name-status $t0 $t1 >diff-tree.z && - "$PERL_PATH" -pe y/\\000/\\012/ <diff-tree.z >current && + perl -pe y/\\000/\\012/ <diff-tree.z >current && test_cmp expected current ' diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index 16de05aff9..3bb79a47af 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -812,6 +812,33 @@ test_expect_success 'create note from non-existing note with "git notes add -C" test_must_fail git notes list HEAD ' +test_expect_success 'create note from non-blob with "git notes add -C" fails' ' + commit=$(git rev-parse --verify HEAD) && + tree=$(git rev-parse --verify HEAD:) && + test_must_fail git notes add -C $commit && + test_must_fail git notes add -C $tree && + test_must_fail git notes list HEAD +' + +cat > expect << EOF +commit 80d796defacd5db327b7a4e50099663902fbdc5c +Author: A U Thor <author@example.com> +Date: Thu Apr 7 15:20:13 2005 -0700 + + 8th + +Notes (other): + This is a blob object +EOF + +test_expect_success 'create note from blob with "git notes add -C" reuses blob id' ' + blob=$(echo "This is a blob object" | git hash-object -w --stdin) && + git notes add -C $blob && + git log -1 > actual && + test_cmp expect actual && + test "$(git notes list HEAD)" = "$blob" +' + cat > expect << EOF commit 016e982bad97eacdbda0fcbd7ce5b0ba87c81f1b Author: A U Thor <author@example.com> diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index ebf93b0695..6d94b1fcd9 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -134,12 +134,22 @@ test_expect_success 'fail when upstream arg is missing and not configured' ' test_must_fail git rebase ' -test_expect_success 'default to @{upstream} when upstream arg is missing' ' +test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' ' + git checkout -b default-base master && git checkout -b default topic && git config branch.default.remote . && - git config branch.default.merge refs/heads/master && + git config branch.default.merge refs/heads/default-base && git rebase && - test "$(git rev-parse default~1)" = "$(git rev-parse master)" + git rev-parse --verify default-base >expect && + git rev-parse default~1 >actual && + test_cmp expect actual && + git checkout default-base && + git reset --hard HEAD^ && + git checkout default && + git rebase && + git rev-parse --verify default-base >expect && + git rev-parse default~1 >actual && + test_cmp expect actual ' test_expect_success 'rebase -q is quiet' ' diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 639cb70941..3d305814b9 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -240,18 +240,15 @@ test_expect_success 'refresh index before checking if it is up-to-date' ' test_expect_success 'choking "git rm" should not let it die with cruft' ' git reset -q --hard && + test_when_finished "rm -f .git/index.lock && git reset -q --hard" && i=0 && while test $i -lt 12000 do - echo "100644 $_z40 0 some-file-$i" + echo "100644 1234567890123456789012345678901234567890 0 some-file-$i" i=$(( $i + 1 )) done | git update-index --index-info && - git rm -n "some-file-*" | :; - test -f .git/index.lock - status=$? - rm -f .git/index.lock - git reset -q --hard - test "$status" != 0 + git rm -n "some-file-*" | : && + test_path_is_missing .git/index.lock ' test_expect_success 'rm removes subdirectories recursively' ' @@ -708,6 +705,22 @@ test_expect_success 'rm of a populated nested submodule with a nested .git direc rm -rf submod ' +test_expect_success 'checking out a commit after submodule removal needs manual updates' ' + git commit -m "submodule removal" submod && + git checkout HEAD^ && + git submodule update && + git checkout -q HEAD^ 2>actual && + git checkout -q master 2>actual && + echo "warning: unable to rmdir submod: Directory not empty" >expected && + test_i18ncmp expected actual && + git status -s submod >actual && + echo "?? submod/" >expected && + test_cmp expected actual && + rm -rf submod && + git status -s -uno --ignore-submodules=none > actual && + ! test -s actual +' + test_expect_success 'rm of d/f when d has become a non-directory' ' rm -rf d && mkdir d && diff --git a/t/t3700-add.sh b/t/t3700-add.sh index aab86e838b..fe274e2fb1 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -272,6 +272,25 @@ test_expect_success '"add non-existent" should fail' ' ! (git ls-files | grep "non-existent") ' +test_expect_success 'git add -A on empty repo does not error out' ' + rm -fr empty && + git init empty && + ( + cd empty && + git add -A . && + git add -A + ) +' + +test_expect_success '"git add ." in empty repo' ' + rm -fr empty && + git init empty && + ( + cd empty && + git add . + ) +' + test_expect_success 'git add --dry-run of existing changed file' " echo new >>track-this && git add --dry-run track-this >actual 2>&1 && diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 9dc91d09d7..24ddd8a704 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -2,7 +2,6 @@ test_description='add -i basic tests' . ./test-lib.sh -. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh if ! test_have_prereq PERL then diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index debda7a678..5b79b216e2 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -673,4 +673,16 @@ test_expect_success 'store updates stash ref and reflog' ' grep quux bazzy ' +test_expect_success 'handle stash specification with spaces' ' + git stash clear && + echo pig >file && + git stash && + stamp=$(git log -g --format="%cd" -1 refs/stash) && + test_tick && + echo cow >file && + git stash && + git stash apply "stash@{$stamp}" && + grep pig file +' + test_done diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index af5134b70c..2bb973655b 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -110,4 +110,40 @@ test_expect_success 'diff-tree -r with wildcard' ' test_cmp expected result ' +test_expect_success 'setup submodules' ' + test_tick && + git init submod && + ( cd submod && test_commit first; ) && + git add submod && + git commit -m first && + ( cd submod && test_commit second; ) && + git add submod && + git commit -m second +' + +test_expect_success 'diff-tree ignores trailing slash on submodule path' ' + git diff --name-only HEAD^ HEAD submod >expect && + git diff --name-only HEAD^ HEAD submod/ >actual && + test_cmp expect actual +' + +test_expect_success 'diff multiple wildcard pathspecs' ' + mkdir path2 && + echo rezrov >path2/file1 && + git update-index --add path2/file1 && + tree3=`git write-tree` && + git diff --name-only $tree $tree3 -- "path2*1" "path1*1" >actual && + cat <<-\EOF >expect && + path1/file1 + path2/file1 + EOF + test_cmp expect actual +' + +test_expect_success 'diff-cache ignores trailing slash on submodule path' ' + git diff --name-only HEAD^ submod >expect && + git diff --name-only HEAD^ submod/ >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 8f272bce84..73194b2c3d 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -293,7 +293,7 @@ check_threading () { (git format-patch --stdout "$@"; echo $? > status.out) | # Prints everything between the Message-ID and In-Reply-To, # and replaces all Message-ID-lookalikes by a sequence number - "$PERL_PATH" -ne ' + perl -ne ' if (/^(message-id|references|in-reply-to)/i) { $printing = 1; } elsif (/^\S/) { diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 3fb4b976a2..604a838c1a 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -145,7 +145,7 @@ test_expect_success 'another test, with --ignore-space-at-eol' 'test_cmp expect test_expect_success 'ignore-blank-lines: only new lines' ' test_seq 5 >x && git update-index x && - test_seq 5 | sed "/3/i \\ + test_seq 5 | sed "/3/i\\ " >x && git diff --ignore-blank-lines >out && >expect && @@ -155,7 +155,8 @@ test_expect_success 'ignore-blank-lines: only new lines' ' test_expect_success 'ignore-blank-lines: only new lines with space' ' test_seq 5 >x && git update-index x && - test_seq 5 | sed "/3/i \ " >x && + test_seq 5 | sed "/3/i\\ + " >x && git diff -w --ignore-blank-lines >out && >expect && test_cmp out expect diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index 2e7d73f090..044620186d 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -177,7 +177,7 @@ test_expect_success 'no diff with -diff' ' git diff | grep Binary ' -echo NULZbetweenZwords | "$PERL_PATH" -pe 'y/Z/\000/' > file +echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file test_expect_success 'force diff with "diff"' ' echo >.gitattributes "file diff" && @@ -193,6 +193,19 @@ test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' ' GIT_EXTERNAL_DIFF=echo git diff ' +test_expect_success 'GIT_EXTERNAL_DIFF path counter/total' ' + write_script external-diff.sh <<-\EOF && + echo $GIT_DIFF_PATH_COUNTER of $GIT_DIFF_PATH_TOTAL >>counter.txt + EOF + >counter.txt && + cat >expect <<-\EOF && + 1 of 2 + 2 of 2 + EOF + GIT_EXTERNAL_DIFF=./external-diff.sh git diff && + test_cmp expect counter.txt +' + test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' ' touch file.ext && git add file.ext && @@ -213,12 +226,13 @@ keep_only_cr () { } test_expect_success 'external diff with autocrlf = true' ' - git config core.autocrlf true && + test_config core.autocrlf true && GIT_EXTERNAL_DIFF=./fake-diff.sh git diff && test $(wc -l < crlfed.txt) = $(cat crlfed.txt | keep_only_cr | wc -c) ' test_expect_success 'diff --cached' ' + test_config core.autocrlf true && git add file && git update-index --assume-unchanged file && echo second >file && @@ -226,4 +240,31 @@ test_expect_success 'diff --cached' ' test_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual ' +test_expect_success 'clean up crlf leftovers' ' + git update-index --no-assume-unchanged file && + rm -f file* && + git reset --hard +' + +test_expect_success 'submodule diff' ' + git init sub && + ( cd sub && test_commit sub1 ) && + git add sub && + test_tick && + git commit -m "add submodule" && + ( cd sub && test_commit sub2 ) && + write_script gather_pre_post.sh <<-\EOF && + echo "$1 $4" # path, mode + cat "$2" # old file + cat "$5" # new file + EOF + GIT_EXTERNAL_DIFF=./gather_pre_post.sh git diff >actual && + cat >expected <<-EOF && + sub 160000 + Subproject commit $(git rev-parse HEAD:sub) + Subproject commit $(cd sub && git rev-parse HEAD) + EOF + test_cmp expected actual +' + test_done diff --git a/t/t4029-diff-trailing-space.sh b/t/t4029-diff-trailing-space.sh index 36e2f075c9..3ccc237a8d 100755 --- a/t/t4029-diff-trailing-space.sh +++ b/t/t4029-diff-trailing-space.sh @@ -27,7 +27,7 @@ test_expect_success \ git config --bool diff.suppressBlankEmpty true && git diff f > actual && test_cmp exp actual && - "$PERL_PATH" -i.bak -p -e "s/^\$/ /" exp && + perl -i.bak -p -e "s/^\$/ /" exp && git config --bool diff.suppressBlankEmpty false && git diff f > actual && test_cmp exp actual && diff --git a/t/t4034/ada/expect b/t/t4034/ada/expect index be2376e904..a682d288b2 100644 --- a/t/t4034/ada/expect +++ b/t/t4034/ada/expect @@ -4,7 +4,7 @@ <BOLD>+++ b/post<RESET> <CYAN>@@ -1,13 +1,13 @@<RESET> Ada.Text_IO.Put_Line("Hello World<RED>!<RESET><GREEN>?<RESET>"); -1 1e<RED>-<RESET>10 16#FE12#E2 3.141_592 '<RED>x<RESET><GREEN>y<RESET>' +1 <RED>1e-10<RESET><GREEN>1e10<RESET> 16#FE12#E2 3.141_592 '<RED>x<RESET><GREEN>y<RESET>' <RED>a<RESET><GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET> <RED>a<RESET><GREEN>y<RESET> <GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b<RESET> diff --git a/t/t4035-diff-quiet.sh b/t/t4035-diff-quiet.sh index 231412d100..e8ae2a03fd 100755 --- a/t/t4035-diff-quiet.sh +++ b/t/t4035-diff-quiet.sh @@ -148,4 +148,10 @@ test_expect_success 'git diff --ignore-all-space, both files outside repo' ' ) ' +test_expect_success 'git diff --quiet ignores stat-change only entries' ' + test-chmtime +10 a && + echo modified >>b && + test_expect_code 1 git diff --quiet +' + test_done diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 979e98398b..2ab3c48734 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -29,4 +29,30 @@ test_expect_success 'git diff --no-index relative path outside repo' ' ) ' +test_expect_success 'git diff --no-index with broken index' ' + ( + cd repo && + echo broken >.git/index && + git diff --no-index a ../non/git/a + ) +' + +test_expect_success 'git diff outside repo with broken index' ' + ( + cd repo && + git diff ../non/git/a ../non/git/b + ) +' + +test_expect_success 'git diff --no-index executed outside repo gives correct error message' ' + ( + GIT_CEILING_DIRECTORIES=$TRASH_DIRECTORY/non && + export GIT_CEILING_DIRECTORIES && + cd non/git && + test_must_fail git diff --no-index a 2>actual.err && + echo "usage: git diff --no-index <path> <path>" >expect.err && + test_cmp expect.err actual.err + ) +' + test_done diff --git a/t/t4056-diff-order.sh b/t/t4056-diff-order.sh new file mode 100755 index 0000000000..c0460bb0e5 --- /dev/null +++ b/t/t4056-diff-order.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +test_description='diff order' + +. ./test-lib.sh + +create_files () { + echo "$1" >a.h && + echo "$1" >b.c && + echo "$1" >c/Makefile && + echo "$1" >d.txt && + git add a.h b.c c/Makefile d.txt && + git commit -m"$1" +} + +test_expect_success 'setup' ' + mkdir c && + create_files 1 && + create_files 2 && + + cat >order_file_1 <<-\EOF && + *Makefile + *.txt + *.h + EOF + + cat >order_file_2 <<-\EOF && + *Makefile + *.h + *.c + EOF + + cat >expect_none <<-\EOF && + a.h + b.c + c/Makefile + d.txt + EOF + + cat >expect_1 <<-\EOF && + c/Makefile + d.txt + a.h + b.c + EOF + + cat >expect_2 <<-\EOF + c/Makefile + a.h + b.c + d.txt + EOF +' + +test_expect_success "no order (=tree object order)" ' + git diff --name-only HEAD^..HEAD >actual && + test_cmp expect_none actual +' + +test_expect_success 'missing orderfile' ' + rm -f bogus_file && + test_must_fail git diff -Obogus_file --name-only HEAD^..HEAD +' + +test_expect_success POSIXPERM,SANITY 'unreadable orderfile' ' + >unreadable_file && + chmod -r unreadable_file && + test_must_fail git diff -Ounreadable_file --name-only HEAD^..HEAD +' + +for i in 1 2 +do + test_expect_success "orderfile using option ($i)" ' + git diff -Oorder_file_$i --name-only HEAD^..HEAD >actual && + test_cmp expect_$i actual + ' + + test_expect_success PIPE "orderfile is fifo ($i)" ' + rm -f order_fifo && + mkfifo order_fifo && + { + cat order_file_$i >order_fifo & + } && + git diff -O order_fifo --name-only HEAD^..HEAD >actual && + wait && + test_cmp expect_$i actual + ' + + test_expect_success "orderfile using config ($i)" ' + git -c diff.orderfile=order_file_$i diff --name-only HEAD^..HEAD >actual && + test_cmp expect_$i actual + ' + + test_expect_success "cancelling configured orderfile ($i)" ' + git -c diff.orderfile=order_file_$i diff -O/dev/null --name-only HEAD^..HEAD >actual && + test_cmp expect_none actual + ' +done + +test_expect_success 'setup for testing combine-diff order' ' + git checkout -b tmp HEAD~ && + create_files 3 && + git checkout master && + git merge --no-commit -s ours tmp && + create_files 5 +' + +test_expect_success "combine-diff: no order (=tree object order)" ' + git diff --name-only HEAD HEAD^ HEAD^2 >actual && + test_cmp expect_none actual +' + +for i in 1 2 +do + test_expect_success "combine-diff: orderfile using option ($i)" ' + git diff -Oorder_file_$i --name-only HEAD HEAD^ HEAD^2 >actual && + test_cmp expect_$i actual + ' +done + +test_done diff --git a/t/t4057-diff-combined-paths.sh b/t/t4057-diff-combined-paths.sh new file mode 100755 index 0000000000..097e63215e --- /dev/null +++ b/t/t4057-diff-combined-paths.sh @@ -0,0 +1,106 @@ +#!/bin/sh + +test_description='combined diff show only paths that are different to all parents' + +. ./test-lib.sh + +# verify that diffc.expect matches output of +# `git diff -c --name-only HEAD HEAD^ HEAD^2` +diffc_verify () { + git diff -c --name-only HEAD HEAD^ HEAD^2 >diffc.actual && + test_cmp diffc.expect diffc.actual +} + +test_expect_success 'trivial merge - combine-diff empty' ' + for i in $(test_seq 1 9) + do + echo $i >$i.txt && + git add $i.txt + done && + git commit -m "init" && + git checkout -b side && + for i in $(test_seq 2 9) + do + echo $i/2 >>$i.txt + done && + git commit -a -m "side 2-9" && + git checkout master && + echo 1/2 >1.txt && + git commit -a -m "master 1" && + git merge side && + >diffc.expect && + diffc_verify +' + + +test_expect_success 'only one trully conflicting path' ' + git checkout side && + for i in $(test_seq 2 9) + do + echo $i/3 >>$i.txt + done && + echo "4side" >>4.txt && + git commit -a -m "side 2-9 +4" && + git checkout master && + for i in $(test_seq 1 9) + do + echo $i/3 >>$i.txt + done && + echo "4master" >>4.txt && + git commit -a -m "master 1-9 +4" && + test_must_fail git merge side && + cat <<-\EOF >4.txt && + 4 + 4/2 + 4/3 + 4master + 4side + EOF + git add 4.txt && + git commit -m "merge side (2)" && + echo 4.txt >diffc.expect && + diffc_verify +' + +test_expect_success 'merge introduces new file' ' + git checkout side && + for i in $(test_seq 5 9) + do + echo $i/4 >>$i.txt + done && + git commit -a -m "side 5-9" && + git checkout master && + for i in $(test_seq 1 3) + do + echo $i/4 >>$i.txt + done && + git commit -a -m "master 1-3 +4hello" && + git merge side && + echo "Hello World" >4hello.txt && + git add 4hello.txt && + git commit --amend && + echo 4hello.txt >diffc.expect && + diffc_verify +' + +test_expect_success 'merge removed a file' ' + git checkout side && + for i in $(test_seq 5 9) + do + echo $i/5 >>$i.txt + done && + git commit -a -m "side 5-9" && + git checkout master && + for i in $(test_seq 1 3) + do + echo $i/4 >>$i.txt + done && + git commit -a -m "master 1-3" && + git merge side && + git rm 4.txt && + git commit --amend && + echo 4.txt >diffc.expect && + diffc_verify +' + +test_done diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh index e3ea3d5114..49e2d6c349 100755 --- a/t/t4102-apply-rename.sh +++ b/t/t4102-apply-rename.sh @@ -7,7 +7,6 @@ test_description='git apply handling copy/rename patch. ' . ./test-lib.sh -. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh # setup diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index b1b906b1bb..1b420e3b5f 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -23,10 +23,10 @@ test_expect_success 'setup' ' git commit -m "Initial Version" 2>/dev/null && git checkout -b binary && - "$PERL_PATH" -pe "y/x/\000/" <file1 >file3 && + perl -pe "y/x/\000/" <file1 >file3 && cat file3 >file4 && git add file2 && - "$PERL_PATH" -pe "y/\000/v/" <file3 >file1 && + perl -pe "y/\000/v/" <file3 >file1 && rm -f file2 && git update-index --add --remove file1 file2 file3 file4 && git commit -m "Second Version" && diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh index fca815392e..1e4d4380bf 100755 --- a/t/t4116-apply-reverse.sh +++ b/t/t4116-apply-reverse.sh @@ -12,14 +12,14 @@ test_description='git apply in reverse test_expect_success setup ' for i in a b c d e f g h i j k l m n; do echo $i; done >file1 && - "$PERL_PATH" -pe "y/ijk/\\000\\001\\002/" <file1 >file2 && + perl -pe "y/ijk/\\000\\001\\002/" <file1 >file2 && git add file1 file2 && git commit -m initial && git tag initial && for i in a b c g h i J K L m o n p q; do echo $i; done >file1 && - "$PERL_PATH" -pe "y/mon/\\000\\001\\002/" <file1 >file2 && + perl -pe "y/mon/\\000\\001\\002/" <file1 >file2 && git commit -a -m second && git tag second && @@ -48,12 +48,12 @@ test_expect_success 'apply in reverse' ' test_expect_success 'setup separate repository lacking postimage' ' - git tar-tree initial initial | $TAR xf - && + git archive --format=tar --prefix=initial/ initial | $TAR xf - && ( cd initial && git init && git add . ) && - git tar-tree second second | $TAR xf - && + git archive --format=tar --prefix=second/ second | $TAR xf - && ( cd second && git init && git add . ) diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh index c5fecdfed4..497b62868d 100755 --- a/t/t4120-apply-popt.sh +++ b/t/t4120-apply-popt.sh @@ -6,7 +6,6 @@ test_description='git apply -p handling.' . ./test-lib.sh -. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh test_expect_success setup ' mkdir sub && diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index 0d36ebdc86..c268298eaf 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -3,7 +3,6 @@ test_description='applying patch with mode bits' . ./test-lib.sh -. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh test_expect_success setup ' echo original >file && diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 7f6666fcd3..ed9c91e25b 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -78,7 +78,7 @@ test_expect_success 'activate rerere, old style (conflicting merge)' ' test_might_fail git config --unset rerere.enabled && test_must_fail git merge first && - sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) && + sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) && rr=.git/rr-cache/$sha1 && grep "^=======\$" $rr/preimage && ! test -f $rr/postimage && @@ -91,7 +91,7 @@ test_expect_success 'rerere.enabled works, too' ' git reset --hard && test_must_fail git merge first && - sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) && + sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) && rr=.git/rr-cache/$sha1 && grep ^=======$ $rr/preimage ' @@ -101,7 +101,7 @@ test_expect_success 'set up rr-cache' ' git config rerere.enabled true && git reset --hard && test_must_fail git merge first && - sha1=$("$PERL_PATH" -pe "s/ .*//" .git/MERGE_RR) && + sha1=$(perl -pe "s/ .*//" .git/MERGE_RR) && rr=.git/rr-cache/$sha1 ' @@ -172,7 +172,7 @@ test_expect_success 'first postimage wins' ' git show second^:a1 | sed "s/To die: t/To die! T/" >a1 && git commit -q -a -m third && - test_must_fail git pull . first && + test_must_fail git merge first && # rerere kicked in ! grep "^=======\$" a1 && test_cmp expect a1 @@ -185,7 +185,7 @@ test_expect_success 'rerere updates postimage timestamp' ' test_expect_success 'rerere clear' ' rm $rr/postimage && - echo "$sha1 a1" | "$PERL_PATH" -pe "y/\012/\000/" >.git/MERGE_RR && + echo "$sha1 a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR && git rerere clear && ! test -d $rr ' diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index fb00041139..2a6278bb33 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -310,4 +310,19 @@ EOF test_cmp expected actual ' +test_expect_success 'log decoration properly follows tag chain' ' + git tag -a tag1 -m tag1 && + git tag -a tag2 -m tag2 tag1 && + git tag -d tag1 && + git commit --amend -m shorter && + git log --no-walk --tags --pretty="%H %d" --decorate=full >actual && + cat <<EOF >expected && +6a908c10688b2503073c39c9ba26322c73902bb5 (tag: refs/tags/tag2) +9f716384d92283fb915a4eee5073f030638e05f9 (tag: refs/tags/message-one) +b87e4cccdb77336ea79d89224737be7ea8e95367 (tag: refs/tags/message-two) +EOF + sort actual >actual1 && + test_cmp expected actual1 +' + test_done diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh index 72300b5f24..d8f23f488e 100755 --- a/t/t4208-log-magic-pathspec.sh +++ b/t/t4208-log-magic-pathspec.sh @@ -46,4 +46,19 @@ test_expect_success 'git log HEAD -- :/' ' test_cmp expected actual ' +test_expect_success 'command line pathspec parsing for "git log"' ' + git reset --hard && + >a && + git add a && + git commit -m "add an empty a" --allow-empty && + echo 1 >a && + git commit -a -m "update a to 1" && + git checkout HEAD^ && + echo 2 >a && + git commit -a -m "update a to 2" && + test_must_fail git merge master && + git add a && + git log --merge -- a +' + test_done diff --git a/t/t4212-log-corrupt.sh b/t/t4212-log-corrupt.sh index ec5099b83d..3fa171541a 100755 --- a/t/t4212-log-corrupt.sh +++ b/t/t4212-log-corrupt.sh @@ -13,11 +13,16 @@ test_expect_success 'setup' ' git update-ref refs/heads/broken_email $(cat broken_email.hash) ' +test_expect_success 'fsck notices broken commit' ' + git fsck 2>actual && + test_i18ngrep invalid.author actual +' + test_expect_success 'git log with broken author email' ' { echo commit $(cat broken_email.hash) echo "Author: A U Thor <author@example.com>" - echo "Date: Thu Jan 1 00:00:00 1970 +0000" + echo "Date: Thu Apr 7 15:13:13 2005 -0700" echo echo " foo" } >expect.out && @@ -30,7 +35,7 @@ test_expect_success 'git log with broken author email' ' ' test_expect_success 'git log --format with broken author email' ' - echo "A U Thor+author@example.com+" >expect.out && + echo "A U Thor+author@example.com+Thu Apr 7 15:13:13 2005 -0700" >expect.out && : >expect.err && git log --format="%an+%ae+%ad" broken_email >actual.out 2>actual.err && @@ -39,4 +44,49 @@ test_expect_success 'git log --format with broken author email' ' test_cmp expect.err actual.err ' +munge_author_date () { + git cat-file commit "$1" >commit.orig && + sed "s/^\(author .*>\) [0-9]*/\1 $2/" <commit.orig >commit.munge && + git hash-object -w -t commit commit.munge +} + +test_expect_success 'unparsable dates produce sentinel value' ' + commit=$(munge_author_date HEAD totally_bogus) && + echo "Date: Thu Jan 1 00:00:00 1970 +0000" >expect && + git log -1 $commit >actual.full && + grep Date <actual.full >actual && + test_cmp expect actual +' + +test_expect_success 'unparsable dates produce sentinel value (%ad)' ' + commit=$(munge_author_date HEAD totally_bogus) && + echo >expect && + git log -1 --format=%ad $commit >actual + test_cmp expect actual +' + +# date is 2^64 + 1 +test_expect_success 'date parser recognizes integer overflow' ' + commit=$(munge_author_date HEAD 18446744073709551617) && + echo "Thu Jan 1 00:00:00 1970 +0000" >expect && + git log -1 --format=%ad $commit >actual && + test_cmp expect actual +' + +# date is 2^64 - 2 +test_expect_success 'date parser recognizes time_t overflow' ' + commit=$(munge_author_date HEAD 18446744073709551614) && + echo "Thu Jan 1 00:00:00 1970 +0000" >expect && + git log -1 --format=%ad $commit >actual && + test_cmp expect actual +' + +# date is within 2^63-1, but enough to choke glibc's gmtime +test_expect_success 'absurdly far-in-future dates produce sentinel' ' + commit=$(munge_author_date HEAD 999999999999999999) && + echo "Thu Jan 1 00:00:00 1970 +0000" >expect && + git log -1 --format=%ad $commit >actual && + test_cmp expect actual +' + test_done diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index c2023b1a3d..1cf0a4e103 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -3,7 +3,7 @@ # Copyright (C) 2005 Rene Scharfe # -test_description='git tar-tree and git get-tar-commit-id test +test_description='git archive and git get-tar-commit-id test This test covers the topics of file contents, commit date handling and commit id embedding: @@ -13,11 +13,11 @@ commit id embedding: binary file (/bin/sh). Only paths shorter than 99 characters are used. - git tar-tree applies the commit date to every file in the archive it + git archive applies the commit date to every file in the archive it creates. The test sets the commit date to a specific value and checks if the tar archive contains that value. - When giving git tar-tree a commit id (in contrast to a tree id) it + When giving git archive a commit id (in contrast to a tree id) it embeds this commit id into the tar archive as a comment. The test checks the ability of git get-tar-commit-id to figure it out from the tar file. @@ -25,8 +25,6 @@ commit id embedding: ' . ./test-lib.sh -GZIP=${GZIP:-gzip} -GUNZIP=${GUNZIP:-gzip -d} SUBSTFORMAT=%H%n @@ -39,6 +37,8 @@ test_lazy_prereq TAR_NEEDS_PAX_FALLBACK ' ) ' +test_lazy_prereq GZIP 'gzip --version' + get_pax_header() { file=$1 header=$2= @@ -196,16 +196,6 @@ test_expect_success \ 'git get-tar-commit-id <b.tar >b.commitid && test_cmp .git/$(git symbolic-ref HEAD) b.commitid' -test_expect_success 'git tar-tree' ' - git tar-tree HEAD >tar-tree.tar && - test_cmp b.tar tar-tree.tar -' - -test_expect_success 'git tar-tree with prefix' ' - git tar-tree HEAD prefix >tar-tree_with_prefix.tar && - test_cmp with_prefix.tar tar-tree_with_prefix.tar -' - test_expect_success 'git archive with --output, override inferred format' ' git archive --format=tar --output=d4.zip HEAD && test_cmp b.tar d4.zip @@ -223,6 +213,15 @@ test_expect_success 'clients cannot access unreachable commits' ' test_must_fail git archive --remote=. $sha1 >remote.tar ' +test_expect_success 'upload-archive can allow unreachable commits' ' + test_commit unreachable1 && + sha1=`git rev-parse HEAD` && + git reset --hard HEAD^ && + git archive $sha1 >remote.tar && + test_config uploadarchive.allowUnreachable true && + git archive --remote=. $sha1 >remote.tar +' + test_expect_success 'setup tar filters' ' git config tar.tar.foo.command "tr ab ba" && git config tar.bar.command "tr ab ba" && @@ -275,12 +274,6 @@ test_expect_success 'only enabled filters are available remotely' ' test_cmp remote.bar config.bar ' -if $GZIP --version >/dev/null 2>&1; then - test_set_prereq GZIP -else - say "Skipping some tar.gz tests because gzip not found" -fi - test_expect_success GZIP 'git archive --format=tgz' ' git archive --format=tgz HEAD >j.tgz ' @@ -300,14 +293,8 @@ test_expect_success GZIP 'infer tgz from .tar.gz filename' ' test_cmp j.tgz j3.tar.gz ' -if $GUNZIP --version >/dev/null 2>&1; then - test_set_prereq GUNZIP -else - say "Skipping some tar.gz tests because gunzip was not found" -fi - -test_expect_success GZIP,GUNZIP 'extract tgz file' ' - $GUNZIP -c <j.tgz >j.tar && +test_expect_success GZIP 'extract tgz file' ' + gzip -d -c <j.tgz >j.tar && test_cmp b.tar j.tar ' diff --git a/t/t5001-archive-attr.sh b/t/t5001-archive-attr.sh index f47d8717fd..51dedab29b 100755 --- a/t/t5001-archive-attr.sh +++ b/t/t5001-archive-attr.sh @@ -87,14 +87,4 @@ test_expect_success 'export-subst' ' test_cmp substfile2 archive/substfile2 ' -test_expect_success 'git tar-tree vs. git archive with worktree attributes' ' - git tar-tree HEAD >tar-tree.tar && - test_cmp worktree.tar tar-tree.tar -' - -test_expect_success 'git tar-tree vs. git archive with worktree attrs, bare' ' - (cd bare && git tar-tree HEAD) >bare-tar-tree.tar && - test_cmp bare-worktree.tar bare-tar-tree.tar -' - test_done diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh index 1afa0d5c44..75d6b3843a 100755 --- a/t/t5150-request-pull.sh +++ b/t/t5150-request-pull.sh @@ -86,7 +86,7 @@ test_expect_success 'setup: two scripts for reading pull requests' ' s/[-0-9]\{10\} [:0-9]\{8\} [-+][0-9]\{4\}/DATE/g s/ [^ ].*/ SUBJECT/g s/ [^ ].* (DATE)/ SUBJECT (DATE)/g - s/for-upstream/BRANCH/g + s|tags/full|BRANCH|g s/mnemonic.txt/FILENAME/g s/^version [0-9]/VERSION/ /^ FILENAME | *[0-9]* [-+]*\$/ b diffstat @@ -127,7 +127,7 @@ test_expect_success 'pull request when forgot to push' ' test_must_fail git request-pull initial "$downstream_url" \ 2>../err ) && - grep "No branch of.*is at:\$" err && + grep "No match for commit .*" err && grep "Are you sure you pushed" err ' @@ -141,7 +141,7 @@ test_expect_success 'pull request after push' ' git checkout initial && git merge --ff-only master && git push origin master:for-upstream && - git request-pull initial origin >../request + git request-pull initial origin master:for-upstream >../request ) && sed -nf read-request.sed <request >digest && cat digest && @@ -160,7 +160,7 @@ test_expect_success 'pull request after push' ' ' -test_expect_success 'request names an appropriate branch' ' +test_expect_success 'request asks HEAD to be pulled' ' rm -fr downstream.git && git init --bare downstream.git && @@ -179,7 +179,7 @@ test_expect_success 'request names an appropriate branch' ' read repository && read branch } <digest && - test "$branch" = tags/full + test -z "$branch" ' @@ -212,12 +212,18 @@ test_expect_success 'pull request format' ' cd local && git checkout initial && git merge --ff-only master && - git push origin master:for-upstream && - git request-pull initial "$downstream_url" >../request + git push origin tags/full && + git request-pull initial "$downstream_url" tags/full >../request ) && <request sed -nf fuzz.sed >request.fuzzy && - test_i18ncmp expect request.fuzzy + test_i18ncmp expect request.fuzzy && + ( + cd local && + git request-pull initial "$downstream_url" tags/full:refs/tags/full + ) >request && + sed -nf fuzz.sed <request >request.fuzzy && + test_i18ncmp expect request.fuzzy ' test_expect_success 'request-pull ignores OPTIONS_KEEPDASHDASH poison' ' @@ -229,7 +235,7 @@ test_expect_success 'request-pull ignores OPTIONS_KEEPDASHDASH poison' ' git checkout initial && git merge --ff-only master && git push origin master:for-upstream && - git request-pull -- initial "$downstream_url" >../request + git request-pull -- initial "$downstream_url" master:for-upstream >../request ) ' diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index a07c871797..20c1961515 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -13,9 +13,9 @@ TRASH=`pwd` test_expect_success \ 'setup' \ 'rm -f .git/index* && - "$PERL_PATH" -e "print \"a\" x 4096;" > a && - "$PERL_PATH" -e "print \"b\" x 4096;" > b && - "$PERL_PATH" -e "print \"c\" x 4096;" > c && + perl -e "print \"a\" x 4096;" > a && + perl -e "print \"b\" x 4096;" > b && + perl -e "print \"c\" x 4096;" > 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 && @@ -129,7 +129,7 @@ test_expect_success \ cd "$TRASH" test_expect_success 'compare delta flavors' ' - "$PERL_PATH" -e '\'' + perl -e '\'' defined($_ = -s $_) or die for @ARGV; exit 1 if $ARGV[0] <= $ARGV[1]; '\'' test-2-$packname_2.pack test-3-$packname_3.pack @@ -151,7 +151,7 @@ test_expect_success \ git cat-file $t $object || return 1 done <obj-list } >current && - test_cmp expect current' + cmp expect current' test_expect_success \ 'use packed deltified (REF_DELTA) objects' \ @@ -166,7 +166,7 @@ test_expect_success \ git cat-file $t $object || return 1 done <obj-list } >current && - test_cmp expect current' + cmp expect current' test_expect_success \ 'use packed deltified (OFS_DELTA) objects' \ @@ -181,7 +181,7 @@ test_expect_success \ git cat-file $t $object || return 1 done <obj-list } >current && - test_cmp expect current' + cmp expect current' unset GIT_OBJECT_DIRECTORY @@ -195,9 +195,9 @@ test_expect_success 'survive missing objects/pack directory' ' rm -fr $GOP && git index-pack --stdin --keep=test <../test-3-${packname_3}.pack && test -f $GOP/pack-${packname_3}.pack && - test_cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack && + cmp $GOP/pack-${packname_3}.pack ../test-3-${packname_3}.pack && test -f $GOP/pack-${packname_3}.idx && - test_cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx && + cmp $GOP/pack-${packname_3}.idx ../test-3-${packname_3}.idx && test -f $GOP/pack-${packname_3}.keep ) ' diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index fe82025d4a..4bbb718751 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -174,11 +174,11 @@ test_expect_success \ test_expect_success \ '[index v1] 5) pack-objects happily reuses corrupted data' \ 'pack4=$(git pack-objects test-4 <obj-list) && - test -f "test-4-${pack1}.pack"' + test -f "test-4-${pack4}.pack"' test_expect_success \ '[index v1] 6) newly created pack is BAD !' \ - 'test_must_fail git verify-pack -v "test-4-${pack1}.pack"' + 'test_must_fail git verify-pack -v "test-4-${pack4}.pack"' test_expect_success \ '[index v2] 1) stream pack to repository' \ diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh index 35926debe3..663b02bbb1 100755 --- a/t/t5303-pack-corruption-resilience.sh +++ b/t/t5303-pack-corruption-resilience.sh @@ -98,7 +98,7 @@ test_expect_success \ 'create_new_pack && git prune-packed && chmod +w ${pack}.pack && - "$PERL_PATH" -i.bak -pe "s/ base /abcdef/" ${pack}.pack && + perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack && test_must_fail git cat-file blob $blob_1 > /dev/null && test_must_fail git cat-file blob $blob_2 > /dev/null && test_must_fail git cat-file blob $blob_3 > /dev/null' @@ -155,7 +155,7 @@ test_expect_success \ 'create_new_pack && git prune-packed && chmod +w ${pack}.pack && - "$PERL_PATH" -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack && + perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack && git cat-file blob $blob_1 > /dev/null && test_must_fail git cat-file blob $blob_2 > /dev/null && test_must_fail git cat-file blob $blob_3 > /dev/null' diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index e4bb3a1457..66c9a41739 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -221,4 +221,14 @@ EOF test_cmp expected actual ' +test_expect_success 'prune .git/shallow' ' + SHA1=`echo hi|git commit-tree HEAD^{tree}` && + echo $SHA1 >.git/shallow && + git prune --dry-run >out && + grep $SHA1 .git/shallow && + grep $SHA1 out && + git prune && + ! test -f .git/shallow +' + test_done diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index 129fc88bd2..0736bcbcd5 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -164,6 +164,7 @@ test_expect_success 'receive-pack runs auto-gc in remote repo' ' # Set the child to auto-pack if more than one pack exists cd child && git config gc.autopacklimit 1 && + git config gc.autodetach false && git branch test_auto_gc && # And create a file that follows the temporary object naming # convention for the auto-gc to remove diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index d87ddf73b7..5b2b1c2c13 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -531,5 +531,92 @@ test_expect_success 'shallow fetch with tags does not break the repository' ' git fsck ) ' +check_prot_path () { + cat >expected <<-EOF && + Diag: url=$1 + Diag: protocol=$2 + Diag: path=$3 + EOF + git fetch-pack --diag-url "$1" | grep -v hostandport= >actual && + test_cmp expected actual +} + +check_prot_host_path () { + cat >expected <<-EOF && + Diag: url=$1 + Diag: protocol=$2 + Diag: hostandport=$3 + Diag: path=$4 + EOF + git fetch-pack --diag-url "$1" >actual && + test_cmp expected actual +} + +for r in repo re:po re/po +do + # git or ssh with scheme + for p in "ssh+git" "git+ssh" git ssh + do + for h in host host:12 [::1] [::1]:23 + do + case "$p" in + *ssh*) + pp=ssh + ;; + *) + pp=$p + ;; + esac + test_expect_success "fetch-pack --diag-url $p://$h/$r" ' + check_prot_host_path $p://$h/$r $pp "$h" "/$r" + ' + # "/~" -> "~" conversion + test_expect_success "fetch-pack --diag-url $p://$h/~$r" ' + check_prot_host_path $p://$h/~$r $pp "$h" "~$r" + ' + done + done + # file with scheme + for p in file + do + test_expect_success "fetch-pack --diag-url $p://$h/$r" ' + check_prot_path $p://$h/$r $p "/$r" + ' + # No "/~" -> "~" conversion for file + test_expect_success "fetch-pack --diag-url $p://$h/~$r" ' + check_prot_path $p://$h/~$r $p "/~$r" + ' + done + # file without scheme + for h in nohost nohost:12 [::1] [::1]:23 [ [:aa + do + test_expect_success "fetch-pack --diag-url ./$h:$r" ' + check_prot_path ./$h:$r $p "./$h:$r" + ' + # No "/~" -> "~" conversion for file + test_expect_success "fetch-pack --diag-url ./$p:$h/~$r" ' + check_prot_path ./$p:$h/~$r $p "./$p:$h/~$r" + ' + done + #ssh without scheme + p=ssh + for h in host [::1] + do + test_expect_success "fetch-pack --diag-url $h:$r" ' + check_prot_path $h:$r $p "$r" + ' + # Do "/~" -> "~" conversion + test_expect_success "fetch-pack --diag-url $h:/~$r" ' + check_prot_host_path $h:/~$r $p "$h" "~$r" + ' + done +done + +test_expect_success MINGW 'fetch-pack --diag-url file://c:/repo' ' + check_prot_path file://c:/repo file c:/repo +' +test_expect_success MINGW 'fetch-pack --diag-url c:repo' ' + check_prot_path c:repo file c:repo +' test_done diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 8f6e3922dc..ac79dd915d 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -160,9 +160,7 @@ cat >test/expect <<EOF * remote two Fetch URL: ../two Push URL: ../three - HEAD branch (remote HEAD is ambiguous, may be one of the following): - another - master + HEAD branch: master Local refs configured for 'git push': ahead forces to master (fast-forwardable) master pushes to another (up to date) @@ -262,16 +260,12 @@ test_expect_success 'set-head --auto' ' ) ' -cat >test/expect <<\EOF -error: Multiple remote HEAD branches. Please choose one explicitly with: - git remote set-head two another - git remote set-head two master -EOF - -test_expect_success 'set-head --auto fails w/multiple HEADs' ' +test_expect_success 'set-head --auto has no problem w/multiple HEADs' ' ( cd test && - test_must_fail git remote set-head --auto two >output 2>&1 && + git fetch two "refs/heads/*:refs/remotes/two/*" && + git remote set-head --auto two >output 2>&1 && + echo "two/HEAD set to master" >expect && test_i18ncmp expect output ) ' diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 1f0f8e6827..5acd753dcf 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -88,7 +88,7 @@ test_expect_success 'fetch --prune on its own works as expected' ' cd "$D" && git clone . prune && cd prune && - git fetch origin refs/heads/master:refs/remotes/origin/extrabranch && + git update-ref refs/remotes/origin/extrabranch master && git fetch --prune origin && test_must_fail git rev-parse origin/extrabranch @@ -98,7 +98,7 @@ test_expect_success 'fetch --prune with a branch name keeps branches' ' cd "$D" && git clone . prune-branch && cd prune-branch && - git fetch origin refs/heads/master:refs/remotes/origin/extrabranch && + git update-ref refs/remotes/origin/extrabranch master && git fetch --prune origin master && git rev-parse origin/extrabranch @@ -113,25 +113,45 @@ test_expect_success 'fetch --prune with a namespace keeps other namespaces' ' git rev-parse origin/master ' -test_expect_success 'fetch --prune --tags does not delete the remote-tracking branches' ' +test_expect_success 'fetch --prune --tags prunes branches but not tags' ' cd "$D" && git clone . prune-tags && cd prune-tags && - git fetch origin refs/heads/master:refs/tags/sometag && + git tag sometag master && + # Create what looks like a remote-tracking branch from an earlier + # fetch that has since been deleted from the remote: + git update-ref refs/remotes/origin/fake-remote master && git fetch --prune --tags origin && git rev-parse origin/master && - test_must_fail git rev-parse somebranch + test_must_fail git rev-parse origin/fake-remote && + git rev-parse sometag ' -test_expect_success 'fetch --prune --tags with branch does not delete other remote-tracking branches' ' +test_expect_success 'fetch --prune --tags with branch does not prune other things' ' cd "$D" && git clone . prune-tags-branch && cd prune-tags-branch && - git fetch origin refs/heads/master:refs/remotes/origin/extrabranch && + git tag sometag master && + git update-ref refs/remotes/origin/extrabranch master && git fetch --prune --tags origin master && - git rev-parse origin/extrabranch + git rev-parse origin/extrabranch && + git rev-parse sometag +' + +test_expect_success 'fetch --prune --tags with refspec prunes based on refspec' ' + cd "$D" && + git clone . prune-tags-refspec && + cd prune-tags-refspec && + git tag sometag master && + git update-ref refs/remotes/origin/foo/otherbranch master && + git update-ref refs/remotes/origin/extrabranch master && + + git fetch --prune --tags origin refs/heads/foo/*:refs/remotes/origin/foo/* && + test_must_fail git rev-parse refs/remotes/origin/foo/otherbranch && + git rev-parse origin/extrabranch && + git rev-parse sometag ' test_expect_success 'fetch tags when there is no tags' ' @@ -281,7 +301,7 @@ test_expect_success 'fetch via rsync' ' mkdir rsynced && (cd rsynced && git init --bare && - git fetch "rsync:$(pwd)/../.git" master:refs/heads/master && + git fetch "rsync:../.git" master:refs/heads/master && git gc --prune && test $(git rev-parse master) = $(cd .. && git rev-parse master) && git fsck --full) @@ -292,7 +312,7 @@ test_expect_success 'push via rsync' ' (cd rsynced2 && git init) && (cd rsynced && - git push "rsync:$(pwd)/../rsynced2/.git" master) && + git push "rsync:../rsynced2/.git" master) && (cd rsynced2 && git gc --prune && test $(git rev-parse master) = $(cd .. && git rev-parse master) && @@ -303,7 +323,7 @@ test_expect_success 'push via rsync' ' mkdir rsynced3 && (cd rsynced3 && git init) && - git push --all "rsync:$(pwd)/rsynced3/.git" && + git push --all "rsync:rsynced3/.git" && (cd rsynced3 && test $(git rev-parse master) = $(cd .. && git rev-parse master) && git fsck --full) @@ -594,4 +614,41 @@ test_expect_success 'all boundary commits are excluded' ' test_bundle_object_count .git/objects/pack/pack-${pack##pack }.pack 3 ' +test_expect_success 'fetch --prune prints the remotes url' ' + git branch goodbye && + git clone . only-prunes && + git branch -D goodbye && + ( + cd only-prunes && + git fetch --prune origin 2>&1 | head -n1 >../actual + ) && + echo "From ${D}/." >expect && + test_cmp expect actual +' + +test_expect_success 'branchname D/F conflict resolved by --prune' ' + git branch dir/file && + git clone . prune-df-conflict && + git branch -D dir/file && + git branch dir && + ( + cd prune-df-conflict && + git fetch --prune && + git rev-parse origin/dir >../actual + ) && + git rev-parse dir >expect && + test_cmp expect actual +' + +test_expect_success 'fetching a one-level ref works' ' + test_commit extra && + git reset --hard HEAD^ && + git update-ref refs/foo extra && + git init one-level && + ( + cd one-level && + git fetch .. HEAD refs/foo + ) +' + test_done diff --git a/t/t5515/fetch.br-unconfig_--tags_.._.git b/t/t5515/fetch.br-unconfig_--tags_.._.git index 1669cc4af0..0f70f66c70 100644 --- a/t/t5515/fetch.br-unconfig_--tags_.._.git +++ b/t/t5515/fetch.br-unconfig_--tags_.._.git @@ -1,4 +1,5 @@ # br-unconfig --tags ../.git +0567da4d5edd2ff4bb292a465ba9e64dcad9536b ../ 6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../ 8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ 22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ diff --git a/t/t5515/fetch.master_--tags_.._.git b/t/t5515/fetch.master_--tags_.._.git index 8a7493537b..ab473a6e1f 100644 --- a/t/t5515/fetch.master_--tags_.._.git +++ b/t/t5515/fetch.master_--tags_.._.git @@ -1,4 +1,5 @@ # master --tags ../.git +0567da4d5edd2ff4bb292a465ba9e64dcad9536b ../ 6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../ 8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../ 22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../ diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 99c32d7539..67e0ab3462 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -536,6 +536,19 @@ test_expect_success 'push with config branch.*.pushremote' ' check_push_result down_repo $the_commit heads/master ' +test_expect_success 'branch.*.pushremote config order is irrelevant' ' + mk_test one_repo heads/master && + mk_test two_repo heads/master && + test_config remote.one.url one_repo && + test_config remote.two.url two_repo && + test_config branch.master.pushremote two_repo && + test_config remote.pushdefault one_repo && + test_config push.default matching && + git push && + check_push_result one_repo $the_first_commit heads/master && + check_push_result two_repo $the_commit heads/master +' + test_expect_success 'push with dry-run' ' mk_test testrepo heads/master && @@ -1126,6 +1139,81 @@ test_expect_success 'fetch follows tags by default' ' test_cmp expect actual ' +test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' ' + mk_test testrepo heads/master && + rm -fr src dst && + git init src && + git init --bare dst && + ( + cd src && + git pull ../testrepo master && + git branch next && + git config remote.dst.url ../dst && + git config remote.dst.push "+refs/heads/*:refs/remotes/src/*" && + git push dst master && + git show-ref refs/heads/master | + sed -e "s|refs/heads/|refs/remotes/src/|" >../dst/expect + ) && + ( + cd dst && + test_must_fail git show-ref refs/heads/next && + test_must_fail git show-ref refs/heads/master && + git show-ref refs/remotes/src/master >actual + ) && + test_cmp dst/expect dst/actual +' + +test_expect_success 'with no remote.$name.push, it is not used as refmap' ' + mk_test testrepo heads/master && + rm -fr src dst && + git init src && + git init --bare dst && + ( + cd src && + git pull ../testrepo master && + git branch next && + git config remote.dst.url ../dst && + git config push.default matching && + git push dst master && + git show-ref refs/heads/master >../dst/expect + ) && + ( + cd dst && + test_must_fail git show-ref refs/heads/next && + git show-ref refs/heads/master >actual + ) && + test_cmp dst/expect dst/actual +' + +test_expect_success 'with no remote.$name.push, upstream mapping is used' ' + mk_test testrepo heads/master && + rm -fr src dst && + git init src && + git init --bare dst && + ( + cd src && + git pull ../testrepo master && + git branch next && + git config remote.dst.url ../dst && + git config remote.dst.fetch "+refs/heads/*:refs/remotes/dst/*" && + git config push.default upstream && + + git config branch.master.merge refs/heads/trunk && + git config branch.master.remote dst && + + git push dst master && + git show-ref refs/heads/master | + sed -e "s|refs/heads/master|refs/heads/trunk|" >../dst/expect + ) && + ( + cd dst && + test_must_fail git show-ref refs/heads/master && + test_must_fail git show-ref refs/heads/next && + git show-ref refs/heads/trunk >actual + ) && + test_cmp dst/expect dst/actual +' + test_expect_success 'push does not follow tags by default' ' mk_test testrepo heads/master && rm -fr src dst && diff --git a/t/t5525-fetch-tagopt.sh b/t/t5525-fetch-tagopt.sh index 4fbf7a120f..45815f7378 100755 --- a/t/t5525-fetch-tagopt.sh +++ b/t/t5525-fetch-tagopt.sh @@ -8,7 +8,8 @@ setup_clone () { git clone --mirror . $1 && git remote add remote_$1 $1 && (cd $1 && - git tag tag_$1) + git tag tag_$1 && + git branch branch_$1) } test_expect_success setup ' @@ -21,21 +22,33 @@ test_expect_success setup ' test_expect_success "fetch with tagopt=--no-tags does not get tag" ' git fetch remote_one && - test_must_fail git show-ref tag_one + test_must_fail git show-ref tag_one && + git show-ref remote_one/branch_one ' test_expect_success "fetch --tags with tagopt=--no-tags gets tag" ' + ( + cd one && + git branch second_branch_one + ) && git fetch --tags remote_one && - git show-ref tag_one + git show-ref tag_one && + git show-ref remote_one/second_branch_one ' test_expect_success "fetch --no-tags with tagopt=--tags does not get tag" ' git fetch --no-tags remote_two && - test_must_fail git show-ref tag_two + test_must_fail git show-ref tag_two && + git show-ref remote_two/branch_two ' test_expect_success "fetch with tagopt=--tags gets tag" ' + ( + cd two && + git branch second_branch_two + ) && git fetch remote_two && - git show-ref tag_two + git show-ref tag_two && + git show-ref remote_two/second_branch_two ' test_done diff --git a/t/t5529-push-errors.sh b/t/t5529-push-errors.sh new file mode 100755 index 0000000000..9871307fd4 --- /dev/null +++ b/t/t5529-push-errors.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +test_description='detect some push errors early (before contacting remote)' +. ./test-lib.sh + +test_expect_success 'setup commits' ' + test_commit one +' + +test_expect_success 'setup remote' ' + git init --bare remote.git && + git remote add origin remote.git +' + +test_expect_success 'setup fake receive-pack' ' + FAKE_RP_ROOT=$(pwd) && + export FAKE_RP_ROOT && + write_script fake-rp <<-\EOF && + echo yes >"$FAKE_RP_ROOT"/rp-ran + exit 1 + EOF + git config remote.origin.receivepack "\"\$FAKE_RP_ROOT/fake-rp\"" +' + +test_expect_success 'detect missing branches early' ' + echo no >rp-ran && + echo no >expect && + test_must_fail git push origin missing && + test_cmp expect rp-ran +' + +test_expect_success 'detect missing sha1 expressions early' ' + echo no >rp-ran && + echo no >expect && + test_must_fail git push origin master~2:master && + test_cmp expect rp-ran +' + +test_expect_success 'detect ambiguous refs early' ' + git branch foo && + git tag foo && + echo no >rp-ran && + echo no >expect && + test_must_fail git push origin foo && + test_cmp expect rp-ran +' + +test_done diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index 8c16e045a0..445bb5fe26 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -12,6 +12,7 @@ test_expect_success setup ' ( cd work && git init && + git config push.default matching && mkdir -p gar/bage && ( cd gar/bage && diff --git a/t/t5536-fetch-conflicts.sh b/t/t5536-fetch-conflicts.sh new file mode 100755 index 0000000000..6c5d3a4ce0 --- /dev/null +++ b/t/t5536-fetch-conflicts.sh @@ -0,0 +1,100 @@ +#!/bin/sh + +test_description='fetch handles conflicting refspecs correctly' + +. ./test-lib.sh + +D=$(pwd) + +setup_repository () { + git init "$1" && ( + cd "$1" && + git config remote.origin.url "$D" && + shift && + for refspec in "$@" + do + git config --add remote.origin.fetch "$refspec" + done + ) +} + +verify_stderr () { + cat >expected && + # We're not interested in the error + # "fatal: The remote end hung up unexpectedly": + grep -E '^(fatal|warning):' <error | grep -v 'hung up' >actual | sort && + test_cmp expected actual +} + +test_expect_success 'setup' ' + git commit --allow-empty -m "Initial" && + git branch branch1 && + git tag tag1 && + git commit --allow-empty -m "First" && + git branch branch2 && + git tag tag2 +' + +test_expect_success 'fetch with no conflict' ' + setup_repository ok "+refs/heads/*:refs/remotes/origin/*" && ( + cd ok && + git fetch origin + ) +' + +test_expect_success 'fetch conflict: config vs. config' ' + setup_repository ccc \ + "+refs/heads/branch1:refs/remotes/origin/branch1" \ + "+refs/heads/branch2:refs/remotes/origin/branch1" && ( + cd ccc && + test_must_fail git fetch origin 2>error && + verify_stderr <<-\EOF + fatal: Cannot fetch both refs/heads/branch1 and refs/heads/branch2 to refs/remotes/origin/branch1 + EOF + ) +' + +test_expect_success 'fetch duplicate: config vs. config' ' + setup_repository dcc \ + "+refs/heads/*:refs/remotes/origin/*" \ + "+refs/heads/branch1:refs/remotes/origin/branch1" && ( + cd dcc && + git fetch origin + ) +' + +test_expect_success 'fetch conflict: arg overrides config' ' + setup_repository aoc \ + "+refs/heads/*:refs/remotes/origin/*" && ( + cd aoc && + git fetch origin refs/heads/branch2:refs/remotes/origin/branch1 + ) +' + +test_expect_success 'fetch conflict: arg vs. arg' ' + setup_repository caa && ( + cd caa && + test_must_fail git fetch origin \ + refs/heads/*:refs/remotes/origin/* \ + refs/heads/branch2:refs/remotes/origin/branch1 2>error && + verify_stderr <<-\EOF + fatal: Cannot fetch both refs/heads/branch1 and refs/heads/branch2 to refs/remotes/origin/branch1 + EOF + ) +' + +test_expect_success 'fetch conflict: criss-cross args' ' + setup_repository xaa \ + "+refs/heads/*:refs/remotes/origin/*" && ( + cd xaa && + git fetch origin \ + refs/heads/branch1:refs/remotes/origin/branch2 \ + refs/heads/branch2:refs/remotes/origin/branch1 2>error && + verify_stderr <<-\EOF + warning: refs/remotes/origin/branch1 usually tracks refs/heads/branch1, not refs/heads/branch2 + warning: refs/remotes/origin/branch2 usually tracks refs/heads/branch2, not refs/heads/branch1 + EOF + ) +' + +test_done diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh new file mode 100755 index 0000000000..be951a4679 --- /dev/null +++ b/t/t5537-fetch-shallow.sh @@ -0,0 +1,217 @@ +#!/bin/sh + +test_description='fetch/clone from a shallow clone' + +. ./test-lib.sh + +commit() { + echo "$1" >tracked && + git add tracked && + git commit -m "$1" +} + +test_expect_success 'setup' ' + commit 1 && + commit 2 && + commit 3 && + commit 4 && + git config --global transfer.fsckObjects true +' + +test_expect_success 'setup shallow clone' ' + git clone --no-local --depth=2 .git shallow && + git --git-dir=shallow/.git log --format=%s >actual && + cat <<EOF >expect && +4 +3 +EOF + test_cmp expect actual +' + +test_expect_success 'clone from shallow clone' ' + git clone --no-local shallow shallow2 && + ( + cd shallow2 && + git fsck && + git log --format=%s >actual && + cat <<EOF >expect && +4 +3 +EOF + test_cmp expect actual + ) +' + +test_expect_success 'fetch from shallow clone' ' + ( + cd shallow && + commit 5 + ) && + ( + cd shallow2 && + git fetch && + git fsck && + git log --format=%s origin/master >actual && + cat <<EOF >expect && +5 +4 +3 +EOF + test_cmp expect actual + ) +' + +test_expect_success 'fetch --depth from shallow clone' ' + ( + cd shallow && + commit 6 + ) && + ( + cd shallow2 && + git fetch --depth=2 && + git fsck && + git log --format=%s origin/master >actual && + cat <<EOF >expect && +6 +5 +EOF + test_cmp expect actual + ) +' + +test_expect_success 'fetch --unshallow from shallow clone' ' + ( + cd shallow2 && + git fetch --unshallow && + git fsck && + git log --format=%s origin/master >actual && + cat <<EOF >expect && +6 +5 +4 +3 +EOF + test_cmp expect actual + ) +' + +test_expect_success 'fetch something upstream has but hidden by clients shallow boundaries' ' + # the blob "1" is available in .git but hidden by the + # shallow2/.git/shallow and it should be resent + ! git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object --stdin` >/dev/null && + echo 1 >1.t && + git add 1.t && + git commit -m add-1-back && + ( + cd shallow2 && + git fetch ../.git +refs/heads/master:refs/remotes/top/master && + git fsck && + git log --format=%s top/master >actual && + cat <<EOF >expect && +add-1-back +4 +3 +EOF + test_cmp expect actual + ) && + git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object --stdin` >/dev/null + +' + +test_expect_success 'fetch that requires changes in .git/shallow is filtered' ' + ( + cd shallow && + git checkout --orphan no-shallow && + commit no-shallow + ) && + git init notshallow && + ( + cd notshallow && + git fetch ../shallow/.git refs/heads/*:refs/remotes/shallow/*&& + git for-each-ref --format="%(refname)" >actual.refs && + cat <<EOF >expect.refs && +refs/remotes/shallow/no-shallow +EOF + test_cmp expect.refs actual.refs && + git log --format=%s shallow/no-shallow >actual && + cat <<EOF >expect && +no-shallow +EOF + test_cmp expect actual + ) +' + +test_expect_success 'fetch --update-shallow' ' + ( + cd shallow && + git checkout master && + commit 7 && + git tag -m foo heavy-tag HEAD^ && + git tag light-tag HEAD^:tracked + ) && + ( + cd notshallow && + git fetch --update-shallow ../shallow/.git refs/heads/*:refs/remotes/shallow/* && + git fsck && + git for-each-ref --sort=refname --format="%(refname)" >actual.refs && + cat <<EOF >expect.refs && +refs/remotes/shallow/master +refs/remotes/shallow/no-shallow +refs/tags/heavy-tag +refs/tags/light-tag +EOF + test_cmp expect.refs actual.refs && + git log --format=%s shallow/master >actual && + cat <<EOF >expect && +7 +6 +5 +4 +3 +EOF + test_cmp expect actual + ) +' + +if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then + say 'skipping remaining tests, git built without http support' + test_done +fi + +LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5537'} +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +test_expect_success 'clone http repository' ' + git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git clone $HTTPD_URL/smart/repo.git clone && + ( + cd clone && + git fsck && + git log --format=%s origin/master >actual && + cat <<EOF >expect && +7 +6 +5 +4 +3 +EOF + test_cmp expect actual + ) +' + +test_expect_success POSIXPERM,SANITY 'shallow fetch from a read-only repo' ' + cp -R .git read-only.git && + find read-only.git -print | xargs chmod -w && + test_when_finished "find read-only.git -type d -print | xargs chmod +w" && + git clone --no-local --depth=2 read-only.git from-read-only && + git --git-dir=from-read-only/.git log --format=%s >actual && + cat >expect <<EOF && +add-1-back +4 +EOF + test_cmp expect actual +' + +stop_httpd +test_done diff --git a/t/t5538-push-shallow.sh b/t/t5538-push-shallow.sh new file mode 100755 index 0000000000..8e54ac5746 --- /dev/null +++ b/t/t5538-push-shallow.sh @@ -0,0 +1,182 @@ +#!/bin/sh + +test_description='push from/to a shallow clone' + +. ./test-lib.sh + +commit() { + echo "$1" >tracked && + git add tracked && + git commit -m "$1" +} + +test_expect_success 'setup' ' + git config --global transfer.fsckObjects true && + commit 1 && + commit 2 && + commit 3 && + commit 4 && + git clone . full && + ( + git init full-abc && + cd full-abc && + commit a && + commit b && + commit c + ) && + git clone --no-local --depth=2 .git shallow && + git --git-dir=shallow/.git log --format=%s >actual && + cat <<EOF >expect && +4 +3 +EOF + test_cmp expect actual && + git clone --no-local --depth=2 full-abc/.git shallow2 && + git --git-dir=shallow2/.git log --format=%s >actual && + cat <<EOF >expect && +c +b +EOF + test_cmp expect actual +' + +test_expect_success 'push from shallow clone' ' + ( + cd shallow && + commit 5 && + git push ../.git +master:refs/remotes/shallow/master + ) && + git log --format=%s shallow/master >actual && + git fsck && + cat <<EOF >expect && +5 +4 +3 +2 +1 +EOF + test_cmp expect actual +' + +test_expect_success 'push from shallow clone, with grafted roots' ' + ( + cd shallow2 && + test_must_fail git push ../.git +master:refs/remotes/shallow2/master 2>err && + grep "shallow2/master.*shallow update not allowed" err + ) && + test_must_fail git rev-parse shallow2/master && + git fsck +' + +test_expect_success 'add new shallow root with receive.updateshallow on' ' + test_config receive.shallowupdate true && + ( + cd shallow2 && + git push ../.git +master:refs/remotes/shallow2/master + ) && + git log --format=%s shallow2/master >actual && + git fsck && + cat <<EOF >expect && +c +b +EOF + test_cmp expect actual +' + +test_expect_success 'push from shallow to shallow' ' + ( + cd shallow && + git --git-dir=../shallow2/.git config receive.shallowupdate true && + git push ../shallow2/.git +master:refs/remotes/shallow/master && + git --git-dir=../shallow2/.git config receive.shallowupdate false + ) && + ( + cd shallow2 && + git log --format=%s shallow/master >actual && + git fsck && + cat <<EOF >expect && +5 +4 +3 +EOF + test_cmp expect actual + ) +' + +test_expect_success 'push from full to shallow' ' + ! git --git-dir=shallow2/.git cat-file blob `echo 1|git hash-object --stdin` && + commit 1 && + git push shallow2/.git +master:refs/remotes/top/master && + ( + cd shallow2 && + git log --format=%s top/master >actual && + git fsck && + cat <<EOF >expect && +1 +4 +3 +EOF + test_cmp expect actual && + git cat-file blob `echo 1|git hash-object --stdin` >/dev/null + ) +' + +if test -n "$NO_CURL" -o -z "$GIT_TEST_HTTPD"; then + say 'skipping remaining tests, git built without http support' + test_done +fi + +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +test_expect_success 'push to shallow repo via http' ' + git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + ( + cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git config http.receivepack true + ) && + ( + cd full && + commit 9 && + git push $HTTPD_URL/smart/repo.git +master:refs/remotes/top/master + ) && + ( + cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git fsck && + git log --format=%s top/master >actual && + cat <<EOF >expect && +9 +4 +3 +EOF + test_cmp expect actual + ) +' + +test_expect_success 'push from shallow repo via http' ' + mv "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" shallow-upstream.git && + git clone --bare --no-local full "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + ( + cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git config http.receivepack true + ) && + commit 10 && + git push $HTTPD_URL/smart/repo.git +master:refs/remotes/top/master && + ( + cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git fsck && + git log --format=%s top/master >actual && + cat <<EOF >expect && +10 +1 +4 +3 +2 +1 +EOF + test_cmp expect actual + ) +' + +stop_httpd +test_done diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh new file mode 100755 index 0000000000..94553e1039 --- /dev/null +++ b/t/t5539-fetch-http-shallow.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +test_description='fetch/clone from a shallow clone over http' + +. ./test-lib.sh + +if test -n "$NO_CURL"; then + skip_all='skipping test, git built without http support' + test_done +fi + +. "$TEST_DIRECTORY"/lib-httpd.sh +start_httpd + +commit() { + echo "$1" >tracked && + git add tracked && + git commit -m "$1" +} + +test_expect_success 'setup shallow clone' ' + commit 1 && + commit 2 && + commit 3 && + commit 4 && + commit 5 && + commit 6 && + commit 7 && + git clone --no-local --depth=5 .git shallow && + git config --global transfer.fsckObjects true +' + +test_expect_success 'clone http repository' ' + git clone --bare --no-local shallow "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && + git clone $HTTPD_URL/smart/repo.git clone && + ( + cd clone && + git fsck && + git log --format=%s origin/master >actual && + cat <<EOF >expect && +7 +6 +5 +4 +3 +EOF + test_cmp expect actual + ) +' + +# This test is tricky. We need large enough "have"s that fetch-pack +# will put pkt-flush in between. Then we need a "have" the server +# does not have, it'll send "ACK %s ready" +test_expect_success 'no shallow lines after receiving ACK ready' ' + ( + cd shallow && + for i in $(test_seq 15) + do + git checkout --orphan unrelated$i && + test_commit unrelated$i && + git push -q "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \ + refs/heads/unrelated$i:refs/heads/unrelated$i && + git push -q ../clone/.git \ + refs/heads/unrelated$i:refs/heads/unrelated$i || + exit 1 + done && + git checkout master && + test_commit new && + git push "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" master + ) && + ( + cd clone && + git checkout --orphan newnew && + test_commit new-too && + GIT_TRACE_PACKET="$TRASH_DIRECTORY/trace" git fetch --depth=2 && + grep "fetch-pack< ACK .* ready" ../trace && + ! grep "fetch-pack> done" ../trace + ) +' + +stop_httpd +test_done diff --git a/t/t5540-http-push.sh b/t/t5540-http-push-webdav.sh index 01d0d95b4d..8d7b3c57e3 100755 --- a/t/t5540-http-push.sh +++ b/t/t5540-http-push-webdav.sh @@ -16,7 +16,6 @@ then fi LIB_HTTPD_DAV=t -LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5540'} . "$TEST_DIRECTORY"/lib-httpd.sh ROOT_PATH="$PWD" start_httpd @@ -154,7 +153,7 @@ test_http_push_nonff "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git \ test_expect_success 'push to password-protected repository (user in URL)' ' test_commit pw-user && - set_askpass user@host && + set_askpass user@host pass@host && git push "$HTTPD_URL_USER/auth/dumb/test_repo.git" HEAD && git rev-parse --verify HEAD >expect && git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/test_repo.git" \ @@ -168,7 +167,7 @@ test_expect_failure 'user was prompted only once for password' ' test_expect_failure 'push to password-protected repository (no user in URL)' ' test_commit pw-nouser && - set_askpass user@host && + set_askpass user@host pass@host && git push "$HTTPD_URL/auth/dumb/test_repo.git" HEAD && expect_askpass both user@host git rev-parse --verify HEAD >expect && diff --git a/t/t5541-http-push.sh b/t/t5541-http-push-smart.sh index 470ac54295..73af16f481 100755 --- a/t/t5541-http-push.sh +++ b/t/t5541-http-push-smart.sh @@ -12,7 +12,6 @@ if test -n "$NO_CURL"; then fi ROOT_PATH="$PWD" -LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5541'} . "$TEST_DIRECTORY"/lib-httpd.sh . "$TEST_DIRECTORY"/lib-terminal.sh start_httpd @@ -274,7 +273,7 @@ test_expect_success 'push over smart http with auth' ' cd "$ROOT_PATH/test_repo_clone" && echo push-auth-test >expect && test_commit push-auth-test && - set_askpass user@host && + set_askpass user@host pass@host && git push "$HTTPD_URL"/auth/smart/test_repo.git && git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \ log -1 --format=%s >actual && @@ -286,7 +285,7 @@ test_expect_success 'push to auth-only-for-push repo' ' cd "$ROOT_PATH/test_repo_clone" && echo push-half-auth >expect && test_commit push-half-auth && - set_askpass user@host && + set_askpass user@host pass@host && git push "$HTTPD_URL"/auth-push/smart/test_repo.git && git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git" \ log -1 --format=%s >actual && @@ -316,7 +315,7 @@ test_expect_success 'push into half-auth-complete requires password' ' cd "$ROOT_PATH/half-auth-clone" && echo two >expect && test_commit two && - set_askpass user@host && + set_askpass user@host pass@host && git push "$HTTPD_URL/half-auth-complete/smart/half-auth.git" && git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/half-auth.git" \ log -1 --format=%s >actual && diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch-dumb.sh index f7d0f146f0..1a3a2b6c1a 100755 --- a/t/t5550-http-fetch.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -8,7 +8,6 @@ if test -n "$NO_CURL"; then test_done fi -LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5550'} . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd @@ -62,13 +61,13 @@ test_expect_success 'http auth can use user/pass in URL' ' ' test_expect_success 'http auth can use just user in URL' ' - set_askpass user@host && + set_askpass wrong pass@host && git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-pass && expect_askpass pass user@host ' test_expect_success 'http auth can request both user and pass' ' - set_askpass user@host && + set_askpass user@host pass@host && git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-both && expect_askpass both user@host ' @@ -77,7 +76,7 @@ test_expect_success 'http auth respects credential helper config' ' test_config_global credential.helper "!f() { cat >/dev/null echo username=user@host - echo password=user@host + echo password=pass@host }; f" && set_askpass wrong && git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-helper && @@ -86,14 +85,14 @@ test_expect_success 'http auth respects credential helper config' ' test_expect_success 'http auth can get username from config' ' test_config_global "credential.$HTTPD_URL.username" user@host && - set_askpass user@host && + set_askpass wrong pass@host && git clone "$HTTPD_URL/auth/dumb/repo.git" clone-auth-user && expect_askpass pass user@host ' test_expect_success 'configured username does not override URL' ' test_config_global "credential.$HTTPD_URL.username" wrong && - set_askpass user@host && + set_askpass wrong pass@host && git clone "$HTTPD_URL_USER/auth/dumb/repo.git" clone-auth-user2 && expect_askpass pass user@host ' diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch-smart.sh index 8196af19f6..e07eaf35f1 100755 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch-smart.sh @@ -8,7 +8,6 @@ if test -n "$NO_CURL"; then test_done fi -LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5551'} . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd @@ -113,9 +112,13 @@ test_expect_success 'follow redirects (302)' ' git clone $HTTPD_URL/smart-redir-temp/repo.git --quiet repo-t ' +test_expect_success 'redirects re-root further requests' ' + git clone $HTTPD_URL/smart-redir-limited/repo.git repo-redir-limited +' + test_expect_success 'clone from password-protected repository' ' echo two >expect && - set_askpass user@host && + set_askpass user@host pass@host && git clone --bare "$HTTPD_URL/auth/smart/repo.git" smart-auth && expect_askpass both user@host && git --git-dir=smart-auth log -1 --format=%s >actual && @@ -133,7 +136,7 @@ test_expect_success 'clone from auth-only-for-push repository' ' test_expect_success 'clone from auth-only-for-objects repository' ' echo two >expect && - set_askpass user@host && + set_askpass user@host pass@host && git clone --bare "$HTTPD_URL/auth-fetch/smart/repo.git" half-auth && expect_askpass both user@host && git --git-dir=half-auth log -1 --format=%s >actual && @@ -146,6 +149,13 @@ test_expect_success 'no-op half-auth fetch does not require a password' ' expect_askpass none ' +test_expect_success 'redirects send auth to new location' ' + set_askpass user@host pass@host && + git -c credential.useHttpPath=true \ + clone $HTTPD_URL/smart-redir-auth/repo.git repo-redir-auth && + expect_askpass both user@host auth/smart/repo.git +' + test_expect_success 'disable dumb http on server' ' git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \ config http.getanyfile false @@ -224,7 +234,7 @@ test_expect_success EXPENSIVE 'create 50,000 tags in the repo' ' done | git fast-import --export-marks=marks && # now assign tags to all the dangling commits we created above - tag=$("$PERL_PATH" -e "print \"bla\" x 30") && + tag=$(perl -e "print \"bla\" x 30") && sed -e "s|^:\([^ ]*\) \(.*\)$|\2 refs/tags/$tag-\1|" <marks >>packed-refs ) ' diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh index b5d7fbc381..d23fb02384 100755 --- a/t/t5561-http-backend.sh +++ b/t/t5561-http-backend.sh @@ -8,7 +8,6 @@ if test -n "$NO_CURL"; then test_done fi -LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5561'} . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh index f01edffa3c..6b16379951 100755 --- a/t/t5570-git-daemon.sh +++ b/t/t5570-git-daemon.sh @@ -3,7 +3,6 @@ test_description='test fetching over git protocol' . ./test-lib.sh -LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-5570} . "$TEST_DIRECTORY"/lib-git-daemon.sh start_git_daemon @@ -37,7 +36,7 @@ test_expect_success 'fetch changes via git protocol' ' test_cmp file clone/file ' -test_expect_failure 'remote detects correct HEAD' ' +test_expect_success 'remote detects correct HEAD' ' git push public master:other && (cd clone && git remote set-head -d origin && @@ -122,8 +121,7 @@ test_remote_error() fi test_must_fail git "$cmd" "$GIT_DAEMON_URL/$repo" "$@" 2>output && - echo "fatal: remote error: $msg: /$repo" >expect && - test_cmp expect output + test_i18ngrep "fatal: remote error: $msg: /$repo" output && ret=$? chmod +x "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" (exit $ret) diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 8f3cd44d51..5e67035be8 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -280,25 +280,26 @@ test_expect_success 'clone checking out a tag' ' test_cmp fetch.expected fetch.actual ' -test_expect_success 'setup ssh wrapper' ' - write_script "$TRASH_DIRECTORY/ssh-wrapper" <<-\EOF && - echo >>"$TRASH_DIRECTORY/ssh-output" "ssh: $*" && - # throw away all but the last argument, which should be the - # command - while test $# -gt 1; do shift; done - eval "$1" - EOF - - GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper" && - export GIT_SSH && - export TRASH_DIRECTORY -' - -clear_ssh () { - >"$TRASH_DIRECTORY/ssh-output" +setup_ssh_wrapper () { + test_expect_success 'setup ssh wrapper' ' + write_script "$TRASH_DIRECTORY/ssh-wrapper" <<-\EOF && + echo >>"$TRASH_DIRECTORY/ssh-output" "ssh: $*" && + # throw away all but the last argument, which should be the + # command + while test $# -gt 1; do shift; done + eval "$1" + EOF + GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper" && + export GIT_SSH && + export TRASH_DIRECTORY && + >"$TRASH_DIRECTORY"/ssh-output + ' } expect_ssh () { + test_when_finished ' + (cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output) + ' && { case "$1" in none) @@ -310,23 +311,130 @@ expect_ssh () { (cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output) } -test_expect_success 'cloning myhost:src uses ssh' ' - clear_ssh && +setup_ssh_wrapper + +test_expect_success 'clone myhost:src uses ssh' ' git clone myhost:src ssh-clone && expect_ssh myhost src ' test_expect_success NOT_MINGW,NOT_CYGWIN 'clone local path foo:bar' ' - clear_ssh && cp -R src "foo:bar" && - git clone "./foo:bar" foobar && + git clone "foo:bar" foobar && expect_ssh none ' test_expect_success 'bracketed hostnames are still ssh' ' - clear_ssh && git clone "[myhost:123]:src" ssh-bracket-clone && expect_ssh myhost:123 src ' +counter=0 +# $1 url +# $2 none|host +# $3 path +test_clone_url () { + counter=$(($counter + 1)) + test_might_fail git clone "$1" tmp$counter && + expect_ssh "$2" "$3" +} + +test_expect_success NOT_MINGW 'clone c:temp is ssl' ' + test_clone_url c:temp c temp +' + +test_expect_success MINGW 'clone c:temp is dos drive' ' + test_clone_url c:temp none +' + +#ip v4 +for repo in rep rep/home/project 123 +do + test_expect_success "clone host:$repo" ' + test_clone_url host:$repo host $repo + ' +done + +#ipv6 +for repo in rep rep/home/project 123 +do + test_expect_success "clone [::1]:$repo" ' + test_clone_url [::1]:$repo ::1 $repo + ' +done +#home directory +test_expect_success "clone host:/~repo" ' + test_clone_url host:/~repo host "~repo" +' + +test_expect_success "clone [::1]:/~repo" ' + test_clone_url [::1]:/~repo ::1 "~repo" +' + +# Corner cases +for url in foo/bar:baz [foo]bar/baz:qux [foo/bar]:baz +do + test_expect_success "clone $url is not ssh" ' + test_clone_url $url none + ' +done + +#with ssh:// scheme +test_expect_success 'clone ssh://host.xz/home/user/repo' ' + test_clone_url "ssh://host.xz/home/user/repo" host.xz "/home/user/repo" +' + +# from home directory +test_expect_success 'clone ssh://host.xz/~repo' ' + test_clone_url "ssh://host.xz/~repo" host.xz "~repo" +' + +# with port number +test_expect_success 'clone ssh://host.xz:22/home/user/repo' ' + test_clone_url "ssh://host.xz:22/home/user/repo" "-p 22 host.xz" "/home/user/repo" +' + +# from home directory with port number +test_expect_success 'clone ssh://host.xz:22/~repo' ' + test_clone_url "ssh://host.xz:22/~repo" "-p 22 host.xz" "~repo" +' + +#IPv6 +test_expect_success 'clone ssh://[::1]/home/user/repo' ' + test_clone_url "ssh://[::1]/home/user/repo" "::1" "/home/user/repo" +' + +#IPv6 from home directory +test_expect_success 'clone ssh://[::1]/~repo' ' + test_clone_url "ssh://[::1]/~repo" "::1" "~repo" +' + +#IPv6 with port number +test_expect_success 'clone ssh://[::1]:22/home/user/repo' ' + test_clone_url "ssh://[::1]:22/home/user/repo" "-p 22 ::1" "/home/user/repo" +' + +#IPv6 from home directory with port number +test_expect_success 'clone ssh://[::1]:22/~repo' ' + test_clone_url "ssh://[::1]:22/~repo" "-p 22 ::1" "~repo" +' + +test_expect_success 'clone from a repository with two identical branches' ' + + ( + cd src && + git checkout -b another master + ) && + git clone src target-11 && + test "z$( cd target-11 && git symbolic-ref HEAD )" = zrefs/heads/another + +' + +test_expect_success 'shallow clone locally' ' + git clone --depth=1 --no-local src ssrrcc && + git clone ssrrcc ddsstt && + test_cmp ssrrcc/.git/shallow ddsstt/.git/shallow && + ( cd ddsstt && git fsck ) +' + test_done diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index 613f69a254..c33cc25805 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -94,6 +94,19 @@ test_expect_failure 'push new branch with old:new refspec' ' compare_refs local HEAD server refs/heads/new-refspec ' +test_expect_success 'forced push' ' + (cd local && + git checkout -b force-test && + echo content >> file && + git commit -a -m eight && + git push origin force-test && + echo content >> file && + git commit -a --amend -m eight-modified && + git push --force origin force-test + ) && + compare_refs local refs/heads/force-test server refs/heads/force-test +' + test_expect_success 'cloning without refspec' ' GIT_REMOTE_TESTGIT_REFSPEC="" \ git clone "testgit::${PWD}/server" local2 2>error && diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index b10685af4e..3794e4ceaf 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -48,4 +48,29 @@ test_expect_success 'rev-list --objects with pathspecs and copied files' ' ! grep one output ' +test_expect_success 'rev-list A..B and rev-list ^A B are the same' ' + git commit --allow-empty -m another && + git tag -a -m "annotated" v1.0 && + git rev-list --objects ^v1.0^ v1.0 >expect && + git rev-list --objects v1.0^..v1.0 >actual && + test_cmp expect actual +' + +test_expect_success 'propagate uninteresting flag down correctly' ' + git rev-list --objects ^HEAD^{tree} HEAD^{tree} >actual && + >expect && + test_cmp expect actual +' + +test_expect_success 'symleft flag bit is propagated down from tag' ' + git log --format="%m %s" --left-right v1.0...master >actual && + cat >expect <<-\EOF && + > two + > one + < another + < that + EOF + test_cmp expect actual +' + test_done diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh index f80bba871c..39b3238da2 100755 --- a/t/t6010-merge-base.sh +++ b/t/t6010-merge-base.sh @@ -230,4 +230,71 @@ test_expect_success 'criss-cross merge-base for octopus-step' ' test_cmp expected.sorted actual.sorted ' +test_expect_success 'using reflog to find the fork point' ' + git reset --hard && + git checkout -b base $E && + + ( + for count in 1 2 3 + do + git commit --allow-empty -m "Base commit #$count" && + git rev-parse HEAD >expect$count && + git checkout -B derived && + git commit --allow-empty -m "Derived #$count" && + git rev-parse HEAD >derived$count && + git checkout -B base $E || exit 1 + done + + for count in 1 2 3 + do + git merge-base --fork-point base $(cat derived$count) >actual && + test_cmp expect$count actual || exit 1 + done + + ) && + # check that we correctly default to HEAD + git checkout derived && + git merge-base --fork-point base >actual && + test_cmp expect3 actual +' + +test_expect_success 'merge-base --octopus --all for complex tree' ' + # Best common ancestor for JE, JAA and JDD is JC + # JE + # / | + # / | + # / | + # JAA / | + # |\ / | + # | \ | JDD | + # | \ |/ | | + # | JC JD | + # | | /| | + # | |/ | | + # JA | | | + # |\ /| | | + # X JB | X X + # \ \ | / / + # \__\|/___/ + # J + test_commit J && + test_commit JB && + git reset --hard J && + test_commit JC && + git reset --hard J && + test_commit JTEMP1 && + test_merge JA JB && + test_merge JAA JC && + git reset --hard J && + test_commit JTEMP2 && + test_merge JD JB && + test_merge JDD JC && + git reset --hard J && + test_commit JTEMP3 && + test_merge JE JC && + git rev-parse JC >expected && + git merge-base --all --octopus JAA JDD JE >actual && + test_cmp expected actual +' + test_done diff --git a/t/t6011-rev-list-with-bad-commit.sh b/t/t6011-rev-list-with-bad-commit.sh index bbb0581f88..e51eb41f4b 100755 --- a/t/t6011-rev-list-with-bad-commit.sh +++ b/t/t6011-rev-list-with-bad-commit.sh @@ -37,7 +37,7 @@ test_expect_success 'verify number of revisions' \ test_expect_success 'corrupt second commit object' \ ' - "$PERL_PATH" -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack && + perl -i.bak -pe "s/second commit/socond commit/" .git/objects/pack/*.pack && test_must_fail git fsck --full ' diff --git a/t/t6013-rev-list-reverse-parents.sh b/t/t6013-rev-list-reverse-parents.sh index 892a537989..59fc2f06e0 100755 --- a/t/t6013-rev-list-reverse-parents.sh +++ b/t/t6013-rev-list-reverse-parents.sh @@ -25,7 +25,7 @@ test_expect_success 'set up --reverse example' ' test_expect_success '--reverse --parents --full-history combines correctly' ' git rev-list --parents --full-history master -- foo | - "$PERL_PATH" -e "print reverse <>" > expected && + perl -e "print reverse <>" > expected && git rev-list --reverse --parents --full-history master -- foo \ > actual && test_cmp actual expected @@ -33,7 +33,7 @@ test_expect_success '--reverse --parents --full-history combines correctly' ' test_expect_success '--boundary does too' ' git rev-list --boundary --parents --full-history master ^root -- foo | - "$PERL_PATH" -e "print reverse <>" > expected && + perl -e "print reverse <>" > expected && git rev-list --boundary --reverse --parents --full-history \ master ^root -- foo > actual && test_cmp actual expected diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index f00cebff3e..d00f7db868 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -129,6 +129,18 @@ test_expect_success 'rev-parse --remotes=foo' ' ' +test_expect_success 'rev-parse --exclude with --branches' ' + compare rev-parse "--exclude=*/* --branches" "master someref subspace-x" +' + +test_expect_success 'rev-parse --exclude with --all' ' + compare rev-parse "--exclude=refs/remotes/* --all" "--branches --tags" +' + +test_expect_success 'rev-parse accumulates multiple --exclude' ' + compare rev-parse "--exclude=refs/remotes/* --exclude=refs/tags/* --all" --branches +' + test_expect_success 'rev-list --glob=refs/heads/subspace/*' ' compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*" @@ -231,6 +243,48 @@ test_expect_success 'rev-list --remotes=foo' ' ' +test_expect_success 'rev-list --exclude with --branches' ' + compare rev-list "--exclude=*/* --branches" "master someref subspace-x" +' + +test_expect_success 'rev-list --exclude with --all' ' + compare rev-list "--exclude=refs/remotes/* --all" "--branches --tags" +' + +test_expect_success 'rev-list accumulates multiple --exclude' ' + compare rev-list "--exclude=refs/remotes/* --exclude=refs/tags/* --all" --branches +' + + +# "git rev-list<ENTER>" is likely to be a bug in the calling script and may +# deserve an error message, but do cases where set of refs programatically +# given using globbing and/or --stdin need to fail with the same error, or +# are we better off reporting a success with no output? The following few +# tests document the current behaviour to remind us that we might want to +# think about this issue. + +test_expect_failure 'rev-list may want to succeed with empty output on no input (1)' ' + >expect && + git rev-list --stdin <expect >actual && + test_cmp expect actual +' + +test_expect_failure 'rev-list may want to succeed with empty output on no input (2)' ' + >expect && + git rev-list --exclude=* --all >actual && + test_cmp expect actual +' + +test_expect_failure 'rev-list may want to succeed with empty output on no input (3)' ' + ( + test_create_repo empty && + cd empty && + >expect && + git rev-list --all >actual && + test_cmp expect actual + ) +' + test_expect_success 'shortlog accepts --glob/--tags/--remotes' ' compare shortlog "subspace/one subspace/two" --branches=subspace && diff --git a/t/t6031-merge-recursive.sh b/t/t6031-merge-recursive.sh index 1cd649e245..a953f1b55c 100755 --- a/t/t6031-merge-recursive.sh +++ b/t/t6031-merge-recursive.sh @@ -2,7 +2,6 @@ test_description='merge-recursive: handle file mode' . ./test-lib.sh -. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh test_expect_success 'mode change in one branch: keep changed version' ' : >file1 && diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh index ba26cfe923..7ac8fd06c3 100755 --- a/t/t6040-tracking-info.sh +++ b/t/t6040-tracking-info.sh @@ -39,12 +39,14 @@ test_expect_success setup ' advance h ' -script='s/^..\(b.\)[ 0-9a-f]*\[\([^]]*\)\].*/\1 \2/p' +script='s/^..\(b.\) *[0-9a-f]* \(.*\)$/\1 \2/p' cat >expect <<\EOF -b1 ahead 1, behind 1 -b2 ahead 1, behind 1 -b3 behind 1 -b4 ahead 2 +b1 [ahead 1, behind 1] d +b2 [ahead 1, behind 1] d +b3 [behind 1] b +b4 [ahead 2] f +b5 g +b6 c EOF test_expect_success 'branch -v' ' @@ -57,12 +59,12 @@ test_expect_success 'branch -v' ' ' cat >expect <<\EOF -b1 origin/master: ahead 1, behind 1 -b2 origin/master: ahead 1, behind 1 -b3 origin/master: behind 1 -b4 origin/master: ahead 2 -b5 brokenbase: gone -b6 origin/master +b1 [origin/master: ahead 1, behind 1] d +b2 [origin/master: ahead 1, behind 1] d +b3 [origin/master: behind 1] b +b4 [origin/master: ahead 2] f +b5 [brokenbase: gone] g +b6 [origin/master] c EOF test_expect_success 'branch -vv' ' diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index 7d47984352..719a11673b 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -276,6 +276,48 @@ test_expect_success '-f option bypasses the type check' ' git replace -f HEAD^ $BLOB ' +test_expect_success 'git cat-file --batch works on replace objects' ' + git replace | grep $PARA3 && + echo $PARA3 | git cat-file --batch +' + +test_expect_success 'test --format bogus' ' + test_must_fail git replace --format bogus >/dev/null 2>&1 +' + +test_expect_success 'test --format short' ' + git replace --format=short >actual && + git replace >expected && + test_cmp expected actual +' + +test_expect_success 'test --format medium' ' + H1=$(git --no-replace-objects rev-parse HEAD~1) && + HT=$(git --no-replace-objects rev-parse HEAD^{tree}) && + MYTAG=$(git --no-replace-objects rev-parse mytag) && + { + echo "$H1 -> $BLOB" && + echo "$BLOB -> $REPLACED" && + echo "$HT -> $H1" && + echo "$PARA3 -> $S" && + echo "$MYTAG -> $HASH1" + } | sort >expected && + git replace -l --format medium | sort > actual && + test_cmp expected actual +' + +test_expect_success 'test --format long' ' + { + echo "$H1 (commit) -> $BLOB (blob)" && + echo "$BLOB (blob) -> $REPLACED (blob)" && + echo "$HT (tree) -> $H1 (commit)" && + echo "$PARA3 (commit) -> $S (commit)" && + echo "$MYTAG (tag) -> $HASH1 (commit)" + } | sort >expected && + git replace --format=long | sort > actual && + test_cmp expected actual +' + test_expect_success 'replace ref cleanup' ' test -n "$(git replace)" && git replace -d $(git replace) && diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index 7ea14ced31..10b1452766 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -20,7 +20,17 @@ test_expect_success 'setup' ' test_commit start2 && git checkout master && git merge -m next start2 && - test_commit final + test_commit final && + + test_seq 40 | + while read i + do + git checkout --orphan "b$i" && + test_tick && + git commit --allow-empty -m "$i" && + commit=$(git rev-parse --verify HEAD) && + printf "$commit " >>.git/info/grafts + done ' test_expect_success 'start is valid' ' @@ -79,6 +89,10 @@ test_expect_success 'final^1^! = final^1 ^final^1^1 ^final^1^2' ' test_cmp expect actual ' +test_expect_success 'large graft octopus' ' + test_cmp_rev_output b31 "git rev-parse --verify b1^30" +' + test_expect_success 'repack for next test' ' git repack -a -d ' diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh index ea00d71e77..658353277e 100755 --- a/t/t6130-pathspec-noglob.sh +++ b/t/t6130-pathspec-noglob.sh @@ -108,6 +108,13 @@ test_expect_success 'no-glob environment variable works' ' test_cmp expect actual ' +test_expect_success 'blame takes global pathspec flags' ' + git --literal-pathspecs blame -- foo && + git --icase-pathspecs blame -- foo && + git --glob-pathspecs blame -- foo && + git --noglob-pathspecs blame -- foo +' + test_expect_success 'setup xxx/bar' ' mkdir xxx && test_commit xxx xxx/bar diff --git a/t/t6131-pathspec-icase.sh b/t/t6131-pathspec-icase.sh index 8d4a7fcb91..39fc3f6769 100755 --- a/t/t6131-pathspec-icase.sh +++ b/t/t6131-pathspec-icase.sh @@ -69,7 +69,7 @@ test_expect_success 'tree_entry_interesting matches :(icase)bar with empty prefi test_cmp expect actual ' -test_expect_success 'match_pathspec_depth matches :(icase)bar' ' +test_expect_success 'match_pathspec matches :(icase)bar' ' cat <<-EOF >expect && BAR bAr @@ -79,7 +79,7 @@ test_expect_success 'match_pathspec_depth matches :(icase)bar' ' test_cmp expect actual ' -test_expect_success 'match_pathspec_depth matches :(icase)bar with prefix' ' +test_expect_success 'match_pathspec matches :(icase)bar with prefix' ' cat <<-EOF >expect && fOo/BAR fOo/bAr @@ -89,7 +89,7 @@ test_expect_success 'match_pathspec_depth matches :(icase)bar with prefix' ' test_cmp expect actual ' -test_expect_success 'match_pathspec_depth matches :(icase)bar with empty prefix' ' +test_expect_success 'match_pathspec matches :(icase)bar with empty prefix' ' cat <<-EOF >expect && bar fOo/BAR @@ -100,4 +100,10 @@ test_expect_success 'match_pathspec_depth matches :(icase)bar with empty prefix' test_cmp expect actual ' +test_expect_success '"git diff" can take magic :(icase) pathspec' ' + echo FOO/BAR >expect && + git diff --name-only HEAD^ HEAD -- ":(icase)foo/bar" >actual && + test_cmp expect actual +' + test_done diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh new file mode 100755 index 0000000000..62049be0c7 --- /dev/null +++ b/t/t6132-pathspec-exclude.sh @@ -0,0 +1,184 @@ +#!/bin/sh + +test_description='test case exclude pathspec' + +. ./test-lib.sh + +test_expect_success 'setup' ' + for p in file sub/file sub/sub/file sub/file2 sub/sub/sub/file sub2/file; do + if echo $p | grep /; then + mkdir -p `dirname $p` + fi && + : >$p && + git add $p && + git commit -m $p + done && + git log --oneline --format=%s >actual && + cat <<EOF >expect && +sub2/file +sub/sub/sub/file +sub/file2 +sub/sub/file +sub/file +file +EOF + test_cmp expect actual +' + +test_expect_success 'exclude only should error out' ' + test_must_fail git log --oneline --format=%s -- ":(exclude)sub" +' + +test_expect_success 't_e_i() exclude sub' ' + git log --oneline --format=%s -- . ":(exclude)sub" >actual + cat <<EOF >expect && +sub2/file +file +EOF + test_cmp expect actual +' + +test_expect_success 't_e_i() exclude sub/sub/file' ' + git log --oneline --format=%s -- . ":(exclude)sub/sub/file" >actual + cat <<EOF >expect && +sub2/file +sub/sub/sub/file +sub/file2 +sub/file +file +EOF + test_cmp expect actual +' + +test_expect_success 't_e_i() exclude sub using mnemonic' ' + git log --oneline --format=%s -- . ":!sub" >actual + cat <<EOF >expect && +sub2/file +file +EOF + test_cmp expect actual +' + +test_expect_success 't_e_i() exclude :(icase)SUB' ' + git log --oneline --format=%s -- . ":(exclude,icase)SUB" >actual + cat <<EOF >expect && +sub2/file +file +EOF + test_cmp expect actual +' + +test_expect_success 't_e_i() exclude sub2 from sub' ' + ( + cd sub && + git log --oneline --format=%s -- :/ ":/!sub2" >actual + cat <<EOF >expect && +sub/sub/sub/file +sub/file2 +sub/sub/file +sub/file +file +EOF + test_cmp expect actual + ) +' + +test_expect_success 't_e_i() exclude sub/*file' ' + git log --oneline --format=%s -- . ":(exclude)sub/*file" >actual + cat <<EOF >expect && +sub2/file +sub/file2 +file +EOF + test_cmp expect actual +' + +test_expect_success 't_e_i() exclude :(glob)sub/*/file' ' + git log --oneline --format=%s -- . ":(exclude,glob)sub/*/file" >actual + cat <<EOF >expect && +sub2/file +sub/sub/sub/file +sub/file2 +sub/file +file +EOF + test_cmp expect actual +' + +test_expect_success 'm_p_d() exclude sub' ' + git ls-files -- . ":(exclude)sub" >actual + cat <<EOF >expect && +file +sub2/file +EOF + test_cmp expect actual +' + +test_expect_success 'm_p_d() exclude sub/sub/file' ' + git ls-files -- . ":(exclude)sub/sub/file" >actual + cat <<EOF >expect && +file +sub/file +sub/file2 +sub/sub/sub/file +sub2/file +EOF + test_cmp expect actual +' + +test_expect_success 'm_p_d() exclude sub using mnemonic' ' + git ls-files -- . ":!sub" >actual + cat <<EOF >expect && +file +sub2/file +EOF + test_cmp expect actual +' + +test_expect_success 'm_p_d() exclude :(icase)SUB' ' + git ls-files -- . ":(exclude,icase)SUB" >actual + cat <<EOF >expect && +file +sub2/file +EOF + test_cmp expect actual +' + +test_expect_success 'm_p_d() exclude sub2 from sub' ' + ( + cd sub && + git ls-files -- :/ ":/!sub2" >actual + cat <<EOF >expect && +../file +file +file2 +sub/file +sub/sub/file +EOF + test_cmp expect actual + ) +' + +test_expect_success 'm_p_d() exclude sub/*file' ' + git ls-files -- . ":(exclude)sub/*file" >actual + cat <<EOF >expect && +file +sub/file2 +sub2/file +EOF + test_cmp expect actual +' + +test_expect_success 'm_p_d() exclude :(glob)sub/*/file' ' + git ls-files -- . ":(exclude,glob)sub/*/file" >actual + cat <<EOF >expect && +file +sub/file +sub/file2 +sub/sub/sub/file +sub2/file +EOF + test_cmp expect actual +' + +test_done diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 752f5cb7d0..bda354c1c4 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -18,16 +18,13 @@ setdate_and_increment () { export GIT_COMMITTER_DATE GIT_AUTHOR_DATE } -test_expect_success 'Create sample commit with known timestamp' ' +test_expect_success setup ' setdate_and_increment && echo "Using $datestamp" > one && git add one && git commit -m "Initial" && setdate_and_increment && - git tag -a -m "Tagging at $datestamp" testtag -' - -test_expect_success 'Create upstream config' ' + git tag -a -m "Tagging at $datestamp" testtag && git update-ref refs/remotes/origin/master master && git remote add origin nowhere && git config branch.master.remote origin && @@ -52,12 +49,14 @@ test_atom head refname refs/heads/master test_atom head upstream refs/remotes/origin/master test_atom head objecttype commit test_atom head objectsize 171 -test_atom head objectname 67a36f10722846e891fbada1ba48ed035de75581 -test_atom head tree 0e51c00fcb93dffc755546f27593d511e1bdb46f +test_atom head objectname $(git rev-parse refs/heads/master) +test_atom head tree $(git rev-parse refs/heads/master^{tree}) test_atom head parent '' test_atom head numparent 0 test_atom head object '' test_atom head type '' +test_atom head '*objectname' '' +test_atom head '*objecttype' '' test_atom head author 'A U Thor <author@example.com> 1151939924 +0200' test_atom head authorname 'A U Thor' test_atom head authoremail '<author@example.com>' @@ -80,17 +79,20 @@ test_atom head contents:body '' test_atom head contents:signature '' test_atom head contents 'Initial ' +test_atom head HEAD '*' test_atom tag refname refs/tags/testtag test_atom tag upstream '' test_atom tag objecttype tag test_atom tag objectsize 154 -test_atom tag objectname 98b46b1d36e5b07909de1b3886224e3e81e87322 +test_atom tag objectname $(git rev-parse refs/tags/testtag) test_atom tag tree '' test_atom tag parent '' test_atom tag numparent '' -test_atom tag object '67a36f10722846e891fbada1ba48ed035de75581' +test_atom tag object $(git rev-parse refs/tags/testtag^0) test_atom tag type 'commit' +test_atom tag '*objectname' '67a36f10722846e891fbada1ba48ed035de75581' +test_atom tag '*objecttype' 'commit' test_atom tag author '' test_atom tag authorname '' test_atom tag authoremail '' @@ -113,6 +115,7 @@ test_atom tag contents:body '' test_atom tag contents:signature '' test_atom tag contents 'Tagging at 1151939927 ' +test_atom tag HEAD ' ' test_expect_success 'Check invalid atoms names are errors' ' test_must_fail git for-each-ref --format="%(INVALID)" refs/heads @@ -304,8 +307,35 @@ test_expect_success 'Check short upstream format' ' test_cmp expected actual ' +test_expect_success 'setup for upstream:track[short]' ' + test_commit two +' + +cat >expected <<EOF +[ahead 1] +EOF + +test_expect_success 'Check upstream:track format' ' + git for-each-ref --format="%(upstream:track)" refs/heads >actual && + test_cmp expected actual +' + +cat >expected <<EOF +> +EOF + +test_expect_success 'Check upstream:trackshort format' ' + git for-each-ref --format="%(upstream:trackshort)" refs/heads >actual && + test_cmp expected actual +' + +test_expect_success 'Check that :track[short] cannot be used with other atoms' ' + test_must_fail git for-each-ref --format="%(refname:track)" 2>/dev/null && + test_must_fail git for-each-ref --format="%(refname:trackshort)" 2>/dev/null +' + cat >expected <<EOF -67a36f1 +$(git rev-parse --short HEAD) EOF test_expect_success 'Check short objectname format' ' @@ -317,6 +347,23 @@ test_expect_success 'Check for invalid refname format' ' test_must_fail git for-each-ref --format="%(refname:INVALID)" ' +get_color () +{ + git config --get-color no.such.slot "$1" +} + +cat >expected <<EOF +$(git rev-parse --short refs/heads/master) $(get_color green)master$(get_color reset) +$(git rev-parse --short refs/remotes/origin/master) $(get_color green)origin/master$(get_color reset) +$(git rev-parse --short refs/tags/testtag) $(get_color green)testtag$(get_color reset) +$(git rev-parse --short refs/tags/two) $(get_color green)two$(get_color reset) +EOF + +test_expect_success 'Check %(color:...) ' ' + git for-each-ref --format="%(objectname:short) %(color:green)%(refname:short)" >actual && + test_cmp expected actual +' + cat >expected <<\EOF heads/master tags/master @@ -456,9 +503,9 @@ test_atom refs/tags/signed-long contents "subject line body contents $sig" -cat >expected <<\EOF -408fe76d02a785a006c2e9c669b7be5589ede96d <committer@example.com> refs/tags/master -90b5ebede4899eda64893bc2a4c8f1d6fb6dfc40 <committer@example.com> refs/tags/bogo +cat >expected <<EOF +$(git rev-parse refs/tags/master) <committer@example.com> refs/tags/master +$(git rev-parse refs/tags/bogo) <committer@example.com> refs/tags/bogo EOF test_expect_success 'Verify sort with multiple keys' ' diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index b1a63655f9..63194d819e 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -9,6 +9,11 @@ test_expect_success 'gc empty repository' ' git gc ' +test_expect_success 'gc does not leave behind pid file' ' + git gc && + test_path_is_missing .git/gc.pid +' + test_expect_success 'gc --gobbledegook' ' test_expect_code 129 git gc --nonsense 2>err && test_i18ngrep "[Uu]sage: git gc" err diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index d432f42bcb..215d43d6a6 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -70,6 +70,35 @@ test_expect_success \ rm -f idontexist untracked1 untracked2 \ path0/idontexist path0/untracked1 path0/untracked2 \ .git/index.lock +rmdir path1 + +test_expect_success \ + 'moving to absent target with trailing slash' \ + 'test_must_fail git mv path0/COPYING no-such-dir/ && + test_must_fail git mv path0/COPYING no-such-dir// && + git mv path0/ no-such-dir/ && + test_path_is_dir no-such-dir' + +test_expect_success \ + 'clean up' \ + 'git reset --hard' + +test_expect_success \ + 'moving to existing untracked target with trailing slash' \ + 'mkdir path1 && + git mv path0/ path1/ && + test_path_is_dir path1/path0/' + +test_expect_success \ + 'moving to existing tracked target with trailing slash' \ + 'mkdir path2 && + >path2/file && git add path2/file && + git mv path1/path0/ path2/ && + test_path_is_dir path2/path0/' + +test_expect_success \ + 'clean up' \ + 'git reset --hard' test_expect_success \ 'adding another file' \ @@ -265,7 +294,8 @@ test_expect_success 'setup submodule' ' git submodule add ./. sub && echo content >file && git add file && - git commit -m "added sub and file" + git commit -m "added sub and file" && + git branch submodule ' test_expect_success 'git mv cannot move a submodule in a file' ' @@ -293,6 +323,32 @@ test_expect_success 'git mv moves a submodule with a .git directory and no .gitm git diff-files --quiet ' +test_expect_success 'git mv moves a submodule with a .git directory and .gitmodules' ' + rm -rf mod && + git reset --hard && + git submodule update && + entry="$(git ls-files --stage sub | cut -f 1)" && + ( + cd sub && + rm -f .git && + cp -a ../.git/modules/sub .git && + GIT_WORK_TREE=. git config --unset core.worktree + ) && + mkdir mod && + git mv sub mod/sub && + ! test -e sub && + [ "$entry" = "$(git ls-files --stage mod/sub | cut -f 1)" ] && + ( + cd mod/sub && + git status + ) && + echo mod/sub >expected && + git config -f .gitmodules submodule.sub.path >actual && + test_cmp expected actual && + git update-index --refresh && + git diff-files --quiet +' + test_expect_success 'git mv moves a submodule with gitfile' ' rm -rf mod/sub && git reset --hard && @@ -387,4 +443,35 @@ test_expect_success 'mv --dry-run does not touch the submodule or .gitmodules' ' git diff-files --quiet -- sub .gitmodules ' +test_expect_success 'checking out a commit before submodule moved needs manual updates' ' + git mv sub sub2 && + git commit -m "moved sub to sub2" && + git checkout -q HEAD^ 2>actual && + echo "warning: unable to rmdir sub2: Directory not empty" >expected && + test_i18ncmp expected actual && + git status -s sub2 >actual && + echo "?? sub2/" >expected && + test_cmp expected actual && + ! test -f sub/.git && + test -f sub2/.git && + git submodule update && + test -f sub/.git && + rm -rf sub2 && + git diff-index --exit-code HEAD && + git update-index --refresh && + git diff-files --quiet -- sub .gitmodules && + git status -s sub2 >actual && + ! test -s actual +' + +test_expect_success 'mv -k does not accidentally destroy submodules' ' + git checkout submodule && + mkdir dummy dest && + git mv -k dummy sub dest && + git status --porcelain >actual && + grep "^R sub -> dest/sub" actual && + git reset --hard && + git checkout . +' + test_done diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index c8d6e9f88c..143a8ea605 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1380,4 +1380,47 @@ test_expect_success 'multiple --points-at are OR-ed together' ' test_cmp expect actual ' +test_expect_success 'lexical sort' ' + git tag foo1.3 && + git tag foo1.6 && + git tag foo1.10 && + git tag -l --sort=refname "foo*" >actual && + cat >expect <<EOF && +foo1.10 +foo1.3 +foo1.6 +EOF + test_cmp expect actual +' + +test_expect_success 'version sort' ' + git tag -l --sort=version:refname "foo*" >actual && + cat >expect <<EOF && +foo1.3 +foo1.6 +foo1.10 +EOF + test_cmp expect actual +' + +test_expect_success 'reverse version sort' ' + git tag -l --sort=-version:refname "foo*" >actual && + cat >expect <<EOF && +foo1.10 +foo1.6 +foo1.3 +EOF + test_cmp expect actual +' + +test_expect_success 'reverse lexical sort' ' + git tag -l --sort=-refname "foo*" >actual && + cat >expect <<EOF && +foo1.6 +foo1.3 +foo1.10 +EOF + test_cmp expect actual +' + test_done diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh index ff2590849d..b9365b431d 100755 --- a/t/t7006-pager.sh +++ b/t/t7006-pager.sh @@ -37,6 +37,18 @@ test_expect_failure TTY 'pager runs from subdir' ' test_cmp expected actual ' +test_expect_success TTY 'LESS and LV envvars are set for pagination' ' + ( + sane_unset LESS LV && + PAGER="env >pager-env.out; wc" && + export PAGER && + + test_terminal git log + ) && + grep ^LESS= pager-env.out && + grep ^LV= pager-env.out +' + test_expect_success TTY 'some commands do not use a pager' ' rm -f paginated.out && test_terminal git rev-list HEAD && diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh index 7d467c034a..741ec08576 100755 --- a/t/t7060-wtstatus.sh +++ b/t/t7060-wtstatus.sh @@ -38,7 +38,7 @@ You have unmerged paths. Unmerged paths: (use "git add/rm <file>..." as appropriate to mark resolution) - deleted by us: foo + deleted by us: foo no changes added to commit (use "git add" and/or "git commit -a") EOF @@ -142,8 +142,8 @@ You have unmerged paths. Unmerged paths: (use "git add/rm <file>..." as appropriate to mark resolution) - both added: conflict.txt - deleted by them: main.txt + both added: conflict.txt + deleted by them: main.txt no changes added to commit (use "git add" and/or "git commit -a") EOF @@ -175,9 +175,9 @@ You have unmerged paths. Unmerged paths: (use "git add/rm <file>..." as appropriate to mark resolution) - both deleted: main.txt - added by them: sub_master.txt - added by us: sub_second.txt + both deleted: main.txt + added by them: sub_master.txt + added by us: sub_second.txt no changes added to commit (use "git add" and/or "git commit -a") EOF @@ -203,7 +203,7 @@ Changes to be committed: Unmerged paths: (use "git rm <file>..." to mark resolution) - both deleted: main.txt + both deleted: main.txt Untracked files not listed (use -u option to show untracked files) EOF diff --git a/t/t7101-reset.sh b/t/t7101-reset-empty-subdirs.sh index 96e163f084..96e163f084 100755 --- a/t/t7101-reset.sh +++ b/t/t7101-reset-empty-subdirs.sh diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 8d4b50d1b5..450529404c 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -535,4 +535,30 @@ test_expect_success 'reset with paths accepts tree' ' git diff HEAD --exit-code ' +test_expect_success 'reset -N keeps removed files as intent-to-add' ' + echo new-file >new-file && + git add new-file && + git reset -N HEAD && + + tree=$(git write-tree) && + git ls-tree $tree new-file >actual && + >expect && + test_cmp expect actual && + + git diff --name-only >actual && + echo new-file >expect && + test_cmp expect actual +' + +test_expect_success 'reset --mixed sets up work tree' ' + git init mixed_worktree && + ( + cd mixed_worktree && + test_commit dummy + ) && + : >expect && + git --git-dir=mixed_worktree/.git --work-tree=mixed_worktree reset >actual && + test_cmp expect actual +' + test_done diff --git a/t/t7104-reset.sh b/t/t7104-reset-hard.sh index f136ee7bb5..f136ee7bb5 100755 --- a/t/t7104-reset.sh +++ b/t/t7104-reset-hard.sh diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh index 95fab20361..98b7d7b969 100755 --- a/t/t7105-reset-patch.sh +++ b/t/t7105-reset-patch.sh @@ -25,15 +25,17 @@ test_expect_success PERL 'saying "n" does nothing' ' ' test_expect_success PERL 'git reset -p' ' - (echo n; echo y) | git reset -p && + (echo n; echo y) | git reset -p >output && verify_state dir/foo work head && - verify_saved_state bar + verify_saved_state bar && + test_i18ngrep "Unstage" output ' test_expect_success PERL 'git reset -p HEAD^' ' - (echo n; echo y) | git reset -p HEAD^ && + (echo n; echo y) | git reset -p HEAD^ >output && verify_state dir/foo work parent && - verify_saved_state bar + verify_saved_state bar && + test_i18ngrep "Apply" output ' # The idea in the rest is that bar sorts first, so we always say 'y' diff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh index af00ab4d88..0f95f00477 100755 --- a/t/t7106-reset-unborn-branch.sh +++ b/t/t7106-reset-unborn-branch.sh @@ -37,11 +37,12 @@ test_expect_success PERL 'reset -p' ' rm .git/index && git add a && echo y >yes && - git reset -p <yes && + git reset -p <yes >output && >expect && git ls-files >actual && - test_cmp expect actual + test_cmp expect actual && + test_i18ngrep "Unstage" output ' test_expect_success 'reset --soft is a no-op' ' diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 710be90489..74de814aec 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -511,4 +511,20 @@ test_expect_success SANITY 'git clean -d with an unreadable empty directory' ' ! test -d foo ' +test_expect_success 'git clean -d respects pathspecs (dir is prefix of pathspec)' ' + mkdir -p foo && + mkdir -p foobar && + git clean -df foobar && + test_path_is_dir foo && + test_path_is_missing foobar +' + +test_expect_success 'git clean -d respects pathspecs (pathspec is prefix of dir)' ' + mkdir -p foo && + mkdir -p foobar && + git clean -df foo && + test_path_is_missing foo && + test_path_is_dir foobar +' + test_done diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index f0b33053ab..28ca76384f 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -63,6 +63,9 @@ test_expect_success 'setup a submodule tree' ' git submodule add ../none none && test_tick && git commit -m "none" + ) && + (cd super && + git tag initial-setup ) ' @@ -323,6 +326,21 @@ test_expect_success 'submodule update - command in .git/config catches failure' ) ' +test_expect_success 'submodule init does not copy command into .git/config' ' + (cd super && + H=$(git ls-files -s submodule | cut -d" " -f2) && + mkdir submodule1 && + git update-index --add --cacheinfo 160000 $H submodule1 && + git config -f .gitmodules submodule.submodule1.path submodule1 && + git config -f .gitmodules submodule.submodule1.url ../submodule && + git config -f .gitmodules submodule.submodule1.update !false && + git submodule init submodule1 && + echo "none" >expect && + git config submodule.submodule1.update >actual && + test_cmp expect actual + ) +' + test_expect_success 'submodule init picks up rebase' ' (cd super && git config -f .gitmodules submodule.rebasing.update rebase && @@ -688,7 +706,7 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re git clone super_update_r super_update_r2 && (cd super_update_r2 && git submodule update --init --recursive >actual && - test_i18ngrep "Submodule path .submodule/subsubmodule.: checked out" actual && + test_i18ngrep "Submodule path .submodule/subsubmodule.: .git reset --hard -q" actual && (cd submodule/subsubmodule && git log > ../../expected ) && @@ -747,6 +765,50 @@ test_expect_success 'submodule update clone shallow submodule' ' (cd submodule && test 1 = $(git log --oneline | wc -l) ) +) +' + +test_expect_success 'submodule update --recursive drops module name before recursing' ' + (cd super2 && + (cd deeper/submodule/subsubmodule && + git checkout HEAD^ + ) && + git submodule update --recursive deeper/submodule >actual && + test_i18ngrep "Submodule path .deeper/submodule/subsubmodule.: checked out" actual ) ' + +test_expect_success 'submodule update --checkout clones detached HEAD' ' + git clone super super4 && + echo "detached HEAD" >expected && + (cd super4 && + git reset --hard initial-setup && + git submodule init submodule && + git submodule update >> /tmp/log 2>&1 && + (cd submodule && + git symbolic-ref HEAD > ../../actual || + echo "detached HEAD" > ../../actual + ) + ) && + test_cmp actual expected && + rm -rf super4 +' + +test_expect_success 'submodule update --merge clones attached HEAD' ' + git clone super super4 && + echo "refs/heads/master" >expected && + (cd super4 && + git reset --hard initial-setup && + git submodule init submodule && + git config submodule.submodule.update merge && + git submodule update --merge && + (cd submodule && + git symbolic-ref HEAD > ../../actual || + echo "detached HEAD" > ../../actual + ) + ) && + test_cmp actual expected && + rm -rf super4 +' + test_done diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index be93f10cf0..7ca10b8606 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -254,10 +254,6 @@ test_expect_success 'ensure "status --cached --recursive" preserves the --cached ) && git submodule status --cached --recursive -- nested1 > ../actual ) && - if test_have_prereq MINGW - then - dos2unix actual - fi && test_cmp expect actual ' @@ -329,4 +325,13 @@ test_expect_success 'command passed to foreach --recursive retains notion of std test_cmp expected actual ' +test_expect_success 'multi-argument command passed to foreach is not shell-evaluated twice' ' + ( + cd super && + git submodule foreach "echo \\\"quoted\\\"" > ../expected && + git submodule foreach echo \"quoted\" > ../actual + ) && + test_cmp expected actual +' + test_done diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index f04798f872..d58b097ff3 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -57,14 +57,51 @@ test_expect_success 'using invalid commit with -C' ' ' test_expect_success 'nothing to commit' ' + git reset --hard && test_must_fail git commit -m initial ' +test_expect_success '--dry-run fails with nothing to commit' ' + test_must_fail git commit -m initial --dry-run +' + +test_expect_success '--short fails with nothing to commit' ' + test_must_fail git commit -m initial --short +' + +test_expect_success '--porcelain fails with nothing to commit' ' + test_must_fail git commit -m initial --porcelain +' + +test_expect_success '--long fails with nothing to commit' ' + test_must_fail git commit -m initial --long +' + test_expect_success 'setup: non-initial commit' ' echo bongo bongo bongo >file && git commit -m next -a ' +test_expect_success '--dry-run with stuff to commit returns ok' ' + echo bongo bongo bongo >>file && + git commit -m next -a --dry-run +' + +test_expect_failure '--short with stuff to commit returns ok' ' + echo bongo bongo bongo >>file && + git commit -m next -a --short +' + +test_expect_failure '--porcelain with stuff to commit returns ok' ' + echo bongo bongo bongo >>file && + git commit -m next -a --porcelain +' + +test_expect_success '--long with stuff to commit returns ok' ' + echo bongo bongo bongo >>file && + git commit -m next -a --long +' + test_expect_success 'commit message from non-existing file' ' echo more bongo: bongo bongo bongo bongo >file && test_must_fail git commit -F gah -a diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index 6313da2cdd..9a3f3a1b41 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -223,6 +223,22 @@ test_expect_success 'cleanup commit messages (whitespace option,-F)' ' ' +test_expect_success 'cleanup commit messages (scissors option,-F,-e)' ' + + echo >>negative && + cat >text <<EOF && + +# to be kept +# ------------------------ >8 ------------------------ +to be removed +EOF + echo "# to be kept" >expect && + git commit --cleanup=scissors -e -F text -a && + git cat-file -p HEAD |sed -e "1,/^\$/d">actual && + test_cmp expect actual + +' + test_expect_success 'cleanup commit messages (strip option,-F)' ' echo >>negative && diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh index da5bd3b5a5..2ddf28c984 100755 --- a/t/t7507-commit-verbose.sh +++ b/t/t7507-commit-verbose.sh @@ -65,9 +65,35 @@ test_expect_success 'diff in message is retained without -v' ' check_message diff ' -test_expect_failure 'diff in message is retained with -v' ' +test_expect_success 'diff in message is retained with -v' ' git commit --amend -F diff -v && check_message diff ' +test_expect_success 'submodule log is stripped out too with -v' ' + git config diff.submodule log && + git submodule add ./. sub && + git commit -m "sub added" && + ( + cd sub && + echo "more" >>file && + git commit -a -m "submodule commit" + ) && + ( + GIT_EDITOR=cat && + export GIT_EDITOR && + test_must_fail git commit -a -v 2>err + ) && + test_i18ngrep "Aborting commit due to empty commit message." err +' + +test_expect_success 'verbose diff is stripped out with set core.commentChar' ' + ( + GIT_EDITOR=cat && + export GIT_EDITOR && + test_must_fail git -c core.commentchar=";" commit -a -v 2>err + ) && + test_i18ngrep "Aborting commit due to empty commit message." err +' + test_done diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 6fb59f3293..c987b5ed65 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -994,7 +994,7 @@ test_expect_success 'status -s submodule summary (clean submodule)' ' test_expect_success 'status -z implies porcelain' ' git status --porcelain | - "$PERL_PATH" -pe "s/\012/\000/g" >expect && + perl -pe "s/\012/\000/g" >expect && git status -z >output && test_cmp expect output ' diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 1d3c56fe61..5ddac1a9f7 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -5,6 +5,8 @@ test_description='signed commit tests' . "$TEST_DIRECTORY/lib-gpg.sh" test_expect_success GPG 'create signed commits' ' + test_when_finished "test_unconfig commit.gpgsign" && + echo 1 >file && git add file && test_tick && git commit -S -m initial && git tag initial && @@ -25,12 +27,27 @@ test_expect_success GPG 'create signed commits' ' git tag fourth-unsigned && test_tick && git commit --amend -S -m "fourth signed" && - git tag fourth-signed + git tag fourth-signed && + + git config commit.gpgsign true && + echo 5 >file && test_tick && git commit -a -m "fifth signed" && + git tag fifth-signed && + + git config commit.gpgsign false && + echo 6 >file && test_tick && git commit -a -m "sixth" && + git tag sixth-unsigned && + + git config commit.gpgsign true && + echo 7 >file && test_tick && git commit -a -m "seventh" --no-gpg-sign && + git tag seventh-unsigned && + + test_tick && git rebase -f HEAD^^ && git tag sixth-signed HEAD^ && + git tag seventh-signed ' test_expect_success GPG 'show signatures' ' ( - for commit in initial second merge master + for commit in initial second merge fourth-signed fifth-signed sixth-signed master do git show --pretty=short --show-signature $commit >actual && grep "Good signature from" actual || exit 1 @@ -39,7 +56,7 @@ test_expect_success GPG 'show signatures' ' done ) && ( - for commit in merge^2 fourth-unsigned + for commit in merge^2 fourth-unsigned sixth-unsigned seventh-unsigned do git show --pretty=short --show-signature $commit >actual && grep "Good signature from" actual && exit 1 @@ -52,7 +69,7 @@ test_expect_success GPG 'show signatures' ' test_expect_success GPG 'detect fudged signature' ' git cat-file commit master >raw && - sed -e "s/fourth signed/4th forged/" raw >forged1 && + sed -e "s/seventh/7th forged/" raw >forged1 && git hash-object -w -t commit forged1 >forged1.commit && git show --pretty=short --show-signature $(cat forged1.commit) >actual1 && grep "BAD signature from" actual1 && diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index 3cec57af1e..68ad2d7454 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -33,7 +33,7 @@ You have unmerged paths. Unmerged paths: (use "git add <file>..." to mark resolution) - both modified: main.txt + both modified: main.txt no changes added to commit (use "git add" and/or "git commit -a") EOF @@ -87,7 +87,7 @@ Unmerged paths: (use "git reset HEAD <file>..." to unstage) (use "git add <file>..." to mark resolution) - both modified: main.txt + both modified: main.txt no changes added to commit (use "git add" and/or "git commit -a") EOF @@ -146,7 +146,7 @@ Unmerged paths: (use "git reset HEAD <file>..." to unstage) (use "git add <file>..." to mark resolution) - both modified: main.txt + both modified: main.txt no changes added to commit (use "git add" and/or "git commit -a") EOF @@ -602,7 +602,7 @@ rebase in progress; onto $ONTO You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''. Unmerged paths: - both modified: main.txt + both modified: main.txt no changes added to commit EOF @@ -636,7 +636,7 @@ You are currently cherry-picking commit $TO_CHERRY_PICK. Unmerged paths: (use "git add <file>..." to mark resolution) - both modified: main.txt + both modified: main.txt no changes added to commit (use "git add" and/or "git commit -a") EOF @@ -707,7 +707,7 @@ Unmerged paths: (use "git reset HEAD <file>..." to unstage) (use "git add <file>..." to mark resolution) - both modified: to-revert.txt + both modified: to-revert.txt no changes added to commit (use "git add" and/or "git commit -a") EOF diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 830a4c3e9d..f768c900ab 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -38,6 +38,27 @@ test_expect_success 'merge c1 with c2' ' test -f c2.c ' +test_expect_success 'fast-forward pull succeeds with "true" in pull.ff' ' + git reset --hard c0 && + test_config pull.ff true && + git pull . c1 && + test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" +' + +test_expect_success 'fast-forward pull creates merge with "false" in pull.ff' ' + git reset --hard c0 && + test_config pull.ff false && + git pull . c1 && + test "$(git rev-parse HEAD^1)" = "$(git rev-parse c0)" && + test "$(git rev-parse HEAD^2)" = "$(git rev-parse c1)" +' + +test_expect_success 'pull prevents non-fast-forward with "only" in pull.ff' ' + git reset --hard c1 && + test_config pull.ff only && + test_must_fail git pull . c3 +' + test_expect_success 'merge c1 with c2 (ours in pull.twohead)' ' git reset --hard c1 && git config pull.twohead ours && diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index d954b846a1..284018e3cd 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -17,11 +17,11 @@ test_expect_success 'objects in packs marked .keep are not repacked' ' # The second pack will contain the excluded object packsha1=$(git rev-list --objects --all | grep file2 | git pack-objects pack) && - touch -r pack-$packsha1.pack pack-$packsha1.keep && + >pack-$packsha1.keep && objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 | sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") && mv pack-* .git/objects/pack/ && - git repack -A -d -l && + git repack --no-pack-kept-objects -A -d -l && git prune-packed && for p in .git/objects/pack/*.idx; do idx=$(basename $p) @@ -35,6 +35,22 @@ test_expect_success 'objects in packs marked .keep are not repacked' ' test -z "$found_duplicate_object" ' +test_expect_success 'writing bitmaps can duplicate .keep objects' ' + # build on $objsha1, $packsha1, and .keep state from previous + git repack -Adl && + test_when_finished "found_duplicate_object=" && + for p in .git/objects/pack/*.idx; do + idx=$(basename $p) + test "pack-$packsha1.idx" = "$idx" && continue + if git verify-pack -v $p | egrep "^$objsha1"; then + found_duplicate_object=1 + echo "DUPLICATE OBJECT FOUND" + break + fi + done && + test "$found_duplicate_object" = 1 +' + test_expect_success 'loose objects in alternate ODB are not repacked' ' mkdir alt_objects && echo `pwd`/alt_objects > .git/objects/info/alternates && diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 2418528487..5a193c500d 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -434,4 +434,18 @@ test_expect_success PERL 'difftool --no-symlinks detects conflict ' ' ) ' +test_expect_success PERL 'difftool properly honors gitlink and core.worktree' ' + git submodule add ./. submod/ule && + ( + cd submod/ule && + test_config diff.tool checktrees && + test_config difftool.checktrees.cmd '\'' + test -d "$LOCAL" && test -d "$REMOTE" && echo good + '\'' && + echo good >expect && + git difftool --tool=checktrees --dir-diff HEAD~ >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index f698001c99..63b3039243 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -105,7 +105,7 @@ do test_expect_success "grep -w $L (w)" ' : >expected && - test_must_fail git grep -n -w -e "^w" >actual && + test_must_fail git grep -n -w -e "^w" $H >actual && test_cmp expected actual ' @@ -240,92 +240,104 @@ do test_cmp expected actual ' test_expect_success "grep $L with grep.extendedRegexp=false" ' - echo "ab:a+bc" >expected && - git -c grep.extendedRegexp=false grep "a+b*c" ab >actual && + echo "${HC}ab:a+bc" >expected && + git -c grep.extendedRegexp=false grep "a+b*c" $H ab >actual && test_cmp expected actual ' test_expect_success "grep $L with grep.extendedRegexp=true" ' - echo "ab:abc" >expected && - git -c grep.extendedRegexp=true grep "a+b*c" ab >actual && + echo "${HC}ab:abc" >expected && + git -c grep.extendedRegexp=true grep "a+b*c" $H ab >actual && test_cmp expected actual ' test_expect_success "grep $L with grep.patterntype=basic" ' - echo "ab:a+bc" >expected && - git -c grep.patterntype=basic grep "a+b*c" ab >actual && + echo "${HC}ab:a+bc" >expected && + git -c grep.patterntype=basic grep "a+b*c" $H ab >actual && test_cmp expected actual ' test_expect_success "grep $L with grep.patterntype=extended" ' - echo "ab:abc" >expected && - git -c grep.patterntype=extended grep "a+b*c" ab >actual && + echo "${HC}ab:abc" >expected && + git -c grep.patterntype=extended grep "a+b*c" $H ab >actual && test_cmp expected actual ' test_expect_success "grep $L with grep.patterntype=fixed" ' - echo "ab:a+b*c" >expected && - git -c grep.patterntype=fixed grep "a+b*c" ab >actual && + echo "${HC}ab:a+b*c" >expected && + git -c grep.patterntype=fixed grep "a+b*c" $H ab >actual && test_cmp expected actual ' test_expect_success LIBPCRE "grep $L with grep.patterntype=perl" ' - echo "ab:a+b*c" >expected && - git -c grep.patterntype=perl grep "a\x{2b}b\x{2a}c" ab >actual && + echo "${HC}ab:a+b*c" >expected && + git -c grep.patterntype=perl grep "a\x{2b}b\x{2a}c" $H ab >actual && test_cmp expected actual ' test_expect_success "grep $L with grep.patternType=default and grep.extendedRegexp=true" ' - echo "ab:abc" >expected && + echo "${HC}ab:abc" >expected && git \ -c grep.patternType=default \ -c grep.extendedRegexp=true \ - grep "a+b*c" ab >actual && + grep "a+b*c" $H ab >actual && test_cmp expected actual ' test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=default" ' - echo "ab:abc" >expected && + echo "${HC}ab:abc" >expected && git \ -c grep.extendedRegexp=true \ -c grep.patternType=default \ - grep "a+b*c" ab >actual && + grep "a+b*c" $H ab >actual && test_cmp expected actual ' - test_expect_success 'grep $L with grep.patternType=extended and grep.extendedRegexp=false' ' - echo "ab:abc" >expected && + test_expect_success "grep $L with grep.patternType=extended and grep.extendedRegexp=false" ' + echo "${HC}ab:abc" >expected && git \ -c grep.patternType=extended \ -c grep.extendedRegexp=false \ - grep "a+b*c" ab >actual && + grep "a+b*c" $H ab >actual && test_cmp expected actual ' - test_expect_success 'grep $L with grep.patternType=basic and grep.extendedRegexp=true' ' - echo "ab:a+bc" >expected && + test_expect_success "grep $L with grep.patternType=basic and grep.extendedRegexp=true" ' + echo "${HC}ab:a+bc" >expected && git \ -c grep.patternType=basic \ -c grep.extendedRegexp=true \ - grep "a+b*c" ab >actual && + grep "a+b*c" $H ab >actual && test_cmp expected actual ' - test_expect_success 'grep $L with grep.extendedRegexp=false and grep.patternType=extended' ' - echo "ab:abc" >expected && + test_expect_success "grep $L with grep.extendedRegexp=false and grep.patternType=extended" ' + echo "${HC}ab:abc" >expected && git \ -c grep.extendedRegexp=false \ -c grep.patternType=extended \ - grep "a+b*c" ab >actual && + grep "a+b*c" $H ab >actual && test_cmp expected actual ' - test_expect_success 'grep $L with grep.extendedRegexp=true and grep.patternType=basic' ' - echo "ab:a+bc" >expected && + test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=basic" ' + echo "${HC}ab:a+bc" >expected && git \ -c grep.extendedRegexp=true \ -c grep.patternType=basic \ - grep "a+b*c" ab >actual && + grep "a+b*c" $H ab >actual && + test_cmp expected actual + ' + + test_expect_success "grep --count $L" ' + echo ${HC}ab:3 >expected && + git grep --count -e b $H -- ab >actual && + test_cmp expected actual + ' + + test_expect_success "grep --count -h $L" ' + echo 3 >expected && + git grep --count -h -e b $H -- ab >actual && test_cmp expected actual ' done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 2813aa9a61..1ecdacb6fd 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -23,7 +23,6 @@ test_expect_success $PREREQ \ echo do echo " echo \"!\$a!\"" echo "done >commandline\$output" - test_have_prereq MINGW && echo "dos2unix commandline\$output" echo "cat > msgtxt\$output" ) >fake.sendmail && chmod +x ./fake.sendmail && @@ -410,7 +409,7 @@ test_expect_success $PREREQ 'Valid In-Reply-To when prompting' ' (echo "From Example <from@example.com>" echo "To Example <to@example.com>" echo "" - ) | env GIT_SEND_EMAIL_NOTTY=1 git send-email \ + ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \ --smtp-server="$(pwd)/fake.sendmail" \ $patches 2>errors && ! grep "^In-Reply-To: < *>" msgtxt1 diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh index f524d2f383..d33d714006 100755 --- a/t/t9114-git-svn-dcommit-merge.sh +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -62,7 +62,7 @@ test_expect_success 'setup git mirror and merge' ' echo friend > README && cat tmp >> README && git commit -a -m "friend" && - git pull . merge + git merge merge ' test_debug 'gitk --all & sleep 1' diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index 9a40f1e199..8cfdfe790f 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -29,7 +29,7 @@ fi compare_svn_head_with () { # extract just the log message and strip out committer info. # don't use --limit here since svn 1.1.x doesn't have it, - LC_ALL="$a_utf8_locale" svn log `git svn info --url` | "$PERL_PATH" -w -e ' + LC_ALL="$a_utf8_locale" svn log `git svn info --url` | perl -w -e ' use bytes; $/ = ("-"x72) . "\n"; my @x = <STDIN>; diff --git a/t/t9137-git-svn-dcommit-clobber-series.sh b/t/t9137-git-svn-dcommit-clobber-series.sh index c17aa3186f..d60da63f7a 100755 --- a/t/t9137-git-svn-dcommit-clobber-series.sh +++ b/t/t9137-git-svn-dcommit-clobber-series.sh @@ -20,8 +20,8 @@ test_expect_success '(supposedly) non-conflicting change from SVN' ' test x"`sed -n -e 61p < file`" = x61 && svn_cmd co "$svnrepo" tmp && (cd tmp && - "$PERL_PATH" -i.bak -p -e "s/^58$/5588/" file && - "$PERL_PATH" -i.bak -p -e "s/^61$/6611/" file && + perl -i.bak -p -e "s/^58$/5588/" file && + perl -i.bak -p -e "s/^61$/6611/" file && poke file && test x"`sed -n -e 58p < file`" = x5588 && test x"`sed -n -e 61p < file`" = x6611 && @@ -40,8 +40,8 @@ test_expect_success 'some unrelated changes to git' " test_expect_success 'change file but in unrelated area' " test x\"\`sed -n -e 4p < file\`\" = x4 && test x\"\`sed -n -e 7p < file\`\" = x7 && - "$PERL_PATH" -i.bak -p -e 's/^4\$/4444/' file && - "$PERL_PATH" -i.bak -p -e 's/^7\$/7777/' file && + perl -i.bak -p -e 's/^4\$/4444/' file && + perl -i.bak -p -e 's/^7\$/7777/' file && test x\"\`sed -n -e 4p < file\`\" = x4444 && test x\"\`sed -n -e 7p < file\`\" = x7777 && git commit -m '4 => 4444, 7 => 7777' file && diff --git a/t/t9150/make-svk-dump b/t/t9150/make-svk-dump index 2242f14ebe..2242f14ebe 100644..100755 --- a/t/t9150/make-svk-dump +++ b/t/t9150/make-svk-dump diff --git a/t/t9151/make-svnmerge-dump b/t/t9151/make-svnmerge-dump index e1e138cb1a..e1e138cb1a 100644..100755 --- a/t/t9151/make-svnmerge-dump +++ b/t/t9151/make-svnmerge-dump diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index 3fb3368903..812c9cd462 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -5,7 +5,6 @@ test_description='Test export of commits to CVS' . ./test-lib.sh -. "$TEST_DIRECTORY"/lib-prereq-FILEMODE.sh if ! test_have_prereq PERL; then skip_all='skipping git cvsexportcommit tests, perl not available' diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 88fc407ed6..27263dfb80 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -12,7 +12,7 @@ test_description='test git fast-import utility' # This could be written as "head -c $1", but IRIX "head" does not # support the -c option. head_c () { - "$PERL_PATH" -e ' + perl -e ' my $len = $ARGV[1]; while ($len > 0) { my $s; diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 34c2d8f49a..2312dec8f0 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -429,7 +429,7 @@ test_expect_success 'fast-export quotes pathnames' ' --cacheinfo 100644 $blob "path with \\backslash" \ --cacheinfo 100644 $blob "path with space" && git commit -m addition && - git ls-files -z -s | "$PERL_PATH" -0pe "s{\\t}{$&subdir/}" >index && + git ls-files -z -s | perl -0pe "s{\\t}{$&subdir/}" >index && git read-tree --empty && git update-index -z --index-info <index && git commit -m rename && diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 043138631b..3edc4086d8 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -20,7 +20,7 @@ then skip_all='skipping git-cvsserver tests, cvs not found' test_done fi -"$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { +perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable' test_done } diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index 8c3db76301..5a4ed28e49 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -68,7 +68,7 @@ then skip_all='skipping git-cvsserver tests, perl not available' test_done fi -"$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { +perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable' test_done } diff --git a/t/t9402-git-cvsserver-refs.sh b/t/t9402-git-cvsserver-refs.sh index db69af2cff..1e266effff 100755 --- a/t/t9402-git-cvsserver-refs.sh +++ b/t/t9402-git-cvsserver-refs.sh @@ -76,7 +76,7 @@ then skip_all='skipping git-cvsserver tests, perl not available' test_done fi -"$PERL_PATH" -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { +perl -e 'use DBI; use DBD::SQLite' >/dev/null 2>&1 || { skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable' test_done } diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 718014d5de..e74b9ab1e1 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -328,7 +328,7 @@ test_expect_success \ git add b && git commit -a -m "On branch" && git checkout master && - git pull . b && + git merge b && git tag merge_commit' test_expect_success \ diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh index 435d896476..102c133112 100755 --- a/t/t9700-perl-git.sh +++ b/t/t9700-perl-git.sh @@ -11,7 +11,7 @@ if ! test_have_prereq PERL; then test_done fi -"$PERL_PATH" -MTest::More -e 0 2>/dev/null || { +perl -MTest::More -e 0 2>/dev/null || { skip_all="Perl Test::More unavailable, skipping test" test_done } @@ -55,6 +55,6 @@ test_external_has_tap=1 test_external_without_stderr \ 'Perl API' \ - "$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl + perl "$TEST_DIRECTORY"/t9700/test.pl test_done diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh index a82744bab0..66d3fc91a7 100755 --- a/t/t9802-git-p4-filetype.sh +++ b/t/t9802-git-p4-filetype.sh @@ -250,6 +250,89 @@ test_expect_success 'ignore apple' ' ) ' +test_expect_success SYMLINKS 'create p4 symlink' ' + cd "$cli" && + ln -s symlink-target symlink && + p4 add symlink && + p4 submit -d "add symlink" +' + +test_expect_success SYMLINKS 'ensure p4 symlink parsed correctly' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot@all && + ( + cd "$git" && + test -L symlink && + test $(readlink symlink) = symlink-target + ) +' + +test_expect_success SYMLINKS 'empty symlink target' ' + ( + # first create the file as a file + cd "$cli" && + >empty-symlink && + p4 add empty-symlink && + p4 submit -d "add empty-symlink as a file" + ) && + ( + # now change it to be a symlink to "target1" + cd "$cli" && + p4 edit empty-symlink && + p4 reopen -t symlink empty-symlink && + rm empty-symlink && + ln -s target1 empty-symlink && + p4 add empty-symlink && + p4 submit -d "make empty-symlink point to target1" + ) && + ( + # Hack the p4 depot to make the symlink point to nothing; + # this should not happen in reality, but shows up + # in p4 repos in the wild. + # + # The sed expression changes this: + # @@ + # text + # @target1 + # @ + # to this: + # @@ + # text + # @@ + # + cd "$db/depot" && + sed "/@target1/{; s/target1/@/; n; d; }" \ + empty-symlink,v >empty-symlink,v.tmp && + mv empty-symlink,v.tmp empty-symlink,v + ) && + ( + # Make sure symlink really is empty. Asking + # p4 to sync here will make it generate errors. + cd "$cli" && + p4 print -q //depot/empty-symlink#2 >out && + test ! -s out + ) && + test_when_finished cleanup_git && + + # make sure git p4 handles it without error + git p4 clone --dest="$git" //depot@all && + + # fix the symlink, make it point to "target2" + ( + cd "$cli" && + p4 open empty-symlink && + rm empty-symlink && + ln -s target2 empty-symlink && + p4 submit -d "make empty-symlink point to target2" + ) && + cleanup_git && + git p4 clone --dest="$git" //depot@all && + ( + cd "$git" && + test $(readlink empty-symlink) = target2 + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9805-git-p4-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh index ff2cc79701..89311886db 100755 --- a/t/t9805-git-p4-skip-submit-edit.sh +++ b/t/t9805-git-p4-skip-submit-edit.sh @@ -17,7 +17,7 @@ test_expect_success 'init depot' ' ) ' -# this works because EDITOR is set to : +# this works because P4EDITOR is set to true test_expect_success 'no config, unedited, say yes' ' git p4 clone --dest="$git" //depot && test_when_finished cleanup_git && @@ -90,7 +90,9 @@ test_expect_success 'no config, edited' ' cd "$git" && echo line >>file1 && git commit -a -m "change 5" && - P4EDITOR="" EDITOR="\"$TRASH_DIRECTORY/ed.sh\"" git p4 submit && + P4EDITOR="$TRASH_DIRECTORY/ed.sh" && + export P4EDITOR && + git p4 submit && p4 changes //depot/... >wc && test_line_count = 5 wc ) diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh index 1fb7bc7cf9..4caf36e006 100755 --- a/t/t9807-git-p4-submit.sh +++ b/t/t9807-git-p4-submit.sh @@ -17,7 +17,7 @@ test_expect_success 'init depot' ' ) ' -test_expect_failure 'is_cli_file_writeable function' ' +test_expect_success 'is_cli_file_writeable function' ' ( cd "$cli" && echo a >a && diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh index 77f63492d9..23a827fa77 100755 --- a/t/t9809-git-p4-client-view.sh +++ b/t/t9809-git-p4-client-view.sh @@ -76,28 +76,28 @@ test_expect_success 'init depot' ' ' # double % for printf -test_expect_success 'unsupported view wildcard %%n' ' +test_expect_success 'view wildcard %%n' ' client_view "//depot/%%%%1/sub/... //client/sub/%%%%1/..." && test_when_finished cleanup_git && - test_must_fail git p4 clone --use-client-spec --dest="$git" //depot + git p4 clone --use-client-spec --dest="$git" //depot ' -test_expect_success 'unsupported view wildcard *' ' +test_expect_success 'view wildcard *' ' client_view "//depot/*/bar/... //client/*/bar/..." && test_when_finished cleanup_git && - test_must_fail git p4 clone --use-client-spec --dest="$git" //depot + git p4 clone --use-client-spec --dest="$git" //depot ' -test_expect_success 'wildcard ... only supported at end of spec 1' ' +test_expect_success 'wildcard ... in the middle' ' client_view "//depot/.../file11 //client/.../file11" && test_when_finished cleanup_git && - test_must_fail git p4 clone --use-client-spec --dest="$git" //depot + git p4 clone --use-client-spec --dest="$git" //depot ' -test_expect_success 'wildcard ... only supported at end of spec 2' ' +test_expect_success 'wildcard ... in the middle and at the end' ' client_view "//depot/.../a/... //client/.../a/..." && test_when_finished cleanup_git && - test_must_fail git p4 clone --use-client-spec --dest="$git" //depot + git p4 clone --use-client-spec --dest="$git" //depot ' test_expect_success 'basic map' ' diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh index 34fbc90005..8134ab439b 100755 --- a/t/t9810-git-p4-rcs.sh +++ b/t/t9810-git-p4-rcs.sh @@ -263,7 +263,7 @@ test_expect_success 'cope with rcs keyword expansion damage' ' git config git-p4.attemptRCSCleanup true && (cd "$cli" && p4_append_to_file kwfile1.c) && old_lines=$(wc -l <kwfile1.c) && - "$PERL_PATH" -n -i -e "print unless m/Revision:/" kwfile1.c && + perl -n -i -e "print unless m/Revision:/" kwfile1.c && new_lines=$(wc -l <kwfile1.c) && test $new_lines = $(($old_lines - 1)) && diff --git a/t/t9812-git-p4-wildcards.sh b/t/t9812-git-p4-wildcards.sh index 67633257f3..c7472cbf54 100755 --- a/t/t9812-git-p4-wildcards.sh +++ b/t/t9812-git-p4-wildcards.sh @@ -161,6 +161,56 @@ test_expect_success 'wildcard files submit back to p4, delete' ' ) ' +test_expect_success 'p4 deleted a wildcard file' ' + ( + cd "$cli" && + echo "wild delete test" >wild@delete && + p4 add -f wild@delete && + p4 submit -d "add wild@delete" + ) && + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + test_path_is_file wild@delete + ) && + ( + cd "$cli" && + # must use its encoded name + p4 delete wild%40delete && + p4 submit -d "delete wild@delete" + ) && + ( + cd "$git" && + git p4 sync && + git merge --ff-only p4/master && + test_path_is_missing wild@delete + ) +' + +test_expect_success 'wildcard files requiring keyword scrub' ' + ( + cd "$cli" && + cat <<-\EOF >scrub@wild && + $Id$ + line2 + EOF + p4 add -t text+k -f scrub@wild && + p4 submit -d "scrub at wild" + ) && + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + git config git-p4.skipSubmitEdit true && + git config git-p4.attemptRCSCleanup true && + sed "s/^line2/line2 edit/" <scrub@wild >scrub@wild.tmp && + mv -f scrub@wild.tmp scrub@wild && + git commit -m "scrub at wild line2 edit" scrub@wild && + git p4 submit + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9813-git-p4-preserve-users.sh b/t/t9813-git-p4-preserve-users.sh index f2e85e518b..166b840bfa 100755 --- a/t/t9813-git-p4-preserve-users.sh +++ b/t/t9813-git-p4-preserve-users.sh @@ -19,16 +19,6 @@ test_expect_success 'create files' ' ) ' -p4_add_user() { - name=$1 fullname=$2 && - p4 user -f -i <<-EOF && - User: $name - Email: $name@localhost - FullName: $fullname - EOF - p4 passwd -P secret $name -} - p4_grant_admin() { name=$1 && { @@ -51,8 +41,8 @@ make_change_by_user() { # Test username support, submitting as user 'alice' test_expect_success 'preserve users' ' - p4_add_user alice Alice && - p4_add_user bob Bob && + p4_add_user alice && + p4_add_user bob && p4_grant_admin alice && git p4 clone --dest="$git" //depot && test_when_finished cleanup_git && @@ -60,8 +50,8 @@ test_expect_success 'preserve users' ' cd "$git" && echo "username: a change by alice" >>file1 && echo "username: a change by bob" >>file2 && - git commit --author "Alice <alice@localhost>" -m "a change by alice" file1 && - git commit --author "Bob <bob@localhost>" -m "a change by bob" file2 && + git commit --author "Alice <alice@example.com>" -m "a change by alice" file1 && + git commit --author "Bob <bob@example.com>" -m "a change by bob" file2 && git config git-p4.skipSubmitEditCheck true && P4EDITOR=touch P4USER=alice P4PASSWD=secret git p4 commit --preserve-user && p4_check_commit_author file1 alice && @@ -78,7 +68,7 @@ test_expect_success 'refuse to preserve users without perms' ' cd "$git" && git config git-p4.skipSubmitEditCheck true && echo "username-noperms: a change by alice" >>file1 && - git commit --author "Alice <alice@localhost>" -m "perms: a change by alice" file1 && + git commit --author "Alice <alice@example.com>" -m "perms: a change by alice" file1 && P4EDITOR=touch P4USER=bob P4PASSWD=secret && export P4EDITOR P4USER P4PASSWD && test_must_fail git p4 commit --preserve-user && @@ -94,9 +84,9 @@ test_expect_success 'preserve user where author is unknown to p4' ' cd "$git" && git config git-p4.skipSubmitEditCheck true && echo "username-bob: a change by bob" >>file1 && - git commit --author "Bob <bob@localhost>" -m "preserve: a change by bob" file1 && + git commit --author "Bob <bob@example.com>" -m "preserve: a change by bob" file1 && echo "username-unknown: a change by charlie" >>file1 && - git commit --author "Charlie <charlie@localhost>" -m "preserve: a change by charlie" file1 && + git commit --author "Charlie <charlie@example.com>" -m "preserve: a change by charlie" file1 && P4EDITOR=touch P4USER=alice P4PASSWD=secret && export P4EDITOR P4USER P4PASSWD && test_must_fail git p4 commit --preserve-user && @@ -121,24 +111,24 @@ test_expect_success 'not preserving user with mixed authorship' ' ( cd "$git" && git config git-p4.skipSubmitEditCheck true && - p4_add_user derek Derek && + p4_add_user derek && - make_change_by_user usernamefile3 Derek derek@localhost && + make_change_by_user usernamefile3 Derek derek@example.com && P4EDITOR=cat P4USER=alice P4PASSWD=secret && export P4EDITOR P4USER P4PASSWD && git p4 commit |\ - grep "git author derek@localhost does not match" && + grep "git author derek@example.com does not match" && - make_change_by_user usernamefile3 Charlie charlie@localhost && + make_change_by_user usernamefile3 Charlie charlie@example.com && git p4 commit |\ - grep "git author charlie@localhost does not match" && + grep "git author charlie@example.com does not match" && - make_change_by_user usernamefile3 alice alice@localhost && + make_change_by_user usernamefile3 alice alice@example.com && git p4 commit |\ test_must_fail grep "git author.*does not match" && git config git-p4.skipUserNameCheck true && - make_change_by_user usernamefile3 Charlie charlie@localhost && + make_change_by_user usernamefile3 Charlie charlie@example.com && git p4 commit |\ test_must_fail grep "git author.*does not match" && diff --git a/t/t9816-git-p4-locked.sh b/t/t9816-git-p4-locked.sh new file mode 100755 index 0000000000..e71e543343 --- /dev/null +++ b/t/t9816-git-p4-locked.sh @@ -0,0 +1,145 @@ +#!/bin/sh + +test_description='git p4 locked file behavior' + +. ./lib-git-p4.sh + +test_expect_success 'start p4d' ' + start_p4d +' + +# See +# http://www.perforce.com/perforce/doc.current/manuals/p4sag/03_superuser.html#1088563 +# for suggestions on how to configure "sitewide pessimistic locking" +# where only one person can have a file open for edit at a time. +test_expect_success 'init depot' ' + ( + cd "$cli" && + echo "TypeMap: +l //depot/..." | p4 typemap -i && + echo file1 >file1 && + p4 add file1 && + p4 submit -d "add file1" + ) +' + +test_expect_success 'edit with lock not taken' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + echo line2 >>file1 && + git add file1 && + git commit -m "line2 in file1" && + git config git-p4.skipSubmitEdit true && + git p4 submit + ) +' + +test_expect_failure 'add with lock not taken' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + echo line1 >>add-lock-not-taken && + git add file2 && + git commit -m "add add-lock-not-taken" && + git config git-p4.skipSubmitEdit true && + git p4 submit --verbose + ) +' + +lock_in_another_client() { + # build a different client + cli2="$TRASH_DIRECTORY/cli2" && + mkdir -p "$cli2" && + test_when_finished "p4 client -f -d client2 && rm -rf \"$cli2\"" && + ( + cd "$cli2" && + P4CLIENT=client2 && + cli="$cli2" && + client_view "//depot/... //client2/..." && + p4 sync && + p4 open file1 + ) +} + +test_expect_failure 'edit with lock taken' ' + lock_in_another_client && + test_when_finished cleanup_git && + test_when_finished "cd \"$cli\" && p4 sync -f file1" && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + echo line3 >>file1 && + git add file1 && + git commit -m "line3 in file1" && + git config git-p4.skipSubmitEdit true && + git p4 submit --verbose + ) +' + +test_expect_failure 'delete with lock taken' ' + lock_in_another_client && + test_when_finished cleanup_git && + test_when_finished "cd \"$cli\" && p4 sync -f file1" && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + git rm file1 && + git commit -m "delete file1" && + git config git-p4.skipSubmitEdit true && + git p4 submit --verbose + ) +' + +test_expect_failure 'chmod with lock taken' ' + lock_in_another_client && + test_when_finished cleanup_git && + test_when_finished "cd \"$cli\" && p4 sync -f file1" && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + chmod +x file1 && + git add file1 && + git commit -m "chmod +x file1" && + git config git-p4.skipSubmitEdit true && + git p4 submit --verbose + ) +' + +test_expect_failure 'copy with lock taken' ' + lock_in_another_client && + test_when_finished cleanup_git && + test_when_finished "cd \"$cli\" && p4 revert file2 && rm -f file2" && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + cp file1 file2 && + git add file2 && + git commit -m "cp file1 to file2" && + git config git-p4.skipSubmitEdit true && + git config git-p4.detectCopies true && + git p4 submit --verbose + ) +' + +test_expect_failure 'move with lock taken' ' + lock_in_another_client && + test_when_finished cleanup_git && + test_when_finished "cd \"$cli\" && p4 sync file1 && rm -f file2" && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + git mv file1 file2 && + git commit -m "mv file1 to file2" && + git config git-p4.skipSubmitEdit true && + git config git-p4.detectRenames true && + git p4 submit --verbose + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index a7e9aacbb2..158e10a67e 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -1,4 +1,5 @@ -#!/bin/sh +# Library of functions shared by all tests scripts, included by +# test-lib.sh. # # Copyright (c) 2005 Junio C Hamano # @@ -31,6 +32,11 @@ test_set_editor () { export EDITOR } +test_set_index_version () { + GIT_INDEX_VERSION="$1" + export GIT_INDEX_VERSION +} + test_decode_color () { awk ' function name(n) { @@ -76,11 +82,11 @@ test_decode_color () { } nul_to_q () { - "$PERL_PATH" -pe 'y/\000/Q/' + perl -pe 'y/\000/Q/' } q_to_nul () { - "$PERL_PATH" -pe 'y/Q/\000/' + perl -pe 'y/Q/\000/' } q_to_cr () { @@ -648,7 +654,7 @@ test_seq () { 2) ;; *) error "bug in the test script: not 1 or 2 parameters to test_seq" ;; esac - "$PERL_PATH" -le 'print for $ARGV[0]..$ARGV[1]' -- "$@" + perl -le 'print for $ARGV[0]..$ARGV[1]' -- "$@" } # This function can be used to schedule some commands to be run @@ -710,3 +716,131 @@ test_ln_s_add () { git update-index --add --cacheinfo 120000 $ln_s_obj "$2" fi } + +perl () { + command "$PERL_PATH" "$@" +} + +# Is the value one of the various ways to spell a boolean true/false? +test_normalize_bool () { + git -c magic.variable="$1" config --bool magic.variable 2>/dev/null +} + +# Given a variable $1, normalize the value of it to one of "true", +# "false", or "auto" and store the result to it. +# +# test_tristate GIT_TEST_HTTPD +# +# A variable set to an empty string is set to 'false'. +# A variable set to 'false' or 'auto' keeps its value. +# Anything else is set to 'true'. +# An unset variable defaults to 'auto'. +# +# The last rule is to allow people to set the variable to an empty +# string and export it to decline testing the particular feature +# for versions both before and after this change. We used to treat +# both unset and empty variable as a signal for "do not test" and +# took any non-empty string as "please test". + +test_tristate () { + if eval "test x\"\${$1+isset}\" = xisset" + then + # explicitly set + eval " + case \"\$$1\" in + '') $1=false ;; + auto) ;; + *) $1=\$(test_normalize_bool \$$1 || echo true) ;; + esac + " + else + eval "$1=auto" + fi +} + +# Exit the test suite, either by skipping all remaining tests or by +# exiting with an error. If "$1" is "auto", we then we assume we were +# opportunistically trying to set up some tests and we skip. If it is +# "true", then we report a failure. +# +# The error/skip message should be given by $2. +# +test_skip_or_die () { + case "$1" in + auto) + skip_all=$2 + test_done + ;; + true) + error "$2" + ;; + *) + error "BUG: test tristate is '$1' (real error: $2)" + esac +} + +# The following mingw_* functions obey POSIX shell syntax, but are actually +# bash scripts, and are meant to be used only with bash on Windows. + +# A test_cmp function that treats LF and CRLF equal and avoids to fork +# diff when possible. +mingw_test_cmp () { + # Read text into shell variables and compare them. If the results + # are different, use regular diff to report the difference. + local test_cmp_a= test_cmp_b= + + # When text came from stdin (one argument is '-') we must feed it + # to diff. + local stdin_for_diff= + + # Since it is difficult to detect the difference between an + # empty input file and a failure to read the files, we go straight + # to diff if one of the inputs is empty. + if test -s "$1" && test -s "$2" + then + # regular case: both files non-empty + mingw_read_file_strip_cr_ test_cmp_a <"$1" + mingw_read_file_strip_cr_ test_cmp_b <"$2" + elif test -s "$1" && test "$2" = - + then + # read 2nd file from stdin + mingw_read_file_strip_cr_ test_cmp_a <"$1" + mingw_read_file_strip_cr_ test_cmp_b + stdin_for_diff='<<<"$test_cmp_b"' + elif test "$1" = - && test -s "$2" + then + # read 1st file from stdin + mingw_read_file_strip_cr_ test_cmp_a + mingw_read_file_strip_cr_ test_cmp_b <"$2" + stdin_for_diff='<<<"$test_cmp_a"' + fi + test -n "$test_cmp_a" && + test -n "$test_cmp_b" && + test "$test_cmp_a" = "$test_cmp_b" || + eval "diff -u \"\$@\" $stdin_for_diff" +} + +# $1 is the name of the shell variable to fill in +mingw_read_file_strip_cr_ () { + # Read line-wise using LF as the line separator + # and use IFS to strip CR. + local line + while : + do + if IFS=$'\r' read -r -d $'\n' line + then + # good + line=$line$'\n' + else + # we get here at EOF, but also if the last line + # was not terminated by LF; in the latter case, + # some text was read + if test -z "$line" + then + # EOF, really + break + fi + fi + eval "$1=\$$1\$line" + done +} diff --git a/t/test-lib.sh b/t/test-lib.sh index 0fa7dfde7b..87f327ff8b 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1,4 +1,4 @@ -#!/bin/sh +# Test framework for git. See t/README for usage. # # Copyright (c) 2005 Junio C Hamano # @@ -26,6 +26,10 @@ then # outside of t/, e.g. for running tests on the test library # itself. TEST_DIRECTORY=$(pwd) +else + # ensure that TEST_DIRECTORY is an absolute path so that it + # is valid even if the current working directory is changed + TEST_DIRECTORY=$(cd "$TEST_DIRECTORY" && pwd) || exit 1 fi if test -z "$TEST_OUTPUT_DIRECTORY" then @@ -104,6 +108,12 @@ export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME export EDITOR +if test -n "${TEST_GIT_INDEX_VERSION:+isset}" +then + GIT_INDEX_VERSION="$TEST_GIT_INDEX_VERSION" + export GIT_INDEX_VERSION +fi + # Add libc MALLOC and MALLOC_PERTURB test # only if we are not executing the test with valgrind if expr " $GIT_TEST_OPTS " : ".* --valgrind " >/dev/null || @@ -205,29 +215,17 @@ do --valgrind-only=*) valgrind_only=$(expr "z$1" : 'z[^=]*=\(.*\)') shift ;; - --valgrind-parallel=*) - valgrind_parallel=$(expr "z$1" : 'z[^=]*=\(.*\)') - shift ;; - --valgrind-only-stride=*) - valgrind_only_stride=$(expr "z$1" : 'z[^=]*=\(.*\)') - shift ;; - --valgrind-only-offset=*) - valgrind_only_offset=$(expr "z$1" : 'z[^=]*=\(.*\)') - shift ;; --tee) shift ;; # was handled already --root=*) root=$(expr "z$1" : 'z[^=]*=\(.*\)') shift ;; - --statusprefix=*) - statusprefix=$(expr "z$1" : 'z[^=]*=\(.*\)') - shift ;; *) echo "error: unknown test option '$1'" >&2; exit 1 ;; esac done -if test -n "$valgrind_only" || test -n "$valgrind_only_stride" +if test -n "$valgrind_only" then test -z "$valgrind" && valgrind=memcheck test -z "$verbose" && verbose_only="$valgrind_only" @@ -285,7 +283,7 @@ error "Test script did not set test_description." if test "$help" = "t" then - echo "$test_description" + printf '%s\n' "$test_description" exit 0 fi @@ -325,29 +323,29 @@ trap 'die' EXIT . "$TEST_DIRECTORY/test-lib-functions.sh" # You are not expected to call test_ok_ and test_failure_ directly, use -# the text_expect_* functions instead. +# the test_expect_* functions instead. test_ok_ () { test_success=$(($test_success + 1)) - say_color "" "${statusprefix}ok $test_count - $@" + say_color "" "ok $test_count - $@" } test_failure_ () { test_failure=$(($test_failure + 1)) - say_color error "${statusprefix}not ok $test_count - $1" + say_color error "not ok $test_count - $1" shift - echo "$@" | sed -e 's/^/# /' + printf '%s\n' "$*" | sed -e 's/^/# /' test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; } } test_known_broken_ok_ () { test_fixed=$(($test_fixed+1)) - say_color error "${statusprefix}ok $test_count - $@ # TODO known breakage vanished" + say_color error "ok $test_count - $@ # TODO known breakage vanished" } test_known_broken_failure_ () { test_broken=$(($test_broken+1)) - say_color warn "${statusprefix}not ok $test_count - $@ # TODO known breakage" + say_color warn "not ok $test_count - $@ # TODO known breakage" } test_debug () { @@ -377,9 +375,7 @@ maybe_teardown_verbose () { last_verbose=t maybe_setup_verbose () { test -z "$verbose_only" && return - if match_pattern_list $test_count $verbose_only || - { test -n "$valgrind_only_stride" && - expr $test_count "%" $valgrind_only_stride - $valgrind_only_offset = 0 >/dev/null; } + if match_pattern_list $test_count $verbose_only then exec 4>&2 3>&1 # Emit a delimiting blank line when going from @@ -403,7 +399,7 @@ maybe_teardown_valgrind () { maybe_setup_valgrind () { test -z "$GIT_VALGRIND" && return - if test -z "$valgrind_only" && test -z "$valgrind_only_stride" + if test -z "$valgrind_only" then GIT_VALGRIND_ENABLED=t return @@ -412,10 +408,6 @@ maybe_setup_valgrind () { if match_pattern_list $test_count $valgrind_only then GIT_VALGRIND_ENABLED=t - elif test -n "$valgrind_only_stride" && - expr $test_count "%" $valgrind_only_stride - $valgrind_only_offset = 0 >/dev/null - then - GIT_VALGRIND_ENABLED=t fi } @@ -477,8 +469,8 @@ test_skip () { of_prereq=" of $test_prereq" fi - say_color skip >&3 "${statusprefix}skipping test: $@" - say_color skip "${statusprefix}ok $test_count # skip $1 (missing $missing_prereq${of_prereq})" + say_color skip >&3 "skipping test: $@" + say_color skip "ok $test_count # skip $1 (missing $missing_prereq${of_prereq})" : true ;; *) @@ -495,8 +487,6 @@ test_at_end_hook_ () { test_done () { GIT_EXIT_OK=t - # Note: t0000 relies on $HARNESS_ACTIVE disabling the .counts - # output file if test -z "$HARNESS_ACTIVE" then test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results" @@ -516,11 +506,11 @@ test_done () { if test "$test_fixed" != 0 then - say_color error "${statusprefix}# $test_fixed known breakage(s) vanished; please update test(s)" + say_color error "# $test_fixed known breakage(s) vanished; please update test(s)" fi if test "$test_broken" != 0 then - say_color warn "${statusprefix}# still have $test_broken known breakage(s)" + say_color warn "# still have $test_broken known breakage(s)" fi if test "$test_broken" != 0 || test "$test_fixed" != 0 then @@ -543,9 +533,9 @@ test_done () { then if test $test_remaining -gt 0 then - say_color pass "${statusprefix}# passed all $msg" + say_color pass "# passed all $msg" fi - say "${statusprefix}1..$test_count$skip_all" + say "1..$test_count$skip_all" fi test -d "$remove_trash" && @@ -559,8 +549,8 @@ test_done () { *) if test $test_external_has_tap -eq 0 then - say_color error "${statusprefix}# failed $test_failure among $msg" - say "${statusprefix}1..$test_count" + say_color error "# failed $test_failure among $msg" + say "1..$test_count" fi exit 1 ;; @@ -568,9 +558,6 @@ test_done () { esac } - -# Set up a directory that we can put in PATH which redirects all git -# calls to 'valgrind git ...'. if test -n "$valgrind" then make_symlink () { @@ -594,11 +581,9 @@ then make_valgrind_symlink () { # handle only executables, unless they are shell libraries that - # need to be in the exec-path. We will just use "#!" as a - # guess for a shell-script, since we have no idea what the user - # may have configured as the shell path. + # need to be in the exec-path. test -x "$1" || - test "#!" = "$(head -c 2 <"$1")" || + test "# " = "$(head -c 2 <"$1")" || return; base=$(basename "$1") @@ -618,42 +603,33 @@ then make_symlink "$symlink_target" "$GIT_VALGRIND/bin/$base" || exit } - # In the case of --valgrind-parallel, we only need to do the - # wrapping once, in the main script. The worker children all - # have $valgrind_only_stride set, so we can skip based on that. - if test -z "$valgrind_only_stride" - then - # override all git executables in TEST_DIRECTORY/.. - GIT_VALGRIND=$TEST_DIRECTORY/valgrind - mkdir -p "$GIT_VALGRIND"/bin - for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-* - do - make_valgrind_symlink $file - done - # special-case the mergetools loadables - make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools" - OLDIFS=$IFS - IFS=: - for path in $PATH + # override all git executables in TEST_DIRECTORY/.. + GIT_VALGRIND=$TEST_DIRECTORY/valgrind + mkdir -p "$GIT_VALGRIND"/bin + for file in $GIT_BUILD_DIR/git* $GIT_BUILD_DIR/test-* + do + make_valgrind_symlink $file + done + # special-case the mergetools loadables + make_symlink "$GIT_BUILD_DIR"/mergetools "$GIT_VALGRIND/bin/mergetools" + OLDIFS=$IFS + IFS=: + for path in $PATH + do + ls "$path"/git-* 2> /dev/null | + while read file do - ls "$path"/git-* 2> /dev/null | - while read file - do - make_valgrind_symlink "$file" - done + make_valgrind_symlink "$file" done - IFS=$OLDIFS - fi + done + IFS=$OLDIFS PATH=$GIT_VALGRIND/bin:$PATH GIT_EXEC_PATH=$GIT_VALGRIND/bin export GIT_VALGRIND GIT_VALGRIND_MODE="$valgrind" export GIT_VALGRIND_MODE GIT_VALGRIND_ENABLED=t - if test -n "$valgrind_only" || test -n "$valgrind_only_stride" - then - GIT_VALGRIND_ENABLED= - fi + test -n "$valgrind_only" && GIT_VALGRIND_ENABLED= export GIT_VALGRIND_ENABLED elif test -n "$GIT_TEST_INSTALLED" then @@ -730,41 +706,6 @@ then else mkdir -p "$TRASH_DIRECTORY" fi - -# Gross hack to spawn N sub-instances of the tests in parallel, and -# summarize the results. Note that if this is enabled, the script -# terminates at the end of this 'if' block. -if test -n "$valgrind_parallel" -then - for i in $(test_seq 1 $valgrind_parallel) - do - root="$TRASH_DIRECTORY/vgparallel-$i" - mkdir "$root" - TEST_OUTPUT_DIRECTORY="$root" \ - ${SHELL_PATH} "$0" \ - --root="$root" --statusprefix="[$i] " \ - --valgrind="$valgrind" \ - --valgrind-only-stride="$valgrind_parallel" \ - --valgrind-only-offset="$i" & - pids="$pids $!" - done - trap "kill $pids" INT TERM HUP - wait $pids - trap - INT TERM HUP - for i in $(test_seq 1 $valgrind_parallel) - do - root="$TRASH_DIRECTORY/vgparallel-$i" - eval "$(cat "$root/test-results/$(basename "$0" .sh)"-*.counts | - sed 's/^\([a-z][a-z]*\) \([0-9][0-9]*\)/inner_\1=\2/')" - test_count=$(expr $test_count + $inner_total) - test_success=$(expr $test_success + $inner_success) - test_fixed=$(expr $test_fixed + $inner_fixed) - test_broken=$(expr $test_broken + $inner_broken) - test_failure=$(expr $test_failure + $inner_failed) - done - test_done -fi - # Use -P to resolve symlinks in our working directory so that the cwd # in subprocesses like git equals our $PWD (for pathname comparisons). cd -P "$TRASH_DIRECTORY" || exit 1 @@ -817,6 +758,7 @@ case $(uname -s) in test_set_prereq NOT_CYGWIN test_set_prereq SED_STRIPS_CR test_set_prereq GREP_STRIPS_CR + GIT_TEST_CMP=mingw_test_cmp ;; *CYGWIN*) test_set_prereq POSIXPERM @@ -894,6 +836,10 @@ test_lazy_prereq SYMLINKS ' ln -s x y && test -h y ' +test_lazy_prereq FILEMODE ' + test "$(git config --bool core.filemode)" = true +' + test_lazy_prereq CASE_INSENSITIVE_FS ' echo good >CamelCase && echo bad >camelcase && |