summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/Makefile11
-rw-r--r--t/README10
-rwxr-xr-xt/check-non-portable-shell.pl27
-rw-r--r--t/lib-gettext.sh6
-rw-r--r--t/lib-git-p4.sh64
-rw-r--r--t/lib-git-svn.sh2
-rw-r--r--t/lib-httpd.sh1
-rw-r--r--t/lib-httpd/apache.conf11
-rwxr-xr-xt/lib-httpd/broken-smart-http.sh11
-rw-r--r--t/perf/README2
-rwxr-xr-xt/t0000-basic.sh246
-rwxr-xr-xt/t0003-attributes.sh48
-rwxr-xr-xt/t0007-git-var.sh49
-rwxr-xr-xt/t0008-ignores.sh652
-rwxr-xr-xt/t0024-crlf-archive.sh10
-rwxr-xr-xt/t0030-stripspace.sh35
-rwxr-xr-xt/t0050-filesystem.sh52
-rwxr-xr-xt/t0060-path-utils.sh41
-rwxr-xr-xt/t0063-string-list.sh30
-rwxr-xr-xt/t1006-cat-file.sh4
-rwxr-xr-xt/t1020-subdirectory.sh12
-rwxr-xr-xt/t1300-repo-config.sh316
-rwxr-xr-xt/t1401-symbolic-ref.sh30
-rwxr-xr-xt/t1402-check-ref-format.sh6
-rwxr-xr-xt/t1450-fsck.sh31
-rwxr-xr-xt/t1504-ceiling-dirs.sh17
-rwxr-xr-xt/t1505-rev-parse-last.sh18
-rwxr-xr-xt/t1507-rev-parse-upstream.sh4
-rwxr-xr-xt/t1509/prepare-chroot.sh2
-rwxr-xr-xt/t1510-repo-setup.sh19
-rwxr-xr-xt/t2003-checkout-cache-mkdir.sh169
-rwxr-xr-xt/t2013-checkout-submodule.sh2
-rwxr-xr-xt/t2020-checkout-detach.sh1
-rwxr-xr-xt/t2203-add-intent.sh20
-rwxr-xr-xt/t3001-ls-files-others-exclude.sh24
-rwxr-xr-xt/t3070-wildmatch.sh238
-rwxr-xr-xt/t3200-branch.sh501
-rwxr-xr-xt/t3201-branch-contains.sh35
-rwxr-xr-xt/t3211-peel-ref.sh64
-rwxr-xr-xt/t3404-rebase-interactive.sh20
-rwxr-xr-xt/t3501-revert-cherry-pick.sh9
-rwxr-xr-xt/t3506-cherry-pick-ff.sh8
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh6
-rwxr-xr-xt/t3508-cherry-pick-many-commits.sh8
-rwxr-xr-xt/t3510-cherry-pick-sequence.sh6
-rwxr-xr-xt/t3600-rm.sh360
-rwxr-xr-xt/t3701-add-interactive.sh2
-rwxr-xr-xt/t4001-diff-rename.sh54
-rwxr-xr-xt/t4014-format-patch.sh112
-rwxr-xr-xt/t4018-diff-funcname.sh5
-rwxr-xr-xt/t4038-diff-combined.sh135
-rwxr-xr-xt/t4041-diff-submodule-option.sh509
-rwxr-xr-xt/t4042-diff-textconv-caching.sh8
-rwxr-xr-xt/t4055-diff-context.sh92
-rwxr-xr-xt/t4124-apply-ws-rule.sh28
-rwxr-xr-xt/t4150-am.sh2
-rwxr-xr-xt/t4201-shortlog.sh24
-rwxr-xr-xt/t4202-log.sh10
-rwxr-xr-xt/t4203-mailmap.sh154
-rwxr-xr-xt/t4208-log-magic-pathspec.sh17
-rwxr-xr-xt/t4210-log-i18n.sh58
-rwxr-xr-xt/t4300-merge-tree.sh44
-rwxr-xr-xt/t5000-tar-tree.sh74
-rwxr-xr-xt/t5002-archive-attr-pattern.sh84
-rwxr-xr-xt/t5003-archive-zip.sh131
-rw-r--r--t/t5003/infozip-symlinks.zipbin0 -> 328 bytes
-rwxr-xr-xt/t5004-archive-corner-cases.sh102
-rw-r--r--t/t5004/empty.zipbin0 -> 62 bytes
-rwxr-xr-xt/t5500-fetch-pack.sh54
-rwxr-xr-xt/t5512-ls-remote.sh12
-rwxr-xr-xt/t5516-fetch-push.sh56
-rwxr-xr-xt/t5535-fetch-push-symref.sh42
-rwxr-xr-xt/t5551-http-fetch.sh20
-rwxr-xr-xt/t5571-pre-push-hook.sh131
-rwxr-xr-xt/t5600-clone-fail-cleanup.sh12
-rwxr-xr-xt/t5704-bundle.sh10
-rwxr-xr-xt/t5800-remote-testpy.sh (renamed from t/t5800-remote-helpers.sh)35
-rwxr-xr-xt/t5801-remote-helpers.sh169
-rwxr-xr-xt/t6006-rev-list-format.sh63
-rwxr-xr-xt/t6009-rev-list-parent.sh13
-rwxr-xr-xt/t6030-bisect-porcelain.sh6
-rwxr-xr-xt/t6050-replace.sh11
-rwxr-xr-xt/t6130-pathspec-noglob.sh68
-rwxr-xr-xt/t7003-filter-branch.sh19
-rwxr-xr-xt/t7004-tag.sh12
-rwxr-xr-xt/t7060-wtstatus.sh1
-rwxr-xr-xt/t7061-wtstatus-ignore.sh146
-rwxr-xr-xt/t7062-wtstatus-ignorecase.sh20
-rwxr-xr-xt/t7102-reset.sh67
-rwxr-xr-xt/t7106-reset-unborn-branch.sh52
-rwxr-xr-xt/t7400-submodule-basic.sh76
-rwxr-xr-xt/t7402-submodule-rebase.sh30
-rwxr-xr-xt/t7403-submodule-sync.sh55
-rwxr-xr-xt/t7406-submodule-update.sh36
-rwxr-xr-xt/t7407-submodule-foreach.sh4
-rwxr-xr-xt/t7500/add-content-and-comment5
-rwxr-xr-xt/t7502-commit.sh119
-rwxr-xr-xt/t7505-prepare-commit-msg-hook.sh14
-rwxr-xr-xt/t7508-status.sh51
-rwxr-xr-xt/t7512-status-help.sh90
-rwxr-xr-xt/t7601-merge-pull-config.sh2
-rwxr-xr-xt/t7610-mergetool.sh2
-rwxr-xr-xt/t7811-grep-open.sh5
-rwxr-xr-xt/t9001-send-email.sh123
-rwxr-xr-xt/t9010-svn-fe.sh8
-rwxr-xr-xt/t9020-remote-svn.sh88
-rwxr-xr-xt/t9100-git-svn-basic.sh8
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh5
-rwxr-xr-xt/t9300-fast-import.sh8
-rwxr-xr-xt/t9350-fast-export.sh65
-rwxr-xr-xt/t9400-git-cvsserver-server.sh72
-rwxr-xr-xt/t9401-git-cvsserver-crlf.sh35
-rwxr-xr-xt/t9402-git-cvsserver-refs.sh551
-rwxr-xr-xt/t9502-gitweb-standalone-parse-output.sh2
-rwxr-xr-xt/t9604-cvsimport-timestamps.sh71
-rw-r--r--t/t9604/cvsroot/.gitattributes1
-rw-r--r--t/t9604/cvsroot/CVSROOT/.gitignore2
-rw-r--r--t/t9604/cvsroot/module/a,v264
-rwxr-xr-xt/t9700/test.pl6
-rwxr-xr-xt/t9800-git-p4-basic.sh39
-rwxr-xr-xt/t9802-git-p4-filetype.sh128
-rwxr-xr-xt/t9806-git-p4-options.sh161
-rwxr-xr-xt/t9807-git-p4-submit.sh14
-rwxr-xr-xt/t9809-git-p4-client-view.sh16
-rwxr-xr-xt/t9810-git-p4-rcs.sh24
-rwxr-xr-xt/t9812-git-p4-wildcards.sh37
-rwxr-xr-xt/t9814-git-p4-rename.sh35
-rwxr-xr-xt/t9815-git-p4-submit-fail.sh11
-rwxr-xr-xt/t9902-completion.sh164
-rwxr-xr-xt/t9903-bash-prompt.sh78
-rw-r--r--t/test-lib-functions.sh32
-rw-r--r--t/test-lib.sh56
-rwxr-xr-xt/test-terminal.perl2
133 files changed, 7179 insertions, 1318 deletions
diff --git a/t/Makefile b/t/Makefile
index 88e289fc8b..1923cc104b 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -6,16 +6,18 @@
-include ../config.mak.autogen
-include ../config.mak
-#GIT_TEST_OPTS=--verbose --debug
+#GIT_TEST_OPTS = --verbose --debug
SHELL_PATH ?= $(SHELL)
PERL_PATH ?= /usr/bin/perl
TAR ?= $(TAR)
RM ?= rm -f
PROVE ?= prove
DEFAULT_TEST_TARGET ?= test
+TEST_LINT ?= test-lint-duplicates test-lint-executable
# Shell quote;
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH))
T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh))
@@ -43,7 +45,7 @@ clean-except-prove-cache:
clean: clean-except-prove-cache
$(RM) .prove
-test-lint: test-lint-duplicates test-lint-executable
+test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax
test-lint-duplicates:
@dups=`echo $(T) | tr ' ' '\n' | sed 's/-.*//' | sort | uniq -d` && \
@@ -55,6 +57,9 @@ test-lint-executable:
test -z "$$bad" || { \
echo >&2 "non-executable tests:" $$bad; exit 1; }
+test-lint-shell-syntax:
+ @'$(PERL_PATH_SQ)' check-non-portable-shell.pl $(T)
+
aggregate-results-and-cleanup: $(T)
$(MAKE) aggregate-results
$(MAKE) clean
@@ -87,7 +92,7 @@ test-results:
mkdir -p test-results
test-results/git-smoke.tar.gz: test-results
- $(PERL_PATH) ./harness \
+ '$(PERL_PATH_SQ)' ./harness \
--archive="test-results/git-smoke.tar.gz" \
$(T)
diff --git a/t/README b/t/README
index e4128e5769..f8bf3ec318 100644
--- a/t/README
+++ b/t/README
@@ -86,7 +86,10 @@ appropriately before running "make".
--immediate::
This causes the test to immediately exit upon the first
- failed test.
+ failed test. Cleanup commands requested with
+ test_when_finished are not executed if the test failed,
+ in order to keep the state for inspection by the tester
+ to diagnose the bug.
--long-tests::
This causes additional long-running tests to be run (where
@@ -610,6 +613,11 @@ use these, and "test_set_prereq" for how to define your own.
The process retains the same pid across exec(2). See fb9a2bea for
details.
+ - PIPE
+
+ The filesystem we're on supports creation of FIFOs (named pipes)
+ via mkfifo(1).
+
- SYMLINKS
The filesystem we're on supports symbolic links. E.g. a FAT
diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
new file mode 100755
index 0000000000..8b5a71dc05
--- /dev/null
+++ b/t/check-non-portable-shell.pl
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+# Test t0000..t9999.sh for non portable shell scripts
+# This script can be called with one or more filenames as parameters
+
+use strict;
+use warnings;
+
+my $exit_code=0;
+
+sub err {
+ my $msg = shift;
+ print "$ARGV:$.: error: $msg: $_\n";
+ $exit_code = 1;
+}
+
+while (<>) {
+ chomp;
+ /^\s*sed\s+-i/ and err 'sed -i is not portable';
+ /^\s*echo\s+-n/ and err 'echo -n is not portable (please use printf)';
+ /^\s*declare\s+/ and err 'arrays/declare not portable';
+ /^\s*[^#]\s*which\s/ and err 'which is not portable (please use type)';
+ /test\s+[^=]*==/ and err '"test a == b" is not portable (please use =)';
+ # this resets our $. for each file
+ close ARGV if eof;
+}
+exit $exit_code;
diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh
index 0f76f6cdc0..ae8883a075 100644
--- a/t/lib-gettext.sh
+++ b/t/lib-gettext.sh
@@ -14,12 +14,14 @@ export GIT_TEXTDOMAINDIR GIT_PO_PATH
if test_have_prereq GETTEXT && ! test_have_prereq GETTEXT_POISON
then
# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
- is_IS_locale=$(locale -a | sed -n '/^is_IS\.[uU][tT][fF]-*8$/{
+ is_IS_locale=$(locale -a 2>/dev/null |
+ sed -n '/^is_IS\.[uU][tT][fF]-*8$/{
p
q
}')
# is_IS.ISO8859-1 on Solaris and FreeBSD, is_IS.iso88591 on Debian
- is_IS_iso_locale=$(locale -a | sed -n '/^is_IS\.[iI][sS][oO]8859-*1$/{
+ is_IS_iso_locale=$(locale -a 2>/dev/null |
+ sed -n '/^is_IS\.[iI][sS][oO]8859-*1$/{
p
q
}')
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index 7061dce7e5..2098b9ba05 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -8,7 +8,8 @@ TEST_NO_CREATE_REPO=NoThanks
. ./test-lib.sh
-if ! test_have_prereq PYTHON; then
+if ! test_have_prereq PYTHON
+then
skip_all='skipping git p4 tests; python not available'
test_done
fi
@@ -17,6 +18,24 @@ fi
test_done
}
+# On cygwin, the NT version of Perforce can be used. When giving
+# it paths, either on the command-line or in client specifications,
+# be sure to use the native windows form.
+#
+# Older versions of perforce were available compiled natively for
+# cygwin. Those do not accept native windows paths, so make sure
+# not to convert for them.
+native_path() {
+ path="$1" &&
+ if test_have_prereq CYGWIN && ! p4 -V | grep -q CYGWIN
+ then
+ path=$(cygpath --windows "$path")
+ else
+ path=$(test-path-utils real_path "$path")
+ fi &&
+ echo "$path"
+}
+
# Try to pick a unique port: guess a large number, then hope
# no more than one of each test is running.
#
@@ -32,7 +51,7 @@ P4EDITOR=:
export P4PORT P4CLIENT P4EDITOR
db="$TRASH_DIRECTORY/db"
-cli=$(test-path-utils real_path "$TRASH_DIRECTORY/cli")
+cli="$TRASH_DIRECTORY/cli"
git="$TRASH_DIRECTORY/git"
pidfile="$TRASH_DIRECTORY/p4d.pid"
@@ -40,8 +59,11 @@ start_p4d() {
mkdir -p "$db" "$cli" "$git" &&
rm -f "$pidfile" &&
(
- p4d -q -r "$db" -p $P4DPORT &
- echo $! >"$pidfile"
+ cd "$db" &&
+ {
+ p4d -q -p $P4DPORT &
+ echo $! >"$pidfile"
+ }
) &&
# This gives p4d a long time to start up, as it can be
@@ -74,15 +96,8 @@ start_p4d() {
fi
# build a client
- (
- cd "$cli" &&
- p4 client -i <<-EOF
- Client: client
- Description: client
- Root: $cli
- View: //depot/... //client/...
- EOF
- )
+ client_view "//depot/... //client/..." &&
+
return 0
}
@@ -123,13 +138,26 @@ marshal_dump() {
client_view() {
(
cat <<-EOF &&
- Client: client
- Description: client
+ Client: $P4CLIENT
+ Description: $P4CLIENT
Root: $cli
+ AltRoots: $(native_path "$cli")
+ LineEnd: unix
View:
EOF
- for arg ; do
- printf "\t$arg\n"
- done
+ printf "\t%s\n" "$@"
) | p4 client -i
}
+
+is_cli_file_writeable() {
+ # cygwin version of p4 does not set read-only attr,
+ # will be marked 444 but -w is true
+ file="$1" &&
+ if test_have_prereq CYGWIN && p4 -V | grep -q CYGWIN
+ then
+ stat=$(stat --format=%a "$file") &&
+ test $stat = 644
+ else
+ test -w "$file"
+ fi
+}
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index 199f22c231..c5e55b190b 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -148,7 +148,7 @@ stop_httpd () {
convert_to_rev_db () {
"$PERL_PATH" -w -- - "$@" <<\EOF
use strict;
-@ARGV == 2 or die "Usage: convert_to_rev_db <input> <output>";
+@ARGV == 2 or die "usage: convert_to_rev_db <input> <output>";
open my $wr, '+>', $ARGV[1] or die "$!: couldn't open: $ARGV[1]";
open my $rd, '<', $ARGV[0] or die "$!: couldn't open: $ARGV[0]";
my $size = (stat($rd))[7];
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 02f442bfad..895b9258b0 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -80,6 +80,7 @@ fi
prepare_httpd() {
mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH"
cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH"
+ cp "$TEST_PATH"/broken-smart-http.sh "$HTTPD_ROOT_PATH"
ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules"
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 49d5d877ce..938b4cf803 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -62,9 +62,13 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_COMMITTER_EMAIL custom@example.com
</LocationMatch>
ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
+ScriptAlias /broken_smart/ broken-smart-http.sh/
<Directory ${GIT_EXEC_PATH}>
Options FollowSymlinks
</Directory>
+<Files broken-smart-http.sh>
+ Options ExecCGI
+</Files>
<Files ${GIT_EXEC_PATH}/git-http-backend>
Options ExecCGI
</Files>
@@ -99,6 +103,13 @@ SSLEngine On
Require valid-user
</LocationMatch>
+<LocationMatch "^/auth-fetch/.*/git-upload-pack$">
+ AuthType Basic
+ AuthName "git-auth"
+ AuthUserFile passwd
+ Require valid-user
+</LocationMatch>
+
<IfDefine DAV>
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
diff --git a/t/lib-httpd/broken-smart-http.sh b/t/lib-httpd/broken-smart-http.sh
new file mode 100755
index 0000000000..f7ebfffa80
--- /dev/null
+++ b/t/lib-httpd/broken-smart-http.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+printf "Content-Type: text/%s\n" "html"
+echo
+printf "%s\n" "001e# service=git-upload-pack"
+printf "%s" "0000"
+printf "%s%c%s%s\n" \
+ "00a58681d9f286a48b08f37b3a095330da16689e3693 HEAD" \
+ 0 \
+ " include-tag multi_ack_detailed multi_ack ofs-delta" \
+ " side-band side-band-64k thin-pack no-progress shallow no-done "
+printf "%s" "0000"
diff --git a/t/perf/README b/t/perf/README
index b2dbad4d50..c552f561bf 100644
--- a/t/perf/README
+++ b/t/perf/README
@@ -56,7 +56,7 @@ You can set the following variables (also in your config.mak):
GIT_PERF_REPEAT_COUNT
Number of times a test should be repeated for best-of-N
- measurements. Defaults to 5.
+ measurements. Defaults to 3.
GIT_PERF_MAKE_OPTS
Options to use when automatically building a git tree for
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 08677df10e..cefe33d6d1 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -45,39 +45,176 @@ test_expect_failure 'pretend we have a known breakage' '
false
'
-test_expect_success 'pretend we have fixed a known breakage (run in sub test-lib)' "
- mkdir passing-todo &&
- (cd passing-todo &&
- cat >passing-todo.sh <<-EOF &&
- #!$SHELL_PATH
-
- test_description='A passing TODO test
+run_sub_test_lib_test () {
+ name="$1" descr="$2" # stdin is the body of the test code
+ mkdir "$name" &&
+ (
+ cd "$name" &&
+ cat >"$name.sh" <<-EOF &&
+ #!$SHELL_PATH
+
+ test_description='$descr (run in sub test-lib)
+
+ This is run in a sub test-lib so that we do not get incorrect
+ passing metrics
+ '
+
+ # Point to the t/test-lib.sh, which isn't in ../ as usual
+ . "\$TEST_DIRECTORY"/test-lib.sh
+ EOF
+ cat >>"$name.sh" &&
+ chmod +x "$name.sh" &&
+ export TEST_DIRECTORY &&
+ ./"$name.sh" >out 2>err
+ )
+}
- This is run in a sub test-lib so that we do not get incorrect
- passing metrics
- '
+check_sub_test_lib_test () {
+ name="$1" # stdin is the expected output from the test
+ (
+ cd "$name" &&
+ ! test -s err &&
+ sed -e 's/^> //' -e 's/Z$//' >expect &&
+ test_cmp expect out
+ )
+}
+
+test_expect_success 'pretend we have a fully passing test suite' "
+ run_sub_test_lib_test full-pass '3 passing tests' <<-\\EOF &&
+ for i in 1 2 3
+ do
+ test_expect_success \"passing test #\$i\" 'true'
+ done
+ test_done
+ EOF
+ check_sub_test_lib_test full-pass <<-\\EOF
+ > ok 1 - passing test #1
+ > ok 2 - passing test #2
+ > ok 3 - passing test #3
+ > # passed all 3 test(s)
+ > 1..3
+ EOF
+"
- # Point to the t/test-lib.sh, which isn't in ../ as usual
- TEST_DIRECTORY=\"$TEST_DIRECTORY\"
- . \"\$TEST_DIRECTORY\"/test-lib.sh
+test_expect_success 'pretend we have a partially passing test suite' "
+ test_must_fail run_sub_test_lib_test \
+ partial-pass '2/3 tests passing' <<-\\EOF &&
+ test_expect_success 'passing test #1' 'true'
+ test_expect_success 'failing test #2' 'false'
+ test_expect_success 'passing test #3' 'true'
+ test_done
+ EOF
+ check_sub_test_lib_test partial-pass <<-\\EOF
+ > ok 1 - passing test #1
+ > not ok 2 - failing test #2
+ # false
+ > ok 3 - passing test #3
+ > # failed 1 among 3 test(s)
+ > 1..3
+ EOF
+"
- test_expect_failure 'pretend we have fixed a known breakage' '
- :
- '
+test_expect_success 'pretend we have a known breakage' "
+ run_sub_test_lib_test failing-todo 'A failing TODO test' <<-\\EOF &&
+ test_expect_success 'passing test' 'true'
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_done
+ EOF
+ check_sub_test_lib_test failing-todo <<-\\EOF
+ > ok 1 - passing test
+ > not ok 2 - pretend we have a known breakage # TODO known breakage
+ > # still have 1 known breakage(s)
+ > # passed all remaining 1 test(s)
+ > 1..2
+ EOF
+"
+test_expect_success 'pretend we have fixed a known breakage' "
+ run_sub_test_lib_test passing-todo 'A passing TODO test' <<-\\EOF &&
+ test_expect_failure 'pretend we have fixed a known breakage' 'true'
test_done
EOF
- chmod +x passing-todo.sh &&
- ./passing-todo.sh >out 2>err &&
- ! test -s err &&
- sed -e 's/^> //' >expect <<-\\EOF &&
- > ok 1 - pretend we have fixed a known breakage # TODO known breakage
- > # fixed 1 known breakage(s)
- > # passed all 1 test(s)
+ check_sub_test_lib_test passing-todo <<-\\EOF
+ > ok 1 - pretend we have fixed a known breakage # TODO known breakage vanished
+ > # 1 known breakage(s) vanished; please update test(s)
> 1..1
EOF
- test_cmp expect out)
"
+
+test_expect_success 'pretend we have fixed one of two known breakages (run in sub test-lib)' "
+ run_sub_test_lib_test partially-passing-todos \
+ '2 TODO tests, one passing' <<-\\EOF &&
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_expect_success 'pretend we have a passing test' 'true'
+ test_expect_failure 'pretend we have fixed another known breakage' 'true'
+ test_done
+ EOF
+ check_sub_test_lib_test partially-passing-todos <<-\\EOF
+ > not ok 1 - pretend we have a known breakage # TODO known breakage
+ > ok 2 - pretend we have a passing test
+ > ok 3 - pretend we have fixed another known breakage # TODO known breakage vanished
+ > # 1 known breakage(s) vanished; please update test(s)
+ > # still have 1 known breakage(s)
+ > # passed all remaining 1 test(s)
+ > 1..3
+ EOF
+"
+
+test_expect_success 'pretend we have a pass, fail, and known breakage' "
+ test_must_fail run_sub_test_lib_test \
+ mixed-results1 'mixed results #1' <<-\\EOF &&
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'failing test' 'false'
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_done
+ EOF
+ check_sub_test_lib_test mixed-results1 <<-\\EOF
+ > ok 1 - passing test
+ > not ok 2 - failing test
+ > # false
+ > not ok 3 - pretend we have a known breakage # TODO known breakage
+ > # still have 1 known breakage(s)
+ > # failed 1 among remaining 2 test(s)
+ > 1..3
+ EOF
+"
+
+test_expect_success 'pretend we have a mix of all possible results' "
+ test_must_fail run_sub_test_lib_test \
+ mixed-results2 'mixed results #2' <<-\\EOF &&
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'passing test' 'true'
+ test_expect_success 'failing test' 'false'
+ test_expect_success 'failing test' 'false'
+ test_expect_success 'failing test' 'false'
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_expect_failure 'pretend we have a known breakage' 'false'
+ test_expect_failure 'pretend we have fixed a known breakage' 'true'
+ test_done
+ EOF
+ check_sub_test_lib_test mixed-results2 <<-\\EOF
+ > ok 1 - passing test
+ > ok 2 - passing test
+ > ok 3 - passing test
+ > ok 4 - passing test
+ > not ok 5 - failing test
+ > # false
+ > not ok 6 - failing test
+ > # false
+ > not ok 7 - failing test
+ > # false
+ > not ok 8 - pretend we have a known breakage # TODO known breakage
+ > not ok 9 - pretend we have a known breakage # TODO known breakage
+ > ok 10 - pretend we have fixed a known breakage # TODO known breakage vanished
+ > # 1 known breakage(s) vanished; please update test(s)
+ > # still have 2 known breakage(s)
+ > # failed 3 among remaining 7 test(s)
+ > 1..10
+ EOF
+"
+
test_set_prereq HAVEIT
haveit=no
test_expect_success HAVEIT 'test runs if prerequisite is satisfied' '
@@ -115,6 +252,38 @@ then
exit 1
fi
+test_lazy_prereq LAZY_TRUE true
+havetrue=no
+test_expect_success LAZY_TRUE 'test runs if lazy prereq is satisfied' '
+ havetrue=yes
+'
+donthavetrue=yes
+test_expect_success !LAZY_TRUE 'missing lazy prereqs skip tests' '
+ donthavetrue=no
+'
+
+if test "$havetrue$donthavetrue" != yesyes
+then
+ say 'bug in test framework: lazy prerequisites do not work'
+ exit 1
+fi
+
+test_lazy_prereq LAZY_FALSE false
+nothavefalse=no
+test_expect_success !LAZY_FALSE 'negative lazy prereqs checked' '
+ nothavefalse=yes
+'
+havefalse=yes
+test_expect_success LAZY_FALSE 'missing negative lazy prereqs will skip' '
+ havefalse=no
+'
+
+if test "$nothavefalse$havefalse" != yesyes
+then
+ say 'bug in test framework: negative lazy prerequisites do not work'
+ exit 1
+fi
+
clean=no
test_expect_success 'tests clean up after themselves' '
test_when_finished clean=yes
@@ -127,19 +296,8 @@ then
fi
test_expect_success 'tests clean up even on failures' "
- mkdir failing-cleanup &&
- (
- cd failing-cleanup &&
-
- cat >failing-cleanup.sh <<-EOF &&
- #!$SHELL_PATH
-
- test_description='Failing tests with cleanup commands'
-
- # Point to the t/test-lib.sh, which isn't in ../ as usual
- TEST_DIRECTORY=\"$TEST_DIRECTORY\"
- . \"\$TEST_DIRECTORY\"/test-lib.sh
-
+ test_must_fail run_sub_test_lib_test \
+ failing-cleanup 'Failing tests with cleanup commands' <<-\\EOF &&
test_expect_success 'tests clean up even after a failure' '
touch clean-after-failure &&
test_when_finished rm clean-after-failure &&
@@ -149,29 +307,21 @@ test_expect_success 'tests clean up even on failures' "
test_when_finished \"(exit 2)\"
'
test_done
-
EOF
-
- chmod +x failing-cleanup.sh &&
- test_must_fail ./failing-cleanup.sh >out 2>err &&
- ! test -s err &&
- ! test -f \"trash directory.failing-cleanup/clean-after-failure\" &&
- sed -e 's/Z$//' -e 's/^> //' >expect <<-\\EOF &&
- > not ok - 1 tests clean up even after a failure
+ check_sub_test_lib_test failing-cleanup <<-\\EOF
+ > not ok 1 - tests clean up even after a failure
> # Z
> # touch clean-after-failure &&
> # test_when_finished rm clean-after-failure &&
> # (exit 1)
> # Z
- > not ok - 2 failure to clean up causes the test to fail
+ > not ok 2 - failure to clean up causes the test to fail
> # Z
> # test_when_finished \"(exit 2)\"
> # Z
> # failed 2 among 2 test(s)
> 1..2
EOF
- test_cmp expect out
- )
"
################################################################
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index febc45c9cc..0b98b6f8d0 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -196,6 +196,54 @@ test_expect_success 'root subdir attribute test' '
attr_check subdir/a/i unspecified
'
+test_expect_success 'negative patterns' '
+ echo "!f test=bar" >.gitattributes &&
+ git check-attr test -- '"'"'!f'"'"' 2>errors &&
+ test_i18ngrep "Negative patterns are ignored" errors
+'
+
+test_expect_success 'patterns starting with exclamation' '
+ echo "\!f test=foo" >.gitattributes &&
+ attr_check "!f" foo
+'
+
+test_expect_success '"**" test' '
+ echo "**/f foo=bar" >.gitattributes &&
+ cat <<\EOF >expect &&
+f: foo: bar
+a/f: foo: bar
+a/b/f: foo: bar
+a/b/c/f: foo: bar
+EOF
+ git check-attr foo -- "f" >actual 2>err &&
+ git check-attr foo -- "a/f" >>actual 2>>err &&
+ git check-attr foo -- "a/b/f" >>actual 2>>err &&
+ git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
+ test_cmp expect actual &&
+ test_line_count = 0 err
+'
+
+test_expect_success '"**" with no slashes test' '
+ echo "a**f foo=bar" >.gitattributes &&
+ git check-attr foo -- "f" >actual &&
+ cat <<\EOF >expect &&
+f: foo: unspecified
+af: foo: bar
+axf: foo: bar
+a/f: foo: unspecified
+a/b/f: foo: unspecified
+a/b/c/f: foo: unspecified
+EOF
+ git check-attr foo -- "f" >actual 2>err &&
+ git check-attr foo -- "af" >>actual 2>err &&
+ git check-attr foo -- "axf" >>actual 2>err &&
+ git check-attr foo -- "a/f" >>actual 2>>err &&
+ git check-attr foo -- "a/b/f" >>actual 2>>err &&
+ git check-attr foo -- "a/b/c/f" >>actual 2>>err &&
+ test_cmp expect actual &&
+ test_line_count = 0 err
+'
+
test_expect_success 'setup bare' '
git clone --bare . bare.git &&
cd bare.git
diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh
new file mode 100755
index 0000000000..5868a87352
--- /dev/null
+++ b/t/t0007-git-var.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='basic sanity checks for git var'
+. ./test-lib.sh
+
+test_expect_success 'get GIT_AUTHOR_IDENT' '
+ test_tick &&
+ echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE" >expect &&
+ git var GIT_AUTHOR_IDENT >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'get GIT_COMMITTER_IDENT' '
+ test_tick &&
+ echo "$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" >expect &&
+ git var GIT_COMMITTER_IDENT >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success !AUTOIDENT 'requested identites are strict' '
+ (
+ sane_unset GIT_COMMITTER_NAME &&
+ sane_unset GIT_COMMITTER_EMAIL &&
+ test_must_fail git var GIT_COMMITTER_IDENT
+ )
+'
+
+# For git var -l, we check only a representative variable;
+# testing the whole output would make our test too brittle with
+# respect to unrelated changes in the test suite's environment.
+test_expect_success 'git var -l lists variables' '
+ git var -l >actual &&
+ echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE" >expect &&
+ sed -n s/GIT_AUTHOR_IDENT=//p <actual >actual.author &&
+ test_cmp expect actual.author
+'
+
+test_expect_success 'git var -l lists config' '
+ git var -l >actual &&
+ echo false >expect &&
+ sed -n s/core\\.bare=//p <actual >actual.bare &&
+ test_cmp expect actual.bare
+'
+
+test_expect_success 'listing and asking for variables are exclusive' '
+ test_must_fail git var -l GIT_COMMITTER_IDENT
+'
+
+test_done
diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh
new file mode 100755
index 0000000000..9c1bde1fd6
--- /dev/null
+++ b/t/t0008-ignores.sh
@@ -0,0 +1,652 @@
+#!/bin/sh
+
+test_description=check-ignore
+
+. ./test-lib.sh
+
+init_vars () {
+ global_excludes="$(pwd)/global-excludes"
+}
+
+enable_global_excludes () {
+ init_vars &&
+ git config core.excludesfile "$global_excludes"
+}
+
+expect_in () {
+ dest="$HOME/expected-$1" text="$2"
+ if test -z "$text"
+ then
+ >"$dest" # avoid newline
+ else
+ echo "$text" >"$dest"
+ fi
+}
+
+expect () {
+ expect_in stdout "$1"
+}
+
+expect_from_stdin () {
+ cat >"$HOME/expected-stdout"
+}
+
+test_stderr () {
+ expected="$1"
+ expect_in stderr "$1" &&
+ test_cmp "$HOME/expected-stderr" "$HOME/stderr"
+}
+
+stderr_contains () {
+ regexp="$1"
+ if grep "$regexp" "$HOME/stderr"
+ then
+ return 0
+ else
+ echo "didn't find /$regexp/ in $HOME/stderr"
+ cat "$HOME/stderr"
+ return 1
+ fi
+}
+
+stderr_empty_on_success () {
+ expect_code="$1"
+ if test $expect_code = 0
+ then
+ test_stderr ""
+ else
+ # If we expect failure then stderr might or might not be empty
+ # due to --quiet - the caller can check its contents
+ return 0
+ fi
+}
+
+test_check_ignore () {
+ args="$1" expect_code="${2:-0}" global_args="$3"
+
+ init_vars &&
+ rm -f "$HOME/stdout" "$HOME/stderr" "$HOME/cmd" &&
+ echo git $global_args check-ignore $quiet_opt $verbose_opt $args \
+ >"$HOME/cmd" &&
+ test_expect_code "$expect_code" \
+ git $global_args check-ignore $quiet_opt $verbose_opt $args \
+ >"$HOME/stdout" 2>"$HOME/stderr" &&
+ test_cmp "$HOME/expected-stdout" "$HOME/stdout" &&
+ stderr_empty_on_success "$expect_code"
+}
+
+# Runs the same code with 3 different levels of output verbosity,
+# expecting success each time. Takes advantage of the fact that
+# check-ignore --verbose output is the same as normal output except
+# for the extra first column.
+#
+# Arguments:
+# - (optional) prereqs for this test, e.g. 'SYMLINKS'
+# - test name
+# - output to expect from -v / --verbose mode
+# - code to run (should invoke test_check_ignore)
+test_expect_success_multi () {
+ prereq=
+ if test $# -eq 4
+ then
+ prereq=$1
+ shift
+ fi
+ testname="$1" expect_verbose="$2" code="$3"
+
+ expect=$( echo "$expect_verbose" | sed -e 's/.* //' )
+
+ test_expect_success $prereq "$testname" '
+ expect "$expect" &&
+ eval "$code"
+ '
+
+ for quiet_opt in '-q' '--quiet'
+ do
+ test_expect_success $prereq "$testname${quiet_opt:+ with $quiet_opt}" "
+ expect '' &&
+ $code
+ "
+ done
+ quiet_opt=
+
+ for verbose_opt in '-v' '--verbose'
+ do
+ test_expect_success $prereq "$testname${verbose_opt:+ with $verbose_opt}" "
+ expect '$expect_verbose' &&
+ $code
+ "
+ done
+ verbose_opt=
+}
+
+test_expect_success 'setup' '
+ init_vars &&
+ mkdir -p a/b/ignored-dir a/submodule b &&
+ if test_have_prereq SYMLINKS
+ then
+ ln -s b a/symlink
+ fi &&
+ (
+ cd a/submodule &&
+ git init &&
+ echo a >a &&
+ git add a &&
+ git commit -m"commit in submodule"
+ ) &&
+ git add a/submodule &&
+ cat <<-\EOF >.gitignore &&
+ one
+ ignored-*
+ top-level-dir/
+ EOF
+ for dir in . a
+ do
+ : >$dir/not-ignored &&
+ : >$dir/ignored-and-untracked &&
+ : >$dir/ignored-but-in-index
+ done &&
+ git add -f ignored-but-in-index a/ignored-but-in-index &&
+ cat <<-\EOF >a/.gitignore &&
+ two*
+ *three
+ EOF
+ cat <<-\EOF >a/b/.gitignore &&
+ four
+ five
+ # this comment should affect the line numbers
+ six
+ ignored-dir/
+ # and so should this blank line:
+
+ !on*
+ !two
+ EOF
+ echo "seven" >a/b/ignored-dir/.gitignore &&
+ test -n "$HOME" &&
+ cat <<-\EOF >"$global_excludes" &&
+ globalone
+ !globaltwo
+ globalthree
+ EOF
+ cat <<-\EOF >>.git/info/exclude
+ per-repo
+ EOF
+'
+
+############################################################################
+#
+# test invalid inputs
+
+test_expect_success_multi '. corner-case' '' '
+ test_check_ignore . 1
+'
+
+test_expect_success_multi 'empty command line' '' '
+ test_check_ignore "" 128 &&
+ stderr_contains "fatal: no path specified"
+'
+
+test_expect_success_multi '--stdin with empty STDIN' '' '
+ test_check_ignore "--stdin" 1 </dev/null &&
+ if test -n "$quiet_opt"; then
+ test_stderr ""
+ else
+ test_stderr "no pathspec given."
+ fi
+'
+
+test_expect_success '-q with multiple args' '
+ expect "" &&
+ test_check_ignore "-q one two" 128 &&
+ stderr_contains "fatal: --quiet is only valid with a single pathname"
+'
+
+test_expect_success '--quiet with multiple args' '
+ expect "" &&
+ test_check_ignore "--quiet one two" 128 &&
+ stderr_contains "fatal: --quiet is only valid with a single pathname"
+'
+
+for verbose_opt in '-v' '--verbose'
+do
+ for quiet_opt in '-q' '--quiet'
+ do
+ test_expect_success "$quiet_opt $verbose_opt" "
+ expect '' &&
+ test_check_ignore '$quiet_opt $verbose_opt foo' 128 &&
+ stderr_contains 'fatal: cannot have both --quiet and --verbose'
+ "
+ done
+done
+
+test_expect_success '--quiet with multiple args' '
+ expect "" &&
+ test_check_ignore "--quiet one two" 128 &&
+ stderr_contains "fatal: --quiet is only valid with a single pathname"
+'
+
+test_expect_success_multi 'erroneous use of --' '' '
+ test_check_ignore "--" 128 &&
+ stderr_contains "fatal: no path specified"
+'
+
+test_expect_success_multi '--stdin with superfluous arg' '' '
+ test_check_ignore "--stdin foo" 128 &&
+ stderr_contains "fatal: cannot specify pathnames with --stdin"
+'
+
+test_expect_success_multi '--stdin -z with superfluous arg' '' '
+ test_check_ignore "--stdin -z foo" 128 &&
+ stderr_contains "fatal: cannot specify pathnames with --stdin"
+'
+
+test_expect_success_multi '-z without --stdin' '' '
+ test_check_ignore "-z" 128 &&
+ stderr_contains "fatal: -z only makes sense with --stdin"
+'
+
+test_expect_success_multi '-z without --stdin and superfluous arg' '' '
+ test_check_ignore "-z foo" 128 &&
+ stderr_contains "fatal: -z only makes sense with --stdin"
+'
+
+test_expect_success_multi 'needs work tree' '' '
+ (
+ cd .git &&
+ test_check_ignore "foo" 128
+ ) &&
+ stderr_contains "fatal: This operation must be run in a work tree"
+'
+
+############################################################################
+#
+# test standard ignores
+
+# First make sure that the presence of a file in the working tree
+# does not impact results, but that the presence of a file in the
+# index does.
+
+for subdir in '' 'a/'
+do
+ if test -z "$subdir"
+ then
+ where="at top-level"
+ else
+ where="in subdir $subdir"
+ fi
+
+ test_expect_success_multi "non-existent file $where not ignored" '' "
+ test_check_ignore '${subdir}non-existent' 1
+ "
+
+ test_expect_success_multi "non-existent file $where ignored" \
+ ".gitignore:1:one ${subdir}one" "
+ test_check_ignore '${subdir}one'
+ "
+
+ test_expect_success_multi "existing untracked file $where not ignored" '' "
+ test_check_ignore '${subdir}not-ignored' 1
+ "
+
+ test_expect_success_multi "existing tracked file $where not ignored" '' "
+ test_check_ignore '${subdir}ignored-but-in-index' 1
+ "
+
+ test_expect_success_multi "existing untracked file $where ignored" \
+ ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" "
+ test_check_ignore '${subdir}ignored-and-untracked'
+ "
+done
+
+# Having established the above, from now on we mostly test against
+# files which do not exist in the working tree or index.
+
+test_expect_success 'sub-directory local ignore' '
+ expect "a/3-three" &&
+ test_check_ignore "a/3-three a/three-not-this-one"
+'
+
+test_expect_success 'sub-directory local ignore with --verbose' '
+ expect "a/.gitignore:2:*three a/3-three" &&
+ test_check_ignore "--verbose a/3-three a/three-not-this-one"
+'
+
+test_expect_success 'local ignore inside a sub-directory' '
+ expect "3-three" &&
+ (
+ cd a &&
+ test_check_ignore "3-three three-not-this-one"
+ )
+'
+test_expect_success 'local ignore inside a sub-directory with --verbose' '
+ expect "a/.gitignore:2:*three 3-three" &&
+ (
+ cd a &&
+ test_check_ignore "--verbose 3-three three-not-this-one"
+ )
+'
+
+test_expect_success_multi 'nested include' \
+ 'a/b/.gitignore:8:!on* a/b/one' '
+ test_check_ignore "a/b/one"
+'
+
+############################################################################
+#
+# test ignored sub-directories
+
+test_expect_success_multi 'ignored sub-directory' \
+ 'a/b/.gitignore:5:ignored-dir/ a/b/ignored-dir' '
+ test_check_ignore "a/b/ignored-dir"
+'
+
+test_expect_success 'multiple files inside ignored sub-directory' '
+ expect_from_stdin <<-\EOF &&
+ a/b/ignored-dir/foo
+ a/b/ignored-dir/twoooo
+ a/b/ignored-dir/seven
+ EOF
+ test_check_ignore "a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
+'
+
+test_expect_success 'multiple files inside ignored sub-directory with -v' '
+ expect_from_stdin <<-\EOF &&
+ a/b/.gitignore:5:ignored-dir/ a/b/ignored-dir/foo
+ a/b/.gitignore:5:ignored-dir/ a/b/ignored-dir/twoooo
+ a/b/.gitignore:5:ignored-dir/ a/b/ignored-dir/seven
+ EOF
+ test_check_ignore "-v a/b/ignored-dir/foo a/b/ignored-dir/twoooo a/b/ignored-dir/seven"
+'
+
+test_expect_success 'cd to ignored sub-directory' '
+ expect_from_stdin <<-\EOF &&
+ foo
+ twoooo
+ ../one
+ seven
+ ../../one
+ EOF
+ (
+ cd a/b/ignored-dir &&
+ test_check_ignore "foo twoooo ../one seven ../../one"
+ )
+'
+
+test_expect_success 'cd to ignored sub-directory with -v' '
+ expect_from_stdin <<-\EOF &&
+ a/b/.gitignore:5:ignored-dir/ foo
+ a/b/.gitignore:5:ignored-dir/ twoooo
+ a/b/.gitignore:8:!on* ../one
+ a/b/.gitignore:5:ignored-dir/ seven
+ .gitignore:1:one ../../one
+ EOF
+ (
+ cd a/b/ignored-dir &&
+ test_check_ignore "-v foo twoooo ../one seven ../../one"
+ )
+'
+
+############################################################################
+#
+# test handling of symlinks
+
+test_expect_success_multi SYMLINKS 'symlink' '' '
+ test_check_ignore "a/symlink" 1
+'
+
+test_expect_success_multi SYMLINKS 'beyond a symlink' '' '
+ test_check_ignore "a/symlink/foo" 128 &&
+ test_stderr "fatal: '\''a/symlink/foo'\'' is beyond a symbolic link"
+'
+
+test_expect_success_multi SYMLINKS 'beyond a symlink from subdirectory' '' '
+ (
+ cd a &&
+ test_check_ignore "symlink/foo" 128
+ ) &&
+ test_stderr "fatal: '\''symlink/foo'\'' is beyond a symbolic link"
+'
+
+############################################################################
+#
+# test handling of submodules
+
+test_expect_success_multi 'submodule' '' '
+ test_check_ignore "a/submodule/one" 128 &&
+ test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
+'
+
+test_expect_success_multi 'submodule from subdirectory' '' '
+ (
+ cd a &&
+ test_check_ignore "submodule/one" 128
+ ) &&
+ test_stderr "fatal: Path '\''a/submodule/one'\'' is in submodule '\''a/submodule'\''"
+'
+
+############################################################################
+#
+# test handling of global ignore files
+
+test_expect_success 'global ignore not yet enabled' '
+ expect_from_stdin <<-\EOF &&
+ .git/info/exclude:7:per-repo per-repo
+ a/.gitignore:2:*three a/globalthree
+ .git/info/exclude:7:per-repo a/per-repo
+ EOF
+ test_check_ignore "-v globalone per-repo a/globalthree a/per-repo not-ignored a/globaltwo"
+'
+
+test_expect_success 'global ignore' '
+ enable_global_excludes &&
+ expect_from_stdin <<-\EOF &&
+ globalone
+ per-repo
+ globalthree
+ a/globalthree
+ a/per-repo
+ globaltwo
+ EOF
+ test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
+'
+
+test_expect_success 'global ignore with -v' '
+ enable_global_excludes &&
+ expect_from_stdin <<-EOF &&
+ $global_excludes:1:globalone globalone
+ .git/info/exclude:7:per-repo per-repo
+ $global_excludes:3:globalthree globalthree
+ a/.gitignore:2:*three a/globalthree
+ .git/info/exclude:7:per-repo a/per-repo
+ $global_excludes:2:!globaltwo globaltwo
+ EOF
+ test_check_ignore "-v globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo"
+'
+
+############################################################################
+#
+# test --stdin
+
+cat <<-\EOF >stdin
+ one
+ not-ignored
+ a/one
+ a/not-ignored
+ a/b/on
+ a/b/one
+ a/b/one one
+ "a/b/one two"
+ "a/b/one\"three"
+ a/b/not-ignored
+ a/b/two
+ a/b/twooo
+ globaltwo
+ a/globaltwo
+ a/b/globaltwo
+ b/globaltwo
+EOF
+cat <<-\EOF >expected-default
+ one
+ a/one
+ a/b/on
+ a/b/one
+ a/b/one one
+ a/b/one two
+ "a/b/one\"three"
+ a/b/two
+ a/b/twooo
+ globaltwo
+ a/globaltwo
+ a/b/globaltwo
+ b/globaltwo
+EOF
+cat <<-EOF >expected-verbose
+ .gitignore:1:one one
+ .gitignore:1:one a/one
+ a/b/.gitignore:8:!on* a/b/on
+ a/b/.gitignore:8:!on* a/b/one
+ a/b/.gitignore:8:!on* a/b/one one
+ a/b/.gitignore:8:!on* a/b/one two
+ a/b/.gitignore:8:!on* "a/b/one\"three"
+ a/b/.gitignore:9:!two a/b/two
+ a/.gitignore:1:two* a/b/twooo
+ $global_excludes:2:!globaltwo globaltwo
+ $global_excludes:2:!globaltwo a/globaltwo
+ $global_excludes:2:!globaltwo a/b/globaltwo
+ $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
+
+test_expect_success '--stdin' '
+ expect_from_stdin <expected-default &&
+ test_check_ignore "--stdin" <stdin
+'
+
+test_expect_success '--stdin -q' '
+ expect "" &&
+ test_check_ignore "-q --stdin" <stdin
+'
+
+test_expect_success '--stdin -v' '
+ expect_from_stdin <expected-verbose &&
+ test_check_ignore "-v --stdin" <stdin
+'
+
+for opts in '--stdin -z' '-z --stdin'
+do
+ test_expect_success "$opts" "
+ expect_from_stdin <expected-default0 &&
+ test_check_ignore '$opts' <stdin0
+ "
+
+ test_expect_success "$opts -q" "
+ expect "" &&
+ test_check_ignore '-q $opts' <stdin0
+ "
+
+ test_expect_success "$opts -v" "
+ expect_from_stdin <expected-verbose0 &&
+ test_check_ignore '-v $opts' <stdin0
+ "
+done
+
+cat <<-\EOF >stdin
+ ../one
+ ../not-ignored
+ one
+ not-ignored
+ b/on
+ b/one
+ b/one one
+ "b/one two"
+ "b/one\"three"
+ b/two
+ b/not-ignored
+ b/twooo
+ ../globaltwo
+ globaltwo
+ b/globaltwo
+ ../b/globaltwo
+EOF
+cat <<-\EOF >expected-default
+ ../one
+ one
+ b/on
+ b/one
+ b/one one
+ b/one two
+ "b/one\"three"
+ b/two
+ b/twooo
+ ../globaltwo
+ globaltwo
+ b/globaltwo
+ ../b/globaltwo
+EOF
+cat <<-EOF >expected-verbose
+ .gitignore:1:one ../one
+ .gitignore:1:one one
+ a/b/.gitignore:8:!on* b/on
+ a/b/.gitignore:8:!on* b/one
+ a/b/.gitignore:8:!on* b/one one
+ a/b/.gitignore:8:!on* b/one two
+ a/b/.gitignore:8:!on* "b/one\"three"
+ a/b/.gitignore:9:!two b/two
+ a/.gitignore:1:two* b/twooo
+ $global_excludes:2:!globaltwo ../globaltwo
+ $global_excludes:2:!globaltwo globaltwo
+ $global_excludes:2:!globaltwo b/globaltwo
+ $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
+
+test_expect_success '--stdin from subdirectory' '
+ expect_from_stdin <expected-default &&
+ (
+ cd a &&
+ test_check_ignore "--stdin" <../stdin
+ )
+'
+
+test_expect_success '--stdin from subdirectory with -v' '
+ expect_from_stdin <expected-verbose &&
+ (
+ cd a &&
+ test_check_ignore "--stdin -v" <../stdin
+ )
+'
+
+for opts in '--stdin -z' '-z --stdin'
+do
+ test_expect_success "$opts from subdirectory" '
+ expect_from_stdin <expected-default0 &&
+ (
+ cd a &&
+ test_check_ignore "'"$opts"'" <../stdin0
+ )
+ '
+
+ test_expect_success "$opts from subdirectory with -v" '
+ expect_from_stdin <expected-verbose0 &&
+ (
+ cd a &&
+ test_check_ignore "'"$opts"' -v" <../stdin0
+ )
+ '
+done
+
+
+test_done
diff --git a/t/t0024-crlf-archive.sh b/t/t0024-crlf-archive.sh
index ec6c1b3f8a..4e9fa3cd68 100755
--- a/t/t0024-crlf-archive.sh
+++ b/t/t0024-crlf-archive.sh
@@ -3,7 +3,6 @@
test_description='respect crlf in git archive'
. ./test-lib.sh
-UNZIP=${UNZIP:-unzip}
test_expect_success setup '
@@ -26,18 +25,11 @@ test_expect_success 'tar archive' '
'
-"$UNZIP" -v >/dev/null 2>&1
-if [ $? -eq 127 ]; then
- say "Skipping ZIP test, because unzip was not found"
-else
- test_set_prereq UNZIP
-fi
-
test_expect_success UNZIP 'zip archive' '
git archive --format=zip HEAD >test.zip &&
- ( mkdir unzipped && cd unzipped && unzip ../test.zip ) &&
+ ( mkdir unzipped && cd unzipped && "$GIT_UNZIP" ../test.zip ) &&
test_cmp sample unzipped/sample
diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh
index ccb0a3cb61..a8e84d8546 100755
--- a/t/t0030-stripspace.sh
+++ b/t/t0030-stripspace.sh
@@ -397,4 +397,39 @@ test_expect_success 'strip comments, too' '
test -z "$(echo "# comment" | git stripspace -s)"
'
+test_expect_success 'strip comments with changed comment char' '
+ test ! -z "$(echo "; comment" | git -c core.commentchar=";" stripspace)" &&
+ test -z "$(echo "; comment" | git -c core.commentchar=";" stripspace -s)"
+'
+
+test_expect_success '-c with single line' '
+ printf "# foo\n" >expect &&
+ printf "foo" | git stripspace -c >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '-c with single line followed by empty line' '
+ printf "# foo\n#\n" >expect &&
+ printf "foo\n\n" | git stripspace -c >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '-c with newline only' '
+ printf "#\n" >expect &&
+ printf "\n" | git stripspace -c >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '--comment-lines with single line' '
+ printf "# foo\n" >expect &&
+ printf "foo" | git stripspace -c >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '-c with changed comment char' '
+ printf "; foo\n" >expect &&
+ printf "foo" | git -c core.commentchar=";" stripspace -c >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh
index 78816d9d93..05d78d22a6 100755
--- a/t/t0050-filesystem.sh
+++ b/t/t0050-filesystem.sh
@@ -29,12 +29,10 @@ test_have_prereq SYMLINKS ||
if test_have_prereq CASE_INSENSITIVE_FS
then
test_expect_success "detection of case insensitive filesystem during repo init" '
-
test $(git config --bool core.ignorecase) = true
'
else
test_expect_success "detection of case insensitive filesystem during repo init" '
-
test_must_fail git config --bool core.ignorecase >/dev/null ||
test $(git config --bool core.ignorecase) = false
'
@@ -43,20 +41,17 @@ fi
if test_have_prereq SYMLINKS
then
test_expect_success "detection of filesystem w/o symlink support during repo init" '
-
test_must_fail git config --bool core.symlinks ||
test "$(git config --bool core.symlinks)" = true
'
else
test_expect_success "detection of filesystem w/o symlink support during repo init" '
-
v=$(git config --bool core.symlinks) &&
test "$v" = false
'
fi
test_expect_success "setup case tests" '
-
git config core.ignorecase true &&
touch camelcase &&
git add camelcase &&
@@ -67,29 +62,23 @@ test_expect_success "setup case tests" '
git mv tmp CamelCase &&
git commit -m "rename" &&
git checkout -f master
-
'
$test_case 'rename (case change)' '
-
git mv camelcase CamelCase &&
git commit -m "rename"
-
'
-$test_case 'merge (case change)' '
-
+test_expect_success 'merge (case change)' '
rm -f CamelCase &&
rm -f camelcase &&
git reset --hard initial &&
git merge topic
-
'
-test_expect_failure 'add (with different case)' '
-
+test_expect_failure CASE_INSENSITIVE_FS 'add (with different case)' '
git reset --hard initial &&
rm camelcase &&
echo 1 >CamelCase &&
@@ -97,37 +86,30 @@ test_expect_failure 'add (with different case)' '
camel=$(git ls-files | grep -i camelcase) &&
test $(echo "$camel" | wc -l) = 1 &&
test "z$(git cat-file blob :$camel)" = z1
-
'
test_expect_success "setup unicode normalization tests" '
-
- test_create_repo unicode &&
- cd unicode &&
- touch "$aumlcdiar" &&
- git add "$aumlcdiar" &&
- git commit -m initial &&
- git tag initial &&
- git checkout -b topic &&
- git mv $aumlcdiar tmp &&
- git mv tmp "$auml" &&
- git commit -m rename &&
- git checkout -f master
-
+ test_create_repo unicode &&
+ cd unicode &&
+ touch "$aumlcdiar" &&
+ git add "$aumlcdiar" &&
+ git commit -m initial &&
+ git tag initial &&
+ git checkout -b topic &&
+ git mv $aumlcdiar tmp &&
+ git mv tmp "$auml" &&
+ git commit -m rename &&
+ git checkout -f master
'
$test_unicode 'rename (silent unicode normalization)' '
-
- git mv "$aumlcdiar" "$auml" &&
- git commit -m rename
-
+ git mv "$aumlcdiar" "$auml" &&
+ git commit -m rename
'
$test_unicode 'merge (silent unicode normalization)' '
-
- git reset --hard initial &&
- git merge topic
-
+ git reset --hard initial &&
+ git merge topic
'
test_done
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 4ef2345982..09a42a428e 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -93,47 +93,32 @@ norm_path /d1/s1//../s2/../../d2 /d2 POSIX
norm_path /d1/.../d2 /d1/.../d2 POSIX
norm_path /d1/..././../d2 /d1/d2 POSIX
-ancestor / "" -1
ancestor / / -1
-ancestor /foo "" -1
-ancestor /foo : -1
-ancestor /foo ::. -1
-ancestor /foo ::..:: -1
ancestor /foo / 0
ancestor /foo /fo -1
ancestor /foo /foo -1
-ancestor /foo /foo/ -1
ancestor /foo /bar -1
-ancestor /foo /bar/ -1
ancestor /foo /foo/bar -1
-ancestor /foo /foo:/bar/ -1
-ancestor /foo /foo/:/bar/ -1
-ancestor /foo /foo::/bar/ -1
-ancestor /foo /:/foo:/bar/ 0
-ancestor /foo /foo:/:/bar/ 0
-ancestor /foo /:/bar/:/foo 0
-ancestor /foo/bar "" -1
+ancestor /foo /foo:/bar -1
+ancestor /foo /:/foo:/bar 0
+ancestor /foo /foo:/:/bar 0
+ancestor /foo /:/bar:/foo 0
ancestor /foo/bar / 0
ancestor /foo/bar /fo -1
-ancestor /foo/bar foo -1
ancestor /foo/bar /foo 4
-ancestor /foo/bar /foo/ 4
ancestor /foo/bar /foo/ba -1
ancestor /foo/bar /:/fo 0
ancestor /foo/bar /foo:/foo/ba 4
ancestor /foo/bar /bar -1
-ancestor /foo/bar /bar/ -1
-ancestor /foo/bar /fo: -1
-ancestor /foo/bar :/fo -1
-ancestor /foo/bar /foo:/bar/ 4
-ancestor /foo/bar /:/foo:/bar/ 4
-ancestor /foo/bar /foo:/:/bar/ 4
-ancestor /foo/bar /:/bar/:/fo 0
-ancestor /foo/bar /:/bar/ 0
-ancestor /foo/bar .:/foo/. 4
-ancestor /foo/bar .:/foo/.:.: 4
-ancestor /foo/bar /foo/./:.:/bar 4
-ancestor /foo/bar .:/bar -1
+ancestor /foo/bar /fo -1
+ancestor /foo/bar /foo:/bar 4
+ancestor /foo/bar /:/foo:/bar 4
+ancestor /foo/bar /foo:/:/bar 4
+ancestor /foo/bar /:/bar:/fo 0
+ancestor /foo/bar /:/bar 0
+ancestor /foo/bar /foo 4
+ancestor /foo/bar /foo:/bar 4
+ancestor /foo/bar /bar -1
test_expect_success 'strip_path_suffix' '
test c:/msysgit = $(test-path-utils strip_path_suffix \
diff --git a/t/t0063-string-list.sh b/t/t0063-string-list.sh
index 41c8826a74..dbfc05ebdc 100755
--- a/t/t0063-string-list.sh
+++ b/t/t0063-string-list.sh
@@ -17,14 +17,6 @@ test_split () {
"
}
-test_longest_prefix () {
- test "$(test-string-list longest_prefix "$1" "$2")" = "$3"
-}
-
-test_no_longest_prefix () {
- test_must_fail test-string-list longest_prefix "$1" "$2"
-}
-
test_split "foo:bar:baz" ":" "-1" <<EOF
3
[0]: "foo"
@@ -96,26 +88,4 @@ test_expect_success "test remove_duplicates" '
test a:b:c = "$(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
'
-test_expect_success "test longest_prefix" '
- test_no_longest_prefix - '' &&
- test_no_longest_prefix - x &&
- test_longest_prefix "" x "" &&
- test_longest_prefix x x x &&
- test_longest_prefix "" foo "" &&
- test_longest_prefix : foo "" &&
- test_longest_prefix f foo f &&
- test_longest_prefix foo foobar foo &&
- test_longest_prefix foo foo foo &&
- test_no_longest_prefix bar foo &&
- test_no_longest_prefix bar:bar foo &&
- test_no_longest_prefix foobar foo &&
- test_longest_prefix foo:bar foo foo &&
- test_longest_prefix foo:bar bar bar &&
- test_longest_prefix foo::bar foo foo &&
- test_longest_prefix foo:foobar foo foo &&
- test_longest_prefix foobar:foo foo foo &&
- test_longest_prefix foo: bar "" &&
- test_longest_prefix :foo bar ""
-'
-
test_done
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index d8b7f2ffbc..9820f70c84 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -116,9 +116,9 @@ tree_pretty_content="100644 blob $hello_sha1 hello"
run_tests 'tree' $tree_sha1 $tree_size "" "$tree_pretty_content"
-commit_message="Intial commit"
+commit_message="Initial commit"
commit_sha1=$(echo_without_newline "$commit_message" | git commit-tree $tree_sha1)
-commit_size=176
+commit_size=177
commit_content="tree $tree_sha1
author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 0000000000 +0000
committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 0000000000 +0000
diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh
index e23ac0e69d..1e2945ec7e 100755
--- a/t/t1020-subdirectory.sh
+++ b/t/t1020-subdirectory.sh
@@ -111,19 +111,19 @@ test_expect_success 'read-tree' '
test_expect_success 'alias expansion' '
(
- git config alias.ss status &&
+ git config alias.test-status-alias status &&
cd dir &&
git status &&
- git ss
+ git test-status-alias
)
'
test_expect_success NOT_MINGW '!alias expansion' '
pwd >expect &&
(
- git config alias.test !pwd &&
+ git config alias.test-alias-directory !pwd &&
cd dir &&
- git test >../actual
+ git test-alias-directory >../actual
) &&
test_cmp expect actual
'
@@ -131,9 +131,9 @@ test_expect_success NOT_MINGW '!alias expansion' '
test_expect_success 'GIT_PREFIX for !alias' '
printf "dir/" >expect &&
(
- git config alias.test "!sh -c \"printf \$GIT_PREFIX\"" &&
+ git config alias.test-alias-directory "!sh -c \"printf \$GIT_PREFIX\"" &&
cd dir &&
- git test >../actual
+ git test-alias-directory >../actual
) &&
test_cmp expect actual
'
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 7c4c372e37..3c96fda548 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -55,11 +55,13 @@ test_expect_success 'uppercase section' '
test_cmp expect .git/config
'
-test_expect_success 'replace with non-match' \
- 'git config core.penguin kingpin !blue'
+test_expect_success 'replace with non-match' '
+ git config core.penguin kingpin !blue
+'
-test_expect_success 'replace with non-match (actually matching)' \
- 'git config core.penguin "very blue" !kingpin'
+test_expect_success 'replace with non-match (actually matching)' '
+ git config core.penguin "very blue" !kingpin
+'
cat > expect << EOF
[core]
@@ -108,8 +110,9 @@ baz = multiple \
lines
EOF
-test_expect_success 'unset with cont. lines' \
- 'git config --unset beta.baz'
+test_expect_success 'unset with cont. lines' '
+ git config --unset beta.baz
+'
cat > expect <<\EOF
[alpha]
@@ -133,8 +136,9 @@ EOF
cp .git/config .git/config2
-test_expect_success 'multiple unset' \
- 'git config --unset-all beta.haha'
+test_expect_success 'multiple unset' '
+ git config --unset-all beta.haha
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -145,7 +149,9 @@ noIndent= sillyValue ; 'nother silly comment
[nextSection] noNewline = ouch
EOF
-test_expect_success 'multiple unset is correct' 'test_cmp expect .git/config'
+test_expect_success 'multiple unset is correct' '
+ test_cmp expect .git/config
+'
cp .git/config2 .git/config
@@ -156,8 +162,9 @@ test_expect_success '--replace-all missing value' '
rm .git/config2
-test_expect_success '--replace-all' \
- 'git config --replace-all beta.haha gamma'
+test_expect_success '--replace-all' '
+ git config --replace-all beta.haha gamma
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -169,7 +176,9 @@ noIndent= sillyValue ; 'nother silly comment
[nextSection] noNewline = ouch
EOF
-test_expect_success 'all replaced' 'test_cmp expect .git/config'
+test_expect_success 'all replaced' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -200,7 +209,11 @@ test_expect_success 'really really mean test' '
test_cmp expect .git/config
'
-test_expect_success 'get value' 'test alpha = $(git config beta.haha)'
+test_expect_success 'get value' '
+ echo alpha >expect &&
+ git config beta.haha >actual &&
+ test_cmp expect actual
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -231,18 +244,30 @@ test_expect_success 'multivar' '
test_cmp expect .git/config
'
-test_expect_success 'non-match' \
- 'git config --get nextsection.nonewline !for'
+test_expect_success 'non-match' '
+ git config --get nextsection.nonewline !for
+'
-test_expect_success 'non-match value' \
- 'test wow = $(git config --get nextsection.nonewline !for)'
+test_expect_success 'non-match value' '
+ echo wow >expect &&
+ git config --get nextsection.nonewline !for >actual &&
+ test_cmp expect actual
+'
-test_expect_success 'ambiguous get' '
- test_must_fail git config --get nextsection.nonewline
+test_expect_success 'multi-valued get returns final one' '
+ echo "wow2 for me" >expect &&
+ git config --get nextsection.nonewline >actual &&
+ test_cmp expect actual
'
-test_expect_success 'get multivar' \
- 'git config --get-all nextsection.nonewline'
+test_expect_success 'multi-valued get-all returns all' '
+ cat >expect <<-\EOF &&
+ wow
+ wow2 for me
+ EOF
+ git config --get-all nextsection.nonewline >actual &&
+ test_cmp expect actual
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -259,10 +284,6 @@ test_expect_success 'multivar replace' '
test_cmp expect .git/config
'
-test_expect_success 'ambiguous value' '
- test_must_fail git config nextsection.nonewline
-'
-
test_expect_success 'ambiguous unset' '
test_must_fail git config --unset nextsection.nonewline
'
@@ -290,8 +311,9 @@ test_expect_success 'invalid key' 'test_must_fail git config inval.2key blabla'
test_expect_success 'correct key' 'git config 123456.a123 987'
-test_expect_success 'hierarchical section' \
- 'git config Version.1.2.3eX.Alpha beta'
+test_expect_success 'hierarchical section' '
+ git config Version.1.2.3eX.Alpha beta
+'
cat > expect << EOF
[beta] ; silly comment # another comment
@@ -307,7 +329,9 @@ noIndent= sillyValue ; 'nother silly comment
Alpha = beta
EOF
-test_expect_success 'hierarchical section value' 'test_cmp expect .git/config'
+test_expect_success 'hierarchical section value' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
beta.noindent=sillyValue
@@ -316,9 +340,10 @@ nextsection.nonewline=wow2 for me
version.1.2.3eX.alpha=beta
EOF
-test_expect_success 'working --list' \
- 'git config --list > output && cmp output expect'
-
+test_expect_success 'working --list' '
+ git config --list > output &&
+ test_cmp expect output
+'
cat > expect << EOF
EOF
@@ -332,8 +357,10 @@ beta.noindent sillyValue
nextsection.nonewline wow2 for me
EOF
-test_expect_success '--get-regexp' \
- 'git config --get-regexp in > output && cmp output expect'
+test_expect_success '--get-regexp' '
+ git config --get-regexp in >output &&
+ test_cmp expect output
+'
cat > expect << EOF
wow2 for me
@@ -353,41 +380,48 @@ cat > .git/config << EOF
variable =
EOF
-test_expect_success 'get variable with no value' \
- 'git config --get novalue.variable ^$'
+test_expect_success 'get variable with no value' '
+ git config --get novalue.variable ^$
+'
-test_expect_success 'get variable with empty value' \
- 'git config --get emptyvalue.variable ^$'
+test_expect_success 'get variable with empty value' '
+ git config --get emptyvalue.variable ^$
+'
echo novalue.variable > expect
-test_expect_success 'get-regexp variable with no value' \
- 'git config --get-regexp novalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp variable with no value' '
+ git config --get-regexp novalue > output &&
+ test_cmp expect output
+'
echo 'novalue.variable true' > expect
-test_expect_success 'get-regexp --bool variable with no value' \
- 'git config --bool --get-regexp novalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp --bool variable with no value' '
+ git config --bool --get-regexp novalue > output &&
+ test_cmp expect output
+'
echo 'emptyvalue.variable ' > expect
-test_expect_success 'get-regexp variable with empty value' \
- 'git config --get-regexp emptyvalue > output &&
- cmp output expect'
+test_expect_success 'get-regexp variable with empty value' '
+ git config --get-regexp emptyvalue > output &&
+ test_cmp expect output
+'
echo true > expect
-test_expect_success 'get bool variable with no value' \
- 'git config --bool novalue.variable > output &&
- cmp output expect'
+test_expect_success 'get bool variable with no value' '
+ git config --bool novalue.variable > output &&
+ test_cmp expect output
+'
echo false > expect
-test_expect_success 'get bool variable with empty value' \
- 'git config --bool emptyvalue.variable > output &&
- cmp output expect'
+test_expect_success 'get bool variable with empty value' '
+ git config --bool emptyvalue.variable > output &&
+ test_cmp expect output
+'
test_expect_success 'no arguments, but no crash' '
test_must_fail git config >output 2>&1 &&
@@ -427,8 +461,9 @@ test_expect_success 'new variable inserts into proper section' '
test_cmp expect .git/config
'
-test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' \
- 'test_must_fail git config --file non-existing-config -l'
+test_expect_success 'alternative GIT_CONFIG (non-existing file should fail)' '
+ test_must_fail git config --file non-existing-config -l
+'
cat > other-config << EOF
[ein]
@@ -444,8 +479,10 @@ test_expect_success 'alternative GIT_CONFIG' '
test_cmp expect output
'
-test_expect_success 'alternative GIT_CONFIG (--file)' \
- 'git config --file other-config -l > output && cmp output expect'
+test_expect_success 'alternative GIT_CONFIG (--file)' '
+ git config --file other-config -l > output &&
+ test_cmp expect output
+'
test_expect_success 'refer config from subdirectory' '
mkdir x &&
@@ -489,8 +526,9 @@ cat > .git/config << EOF
weird
EOF
-test_expect_success "rename section" \
- "git config --rename-section branch.eins branch.zwei"
+test_expect_success 'rename section' '
+ git config --rename-section branch.eins branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -503,17 +541,22 @@ cat > expect << EOF
weird
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
-test_expect_success "rename non-existing section" '
+test_expect_success 'rename non-existing section' '
test_must_fail git config --rename-section \
branch."world domination" branch.drei
'
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
-test_expect_success "rename another section" \
- 'git config --rename-section branch."1 234 blabl/a" branch.drei'
+test_expect_success 'rename another section' '
+ git config --rename-section branch."1 234 blabl/a" branch.drei
+'
cat > expect << EOF
# Hallo
@@ -526,14 +569,17 @@ cat > expect << EOF
weird
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
cat >> .git/config << EOF
[branch "vier"] z = 1
EOF
-test_expect_success "rename a section with a var on the same line" \
- 'git config --rename-section branch.vier branch.zwei'
+test_expect_success 'rename a section with a var on the same line' '
+ git config --rename-section branch.vier branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -548,7 +594,9 @@ weird
z = 1
EOF
-test_expect_success "rename succeeded" "test_cmp expect .git/config"
+test_expect_success 'rename succeeded' '
+ test_cmp expect .git/config
+'
test_expect_success 'renaming empty section name is rejected' '
test_must_fail git config --rename-section branch.zwei ""
@@ -562,7 +610,9 @@ cat >> .git/config << EOF
[branch "zwei"] a = 1 [branch "vier"]
EOF
-test_expect_success "remove section" "git config --remove-section branch.zwei"
+test_expect_success 'remove section' '
+ git config --remove-section branch.zwei
+'
cat > expect << EOF
# Hallo
@@ -571,8 +621,9 @@ cat > expect << EOF
weird
EOF
-test_expect_success "section was removed properly" \
- "test_cmp expect .git/config"
+test_expect_success 'section was removed properly' '
+ test_cmp expect .git/config
+'
cat > expect << EOF
[gitcvs]
@@ -583,7 +634,6 @@ cat > expect << EOF
EOF
test_expect_success 'section ending' '
-
rm -f .git/config &&
git config gitcvs.enabled true &&
git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&
@@ -593,30 +643,25 @@ test_expect_success 'section ending' '
'
test_expect_success numbers '
-
git config kilo.gram 1k &&
git config mega.ton 1m &&
- k=$(git config --int --get kilo.gram) &&
- test z1024 = "z$k" &&
- m=$(git config --int --get mega.ton) &&
- test z1048576 = "z$m"
+ echo 1024 >expect &&
+ echo 1048576 >>expect &&
+ git config --int --get kilo.gram >actual &&
+ git config --int --get mega.ton >>actual &&
+ test_cmp expect actual
'
-cat > expect <<EOF
-fatal: bad config value for 'aninvalid.unit' in .git/config
-EOF
-
test_expect_success 'invalid unit' '
-
git config aninvalid.unit "1auto" &&
- s=$(git config aninvalid.unit) &&
- test "z1auto" = "z$s" &&
- if git config --int --get aninvalid.unit 2>actual
- then
- echo config should have failed
- false
- fi &&
- cmp actual expect
+ echo 1auto >expect &&
+ git config aninvalid.unit >actual &&
+ test_cmp expect actual &&
+ cat > expect <<-\EOF
+ fatal: bad config value for '\''aninvalid.unit'\'' in .git/config
+ EOF
+ test_must_fail git config --int --get aninvalid.unit 2>actual &&
+ test_cmp actual expect
'
cat > expect << EOF
@@ -646,7 +691,7 @@ test_expect_success bool '
git config --bool --get bool.true$i >>result
git config --bool --get bool.false$i >>result
done &&
- cmp expect result'
+ test_cmp expect result'
test_expect_success 'invalid bool (--get)' '
@@ -680,7 +725,7 @@ test_expect_success 'set --bool' '
git config --bool bool.false2 "" &&
git config --bool bool.false3 nO &&
git config --bool bool.false4 FALSE &&
- cmp expect .git/config'
+ test_cmp expect .git/config'
cat > expect <<\EOF
[int]
@@ -695,39 +740,37 @@ test_expect_success 'set --int' '
git config --int int.val1 01 &&
git config --int int.val2 -1 &&
git config --int int.val3 5m &&
- cmp expect .git/config'
+ test_cmp expect .git/config
+'
-cat >expect <<\EOF
-[bool]
- true1 = true
+test_expect_success 'get --bool-or-int' '
+ cat >.git/config <<-\EOF &&
+ [bool]
+ true1
true2 = true
- false1 = false
- false2 = false
-[int]
+ false = false
+ [int]
int1 = 0
int2 = 1
int3 = -1
-EOF
-
-test_expect_success 'get --bool-or-int' '
- rm -f .git/config &&
- (
- echo "[bool]"
- echo true1
- echo true2 = true
- echo false = false
- echo "[int]"
- echo int1 = 0
- echo int2 = 1
- echo int3 = -1
- ) >>.git/config &&
- test $(git config --bool-or-int bool.true1) = true &&
- test $(git config --bool-or-int bool.true2) = true &&
- test $(git config --bool-or-int bool.false) = false &&
- test $(git config --bool-or-int int.int1) = 0 &&
- test $(git config --bool-or-int int.int2) = 1 &&
- test $(git config --bool-or-int int.int3) = -1
-
+ EOF
+ cat >expect <<-\EOF &&
+ true
+ true
+ false
+ 0
+ 1
+ -1
+ EOF
+ {
+ git config --bool-or-int bool.true1 &&
+ git config --bool-or-int bool.true2 &&
+ git config --bool-or-int bool.false &&
+ git config --bool-or-int int.int1 &&
+ git config --bool-or-int int.int2 &&
+ git config --bool-or-int int.int3
+ } >actual &&
+ test_cmp expect actual
'
cat >expect <<\EOF
@@ -849,7 +892,7 @@ EOF
test_expect_success 'value continued on next line' '
git config --list > result &&
- cmp result expect
+ test_cmp result expect
'
cat > .git/config <<\EOF
@@ -885,11 +928,12 @@ test_expect_success '--null --get-regexp' '
test_expect_success 'inner whitespace kept verbatim' '
git config section.val "foo bar" &&
- test "z$(git config section.val)" = "zfoo bar"
+ echo "foo bar" >expect &&
+ git config section.val >actual &&
+ test_cmp expect actual
'
test_expect_success SYMLINKS 'symlinked configuration' '
-
ln -s notyet myconfig &&
GIT_CONFIG=myconfig git config test.frotz nitfol &&
test -h myconfig &&
@@ -898,9 +942,15 @@ test_expect_success SYMLINKS 'symlinked configuration' '
GIT_CONFIG=myconfig git config test.xyzzy rezrov &&
test -h myconfig &&
test -f notyet &&
- test "z$(GIT_CONFIG=notyet git config test.frotz)" = znitfol &&
- test "z$(GIT_CONFIG=notyet git config test.xyzzy)" = zrezrov
-
+ cat >expect <<-\EOF &&
+ nitfol
+ rezrov
+ EOF
+ {
+ GIT_CONFIG=notyet git config test.frotz &&
+ GIT_CONFIG=notyet git config test.xyzzy
+ } >actual &&
+ test_cmp expect actual
'
test_expect_success 'nonexistent configuration' '
@@ -932,12 +982,20 @@ test_expect_success 'check split_cmdline return' "
git commit -m 'initial commit' &&
git config branch.master.mergeoptions 'echo \"' &&
test_must_fail git merge master
- "
+"
test_expect_success 'git -c "key=value" support' '
- test "z$(git -c core.name=value config core.name)" = zvalue &&
- test "z$(git -c foo.CamelCase=value config foo.camelcase)" = zvalue &&
- test "z$(git -c foo.flag config --bool foo.flag)" = ztrue &&
+ cat >expect <<-\EOF &&
+ value
+ value
+ true
+ EOF
+ {
+ git -c core.name=value config core.name &&
+ git -c foo.CamelCase=value config foo.camelcase &&
+ git -c foo.flag config --bool foo.flag
+ } >actual &&
+ test_cmp expect actual &&
test_must_fail git -c name=value config core.name
'
diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh
index 2c96551ed0..36378b0e3f 100755
--- a/t/t1401-symbolic-ref.sh
+++ b/t/t1401-symbolic-ref.sh
@@ -33,4 +33,34 @@ test_expect_success 'symbolic-ref refuses bare sha1' '
'
reset_to_sane
+test_expect_success 'symbolic-ref deletes HEAD' '
+ git symbolic-ref -d HEAD &&
+ test_path_is_file .git/refs/heads/foo &&
+ test_path_is_missing .git/HEAD
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref deletes dangling HEAD' '
+ git symbolic-ref HEAD refs/heads/missing &&
+ git symbolic-ref -d HEAD &&
+ test_path_is_missing .git/refs/heads/missing &&
+ test_path_is_missing .git/HEAD
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref fails to delete missing FOO' '
+ echo "fatal: Cannot delete FOO, not a symbolic ref" >expect &&
+ test_must_fail git symbolic-ref -d FOO >actual 2>&1 &&
+ test_cmp expect actual
+'
+reset_to_sane
+
+test_expect_success 'symbolic-ref fails to delete real ref' '
+ echo "fatal: Cannot delete refs/heads/foo, not a symbolic ref" >expect &&
+ test_must_fail git symbolic-ref -d refs/heads/foo >actual 2>&1 &&
+ test_path_is_file .git/refs/heads/foo &&
+ test_cmp expect actual
+'
+reset_to_sane
+
test_done
diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh
index 1ae4d87c92..1a5a5f39fd 100755
--- a/t/t1402-check-ref-format.sh
+++ b/t/t1402-check-ref-format.sh
@@ -11,7 +11,8 @@ valid_ref() {
prereq=$1
shift
esac
- test_expect_success $prereq "ref name '$1' is valid${2:+ with options $2}" "
+ desc="ref name '$1' is valid${2:+ with options $2}"
+ test_expect_success $prereq "$desc" "
git check-ref-format $2 '$1'
"
}
@@ -22,7 +23,8 @@ invalid_ref() {
prereq=$1
shift
esac
- test_expect_success $prereq "ref name '$1' is invalid${2:+ with options $2}" "
+ desc="ref name '$1' is invalid${2:+ with options $2}"
+ test_expect_success $prereq "$desc" "
test_must_fail git check-ref-format $2 '$1'
"
}
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 08aa24ca15..d730734fde 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -237,4 +237,35 @@ test_expect_success 'fsck notices submodule entry pointing to null sha1' '
)
'
+test_expect_success 'fsck notices "." and ".." in trees' '
+ (
+ git init dots &&
+ cd dots &&
+ blob=$(echo foo | git hash-object -w --stdin) &&
+ tab=$(printf "\\t") &&
+ git mktree <<-EOF &&
+ 100644 blob $blob$tab.
+ 100644 blob $blob$tab..
+ EOF
+ git fsck 2>out &&
+ cat out &&
+ grep "warning.*\\." out
+ )
+'
+
+test_expect_success 'fsck notices ".git" in trees' '
+ (
+ git init dotgit &&
+ cd dotgit &&
+ blob=$(echo foo | git hash-object -w --stdin) &&
+ tab=$(printf "\\t") &&
+ git mktree <<-EOF &&
+ 100644 blob $blob$tab.git
+ EOF
+ git fsck 2>out &&
+ cat out &&
+ grep "warning.*\\.git" out
+ )
+'
+
test_done
diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh
index cce87a5ab5..3d51615e42 100755
--- a/t/t1504-ceiling-dirs.sh
+++ b/t/t1504-ceiling-dirs.sh
@@ -44,6 +44,10 @@ test_prefix ceil_at_sub ""
GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/"
test_prefix ceil_at_sub_slash ""
+if test_have_prereq SYMLINKS
+then
+ ln -s sub top
+fi
mkdir -p sub/dir || exit 1
cd sub/dir || exit 1
@@ -68,6 +72,19 @@ test_fail subdir_ceil_at_sub
GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/"
test_fail subdir_ceil_at_sub_slash
+if test_have_prereq SYMLINKS
+then
+ GIT_CEILING_DIRECTORIES="$TRASH_ROOT/top"
+ test_fail subdir_ceil_at_top
+ GIT_CEILING_DIRECTORIES="$TRASH_ROOT/top/"
+ test_fail subdir_ceil_at_top_slash
+
+ GIT_CEILING_DIRECTORIES=":$TRASH_ROOT/top"
+ test_prefix subdir_ceil_at_top_no_resolve "sub/dir/"
+ GIT_CEILING_DIRECTORIES=":$TRASH_ROOT/top/"
+ test_prefix subdir_ceil_at_top_slash_no_resolve "sub/dir/"
+fi
+
GIT_CEILING_DIRECTORIES="$TRASH_ROOT/sub/dir"
test_prefix subdir_ceil_at_subdir "sub/dir/"
diff --git a/t/t1505-rev-parse-last.sh b/t/t1505-rev-parse-last.sh
index d709ecf8df..4969edb314 100755
--- a/t/t1505-rev-parse-last.sh
+++ b/t/t1505-rev-parse-last.sh
@@ -32,32 +32,24 @@ test_expect_success 'setup' '
#
# and 'side' should be the last branch
-test_rev_equivalent () {
-
- git rev-parse "$1" > expect &&
- git rev-parse "$2" > output &&
- test_cmp expect output
-
-}
-
test_expect_success '@{-1} works' '
- test_rev_equivalent side @{-1}
+ test_cmp_rev side @{-1}
'
test_expect_success '@{-1}~2 works' '
- test_rev_equivalent side~2 @{-1}~2
+ test_cmp_rev side~2 @{-1}~2
'
test_expect_success '@{-1}^2 works' '
- test_rev_equivalent side^2 @{-1}^2
+ test_cmp_rev side^2 @{-1}^2
'
test_expect_success '@{-1}@{1} works' '
- test_rev_equivalent side@{1} @{-1}@{1}
+ test_cmp_rev side@{1} @{-1}@{1}
'
test_expect_success '@{-2} works' '
- test_rev_equivalent master @{-2}
+ test_cmp_rev master @{-2}
'
test_expect_success '@{-3} fails' '
diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh
index d6e576192f..b27a7209f7 100755
--- a/t/t1507-rev-parse-upstream.sh
+++ b/t/t1507-rev-parse-upstream.sh
@@ -54,6 +54,10 @@ test_expect_success 'my-side@{upstream} resolves to correct full name' '
test refs/remotes/origin/side = "$(full_name my-side@{u})"
'
+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}
+'
+
test_expect_success 'my-side@{u} resolves to correct commit' '
git checkout side &&
test_commit 5 &&
diff --git a/t/t1509/prepare-chroot.sh b/t/t1509/prepare-chroot.sh
index c5334a8fa4..62691172e3 100755
--- a/t/t1509/prepare-chroot.sh
+++ b/t/t1509/prepare-chroot.sh
@@ -14,7 +14,7 @@ xmkdir() {
R="$1"
-[ -n "$R" ] || die "Usage: prepare-chroot.sh <root>"
+[ -n "$R" ] || die "usage: prepare-chroot.sh <root>"
[ -x git ] || die "This script needs to be executed at git source code's top directory"
[ -x /bin/busybox ] || die "You need busybox"
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 80aedfca8c..cf2ee7885a 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -517,6 +517,25 @@ test_expect_success '#16c: bare .git has no worktree' '
"$here/16c/.git" "(null)" "$here/16c/sub" "(null)"
'
+test_expect_success '#16d: bareness preserved across alias' '
+ setup_repo 16d unset "" unset &&
+ (
+ cd 16d/.git &&
+ test_must_fail git status &&
+ git config alias.st status &&
+ test_must_fail git st
+ )
+'
+
+test_expect_success '#16e: bareness preserved by --bare' '
+ setup_repo 16e unset "" unset &&
+ (
+ cd 16e/.git &&
+ test_must_fail git status &&
+ test_must_fail git --bare status
+ )
+'
+
test_expect_success '#17: GIT_WORK_TREE without explicit GIT_DIR is accepted (bare case)' '
# Just like #16.
setup_repo 17a unset "" true &&
diff --git a/t/t2003-checkout-cache-mkdir.sh b/t/t2003-checkout-cache-mkdir.sh
index 02a4fc5d36..ff163cf675 100755
--- a/t/t2003-checkout-cache-mkdir.sh
+++ b/t/t2003-checkout-cache-mkdir.sh
@@ -12,85 +12,108 @@ the GIT controlled paths.
. ./test-lib.sh
-test_expect_success \
- 'setup' \
- 'mkdir path1 &&
- echo frotz >path0 &&
- echo rezrov >path1/file1 &&
- git update-index --add path0 path1/file1'
+test_expect_success 'setup' '
+ mkdir path1 &&
+ echo frotz >path0 &&
+ echo rezrov >path1/file1 &&
+ git update-index --add path0 path1/file1
+'
+
+test_expect_success SYMLINKS 'have symlink in place where dir is expected.' '
+ rm -fr path0 path1 &&
+ mkdir path2 &&
+ ln -s path2 path1 &&
+ git checkout-index -f -a &&
+ test ! -h path1 && test -d path1 &&
+ test -f path1/file1 && test ! -f path2/file1
+'
-test_expect_success SYMLINKS \
- 'have symlink in place where dir is expected.' \
- 'rm -fr path0 path1 &&
- mkdir path2 &&
- ln -s path2 path1 &&
- git checkout-index -f -a &&
- test ! -h path1 && test -d path1 &&
- test -f path1/file1 && test ! -f path2/file1'
+test_expect_success 'use --prefix=path2/' '
+ rm -fr path0 path1 path2 &&
+ mkdir path2 &&
+ git checkout-index --prefix=path2/ -f -a &&
+ test -f path2/path0 &&
+ test -f path2/path1/file1 &&
+ test ! -f path0 &&
+ test ! -f path1/file1
+'
+
+test_expect_success 'use --prefix=tmp-' '
+ rm -fr path0 path1 path2 tmp* &&
+ git checkout-index --prefix=tmp- -f -a &&
+ test -f tmp-path0 &&
+ test -f tmp-path1/file1 &&
+ test ! -f path0 &&
+ test ! -f path1/file1
+'
-test_expect_success \
- 'use --prefix=path2/' \
- 'rm -fr path0 path1 path2 &&
- mkdir path2 &&
- git checkout-index --prefix=path2/ -f -a &&
- test -f path2/path0 &&
- test -f path2/path1/file1 &&
- test ! -f path0 &&
- test ! -f path1/file1'
+test_expect_success 'use --prefix=tmp- but with a conflicting file and dir' '
+ rm -fr path0 path1 path2 tmp* &&
+ echo nitfol >tmp-path1 &&
+ mkdir tmp-path0 &&
+ git checkout-index --prefix=tmp- -f -a &&
+ test -f tmp-path0 &&
+ test -f tmp-path1/file1 &&
+ test ! -f path0 &&
+ test ! -f path1/file1
+'
-test_expect_success \
- 'use --prefix=tmp-' \
- 'rm -fr path0 path1 path2 tmp* &&
- git checkout-index --prefix=tmp- -f -a &&
- test -f tmp-path0 &&
- test -f tmp-path1/file1 &&
- test ! -f path0 &&
- test ! -f path1/file1'
+test_expect_success SYMLINKS 'use --prefix=tmp/orary/ where tmp is a symlink' '
+ rm -fr path0 path1 path2 tmp* &&
+ mkdir tmp1 tmp1/orary &&
+ ln -s tmp1 tmp &&
+ git checkout-index --prefix=tmp/orary/ -f -a &&
+ test -d tmp1/orary &&
+ test -f tmp1/orary/path0 &&
+ test -f tmp1/orary/path1/file1 &&
+ test -h tmp
+'
-test_expect_success \
- 'use --prefix=tmp- but with a conflicting file and dir' \
- 'rm -fr path0 path1 path2 tmp* &&
- echo nitfol >tmp-path1 &&
- mkdir tmp-path0 &&
- git checkout-index --prefix=tmp- -f -a &&
- test -f tmp-path0 &&
- test -f tmp-path1/file1 &&
- test ! -f path0 &&
- test ! -f path1/file1'
+test_expect_success SYMLINKS 'use --prefix=tmp/orary- where tmp is a symlink' '
+ rm -fr path0 path1 path2 tmp* &&
+ mkdir tmp1 &&
+ ln -s tmp1 tmp &&
+ git checkout-index --prefix=tmp/orary- -f -a &&
+ test -f tmp1/orary-path0 &&
+ test -f tmp1/orary-path1/file1 &&
+ test -h tmp
+'
-# Linus fix #1
-test_expect_success SYMLINKS \
- 'use --prefix=tmp/orary/ where tmp is a symlink' \
- 'rm -fr path0 path1 path2 tmp* &&
- mkdir tmp1 tmp1/orary &&
- ln -s tmp1 tmp &&
- git checkout-index --prefix=tmp/orary/ -f -a &&
- test -d tmp1/orary &&
- test -f tmp1/orary/path0 &&
- test -f tmp1/orary/path1/file1 &&
- test -h tmp'
+test_expect_success SYMLINKS 'use --prefix=tmp- where tmp-path1 is a symlink' '
+ rm -fr path0 path1 path2 tmp* &&
+ mkdir tmp1 &&
+ ln -s tmp1 tmp-path1 &&
+ git checkout-index --prefix=tmp- -f -a &&
+ test -f tmp-path0 &&
+ test ! -h tmp-path1 &&
+ test -d tmp-path1 &&
+ test -f tmp-path1/file1
+'
-# Linus fix #2
-test_expect_success SYMLINKS \
- 'use --prefix=tmp/orary- where tmp is a symlink' \
- 'rm -fr path0 path1 path2 tmp* &&
- mkdir tmp1 &&
- ln -s tmp1 tmp &&
- git checkout-index --prefix=tmp/orary- -f -a &&
- test -f tmp1/orary-path0 &&
- test -f tmp1/orary-path1/file1 &&
- test -h tmp'
+test_expect_success 'apply filter from working tree .gitattributes with --prefix' '
+ rm -fr path0 path1 path2 tmp* &&
+ mkdir path1 &&
+ mkdir tmp &&
+ git config filter.replace-all.smudge "sed -e s/./,/g" &&
+ git config filter.replace-all.clean cat &&
+ git config filter.replace-all.required true &&
+ echo "file1 filter=replace-all" >path1/.gitattributes &&
+ git checkout-index --prefix=tmp/ -f -a &&
+ echo frotz >expected &&
+ test_cmp expected tmp/path0 &&
+ echo ,,,,,, >expected &&
+ test_cmp expected tmp/path1/file1
+'
-# Linus fix #3
-test_expect_success SYMLINKS \
- 'use --prefix=tmp- where tmp-path1 is a symlink' \
- 'rm -fr path0 path1 path2 tmp* &&
- mkdir tmp1 &&
- ln -s tmp1 tmp-path1 &&
- git checkout-index --prefix=tmp- -f -a &&
- test -f tmp-path0 &&
- test ! -h tmp-path1 &&
- test -d tmp-path1 &&
- test -f tmp-path1/file1'
+test_expect_success 'apply CRLF filter from working tree .gitattributes with --prefix' '
+ rm -fr path0 path1 path2 tmp* &&
+ mkdir path1 &&
+ mkdir tmp &&
+ echo "file1 eol=crlf" >path1/.gitattributes &&
+ git checkout-index --prefix=tmp/ -f -a &&
+ echo rezrovQ >expected &&
+ tr \\015 Q <tmp/path1/file1 >actual &&
+ test_cmp expected actual
+'
test_done
diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh
index 70edbb33e2..06b18f8bc1 100755
--- a/t/t2013-checkout-submodule.sh
+++ b/t/t2013-checkout-submodule.sh
@@ -23,7 +23,7 @@ test_expect_success '"reset <submodule>" updates the index' '
git update-index --refresh &&
git diff-files --quiet &&
git diff-index --quiet --cached HEAD &&
- test_must_fail git reset HEAD^ submodule &&
+ git reset HEAD^ submodule &&
test_must_fail git diff-files --quiet &&
git reset submodule &&
git diff-files --quiet
diff --git a/t/t2020-checkout-detach.sh b/t/t2020-checkout-detach.sh
index 81005373d7..5d68729d7a 100755
--- a/t/t2020-checkout-detach.sh
+++ b/t/t2020-checkout-detach.sh
@@ -151,6 +151,7 @@ test_expect_success 'checkout does not warn leaving reachable commit' '
cat >expect <<'EOF'
Your branch is behind 'master' by 1 commit, and can be fast-forwarded.
+ (use "git pull" to update your local branch)
EOF
test_expect_success 'tracking count is accurate after orphan check' '
reset &&
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index ec35409f9c..2a4a749b4f 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -62,5 +62,25 @@ test_expect_success 'can "commit -a" with an i-t-a entry' '
git commit -a -m all
'
+test_expect_success 'cache-tree invalidates i-t-a paths' '
+ git reset --hard &&
+ mkdir dir &&
+ : >dir/foo &&
+ git add dir/foo &&
+ git commit -m foo &&
+
+ : >dir/bar &&
+ git add -N dir/bar &&
+ git diff --cached --name-only >actual &&
+ echo dir/bar >expect &&
+ test_cmp expect actual &&
+
+ git write-tree >/dev/null &&
+
+ git diff --cached --name-only >actual &&
+ echo dir/bar >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh
index c8fe978267..efb7ebc91f 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -214,4 +214,28 @@ test_expect_success 'subdirectory ignore (l1)' '
test_cmp expect actual
'
+test_expect_success 'pattern matches prefix completely' '
+ : >expect &&
+ git ls-files -i -o --exclude "/three/a.3[abc]" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'ls-files with "**" patterns' '
+ cat <<\EOF >expect &&
+a.1
+one/a.1
+one/two/a.1
+three/a.1
+EOF
+ git ls-files -o -i --exclude "**/a.1" >actual
+ test_cmp expect actual
+'
+
+
+test_expect_success 'ls-files with "**" patterns and no slashes' '
+ : >expect &&
+ git ls-files -o -i --exclude "one**a.1" >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
new file mode 100755
index 0000000000..4c37057ddf
--- /dev/null
+++ b/t/t3070-wildmatch.sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+
+test_description='wildmatch tests'
+
+. ./test-lib.sh
+
+match() {
+ if [ $1 = 1 ]; then
+ test_expect_success "wildmatch: match '$3' '$4'" "
+ test-wildmatch wildmatch '$3' '$4'
+ "
+ else
+ test_expect_success "wildmatch: no match '$3' '$4'" "
+ ! 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
+}
+
+pathmatch() {
+ if [ $1 = 1 ]; then
+ test_expect_success "pathmatch: match '$2' '$3'" "
+ test-wildmatch pathmatch '$2' '$3'
+ "
+ else
+ test_expect_success "pathmatch: no match '$2' '$3'" "
+ ! test-wildmatch pathmatch '$2' '$3'
+ "
+ fi
+}
+
+# Basic wildmat features
+match 1 1 foo foo
+match 0 0 foo bar
+match 1 1 '' ""
+match 1 1 foo '???'
+match 0 0 foo '??'
+match 1 1 foo '*'
+match 1 1 foo 'f*'
+match 0 0 foo '*f'
+match 1 1 foo '*foo*'
+match 1 1 foobar '*ob*a*r*'
+match 1 1 aaaaaaabababab '*ab'
+match 1 1 'foo*' 'foo\*'
+match 0 0 foobar 'foo\*bar'
+match 1 1 'f\oo' 'f\\oo'
+match 1 1 ball '*[al]?'
+match 0 0 ten '[ten]'
+match 0 1 ten '**[!te]'
+match 0 0 ten '**[!ten]'
+match 1 1 ten 't[a-g]n'
+match 0 0 ten 't[!a-g]n'
+match 1 1 ton 't[!a-g]n'
+match 1 1 ton 't[^a-g]n'
+match 1 x 'a]b' 'a[]]b'
+match 1 x a-b 'a[]-]b'
+match 1 x 'a]b' 'a[]-]b'
+match 0 x aab 'a[]-]b'
+match 1 x aab 'a[]a-]b'
+match 1 1 ']' ']'
+
+# Extended slash-matching features
+match 0 0 'foo/baz/bar' 'foo*bar'
+match 0 0 'foo/baz/bar' 'foo**bar'
+match 0 1 'foobazbar' 'foo**bar'
+match 1 1 'foo/baz/bar' 'foo/**/bar'
+match 1 0 'foo/baz/bar' 'foo/**/**/bar'
+match 1 0 'foo/b/a/z/bar' 'foo/**/bar'
+match 1 0 'foo/b/a/z/bar' 'foo/**/**/bar'
+match 1 0 'foo/bar' 'foo/**/bar'
+match 1 0 'foo/bar' 'foo/**/**/bar'
+match 0 0 'foo/bar' 'foo?bar'
+match 0 0 'foo/bar' 'foo[/]bar'
+match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
+match 1 1 'foo-bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
+match 1 0 'foo' '**/foo'
+match 1 x 'XXX/foo' '**/foo'
+match 1 0 'bar/baz/foo' '**/foo'
+match 0 0 'bar/baz/foo' '*/foo'
+match 0 0 'foo/bar/baz' '**/bar*'
+match 1 0 'deep/foo/bar/baz' '**/bar/*'
+match 0 0 'deep/foo/bar/baz/' '**/bar/*'
+match 1 0 'deep/foo/bar/baz/' '**/bar/**'
+match 0 0 'deep/foo/bar' '**/bar/*'
+match 1 0 'deep/foo/bar/' '**/bar/**'
+match 0 0 'foo/bar/baz' '**/bar**'
+match 1 0 'foo/bar/baz/x' '*/bar/**'
+match 0 0 'deep/foo/bar/baz/x' '*/bar/**'
+match 1 0 'deep/foo/bar/baz/x' '**/bar/*/*'
+
+# Various additional tests
+match 0 0 'acrt' 'a[c-c]st'
+match 1 1 'acrt' 'a[c-c]rt'
+match 0 0 ']' '[!]-]'
+match 1 x 'a' '[!]-]'
+match 0 0 '' '\'
+match 0 x '\' '\'
+match 0 x 'XXX/\' '*/\'
+match 1 x 'XXX/\' '*/\\'
+match 1 1 'foo' 'foo'
+match 1 1 '@foo' '@foo'
+match 0 0 'foo' '@foo'
+match 1 1 '[ab]' '\[ab]'
+match 1 1 '[ab]' '[[]ab]'
+match 1 x '[ab]' '[[:]ab]'
+match 0 x '[ab]' '[[::]ab]'
+match 1 x '[ab]' '[[:digit]ab]'
+match 1 x '[ab]' '[\[:]ab]'
+match 1 1 '?a?b' '\??\?b'
+match 1 1 'abc' '\a\b\c'
+match 0 0 'foo' ''
+match 1 0 'foo/bar/baz/to' '**/t[o]'
+
+# Character class tests
+match 1 x 'a1B' '[[:alpha:]][[:digit:]][[:upper:]]'
+match 0 x 'a' '[[:digit:][:upper:][:space:]]'
+match 1 x 'A' '[[:digit:][:upper:][:space:]]'
+match 1 x '1' '[[:digit:][:upper:][:space:]]'
+match 0 x '1' '[[:digit:][:upper:][:spaci:]]'
+match 1 x ' ' '[[:digit:][:upper:][:space:]]'
+match 0 x '.' '[[:digit:][:upper:][:space:]]'
+match 1 x '.' '[[:digit:][:punct:][:space:]]'
+match 1 x '5' '[[:xdigit:]]'
+match 1 x 'f' '[[:xdigit:]]'
+match 1 x 'D' '[[:xdigit:]]'
+match 1 x '_' '[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'
+match 1 x '_' '[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'
+match 1 x '.' '[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]'
+match 1 x '5' '[a-c[:digit:]x-z]'
+match 1 x 'b' '[a-c[:digit:]x-z]'
+match 1 x 'y' '[a-c[:digit:]x-z]'
+match 0 x 'q' '[a-c[:digit:]x-z]'
+
+# Additional tests, including some malformed wildmats
+match 1 x ']' '[\\-^]'
+match 0 0 '[' '[\\-^]'
+match 1 x '-' '[\-_]'
+match 1 x ']' '[\]]'
+match 0 0 '\]' '[\]]'
+match 0 0 '\' '[\]]'
+match 0 0 'ab' 'a[]b'
+match 0 x 'a[]b' 'a[]b'
+match 0 x 'ab[' 'ab['
+match 0 0 'ab' '[!'
+match 0 0 'ab' '[-'
+match 1 1 '-' '[-]'
+match 0 0 '-' '[a-'
+match 0 0 '-' '[!a-'
+match 1 x '-' '[--A]'
+match 1 x '5' '[--A]'
+match 1 1 ' ' '[ --]'
+match 1 1 '$' '[ --]'
+match 1 1 '-' '[ --]'
+match 0 0 '0' '[ --]'
+match 1 x '-' '[---]'
+match 1 x '-' '[------]'
+match 0 0 'j' '[a-e-n]'
+match 1 x '-' '[a-e-n]'
+match 1 x 'a' '[!------]'
+match 0 0 '[' '[]-a]'
+match 1 x '^' '[]-a]'
+match 0 0 '^' '[!]-a]'
+match 1 x '[' '[!]-a]'
+match 1 1 '^' '[a^bc]'
+match 1 x '-b]' '[a-]b]'
+match 0 0 '\' '[\]'
+match 1 1 '\' '[\\]'
+match 0 0 '\' '[!\\]'
+match 1 1 'G' '[A-\\]'
+match 0 0 'aaabbb' 'b*a'
+match 0 0 'aabcaa' '*ba*'
+match 1 1 ',' '[,]'
+match 1 1 ',' '[\\,]'
+match 1 1 '\' '[\\,]'
+match 1 1 '-' '[,-.]'
+match 0 0 '+' '[,-.]'
+match 0 0 '-.]' '[,-.]'
+match 1 1 '2' '[\1-\3]'
+match 1 1 '3' '[\1-\3]'
+match 0 0 '4' '[\1-\3]'
+match 1 1 '\' '[[-\]]'
+match 1 1 '[' '[[-\]]'
+match 1 1 ']' '[[-\]]'
+match 0 0 '-' '[[-\]]'
+
+# Test recursion and the abort code (use "wildtest -i" to see iteration counts)
+match 1 1 '-adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'
+match 0 0 '-adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'
+match 0 0 '-adobe-courier-bold-o-normal--12-120-75-75-/-70-iso8859-1' '-*-*-*-*-*-*-12-*-*-*-m-*-*-*'
+match 1 1 'XXX/adobe/courier/bold/o/normal//12/120/75/75/m/70/iso8859/1' 'XXX/*/*/*/*/*/*/12/*/*/*/m/*/*/*'
+match 0 0 'XXX/adobe/courier/bold/o/normal//12/120/75/75/X/70/iso8859/1' 'XXX/*/*/*/*/*/*/12/*/*/*/m/*/*/*'
+match 1 0 'abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txt' '**/*a*b*g*n*t'
+match 0 0 'abcd/abcdefg/abcdefghijk/abcdefghijklmnop.txtz' '**/*a*b*g*n*t'
+match 0 x foo '*/*/*'
+match 0 x foo/bar '*/*/*'
+match 1 x foo/bba/arr '*/*/*'
+match 0 x foo/bb/aa/rr '*/*/*'
+match 1 x foo/bb/aa/rr '**/**/**'
+match 1 x abcXdefXghi '*X*i'
+match 0 x ab/cXd/efXg/hi '*X*i'
+match 1 x ab/cXd/efXg/hi '*/*X*/*/*i'
+match 1 x ab/cXd/efXg/hi '**/*X*/**/*i'
+
+pathmatch 1 foo foo
+pathmatch 0 foo fo
+pathmatch 1 foo/bar foo/bar
+pathmatch 1 foo/bar 'foo/*'
+pathmatch 1 foo/bba/arr 'foo/*'
+pathmatch 1 foo/bba/arr 'foo/**'
+pathmatch 1 foo/bba/arr 'foo*'
+pathmatch 1 foo/bba/arr 'foo**'
+pathmatch 1 foo/bba/arr 'foo/*arr'
+pathmatch 1 foo/bba/arr 'foo/**arr'
+pathmatch 0 foo/bba/arr 'foo/*z'
+pathmatch 0 foo/bba/arr 'foo/**z'
+pathmatch 1 foo/bar 'foo?bar'
+pathmatch 1 foo/bar 'foo[/]bar'
+pathmatch 0 foo '*/*/*'
+pathmatch 0 foo/bar '*/*/*'
+pathmatch 1 foo/bba/arr '*/*/*'
+pathmatch 1 foo/bb/aa/rr '*/*/*'
+pathmatch 1 abcXdefXghi '*X*i'
+pathmatch 1 ab/cXd/efXg/hi '*/*X*/*/*i'
+pathmatch 1 ab/cXd/efXg/hi '*Xg*i'
+
+test_done
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 80e6be39d7..b08c9f2295 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -7,20 +7,18 @@ test_description='git branch assorted tests'
. ./test-lib.sh
-test_expect_success \
- 'prepare a trivial repository' \
- 'echo Hello > A &&
- git update-index --add A &&
- git commit -m "Initial commit." &&
- echo World >> A &&
- git update-index --add A &&
- git commit -m "Second commit." &&
- HEAD=$(git rev-parse --verify HEAD)'
-
-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_path_is_missing .git/refs/heads/--help
+test_expect_success 'prepare a trivial repository' '
+ echo Hello >A &&
+ git update-index --add A &&
+ git commit -m "Initial commit." &&
+ echo World >>A &&
+ git update-index --add A &&
+ git commit -m "Second commit." &&
+ HEAD=$(git rev-parse --verify HEAD)'
+
+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_path_is_missing .git/refs/heads/--help
'
test_expect_success 'branch -h in broken repository' '
@@ -34,63 +32,67 @@ test_expect_success 'branch -h in broken repository' '
test_i18ngrep "[Uu]sage" broken/usage
'
-test_expect_success \
- 'git branch abc should create a branch' \
- 'git branch abc && test_path_is_file .git/refs/heads/abc'
+test_expect_success 'git branch abc should create a branch' '
+ git branch abc && test_path_is_file .git/refs/heads/abc
+'
+
+test_expect_success 'git branch a/b/c should create a branch' '
+ git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c
+'
-test_expect_success \
- 'git branch a/b/c should create a branch' \
- 'git branch a/b/c && test_path_is_file .git/refs/heads/a/b/c'
+test_expect_success 'git branch HEAD should fail' '
+ test_must_fail git branch HEAD
+'
cat >expect <<EOF
$_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000 branch: Created from master
EOF
-test_expect_success \
- 'git branch -l d/e/f should create a branch and a log' \
- 'GIT_COMMITTER_DATE="2005-05-26 23:30" \
- git branch -l d/e/f &&
- test_path_is_file .git/refs/heads/d/e/f &&
- test_path_is_file .git/logs/refs/heads/d/e/f &&
- test_cmp expect .git/logs/refs/heads/d/e/f'
-
-test_expect_success \
- 'git branch -d d/e/f should delete a branch and a log' \
- 'git branch -d d/e/f &&
- test_path_is_missing .git/refs/heads/d/e/f &&
- test_path_is_missing .git/logs/refs/heads/d/e/f'
-
-test_expect_success \
- 'git branch j/k should work after branch j has been deleted' \
- 'git branch j &&
- git branch -d j &&
- git branch j/k'
-
-test_expect_success \
- 'git branch l should work after branch l/m has been deleted' \
- 'git branch l/m &&
- git branch -d l/m &&
- git branch l'
-
-test_expect_success \
- 'git branch -m dumps usage' \
- 'test_expect_code 129 git branch -m 2>err &&
- test_i18ngrep "[Uu]sage: git branch" err'
-
-test_expect_success \
- 'git branch -m m m/m should work' \
- 'git branch -l m &&
- git branch -m m m/m &&
- test_path_is_file .git/logs/refs/heads/m/m'
-
-test_expect_success \
- 'git branch -m n/n n should work' \
- 'git branch -l n/n &&
+test_expect_success 'git branch -l d/e/f should create a branch and a log' '
+ GIT_COMMITTER_DATE="2005-05-26 23:30" \
+ git branch -l d/e/f &&
+ test_path_is_file .git/refs/heads/d/e/f &&
+ test_path_is_file .git/logs/refs/heads/d/e/f &&
+ test_cmp expect .git/logs/refs/heads/d/e/f
+'
+
+test_expect_success 'git branch -d d/e/f should delete a branch and a log' '
+ git branch -d d/e/f &&
+ test_path_is_missing .git/refs/heads/d/e/f &&
+ test_path_is_missing .git/logs/refs/heads/d/e/f
+'
+
+test_expect_success 'git branch j/k should work after branch j has been deleted' '
+ git branch j &&
+ git branch -d j &&
+ git branch j/k
+'
+
+test_expect_success 'git branch l should work after branch l/m has been deleted' '
+ git branch l/m &&
+ git branch -d l/m &&
+ git branch l
+'
+
+test_expect_success 'git branch -m dumps usage' '
+ test_expect_code 128 git branch -m 2>err &&
+ test_i18ngrep "too many branches for a rename operation" err
+'
+
+test_expect_success 'git branch -m m m/m should work' '
+ git branch -l m &&
+ git branch -m m m/m &&
+ test_path_is_file .git/logs/refs/heads/m/m
+'
+
+test_expect_success 'git branch -m n/n n should work' '
+ git branch -l n/n &&
git branch -m n/n n &&
- test_path_is_file .git/logs/refs/heads/n'
+ test_path_is_file .git/logs/refs/heads/n
+'
test_expect_success 'git branch -m o/o o should fail when o/p exists' '
git branch o/o &&
- git branch o/p &&
+ git branch o/p &&
test_must_fail git branch -m o/o o
'
@@ -248,19 +250,20 @@ mv .git/config-saved .git/config
git config branch.s/s.dummy Hello
-test_expect_success \
- 'git branch -m s/s s should work when s/t is deleted' \
- 'git branch -l s/s &&
+test_expect_success 'git branch -m s/s s should work when s/t is deleted' '
+ git branch -l s/s &&
test_path_is_file .git/logs/refs/heads/s/s &&
- git branch -l s/t &&
+ git branch -l s/t &&
test_path_is_file .git/logs/refs/heads/s/t &&
- git branch -d s/t &&
- git branch -m s/s s &&
- test_path_is_file .git/logs/refs/heads/s'
+ git branch -d s/t &&
+ git branch -m s/s s &&
+ test_path_is_file .git/logs/refs/heads/s
+'
-test_expect_success 'config information was renamed, too' \
- "test $(git config branch.s.dummy) = Hello &&
- test_must_fail git config branch.s/s/dummy"
+test_expect_success 'config information was renamed, too' '
+ test $(git config branch.s.dummy) = Hello &&
+ test_must_fail git config branch.s/s/dummy
+'
test_expect_success 'deleting a symref' '
git branch target &&
@@ -281,8 +284,7 @@ test_expect_success 'deleting a dangling symref' '
test_i18ncmp expect actual
'
-test_expect_success 'renaming a symref is not allowed' \
-'
+test_expect_success 'renaming a symref is not allowed' '
git symbolic-ref refs/heads/master2 refs/heads/master &&
test_must_fail git branch -m master2 master3 &&
git symbolic-ref refs/heads/master2 &&
@@ -290,146 +292,179 @@ test_expect_success 'renaming a symref is not allowed' \
test_path_is_missing .git/refs/heads/master3
'
-test_expect_success SYMLINKS \
- 'git branch -m u v should fail when the reflog for u is a symlink' '
- git branch -l u &&
- mv .git/logs/refs/heads/u real-u &&
- ln -s real-u .git/logs/refs/heads/u &&
- test_must_fail git branch -m u v
-'
-
-test_expect_success 'test tracking setup via --track' \
- 'git config remote.local.url . &&
- git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch --track my1 local/master &&
- test $(git config branch.my1.remote) = local &&
- test $(git config branch.my1.merge) = refs/heads/master'
-
-test_expect_success 'test tracking setup (non-wildcard, matching)' \
- 'git config remote.local.url . &&
- git config remote.local.fetch refs/heads/master:refs/remotes/local/master &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch --track my4 local/master &&
- test $(git config branch.my4.remote) = local &&
- test $(git config branch.my4.merge) = refs/heads/master'
-
-test_expect_success 'test tracking setup (non-wildcard, not matching)' \
- 'git config remote.local.url . &&
- git config remote.local.fetch refs/heads/s:refs/remotes/local/s &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch --track my5 local/master &&
- ! test "$(git config branch.my5.remote)" = local &&
- ! test "$(git config branch.my5.merge)" = refs/heads/master'
-
-test_expect_success 'test tracking setup via config' \
- 'git config branch.autosetupmerge true &&
- git config remote.local.url . &&
- git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch my3 local/master &&
- test $(git config branch.my3.remote) = local &&
- test $(git config branch.my3.merge) = refs/heads/master'
-
-test_expect_success 'test overriding tracking setup via --no-track' \
- 'git config branch.autosetupmerge true &&
- git config remote.local.url . &&
- git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
- (git show-ref -q refs/remotes/local/master || git fetch local) &&
- git branch --no-track my2 local/master &&
- git config branch.autosetupmerge false &&
- ! test "$(git config branch.my2.remote)" = local &&
- ! test "$(git config branch.my2.merge)" = refs/heads/master'
-
-test_expect_success 'no tracking without .fetch entries' \
- 'git config branch.autosetupmerge true &&
- git branch my6 s &&
- git config branch.automsetupmerge false &&
- test -z "$(git config branch.my6.remote)" &&
- test -z "$(git config branch.my6.merge)"'
-
-test_expect_success 'test tracking setup via --track but deeper' \
- 'git config remote.local.url . &&
- git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
- (git show-ref -q refs/remotes/local/o/o || git fetch local) &&
- git branch --track my7 local/o/o &&
- test "$(git config branch.my7.remote)" = local &&
- test "$(git config branch.my7.merge)" = refs/heads/o/o'
-
-test_expect_success 'test deleting branch deletes branch config' \
- 'git branch -d my7 &&
- test -z "$(git config branch.my7.remote)" &&
- test -z "$(git config branch.my7.merge)"'
-
-test_expect_success 'test deleting branch without config' \
- 'git branch my7 s &&
- sha1=$(git rev-parse my7 | cut -c 1-7) &&
- echo "Deleted branch my7 (was $sha1)." >expect &&
- git branch -d my7 >actual 2>&1 &&
- test_i18ncmp expect actual'
-
-test_expect_success 'test --track without .fetch entries' \
- 'git branch --track my8 &&
- test "$(git config branch.my8.remote)" &&
- test "$(git config branch.my8.merge)"'
-
-test_expect_success \
- 'branch from non-branch HEAD w/autosetupmerge=always' \
- 'git config branch.autosetupmerge always &&
- git branch my9 HEAD^ &&
- git config branch.autosetupmerge false'
-
-test_expect_success \
- 'branch from non-branch HEAD w/--track causes failure' \
- 'test_must_fail git branch --track my10 HEAD^'
-
-test_expect_success \
- 'branch from tag w/--track causes failure' \
- 'git tag foobar &&
- test_must_fail git branch --track my11 foobar'
-
-test_expect_success 'use --set-upstream-to modify HEAD' \
- 'test_config branch.master.remote foo &&
- test_config branch.master.merge foo &&
- git branch my12
- git branch --set-upstream-to my12 &&
- test "$(git config branch.master.remote)" = "." &&
- test "$(git config branch.master.merge)" = "refs/heads/my12"'
-
-test_expect_success 'use --set-upstream-to modify a particular branch' \
- 'git branch my13
- git branch --set-upstream-to master my13 &&
- test "$(git config branch.my13.remote)" = "." &&
- test "$(git config branch.my13.merge)" = "refs/heads/master"'
-
-test_expect_success '--unset-upstream should fail if given a non-existent branch' \
- 'test_must_fail git branch --unset-upstream i-dont-exist'
-
-test_expect_success 'test --unset-upstream on HEAD' \
- 'git branch my14
- test_config branch.master.remote foo &&
- test_config branch.master.merge foo &&
- git branch --set-upstream-to my14 &&
- git branch --unset-upstream &&
- test_must_fail git config branch.master.remote &&
- test_must_fail git config branch.master.merge &&
- # fail for a branch without upstream set
- test_must_fail git branch --unset-upstream
-'
-
-test_expect_success 'test --unset-upstream on a particular branch' \
- 'git branch my15
- git branch --set-upstream-to master my14 &&
- git branch --unset-upstream my14 &&
- test_must_fail git config branch.my14.remote &&
- test_must_fail git config branch.my14.merge'
-
-test_expect_success '--set-upstream shows message when creating a new branch that exists as remote-tracking' \
- 'git update-ref refs/remotes/origin/master HEAD &&
- git branch --set-upstream origin/master 2>actual &&
- test_when_finished git update-ref -d refs/remotes/origin/master &&
- test_when_finished git branch -d origin/master &&
- cat >expected <<EOF &&
+test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for u is a symlink' '
+ git branch -l u &&
+ mv .git/logs/refs/heads/u real-u &&
+ ln -s real-u .git/logs/refs/heads/u &&
+ test_must_fail git branch -m u v
+'
+
+test_expect_success 'test tracking setup via --track' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --track my1 local/master &&
+ test $(git config branch.my1.remote) = local &&
+ test $(git config branch.my1.merge) = refs/heads/master
+'
+
+test_expect_success 'test tracking setup (non-wildcard, matching)' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/master:refs/remotes/local/master &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --track my4 local/master &&
+ test $(git config branch.my4.remote) = local &&
+ test $(git config branch.my4.merge) = refs/heads/master
+'
+
+test_expect_success 'test tracking setup (non-wildcard, not matching)' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/s:refs/remotes/local/s &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --track my5 local/master &&
+ ! test "$(git config branch.my5.remote)" = local &&
+ ! test "$(git config branch.my5.merge)" = refs/heads/master
+'
+
+test_expect_success 'test tracking setup via config' '
+ git config branch.autosetupmerge true &&
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch my3 local/master &&
+ test $(git config branch.my3.remote) = local &&
+ test $(git config branch.my3.merge) = refs/heads/master
+'
+
+test_expect_success 'test overriding tracking setup via --no-track' '
+ git config branch.autosetupmerge true &&
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/master || git fetch local) &&
+ git branch --no-track my2 local/master &&
+ git config branch.autosetupmerge false &&
+ ! test "$(git config branch.my2.remote)" = local &&
+ ! test "$(git config branch.my2.merge)" = refs/heads/master
+'
+
+test_expect_success 'no tracking without .fetch entries' '
+ git config branch.autosetupmerge true &&
+ git branch my6 s &&
+ git config branch.automsetupmerge false &&
+ test -z "$(git config branch.my6.remote)" &&
+ test -z "$(git config branch.my6.merge)"
+'
+
+test_expect_success 'test tracking setup via --track but deeper' '
+ git config remote.local.url . &&
+ git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+ (git show-ref -q refs/remotes/local/o/o || git fetch local) &&
+ git branch --track my7 local/o/o &&
+ test "$(git config branch.my7.remote)" = local &&
+ test "$(git config branch.my7.merge)" = refs/heads/o/o
+'
+
+test_expect_success 'test deleting branch deletes branch config' '
+ git branch -d my7 &&
+ test -z "$(git config branch.my7.remote)" &&
+ test -z "$(git config branch.my7.merge)"
+'
+
+test_expect_success 'test deleting branch without config' '
+ git branch my7 s &&
+ sha1=$(git rev-parse my7 | cut -c 1-7) &&
+ echo "Deleted branch my7 (was $sha1)." >expect &&
+ git branch -d my7 >actual 2>&1 &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'test --track without .fetch entries' '
+ git branch --track my8 &&
+ test "$(git config branch.my8.remote)" &&
+ test "$(git config branch.my8.merge)"
+'
+
+test_expect_success 'branch from non-branch HEAD w/autosetupmerge=always' '
+ git config branch.autosetupmerge always &&
+ git branch my9 HEAD^ &&
+ git config branch.autosetupmerge false
+'
+
+test_expect_success 'branch from non-branch HEAD w/--track causes failure' '
+ test_must_fail git branch --track my10 HEAD^
+'
+
+test_expect_success 'branch from tag w/--track causes failure' '
+ git tag foobar &&
+ test_must_fail git branch --track my11 foobar
+'
+
+test_expect_success '--set-upstream-to fails on multiple branches' '
+ test_must_fail git branch --set-upstream-to master a b c
+'
+
+test_expect_success '--set-upstream-to fails on detached HEAD' '
+ git checkout HEAD^{} &&
+ test_must_fail git branch --set-upstream-to master &&
+ git checkout -
+'
+
+test_expect_success 'use --set-upstream-to modify HEAD' '
+ test_config branch.master.remote foo &&
+ test_config branch.master.merge foo &&
+ git branch my12
+ git branch --set-upstream-to my12 &&
+ test "$(git config branch.master.remote)" = "." &&
+ test "$(git config branch.master.merge)" = "refs/heads/my12"
+'
+
+test_expect_success 'use --set-upstream-to modify a particular branch' '
+ git branch my13
+ git branch --set-upstream-to master my13 &&
+ test "$(git config branch.my13.remote)" = "." &&
+ test "$(git config branch.my13.merge)" = "refs/heads/master"
+'
+
+test_expect_success '--unset-upstream should fail if given a non-existent branch' '
+ test_must_fail git branch --unset-upstream i-dont-exist
+'
+
+test_expect_success 'test --unset-upstream on HEAD' '
+ git branch my14
+ test_config branch.master.remote foo &&
+ test_config branch.master.merge foo &&
+ git branch --set-upstream-to my14 &&
+ git branch --unset-upstream &&
+ test_must_fail git config branch.master.remote &&
+ test_must_fail git config branch.master.merge &&
+ # fail for a branch without upstream set
+ test_must_fail git branch --unset-upstream
+'
+
+test_expect_success '--unset-upstream should fail on multiple branches' '
+ test_must_fail git branch --unset-upstream a b c
+'
+
+test_expect_success '--unset-upstream should fail on detached HEAD' '
+ git checkout HEAD^{} &&
+ test_must_fail git branch --unset-upstream &&
+ git checkout -
+'
+
+test_expect_success 'test --unset-upstream on a particular branch' '
+ git branch my15
+ git branch --set-upstream-to master my14 &&
+ git branch --unset-upstream my14 &&
+ test_must_fail git config branch.my14.remote &&
+ test_must_fail git config branch.my14.merge
+'
+
+test_expect_success '--set-upstream shows message when creating a new branch that exists as remote-tracking' '
+ git update-ref refs/remotes/origin/master HEAD &&
+ git branch --set-upstream origin/master 2>actual &&
+ test_when_finished git update-ref -d refs/remotes/origin/master &&
+ test_when_finished git branch -d origin/master &&
+ cat >expected <<EOF &&
The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
If you wanted to make '"'master'"' track '"'origin/master'"', do this:
@@ -437,38 +472,38 @@ If you wanted to make '"'master'"' track '"'origin/master'"', do this:
git branch -d origin/master
git branch --set-upstream-to origin/master
EOF
- test_cmp expected actual
+ test_cmp expected actual
'
-test_expect_success '--set-upstream with two args only shows the deprecation message' \
- 'git branch --set-upstream master my13 2>actual &&
- test_when_finished git branch --unset-upstream master &&
- cat >expected <<EOF &&
+test_expect_success '--set-upstream with two args only shows the deprecation message' '
+ git branch --set-upstream master my13 2>actual &&
+ test_when_finished git branch --unset-upstream master &&
+ cat >expected <<EOF &&
The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
EOF
- test_cmp expected actual
+ test_cmp expected actual
'
-test_expect_success '--set-upstream with one arg only shows the deprecation message if the branch existed' \
- 'git branch --set-upstream my13 2>actual &&
- test_when_finished git branch --unset-upstream my13 &&
- cat >expected <<EOF &&
+test_expect_success '--set-upstream with one arg only shows the deprecation message if the branch existed' '
+ git branch --set-upstream my13 2>actual &&
+ test_when_finished git branch --unset-upstream my13 &&
+ cat >expected <<EOF &&
The --set-upstream flag is deprecated and will be removed. Consider using --track or --set-upstream-to
EOF
- test_cmp expected actual
+ test_cmp 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
EOF
-test_expect_success \
- 'git checkout -b g/h/i -l should create a branch and a log' \
- 'GIT_COMMITTER_DATE="2005-05-26 23:30" \
- git checkout -b g/h/i -l master &&
- test_path_is_file .git/refs/heads/g/h/i &&
- test_path_is_file .git/logs/refs/heads/g/h/i &&
- test_cmp expect .git/logs/refs/heads/g/h/i'
+test_expect_success 'git checkout -b g/h/i -l should create a branch and a log' '
+ GIT_COMMITTER_DATE="2005-05-26 23:30" \
+ git checkout -b g/h/i -l master &&
+ test_path_is_file .git/refs/heads/g/h/i &&
+ test_path_is_file .git/logs/refs/heads/g/h/i &&
+ test_cmp expect .git/logs/refs/heads/g/h/i
+'
test_expect_success 'checkout -b makes reflog by default' '
git checkout master &&
@@ -739,7 +774,7 @@ test_expect_success 'detect misconfigured autosetuprebase (bad value)' '
test_expect_success 'detect misconfigured autosetuprebase (no value)' '
git config --unset branch.autosetuprebase &&
- echo "[branch] autosetuprebase" >> .git/config &&
+ echo "[branch] autosetuprebase" >>.git/config &&
test_must_fail git branch &&
git config --unset branch.autosetuprebase
'
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index f86f4bc5eb..141b0611ea 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -55,6 +55,16 @@ test_expect_success 'branch --contains=side' '
'
+test_expect_success 'branch --contains with pattern implies --list' '
+
+ git branch --contains=master master >actual &&
+ {
+ echo " master"
+ } >expect &&
+ test_cmp expect actual
+
+'
+
test_expect_success 'side: branch --merged' '
git branch --merged >actual &&
@@ -66,6 +76,16 @@ test_expect_success 'side: branch --merged' '
'
+test_expect_success 'branch --merged with pattern implies --list' '
+
+ git branch --merged=side master >actual &&
+ {
+ echo " master"
+ } >expect &&
+ test_cmp expect actual
+
+'
+
test_expect_success 'side: branch --no-merged' '
git branch --no-merged >actual &&
@@ -95,4 +115,19 @@ test_expect_success 'master: branch --no-merged' '
'
+test_expect_success 'branch --no-merged with pattern implies --list' '
+
+ git branch --no-merged=master master >actual &&
+ >expect &&
+ test_cmp expect actual
+
+'
+
+test_expect_success 'implicit --list conflicts with modification options' '
+
+ test_must_fail git branch --contains=master -d &&
+ test_must_fail git branch --contains=master -m foo
+
+'
+
test_done
diff --git a/t/t3211-peel-ref.sh b/t/t3211-peel-ref.sh
new file mode 100755
index 0000000000..d4d7792eae
--- /dev/null
+++ b/t/t3211-peel-ref.sh
@@ -0,0 +1,64 @@
+#!/bin/sh
+
+test_description='tests for the peel_ref optimization of packed-refs'
+. ./test-lib.sh
+
+test_expect_success 'create annotated tag in refs/tags' '
+ test_commit base &&
+ git tag -m annotated foo
+'
+
+test_expect_success 'create annotated tag outside of refs/tags' '
+ git update-ref refs/outside/foo refs/tags/foo
+'
+
+# This matches show-ref's output
+print_ref() {
+ echo "$(git rev-parse "$1") $1"
+}
+
+test_expect_success 'set up expected show-ref output' '
+ {
+ print_ref "refs/heads/master" &&
+ print_ref "refs/outside/foo" &&
+ print_ref "refs/outside/foo^{}" &&
+ print_ref "refs/tags/base" &&
+ print_ref "refs/tags/foo" &&
+ print_ref "refs/tags/foo^{}"
+ } >expect
+'
+
+test_expect_success 'refs are peeled outside of refs/tags (loose)' '
+ git show-ref -d >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'refs are peeled outside of refs/tags (packed)' '
+ git pack-refs --all &&
+ git show-ref -d >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'create old-style pack-refs without fully-peeled' '
+ # Git no longer writes without fully-peeled, so we just write our own
+ # from scratch; we could also munge the existing file to remove the
+ # fully-peeled bits, but that seems even more prone to failure,
+ # especially if the format ever changes again. At least this way we
+ # know we are emulating exactly what an older git would have written.
+ {
+ echo "# pack-refs with: peeled " &&
+ print_ref "refs/heads/master" &&
+ print_ref "refs/outside/foo" &&
+ print_ref "refs/tags/base" &&
+ print_ref "refs/tags/foo" &&
+ echo "^$(git rev-parse "refs/tags/foo^{}")"
+ } >tmp &&
+ mv tmp .git/packed-refs
+'
+
+test_expect_success 'refs are peeled outside of refs/tags (old packed)' '
+ git show-ref -d >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 32fdc9938e..15dcbd42d3 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -29,12 +29,6 @@ Initial setup:
. "$TEST_DIRECTORY"/lib-rebase.sh
-test_cmp_rev () {
- git rev-parse --verify "$1" >expect.rev &&
- git rev-parse --verify "$2" >actual.rev &&
- test_cmp expect.rev actual.rev
-}
-
set_fake_editor
# WARNING: Modifications to the initial repository can change the SHA ID used
@@ -940,4 +934,18 @@ test_expect_success 'rebase --edit-todo can be used to modify todo' '
test L = $(git cat-file commit HEAD | sed -ne \$p)
'
+test_expect_success 'rebase -i respects core.commentchar' '
+ git reset --hard &&
+ git checkout E^0 &&
+ git config core.commentchar "\\" &&
+ test_when_finished "git config --unset core.commentchar" &&
+ write_script remove-all-but-first.sh <<-\EOF &&
+ sed -e "2,\$s/^/\\\\/" "$1" >"$1.tmp" &&
+ mv "$1.tmp" "$1"
+ EOF
+ test_set_editor "$(pwd)/remove-all-but-first.sh" &&
+ git rebase -i B &&
+ test B = $(git cat-file commit HEAD^ | sed -ne \$p)
+'
+
test_done
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 34c86e5de6..6f489e20ee 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -100,4 +100,13 @@ test_expect_success 'revert forbidden on dirty working tree' '
'
+test_expect_success 'chery-pick on unborn branch' '
+ git checkout --orphan unborn &&
+ git rm --cached -r . &&
+ rm -rf * &&
+ git cherry-pick initial &&
+ git diff --quiet initial &&
+ ! test_cmp_rev initial HEAD
+'
+
test_done
diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
index 51ca391e47..373aad623c 100755
--- a/t/t3506-cherry-pick-ff.sh
+++ b/t/t3506-cherry-pick-ff.sh
@@ -105,4 +105,12 @@ test_expect_success 'cherry pick a root commit with --ff' '
test "$(git rev-parse --verify HEAD)" = "1df192cd8bc58a2b275d842cede4d221ad9000d1"
'
+test_expect_success 'chery-pick --ff on unborn branch' '
+ git checkout --orphan unborn &&
+ git rm --cached -r . &&
+ rm -rf * &&
+ git cherry-pick --ff first &&
+ test_cmp_rev first HEAD
+'
+
test_done
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index c82f7210c4..223b98433c 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -11,12 +11,6 @@ test_description='test cherry-pick and revert with conflicts
. ./test-lib.sh
-test_cmp_rev () {
- git rev-parse --verify "$1" >expect.rev &&
- git rev-parse --verify "$2" >actual.rev &&
- test_cmp expect.rev actual.rev
-}
-
pristine_detach () {
git checkout -f "$1^0" &&
git read-tree -u --reset HEAD &&
diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh
index 340afc760d..4e7136b837 100755
--- a/t/t3508-cherry-pick-many-commits.sh
+++ b/t/t3508-cherry-pick-many-commits.sh
@@ -5,15 +5,11 @@ test_description='test cherry-picking many commits'
. ./test-lib.sh
check_head_differs_from() {
- head=$(git rev-parse --verify HEAD) &&
- arg=$(git rev-parse --verify "$1") &&
- test "$head" != "$arg"
+ ! test_cmp_rev HEAD "$1"
}
check_head_equals() {
- head=$(git rev-parse --verify HEAD) &&
- arg=$(git rev-parse --verify "$1") &&
- test "$head" = "$arg"
+ test_cmp_rev HEAD "$1"
}
test_expect_success setup '
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index b5fb527b2e..7b7a89dbd5 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -24,12 +24,6 @@ pristine_detach () {
git clean -d -f -f -q -x
}
-test_cmp_rev () {
- git rev-parse --verify "$1" >expect.rev &&
- git rev-parse --verify "$2" >actual.rev &&
- test_cmp expect.rev actual.rev
-}
-
test_expect_success setup '
git config advice.detachedhead false &&
echo unrelated >unrelated &&
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 9fd28bcf34..37bf5f13b0 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -262,4 +262,364 @@ test_expect_success 'rm removes subdirectories recursively' '
! test -d dir
'
+cat >expect <<EOF
+D submod
+EOF
+
+cat >expect.modified <<EOF
+ M submod
+EOF
+
+test_expect_success 'rm removes empty submodules from work tree' '
+ mkdir submod &&
+ git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) submod &&
+ git config -f .gitmodules submodule.sub.url ./. &&
+ git config -f .gitmodules submodule.sub.path submod &&
+ git submodule init &&
+ git add .gitmodules &&
+ git commit -m "add submodule" &&
+ git rm submod &&
+ test ! -e submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm removes removed submodule from index' '
+ git reset --hard &&
+ git submodule update &&
+ rm -rf submod &&
+ git rm submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm removes work tree of unmodified submodules' '
+ git reset --hard &&
+ git submodule update &&
+ git rm submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm removes a submodule with a trailing /' '
+ git reset --hard &&
+ git submodule update &&
+ git rm submod/ &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm fails when given a file with a trailing /' '
+ test_must_fail git rm empty/
+'
+
+test_expect_success 'rm succeeds when given a directory with a trailing /' '
+ git rm -r frotz/
+'
+
+test_expect_success 'rm of a populated submodule with different HEAD fails unless forced' '
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ git checkout HEAD^
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with modifications fails unless forced' '
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ echo X >empty
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with untracked files fails unless forced' '
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ echo X >untracked
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'setup submodule conflict' '
+ git reset --hard &&
+ git submodule update &&
+ git checkout -b branch1 &&
+ echo 1 >nitfol &&
+ git add nitfol &&
+ git commit -m "added nitfol 1" &&
+ git checkout -b branch2 master &&
+ echo 2 >nitfol &&
+ git add nitfol &&
+ git commit -m "added nitfol 2" &&
+ git checkout -b conflict1 master &&
+ (cd submod &&
+ git fetch &&
+ git checkout branch1
+ ) &&
+ git add submod &&
+ git commit -m "submod 1" &&
+ git checkout -b conflict2 master &&
+ (cd submod &&
+ git checkout branch2
+ ) &&
+ git add submod &&
+ git commit -m "submod 2"
+'
+
+cat >expect.conflict <<EOF
+UU submod
+EOF
+
+test_expect_success 'rm removes work tree of unmodified conflicted submodule' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ test_must_fail git merge conflict2 &&
+ git rm submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with different HEAD fails unless forced' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ git checkout HEAD^
+ ) &&
+ test_must_fail git merge conflict2 &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with modifications fails unless forced' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ echo X >empty
+ ) &&
+ test_must_fail git merge conflict2 &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with untracked files fails unless forced' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ echo X >untracked
+ ) &&
+ test_must_fail git merge conflict2 &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a conflicted populated submodule with a .git directory fails even when forced' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ rm .git &&
+ cp -R ../.git/modules/sub .git &&
+ GIT_WORK_TREE=. git config --unset core.worktree
+ ) &&
+ test_must_fail git merge conflict2 &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -d submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ test_must_fail git rm -f submod &&
+ test -d submod &&
+ test -d submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.conflict actual &&
+ git merge --abort &&
+ rm -rf submod
+'
+
+test_expect_success 'rm of a conflicted unpopulated submodule succeeds' '
+ git checkout conflict1 &&
+ git reset --hard &&
+ test_must_fail git merge conflict2 &&
+ git rm submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated submodule with a .git directory fails even when forced' '
+ git checkout -f master &&
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ rm .git &&
+ cp -R ../.git/modules/sub .git &&
+ GIT_WORK_TREE=. git config --unset core.worktree
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -d submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ ! test -s actual &&
+ test_must_fail git rm -f submod &&
+ test -d submod &&
+ test -d submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ ! test -s actual &&
+ rm -rf submod
+'
+
+cat >expect.deepmodified <<EOF
+ M submod/subsubmod
+EOF
+
+test_expect_success 'setup subsubmodule' '
+ git reset --hard &&
+ git submodule update &&
+ (cd submod &&
+ git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) subsubmod &&
+ git config -f .gitmodules submodule.sub.url ../. &&
+ git config -f .gitmodules submodule.sub.path subsubmod &&
+ git submodule init &&
+ git add .gitmodules &&
+ git commit -m "add subsubmodule" &&
+ git submodule update subsubmod
+ ) &&
+ git commit -a -m "added deep submodule"
+'
+
+test_expect_success 'rm recursively removes work tree of unmodified submodules' '
+ git rm submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with different nested HEAD fails unless forced' '
+ git reset --hard &&
+ git submodule update --recursive &&
+ (cd submod/subsubmod &&
+ git checkout HEAD^
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with nested modifications fails unless forced' '
+ git reset --hard &&
+ git submodule update --recursive &&
+ (cd submod/subsubmod &&
+ echo X >empty
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with nested untracked files fails unless forced' '
+ git reset --hard &&
+ git submodule update --recursive &&
+ (cd submod/subsubmod &&
+ echo X >untracked
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -f submod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect.modified actual &&
+ git rm -f submod &&
+ test ! -d submod &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rm of a populated nested submodule with a nested .git directory fails even when forced' '
+ git reset --hard &&
+ git submodule update --recursive &&
+ (cd submod/subsubmod &&
+ rm .git &&
+ cp -R ../../.git/modules/sub/modules/sub .git &&
+ GIT_WORK_TREE=. git config --unset core.worktree
+ ) &&
+ test_must_fail git rm submod &&
+ test -d submod &&
+ test -d submod/subsubmod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ ! test -s actual &&
+ test_must_fail git rm -f submod &&
+ test -d submod &&
+ test -d submod/subsubmod/.git &&
+ git status -s -uno --ignore-submodules=none > actual &&
+ ! test -s actual &&
+ rm -rf submod
+'
+
test_done
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 098a6ae4a0..9fab25cc96 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -319,7 +319,7 @@ test_expect_success PERL 'split hunk "add -p (edit)"' '
# times to get out.
#
# 2. Correct version applies the (not)edited version, and asks
- # about the next hunk, against wich we say q and program
+ # about the next hunk, against which we say q and program
# exits.
for a in s e q n q q
do
diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh
index 844277cfa6..2f327b7495 100755
--- a/t/t4001-diff-rename.sh
+++ b/t/t4001-diff-rename.sh
@@ -102,4 +102,58 @@ test_expect_success 'setup for many rename source candidates' '
grep warning actual.err
'
+test_expect_success 'rename pretty print with nothing in common' '
+ mkdir -p a/b/ &&
+ : >a/b/c &&
+ git add a/b/c &&
+ git commit -m "create a/b/c" &&
+ mkdir -p c/b/ &&
+ git mv a/b/c c/b/a &&
+ git commit -m "a/b/c -> c/b/a" &&
+ git diff -M --summary HEAD^ HEAD >output &&
+ test_i18ngrep " a/b/c => c/b/a " output &&
+ git diff -M --stat HEAD^ HEAD >output &&
+ test_i18ngrep " a/b/c => c/b/a " output
+'
+
+test_expect_success 'rename pretty print with common prefix' '
+ mkdir -p c/d &&
+ git mv c/b/a c/d/e &&
+ git commit -m "c/b/a -> c/d/e" &&
+ git diff -M --summary HEAD^ HEAD >output &&
+ test_i18ngrep " c/{b/a => d/e} " output &&
+ git diff -M --stat HEAD^ HEAD >output &&
+ test_i18ngrep " c/{b/a => d/e} " output
+'
+
+test_expect_success 'rename pretty print with common suffix' '
+ mkdir d &&
+ git mv c/d/e d/e &&
+ git commit -m "c/d/e -> d/e" &&
+ git diff -M --summary HEAD^ HEAD >output &&
+ test_i18ngrep " {c/d => d}/e " output &&
+ git diff -M --stat HEAD^ HEAD >output &&
+ test_i18ngrep " {c/d => d}/e " output
+'
+
+test_expect_success 'rename pretty print with common prefix and suffix' '
+ mkdir d/f &&
+ git mv d/e d/f/e &&
+ git commit -m "d/e -> d/f/e" &&
+ git diff -M --summary HEAD^ HEAD >output &&
+ test_i18ngrep " d/{ => f}/e " output &&
+ git diff -M --stat HEAD^ HEAD >output &&
+ test_i18ngrep " d/{ => f}/e " output
+'
+
+test_expect_success 'rename pretty print common prefix and suffix overlap' '
+ mkdir d/f/f &&
+ git mv d/f/e d/f/f/e &&
+ git commit -m "d/f/e d/f/f/e" &&
+ git diff -M --summary HEAD^ HEAD >output &&
+ test_i18ngrep " d/f/{ => f}/e " output &&
+ git diff -M --stat HEAD^ HEAD >output &&
+ test_i18ngrep " d/f/{ => f}/e " output
+'
+
test_done
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index ad9f69e607..183fbe5bb3 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -155,7 +155,7 @@ test_expect_failure 'additional command line cc (rfc822)' '
git config --replace-all format.headers "Cc: R E Cipient <rcipient@example.com>" &&
git format-patch --cc="S. E. Cipient <scipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch5 &&
grep "^Cc: R E Cipient <rcipient@example.com>,\$" patch5 &&
- grep "^ *"S. E. Cipient" <scipient@example.com>\$" patch5
+ grep "^ *\"S. E. Cipient\" <scipient@example.com>\$" patch5
'
test_expect_success 'command line headers' '
@@ -183,7 +183,7 @@ test_expect_success 'command line To: header (ascii)' '
test_expect_failure 'command line To: header (rfc822)' '
git format-patch --to="R. E. Cipient <rcipient@example.com>" --stdout master..side | sed -e "/^\$/q" >patch8 &&
- grep "^To: "R. E. Cipient" <rcipient@example.com>\$" patch8
+ grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch8
'
test_expect_failure 'command line To: header (rfc2047)' '
@@ -203,7 +203,7 @@ test_expect_failure 'configuration To: header (rfc822)' '
git config format.to "R. E. Cipient <rcipient@example.com>" &&
git format-patch --stdout master..side | sed -e "/^\$/q" >patch9 &&
- grep "^To: "R. E. Cipient" <rcipient@example.com>\$" patch9
+ grep "^To: \"R. E. Cipient\" <rcipient@example.com>\$" patch9
'
test_expect_failure 'configuration To: header (rfc2047)' '
@@ -271,6 +271,22 @@ test_expect_success 'multiple files' '
ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
'
+test_expect_success 'reroll count' '
+ rm -fr patches &&
+ git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
+ ! grep -v "^patches/v4-000[0-3]-" list &&
+ sed -n -e "/^Subject: /p" $(cat list) >subjects &&
+ ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
+'
+
+test_expect_success 'reroll count (-v)' '
+ rm -fr patches &&
+ git format-patch -o patches --cover-letter -v4 master..side >list &&
+ ! grep -v "^patches/v4-000[0-3]-" list &&
+ sed -n -e "/^Subject: /p" $(cat list) >subjects &&
+ ! grep -v "^Subject: \[PATCH v4 [0-3]/3\] " subjects
+'
+
check_threading () {
expect="$1" &&
shift &&
@@ -650,8 +666,19 @@ test_expect_success 'format-patch --in-reply-to' '
'
test_expect_success 'format-patch --signoff' '
- git format-patch -1 --signoff --stdout |
- grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+ git format-patch -1 --signoff --stdout >out &&
+ grep "^Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" out
+'
+
+test_expect_success 'format-patch --notes --signoff' '
+ git notes --ref test add -m "test message" HEAD &&
+ git format-patch -1 --signoff --stdout --notes=test >out &&
+ # Three dashes must come after S-o-b
+ ! sed "/^Signed-off-by: /q" out | grep "test message" &&
+ sed "1,/^Signed-off-by: /d" out | grep "test message" &&
+ # Notes message must come after three dashes
+ ! sed "/^---$/q" out | grep "test message" &&
+ sed "1,/^---$/d" out | grep "test message"
'
echo "fatal: --name-only does not make sense" > expect.name-only
@@ -715,21 +742,21 @@ test_expect_success 'format-patch --signature --cover-letter' '
test 2 = $(grep "my sig" output | wc -l)
'
-test_expect_success 'format.signature="" supresses signatures' '
+test_expect_success 'format.signature="" suppresses signatures' '
git config format.signature "" &&
git format-patch --stdout -1 >output &&
check_patch output &&
! grep "^-- \$" output
'
-test_expect_success 'format-patch --no-signature supresses signatures' '
+test_expect_success 'format-patch --no-signature suppresses signatures' '
git config --unset-all format.signature &&
git format-patch --stdout --no-signature -1 >output &&
check_patch output &&
! grep "^-- \$" output
'
-test_expect_success 'format-patch --signature="" supresses signatures' '
+test_expect_success 'format-patch --signature="" suppresses signatures' '
git format-patch --stdout --signature="" -1 >output &&
check_patch output &&
! grep "^-- \$" output
@@ -810,25 +837,26 @@ Subject: [PATCH] =?UTF-8?q?f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
=?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
=?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
=?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
- =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
- =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
- =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
=?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
=?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
=?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
- =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
- =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
- =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
=?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
=?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
=?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
- =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3?=
- =?UTF-8?q?=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
- =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3?=
- =?UTF-8?q?=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
- =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
+ =?UTF-8?q?bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6?=
+ =?UTF-8?q?=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6?=
+ =?UTF-8?q?=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f?=
+ =?UTF-8?q?=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar?=
+ =?UTF-8?q?=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20bar=20f=C3=B6=C3=B6=20?=
+ =?UTF-8?q?bar?=
EOF
test_expect_success 'format-patch wraps extremely long subject (rfc2047)' '
rm -rf patches/ &&
@@ -952,4 +980,46 @@ test_expect_success 'format patch ignores color.ui' '
test_cmp expect actual
'
+test_expect_success 'cover letter using branch description (1)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter master >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (2)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter rebuild-1~2..rebuild-1 >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (3)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter ^master rebuild-1 >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (4)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter master.. >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (5)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter -2 HEAD >actual &&
+ grep hello actual >/dev/null
+'
+
+test_expect_success 'cover letter using branch description (6)' '
+ git checkout rebuild-1 &&
+ test_config branch.rebuild-1.description hello &&
+ git format-patch --stdout --cover-letter -2 >actual &&
+ grep hello actual >/dev/null
+'
+
test_done
diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index 082d3e83bd..38a092a0da 100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
@@ -93,11 +93,6 @@ sed -e '
s/song;/song();/
' <Beer.perl >Beer-correct.perl
-test_config () {
- git config "$1" "$2" &&
- test_when_finished "git config --unset $1"
-}
-
test_expect_funcname () {
lang=${2-java}
test_expect_code 1 git diff --no-index -U1 \
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index 40277c77aa..b7e16a7840 100755
--- a/t/t4038-diff-combined.sh
+++ b/t/t4038-diff-combined.sh
@@ -3,6 +3,7 @@
test_description='combined diff'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/diff-lib.sh
setup_helper () {
one=$1 branch=$2 side=$3 &&
@@ -89,4 +90,138 @@ test_expect_success 'diagnose truncated file' '
grep "diff --cc file" out
'
+test_expect_success 'setup for --cc --raw' '
+ blob=$(echo file | git hash-object --stdin -w) &&
+ base_tree=$(echo "100644 blob $blob file" | git mktree) &&
+ trees= &&
+ for i in `test_seq 1 40`
+ do
+ blob=$(echo file$i | git hash-object --stdin -w) &&
+ trees="$trees$(echo "100644 blob $blob file" | git mktree)$LF"
+ done
+'
+
+test_expect_success 'check --cc --raw with four trees' '
+ four_trees=$(echo "$trees" | sed -e 4q) &&
+ git diff --cc --raw $four_trees $base_tree >out &&
+ # Check for four leading colons in the output:
+ grep "^::::[^:]" out
+'
+
+test_expect_success 'check --cc --raw with forty trees' '
+ git diff --cc --raw $trees $base_tree >out &&
+ # Check for forty leading colons in the output:
+ grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out
+'
+
+test_expect_success 'setup combined ignore spaces' '
+ git checkout master &&
+ >test &&
+ git add test &&
+ git commit -m initial &&
+
+ tr -d Q <<-\EOF >test &&
+ always coalesce
+ eol space coalesce Q
+ space change coalesce
+ all spa ces coalesce
+ eol spaces Q
+ space change
+ all spa ces
+ EOF
+ git commit -m "test space change" -a &&
+
+ git checkout -b side HEAD^ &&
+ tr -d Q <<-\EOF >test &&
+ always coalesce
+ eol space coalesce
+ space change coalesce
+ all spaces coalesce
+ eol spaces
+ space change
+ all spaces
+ EOF
+ git commit -m "test other space changes" -a &&
+
+ test_must_fail git merge master &&
+ tr -d Q <<-\EOF >test &&
+ eol spaces Q
+ space change
+ all spa ces
+ EOF
+ git commit -m merged -a
+'
+
+test_expect_success 'check combined output (no ignore space)' '
+ git show >actual.tmp &&
+ sed -e "1,/^@@@/d" < actual.tmp >actual &&
+ tr -d Q <<-\EOF >expected &&
+ --always coalesce
+ - eol space coalesce
+ - space change coalesce
+ - all spaces coalesce
+ - eol spaces
+ - space change
+ - all spaces
+ -eol space coalesce Q
+ -space change coalesce
+ -all spa ces coalesce
+ + eol spaces Q
+ + space change
+ + all spa ces
+ EOF
+ compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore space at eol)' '
+ git show --ignore-space-at-eol >actual.tmp &&
+ sed -e "1,/^@@@/d" < actual.tmp >actual &&
+ tr -d Q <<-\EOF >expected &&
+ --always coalesce
+ --eol space coalesce
+ - space change coalesce
+ - all spaces coalesce
+ -space change coalesce
+ -all spa ces coalesce
+ eol spaces Q
+ - space change
+ - all spaces
+ + space change
+ + all spa ces
+ EOF
+ compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore space change)' '
+ git show -b >actual.tmp &&
+ sed -e "1,/^@@@/d" < actual.tmp >actual &&
+ tr -d Q <<-\EOF >expected &&
+ --always coalesce
+ --eol space coalesce
+ --space change coalesce
+ - all spaces coalesce
+ -all spa ces coalesce
+ eol spaces Q
+ space change
+ - all spaces
+ + all spa ces
+ EOF
+ compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore all spaces)' '
+ git show -w >actual.tmp &&
+ sed -e "1,/^@@@/d" < actual.tmp >actual &&
+ tr -d Q <<-\EOF >expected &&
+ --always coalesce
+ --eol space coalesce
+ --space change coalesce
+ --all spaces coalesce
+ eol spaces Q
+ space change
+ all spa ces
+ EOF
+ compare_diff_patch expected actual
+'
+
test_done
diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh
index 6c01d0c056..32d4a60425 100755
--- a/t/t4041-diff-submodule-option.sh
+++ b/t/t4041-diff-submodule-option.sh
@@ -11,18 +11,18 @@ This test tries to verify the sanity of the --submodule option of git diff.
. ./test-lib.sh
add_file () {
- sm=$1
- shift
- owd=$(pwd)
- cd "$sm"
- for name; do
- echo "$name" > "$name" &&
- git add "$name" &&
- test_tick &&
- git commit -m "Add $name"
- done >/dev/null
- git rev-parse --verify HEAD | cut -c1-7
- cd "$owd"
+ (
+ cd "$1" &&
+ shift &&
+ for name
+ do
+ echo "$name" >"$name" &&
+ git add "$name" &&
+ test_tick &&
+ git commit -m "Add $name" || exit
+ done >/dev/null &&
+ git rev-parse --short --verify HEAD
+ )
}
commit_file () {
test_tick &&
@@ -33,92 +33,133 @@ test_create_repo sm1 &&
add_file . foo >/dev/null
head1=$(add_file sm1 foo1 foo2)
+fullhead1=$(cd sm1; git rev-parse --verify HEAD)
-test_expect_success 'added submodule' "
+test_expect_success 'added submodule' '
git add sm1 &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 0000000...$head1 (new submodule)
-EOF
+ Submodule sm1 0000000...$head1 (new submodule)
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'added submodule, set diff.submodule' '
+ git config diff.submodule log &&
+ git add sm1 &&
+ git diff --cached >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 0000000...$head1 (new submodule)
+ EOF
+ git config --unset diff.submodule &&
+ test_cmp expected actual
+'
+
+test_expect_success '--submodule=short overrides diff.submodule' '
+ test_config diff.submodule log &&
+ git add sm1 &&
+ git diff --submodule=short --cached >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ new file mode 160000
+ index 0000000..$head1
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +Subproject commit $fullhead1
+ EOF
test_cmp expected actual
-"
+'
+
+test_expect_success 'diff.submodule does not affect plumbing' '
+ test_config diff.submodule log &&
+ git diff-index -p HEAD >actual &&
+ cat >expected <<-EOF &&
+ diff --git a/sm1 b/sm1
+ new file mode 160000
+ index 0000000..$head1
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +Subproject commit $fullhead1
+ EOF
+ test_cmp expected actual
+'
commit_file sm1 &&
head2=$(add_file sm1 foo3)
-test_expect_success 'modified submodule(forward)' "
+test_expect_success 'modified submodule(forward)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head1..$head2:
- > Add foo3
-EOF
+ Submodule sm1 $head1..$head2:
+ > Add foo3
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule(forward)' "
+test_expect_success 'modified submodule(forward)' '
git diff --submodule=log >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head1..$head2:
- > Add foo3
-EOF
+ Submodule sm1 $head1..$head2:
+ > Add foo3
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule(forward) --submodule' "
+test_expect_success 'modified submodule(forward) --submodule' '
git diff --submodule >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head1..$head2:
- > Add foo3
-EOF
+ Submodule sm1 $head1..$head2:
+ > Add foo3
+ EOF
test_cmp expected actual
-"
+'
-fullhead1=$(cd sm1; git rev-list --max-count=1 $head1)
-fullhead2=$(cd sm1; git rev-list --max-count=1 $head2)
-test_expect_success 'modified submodule(forward) --submodule=short' "
+fullhead2=$(cd sm1; git rev-parse --verify HEAD)
+test_expect_success 'modified submodule(forward) --submodule=short' '
git diff --submodule=short >actual &&
cat >expected <<-EOF &&
-diff --git a/sm1 b/sm1
-index $head1..$head2 160000
---- a/sm1
-+++ b/sm1
-@@ -1 +1 @@
--Subproject commit $fullhead1
-+Subproject commit $fullhead2
-EOF
+ diff --git a/sm1 b/sm1
+ index $head1..$head2 160000
+ --- a/sm1
+ +++ b/sm1
+ @@ -1 +1 @@
+ -Subproject commit $fullhead1
+ +Subproject commit $fullhead2
+ EOF
test_cmp expected actual
-"
+'
commit_file sm1 &&
head3=$(
cd sm1 &&
git reset --hard HEAD~2 >/dev/null &&
- git rev-parse --verify HEAD | cut -c1-7
+ git rev-parse --short --verify HEAD
)
-test_expect_success 'modified submodule(backward)' "
+test_expect_success 'modified submodule(backward)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head2..$head3 (rewind):
- < Add foo3
- < Add foo2
-EOF
+ Submodule sm1 $head2..$head3 (rewind):
+ < Add foo3
+ < Add foo2
+ EOF
test_cmp expected actual
-"
+'
-head4=$(add_file sm1 foo4 foo5) &&
-head4_full=$(GIT_DIR=sm1/.git git rev-parse --verify HEAD)
-test_expect_success 'modified submodule(backward and forward)' "
+head4=$(add_file sm1 foo4 foo5)
+test_expect_success 'modified submodule(backward and forward)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head2...$head4:
- > Add foo5
- > Add foo4
- < Add foo3
- < Add foo2
-EOF
+ Submodule sm1 $head2...$head4:
+ > Add foo5
+ > Add foo4
+ < Add foo3
+ < Add foo2
+ EOF
test_cmp expected actual
-"
+'
commit_file sm1 &&
mv sm1 sm1-bak &&
@@ -128,319 +169,319 @@ git add sm1 &&
rm -f sm1 &&
mv sm1-bak sm1
-test_expect_success 'typechanged submodule(submodule->blob), --cached' "
+test_expect_success 'typechanged submodule(submodule->blob), --cached' '
git diff --submodule=log --cached >actual &&
cat >expected <<-EOF &&
-Submodule sm1 41fbea9...0000000 (submodule deleted)
-diff --git a/sm1 b/sm1
-new file mode 100644
-index 0000000..9da5fb8
---- /dev/null
-+++ b/sm1
-@@ -0,0 +1 @@
-+sm1
-EOF
+ Submodule sm1 $head4...0000000 (submodule deleted)
+ diff --git a/sm1 b/sm1
+ new file mode 100644
+ index 0000000..$head5
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +sm1
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'typechanged submodule(submodule->blob)' "
+test_expect_success 'typechanged submodule(submodule->blob)' '
git diff --submodule=log >actual &&
cat >expected <<-EOF &&
-diff --git a/sm1 b/sm1
-deleted file mode 100644
-index 9da5fb8..0000000
---- a/sm1
-+++ /dev/null
-@@ -1 +0,0 @@
--sm1
-Submodule sm1 0000000...$head4 (new submodule)
-EOF
+ diff --git a/sm1 b/sm1
+ deleted file mode 100644
+ index $head5..0000000
+ --- a/sm1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -sm1
+ Submodule sm1 0000000...$head4 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
rm -rf sm1 &&
git checkout-index sm1
-test_expect_success 'typechanged submodule(submodule->blob)' "
+test_expect_success 'typechanged submodule(submodule->blob)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head4...0000000 (submodule deleted)
-diff --git a/sm1 b/sm1
-new file mode 100644
-index 0000000..$head5
---- /dev/null
-+++ b/sm1
-@@ -0,0 +1 @@
-+sm1
-EOF
+ Submodule sm1 $head4...0000000 (submodule deleted)
+ diff --git a/sm1 b/sm1
+ new file mode 100644
+ index 0000000..$head5
+ --- /dev/null
+ +++ b/sm1
+ @@ -0,0 +1 @@
+ +sm1
+ EOF
test_cmp expected actual
-"
+'
rm -f sm1 &&
test_create_repo sm1 &&
head6=$(add_file sm1 foo6 foo7)
-fullhead6=$(cd sm1; git rev-list --max-count=1 $head6)
-test_expect_success 'nonexistent commit' "
+fullhead6=$(cd sm1; git rev-parse --verify HEAD)
+test_expect_success 'nonexistent commit' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head4...$head6 (commits not present)
-EOF
+ Submodule sm1 $head4...$head6 (commits not present)
+ EOF
test_cmp expected actual
-"
+'
commit_file
-test_expect_success 'typechanged submodule(blob->submodule)' "
+test_expect_success 'typechanged submodule(blob->submodule)' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-diff --git a/sm1 b/sm1
-deleted file mode 100644
-index $head5..0000000
---- a/sm1
-+++ /dev/null
-@@ -1 +0,0 @@
--sm1
-Submodule sm1 0000000...$head6 (new submodule)
-EOF
+ diff --git a/sm1 b/sm1
+ deleted file mode 100644
+ index $head5..0000000
+ --- a/sm1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -sm1
+ Submodule sm1 0000000...$head6 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
commit_file sm1 &&
-test_expect_success 'submodule is up to date' "
+test_expect_success 'submodule is up to date' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-EOF
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'submodule contains untracked content' "
+test_expect_success 'submodule contains untracked content' '
echo new > sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains untracked content
-EOF
+ Submodule sm1 contains untracked content
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'submodule contains untracked content (untracked ignored)' "
+test_expect_success 'submodule contains untracked content (untracked ignored)' '
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains untracked content (dirty ignored)' "
+test_expect_success 'submodule contains untracked content (dirty ignored)' '
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains untracked content (all ignored)' "
+test_expect_success 'submodule contains untracked content (all ignored)' '
git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains untracked and modifed content' "
+test_expect_success 'submodule contains untracked and modifed content' '
echo new > sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains untracked content
-Submodule sm1 contains modified content
-EOF
+ Submodule sm1 contains untracked content
+ Submodule sm1 contains modified content
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' "
+test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains modified content
-EOF
+ Submodule sm1 contains modified content
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' "
+test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains untracked and modifed content (all ignored)' "
+test_expect_success 'submodule contains untracked and modifed content (all ignored)' '
echo new > sm1/foo6 &&
git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'submodule contains modifed content' "
+test_expect_success 'submodule contains modifed content' '
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains modified content
-EOF
+ Submodule sm1 contains modified content
+ EOF
test_cmp expected actual
-"
+'
(cd sm1; git commit -mchange foo6 >/dev/null) &&
-head8=$(cd sm1; git rev-parse --verify HEAD | cut -c1-7) &&
-test_expect_success 'submodule is modified' "
+head8=$(cd sm1; git rev-parse --short --verify HEAD) &&
+test_expect_success 'submodule is modified' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked content' "
+test_expect_success 'modified submodule contains untracked content' '
echo new > sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains untracked content
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 contains untracked content
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked content (untracked ignored)' "
+test_expect_success 'modified submodule contains untracked content (untracked ignored)' '
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked content (dirty ignored)' "
+test_expect_success 'modified submodule contains untracked content (dirty ignored)' '
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked content (all ignored)' "
+test_expect_success 'modified submodule contains untracked content (all ignored)' '
git diff-index -p --ignore-submodules=all --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'modified submodule contains untracked and modifed content' "
+test_expect_success 'modified submodule contains untracked and modifed content' '
echo modification >> sm1/foo6 &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains untracked content
-Submodule sm1 contains modified content
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 contains untracked content
+ Submodule sm1 contains modified content
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' "
+test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains modified content
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 contains modified content
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' "
+test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' "
+test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' '
echo modification >> sm1/foo6 &&
git diff-index -p --ignore-submodules --submodule=log HEAD >actual &&
! test -s actual
-"
+'
-test_expect_success 'modified submodule contains modifed content' "
+test_expect_success 'modified submodule contains modifed content' '
rm -f sm1/new-file &&
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 contains modified content
-Submodule sm1 $head6..$head8:
- > change
-EOF
+ Submodule sm1 contains modified content
+ Submodule sm1 $head6..$head8:
+ > change
+ EOF
test_cmp expected actual
-"
+'
rm -rf sm1
-test_expect_success 'deleted submodule' "
+test_expect_success 'deleted submodule' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ EOF
test_cmp expected actual
-"
+'
test_create_repo sm2 &&
head7=$(add_file sm2 foo8 foo9) &&
git add sm2
-test_expect_success 'multiple submodules' "
+test_expect_success 'multiple submodules' '
git diff-index -p --submodule=log HEAD >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'path filter' "
+test_expect_success 'path filter' '
git diff-index -p --submodule=log HEAD sm2 >actual &&
cat >expected <<-EOF &&
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
commit_file sm2
-test_expect_success 'given commit' "
+test_expect_success 'given commit' '
git diff-index -p --submodule=log HEAD^ >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
-test_expect_success 'given commit --submodule' "
+test_expect_success 'given commit --submodule' '
git diff-index -p --submodule HEAD^ >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
-"
+'
-fullhead7=$(cd sm2; git rev-list --max-count=1 $head7)
+fullhead7=$(cd sm2; git rev-parse --verify HEAD)
-test_expect_success 'given commit --submodule=short' "
+test_expect_success 'given commit --submodule=short' '
git diff-index -p --submodule=short HEAD^ >actual &&
cat >expected <<-EOF &&
-diff --git a/sm1 b/sm1
-deleted file mode 160000
-index $head6..0000000
---- a/sm1
-+++ /dev/null
-@@ -1 +0,0 @@
--Subproject commit $fullhead6
-diff --git a/sm2 b/sm2
-new file mode 160000
-index 0000000..$head7
---- /dev/null
-+++ b/sm2
-@@ -0,0 +1 @@
-+Subproject commit $fullhead7
-EOF
- test_cmp expected actual
-"
+ diff --git a/sm1 b/sm1
+ deleted file mode 160000
+ index $head6..0000000
+ --- a/sm1
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -Subproject commit $fullhead6
+ diff --git a/sm2 b/sm2
+ new file mode 160000
+ index 0000000..$head7
+ --- /dev/null
+ +++ b/sm2
+ @@ -0,0 +1 @@
+ +Subproject commit $fullhead7
+ EOF
+ test_cmp expected actual
+'
test_expect_success 'setup .git file for sm2' '
(cd sm2 &&
@@ -452,9 +493,9 @@ test_expect_success 'setup .git file for sm2' '
test_expect_success 'diff --submodule with .git file' '
git diff --submodule HEAD^ >actual &&
cat >expected <<-EOF &&
-Submodule sm1 $head6...0000000 (submodule deleted)
-Submodule sm2 0000000...$head7 (new submodule)
-EOF
+ Submodule sm1 $head6...0000000 (submodule deleted)
+ Submodule sm2 0000000...$head7 (new submodule)
+ EOF
test_cmp expected actual
'
diff --git a/t/t4042-diff-textconv-caching.sh b/t/t4042-diff-textconv-caching.sh
index 91f8198f05..04a44d5c61 100755
--- a/t/t4042-diff-textconv-caching.sh
+++ b/t/t4042-diff-textconv-caching.sh
@@ -106,4 +106,12 @@ test_expect_success 'switching diff driver produces correct results' '
test_cmp expect actual
'
+# The point here is to test that we can log the notes cache and still use it to
+# produce a diff later (older versions of git would segfault on this). It's
+# much more likely to come up in the real world with "log --all -p", but using
+# --no-walk lets us reliably reproduce the order of traversal.
+test_expect_success 'log notes cache and still use cache for -p' '
+ git log --no-walk -p refs/notes/textconv/magic HEAD
+'
+
test_done
diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh
new file mode 100755
index 0000000000..97172b46b2
--- /dev/null
+++ b/t/t4055-diff-context.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+#
+# Copyright (c) 2012 Mozilla Foundation
+#
+
+test_description='diff.context configuration'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ cat >template <<-\EOF &&
+ firstline
+ b
+ c
+ d
+ e
+ f
+ preline
+ TARGET
+ postline
+ i
+ j
+ k
+ l
+ m
+ n
+ EOF
+ sed "/TARGET/d" >x <template &&
+ git update-index --add x &&
+ git commit -m initial &&
+
+ sed "s/TARGET/ADDED/" >x <template &&
+ git update-index --add x &&
+ git commit -m next &&
+
+ sed "s/TARGET/MODIFIED/" >x <template
+'
+
+test_expect_success 'the default number of context lines is 3' '
+ git diff >output &&
+ ! grep "^ d" output &&
+ grep "^ e" output &&
+ grep "^ j" output &&
+ ! grep "^ k" output
+'
+
+test_expect_success 'diff.context honored by "log"' '
+ git log -1 -p >output &&
+ ! grep firstline output &&
+ git config diff.context 8 &&
+ git log -1 -p >output &&
+ grep "^ firstline" output
+'
+
+test_expect_success 'The -U option overrides diff.context' '
+ git config diff.context 8 &&
+ git log -U4 -1 >output &&
+ ! grep "^ firstline" output
+'
+
+test_expect_success 'diff.context honored by "diff"' '
+ git config diff.context 8 &&
+ git diff >output &&
+ grep "^ firstline" output
+'
+
+test_expect_success 'plumbing not affected' '
+ git config diff.context 8 &&
+ git diff-files -p >output &&
+ ! grep "^ firstline" output
+'
+
+test_expect_success 'non-integer config parsing' '
+ git config diff.context no &&
+ test_must_fail git diff 2>output &&
+ test_i18ngrep "bad config value" output
+'
+
+test_expect_success 'negative integer config parsing' '
+ git config diff.context -1 &&
+ test_must_fail git diff 2>output &&
+ test_i18ngrep "bad config file" output
+'
+
+test_expect_success '-U0 is valid, so is diff.context=0' '
+ git config diff.context 0 &&
+ git diff >output &&
+ grep "^-ADDED" output &&
+ grep "^+MODIFIED" output
+'
+
+test_done
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
index 6f6ee88b28..5d0c598338 100755
--- a/t/t4124-apply-ws-rule.sh
+++ b/t/t4124-apply-ws-rule.sh
@@ -47,7 +47,7 @@ test_fix () {
# find touched lines
$DIFF file target | sed -n -e "s/^> //p" >fixed
- # the changed lines are all expeced to change
+ # the changed lines are all expected to change
fixed_cnt=$(wc -l <fixed)
case "$1" in
'') expect_cnt=$fixed_cnt ;;
@@ -486,4 +486,30 @@ test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' '
test_cmp one expect
'
+test_expect_success 'whitespace=fix to expand' '
+ qz_to_tab_space >preimage <<-\EOF &&
+ QQa
+ QQb
+ QQc
+ ZZZZZZZZZZZZZZZZd
+ QQe
+ QQf
+ QQg
+ EOF
+ qz_to_tab_space >patch <<-\EOF &&
+ diff --git a/preimage b/preimage
+ --- a/preimage
+ +++ b/preimage
+ @@ -1,7 +1,6 @@
+ QQa
+ QQb
+ QQc
+ -QQd
+ QQe
+ QQf
+ QQg
+ EOF
+ git -c core.whitespace=tab-in-indent apply --whitespace=fix patch
+'
+
test_done
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index cdafd7e7c1..12f6b027ac 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -17,7 +17,7 @@ test_expect_success 'setup: messages' '
vero eos et accusam et justo duo dolores et ea rebum.
EOF
- q_to_tab <<-\EOF >>msg &&
+ qz_to_tab_space <<-\EOF >>msg &&
QDuis autem vel eum iriure dolor in hendrerit in vulputate velit
Qesse molestie consequat, vel illum dolore eu feugiat nulla facilisis
Qat vero eros et accumsan et iusto odio dignissim qui blandit
diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh
index 6872ba1a42..5493500ef1 100755
--- a/t/t4201-shortlog.sh
+++ b/t/t4201-shortlog.sh
@@ -120,6 +120,30 @@ test_expect_success 'shortlog from non-git directory' '
test_cmp expect out
'
+test_expect_success 'shortlog should add newline when input line matches wraplen' '
+ cat >expect <<\EOF &&
+A U Thor (2):
+ bbbbbbbbbbbbbbbbbb: bbbbbbbb bbb bbbb bbbbbbb bb bbbb bbb bbbbb bbbbbb
+ aaaaaaaaaaaaaaaaaaaaaa: aaaaaa aaaaaaaaaa aaaa aaaaaaaa aa aaaa aa aaa
+
+EOF
+ git shortlog -w >out <<\EOF &&
+commit 0000000000000000000000000000000000000001
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:14:13 2005 -0700
+
+ aaaaaaaaaaaaaaaaaaaaaa: aaaaaa aaaaaaaaaa aaaa aaaaaaaa aa aaaa aa aaa
+
+commit 0000000000000000000000000000000000000002
+Author: A U Thor <author@example.com>
+Date: Thu Apr 7 15:14:13 2005 -0700
+
+ bbbbbbbbbbbbbbbbbb: bbbbbbbb bbb bbbb bbbbbbb bb bbbb bbb bbbbb bbbbbb
+
+EOF
+ test_cmp expect out
+'
+
iconvfromutf8toiso88591() {
printf "%s" "$*" | iconv -f UTF-8 -t ISO8859-1
}
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index a343bf6c62..fa686b887d 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -280,6 +280,16 @@ test_expect_success 'log --graph with merge' '
test_cmp expect actual
'
+test_expect_success 'log --raw --graph -m with merge' '
+ git log --raw --graph --oneline -m master | head -n 500 >actual &&
+ grep "initial" actual
+'
+
+test_expect_success 'diff-tree --graph' '
+ git diff-tree --graph master^ | head -n 500 >actual &&
+ grep "one" actual
+'
+
cat > expect <<\EOF
* commit master
|\ Merge: A B
diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh
index 1f182f612c..842b7549ec 100755
--- a/t/t4203-mailmap.sh
+++ b/t/t4203-mailmap.sh
@@ -149,6 +149,104 @@ test_expect_success 'No mailmap files, but configured' '
test_cmp expect actual
'
+test_expect_success 'setup mailmap blob tests' '
+ git checkout -b map &&
+ test_when_finished "git checkout master" &&
+ cat >just-bugs <<-\EOF &&
+ Blob Guy <bugs@company.xx>
+ EOF
+ cat >both <<-\EOF &&
+ Blob Guy <author@example.com>
+ Blob Guy <bugs@company.xx>
+ EOF
+ git add just-bugs both &&
+ git commit -m "my mailmaps" &&
+ echo "Repo Guy <author@example.com>" >.mailmap &&
+ echo "Internal Guy <author@example.com>" >internal.map
+'
+
+test_expect_success 'mailmap.blob set' '
+ cat >expect <<-\EOF &&
+ Blob Guy (1):
+ second
+
+ Repo Guy (1):
+ initial
+
+ EOF
+ git -c mailmap.blob=map:just-bugs shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.blob overrides .mailmap' '
+ cat >expect <<-\EOF &&
+ Blob Guy (2):
+ initial
+ second
+
+ EOF
+ git -c mailmap.blob=map:both shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.file overrides mailmap.blob' '
+ cat >expect <<-\EOF &&
+ Blob Guy (1):
+ second
+
+ Internal Guy (1):
+ initial
+
+ EOF
+ git \
+ -c mailmap.blob=map:both \
+ -c mailmap.file=internal.map \
+ shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.blob can be missing' '
+ cat >expect <<-\EOF &&
+ Repo Guy (1):
+ initial
+
+ nick1 (1):
+ second
+
+ EOF
+ git -c mailmap.blob=map:nonexistent shortlog HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'mailmap.blob defaults to off in non-bare repo' '
+ git init non-bare &&
+ (
+ cd non-bare &&
+ test_commit one .mailmap "Fake Name <author@example.com>" &&
+ echo " 1 Fake Name" >expect &&
+ git shortlog -ns HEAD >actual &&
+ test_cmp expect actual &&
+ rm .mailmap &&
+ echo " 1 A U Thor" >expect &&
+ git shortlog -ns HEAD >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'mailmap.blob defaults to HEAD:.mailmap in bare repo' '
+ git clone --bare non-bare bare &&
+ (
+ cd bare &&
+ echo " 1 Fake Name" >expect &&
+ git shortlog -ns HEAD >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'cleanup after mailmap.blob tests' '
+ rm -f .mailmap
+'
+
# Extended mailmap configurations should give us the following output for shortlog
cat >expect <<\EOF
A U Thor <author@example.com> (1):
@@ -239,6 +337,62 @@ test_expect_success 'Log output (complex mapping)' '
test_cmp expect actual
'
+cat >expect <<\EOF
+Author: CTO <cto@company.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Other Author <other@author.xx>
+Author: Other Author <other@author.xx>
+Author: Some Dude <some@dude.xx>
+Author: A U Thor <author@example.com>
+EOF
+
+test_expect_success 'Log output with --use-mailmap' '
+ git log --use-mailmap | grep Author >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<\EOF
+Author: CTO <cto@company.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Other Author <other@author.xx>
+Author: Other Author <other@author.xx>
+Author: Some Dude <some@dude.xx>
+Author: A U Thor <author@example.com>
+EOF
+
+test_expect_success 'Log output with log.mailmap' '
+ git -c log.mailmap=True log | grep Author >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<\EOF
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+EOF
+
+test_expect_success 'Grep author with --use-mailmap' '
+ git log --use-mailmap --author Santa | grep Author >actual &&
+ test_cmp expect actual
+'
+cat >expect <<\EOF
+Author: Santa Claus <santa.claus@northpole.xx>
+Author: Santa Claus <santa.claus@northpole.xx>
+EOF
+
+test_expect_success 'Grep author with log.mailmap' '
+ git -c log.mailmap=True log --author Santa | grep Author >actual &&
+ test_cmp expect actual
+'
+
+>expect
+
+test_expect_success 'Only grep replaced author with --use-mailmap' '
+ git log --use-mailmap --author "<cto@coompany.xx>" >actual &&
+ test_cmp expect actual
+'
+
# git blame
cat >expect <<\EOF
^OBJI (A U Thor DATE 1) one
diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh
index 2c482b622b..72300b5f24 100755
--- a/t/t4208-log-magic-pathspec.sh
+++ b/t/t4208-log-magic-pathspec.sh
@@ -11,11 +11,24 @@ test_expect_success 'setup' '
mkdir sub
'
-test_expect_success '"git log :/" should be ambiguous' '
- test_must_fail git log :/ 2>error &&
+test_expect_success '"git log :/" should not be ambiguous' '
+ git log :/
+'
+
+test_expect_success '"git log :/a" should be ambiguous (applied both rev and worktree)' '
+ : >a &&
+ test_must_fail git log :/a 2>error &&
grep ambiguous error
'
+test_expect_success '"git log :/a -- " should not be ambiguous' '
+ git log :/a --
+'
+
+test_expect_success '"git log -- :/a" should not be ambiguous' '
+ git log -- :/a
+'
+
test_expect_success '"git log :" should be ambiguous' '
test_must_fail git log : 2>error &&
grep ambiguous error
diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh
new file mode 100755
index 0000000000..52a74729ba
--- /dev/null
+++ b/t/t4210-log-i18n.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+test_description='test log with i18n features'
+. ./test-lib.sh
+
+# two forms of é
+utf8_e=$(printf '\303\251')
+latin1_e=$(printf '\351')
+
+test_expect_success 'create commits in different encodings' '
+ test_tick &&
+ cat >msg <<-EOF &&
+ utf8
+
+ t${utf8_e}st
+ EOF
+ git add msg &&
+ git -c i18n.commitencoding=utf8 commit -F msg &&
+ cat >msg <<-EOF &&
+ latin1
+
+ t${latin1_e}st
+ EOF
+ git add msg &&
+ git -c i18n.commitencoding=ISO-8859-1 commit -F msg
+'
+
+test_expect_success 'log --grep searches in log output encoding (utf8)' '
+ cat >expect <<-\EOF &&
+ latin1
+ utf8
+ EOF
+ git log --encoding=utf8 --format=%s --grep=$utf8_e >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep searches in log output encoding (latin1)' '
+ cat >expect <<-\EOF &&
+ latin1
+ utf8
+ EOF
+ git log --encoding=ISO-8859-1 --format=%s --grep=$latin1_e >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep does not find non-reencoded values (utf8)' '
+ >expect &&
+ git log --encoding=utf8 --format=%s --grep=$latin1_e >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'log --grep does not find non-reencoded values (latin1)' '
+ >expect &&
+ git log --encoding=ISO-8859-1 --format=%s --grep=$utf8_e >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh
index 46c3fe76d3..d0b2a457b8 100755
--- a/t/t4300-merge-tree.sh
+++ b/t/t4300-merge-tree.sh
@@ -254,4 +254,48 @@ EXPECTED
test_cmp expected actual
'
+test_expect_success 'turn file to tree' '
+ git reset --hard initial &&
+ rm initial-file &&
+ mkdir initial-file &&
+ test_commit "turn-file-to-tree" "initial-file/ONE" "CCC" &&
+ git merge-tree initial initial turn-file-to-tree >actual &&
+ cat >expect <<-\EOF &&
+ added in remote
+ their 100644 43aa4fdec31eb92e1fdc2f0ce6ea9ddb7c32bcf7 initial-file/ONE
+ @@ -0,0 +1 @@
+ +CCC
+ removed in remote
+ base 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file
+ our 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file
+ @@ -1 +0,0 @@
+ -initial
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'turn tree to file' '
+ git reset --hard initial &&
+ mkdir dir &&
+ test_commit "add-tree" "dir/path" "AAA" &&
+ test_commit "add-another-tree" "dir/another" "BBB" &&
+ rm -fr dir &&
+ test_commit "make-file" "dir" "CCC" &&
+ git merge-tree add-tree add-another-tree make-file >actual &&
+ cat >expect <<-\EOF &&
+ added in local
+ our 100644 ba629238ca89489f2b350e196ca445e09d8bb834 dir/another
+ removed in remote
+ base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path
+ our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path
+ @@ -1 +0,0 @@
+ -AAA
+ added in remote
+ their 100644 43aa4fdec31eb92e1fdc2f0ce6ea9ddb7c32bcf7 dir
+ @@ -0,0 +1 @@
+ +CCC
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index ecf00edab2..3fbd366ec3 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -25,32 +25,11 @@ commit id embedding:
'
. ./test-lib.sh
-UNZIP=${UNZIP:-unzip}
GZIP=${GZIP:-gzip}
GUNZIP=${GUNZIP:-gzip -d}
SUBSTFORMAT=%H%n
-check_zip() {
- zipfile=$1.zip
- listfile=$1.lst
- dir=$1
- dir_with_prefix=$dir/$2
-
- test_expect_success UNZIP " extract ZIP archive" "
- (mkdir $dir && cd $dir && $UNZIP ../$zipfile)
- "
-
- test_expect_success UNZIP " validate filenames" "
- (cd ${dir_with_prefix}a && find .) | sort >$listfile &&
- test_cmp a.lst $listfile
- "
-
- test_expect_success UNZIP " validate file contents" "
- diff -r a ${dir_with_prefix}a
- "
-}
-
test_expect_success \
'populate workdir' \
'mkdir a b c &&
@@ -201,62 +180,12 @@ test_expect_success \
test_cmp a/substfile2 g/prefix/a/substfile2
'
-$UNZIP -v >/dev/null 2>&1
-if [ $? -eq 127 ]; then
- say "Skipping ZIP tests, because unzip was not found"
-else
- test_set_prereq UNZIP
-fi
-
-test_expect_success \
- 'git archive --format=zip' \
- 'git archive --format=zip HEAD >d.zip'
-
-check_zip d
-
-test_expect_success \
- 'git archive --format=zip in a bare repo' \
- '(cd bare.git && git archive --format=zip HEAD) >d1.zip'
-
-test_expect_success \
- 'git archive --format=zip vs. the same in a bare repo' \
- 'test_cmp d.zip d1.zip'
-
-test_expect_success 'git archive --format=zip with --output' \
- 'git archive --format=zip --output=d2.zip HEAD &&
- test_cmp d.zip d2.zip'
-
-test_expect_success 'git archive with --output, inferring format' '
- git archive --output=d3.zip HEAD &&
- test_cmp d.zip d3.zip
-'
-
test_expect_success 'git archive with --output, override inferred format' '
git archive --format=tar --output=d4.zip HEAD &&
test_cmp b.tar d4.zip
'
test_expect_success \
- 'git archive --format=zip with prefix' \
- 'git archive --format=zip --prefix=prefix/ HEAD >e.zip'
-
-check_zip e prefix/
-
-test_expect_success 'git archive -0 --format=zip on large files' '
- test_config core.bigfilethreshold 1 &&
- git archive -0 --format=zip HEAD >large.zip
-'
-
-check_zip large
-
-test_expect_success 'git archive --format=zip on large files' '
- test_config core.bigfilethreshold 1 &&
- git archive --format=zip HEAD >large-compressed.zip
-'
-
-check_zip large-compressed
-
-test_expect_success \
'git archive --list outside of a git repo' \
'GIT_DIR=some/non-existing/directory git archive --list'
@@ -283,7 +212,8 @@ test_expect_success 'git-archive --prefix=olde-' '
test_expect_success 'setup tar filters' '
git config tar.tar.foo.command "tr ab ba" &&
git config tar.bar.command "tr ab ba" &&
- git config tar.bar.remote true
+ git config tar.bar.remote true &&
+ git config tar.invalid baz
'
test_expect_success 'archive --list mentions user filter' '
diff --git a/t/t5002-archive-attr-pattern.sh b/t/t5002-archive-attr-pattern.sh
new file mode 100755
index 0000000000..6667d159ab
--- /dev/null
+++ b/t/t5002-archive-attr-pattern.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+test_description='git archive attribute pattern tests'
+
+. ./test-lib.sh
+
+test_expect_exists() {
+ test_expect_success " $1 exists" "test -e $1"
+}
+
+test_expect_missing() {
+ test_expect_success " $1 does not exist" "test ! -e $1"
+}
+
+test_expect_success 'setup' '
+ echo ignored >ignored &&
+ echo ignored export-ignore >>.git/info/attributes &&
+ git add ignored &&
+
+ mkdir not-ignored-dir &&
+ echo ignored-in-tree >not-ignored-dir/ignored &&
+ echo not-ignored-in-tree >not-ignored-dir/ignored-only-if-dir &&
+ git add not-ignored-dir &&
+
+ mkdir ignored-only-if-dir &&
+ echo ignored by ignored dir >ignored-only-if-dir/ignored-by-ignored-dir &&
+ echo ignored-only-if-dir/ export-ignore >>.git/info/attributes &&
+ git add ignored-only-if-dir &&
+
+ mkdir -p ignored-without-slash &&
+ echo "ignored without slash" >ignored-without-slash/foo &&
+ git add ignored-without-slash/foo &&
+ echo "ignored-without-slash export-ignore" >>.git/info/attributes &&
+
+ mkdir -p wildcard-without-slash &&
+ echo "ignored without slash" >wildcard-without-slash/foo &&
+ git add wildcard-without-slash/foo &&
+ echo "wild*-without-slash export-ignore" >>.git/info/attributes &&
+
+ mkdir -p deep/and/slashless &&
+ echo "ignored without slash" >deep/and/slashless/foo &&
+ git add deep/and/slashless/foo &&
+ echo "deep/and/slashless export-ignore" >>.git/info/attributes &&
+
+ mkdir -p deep/with/wildcard &&
+ echo "ignored without slash" >deep/with/wildcard/foo &&
+ git add deep/with/wildcard/foo &&
+ echo "deep/*t*/wildcard export-ignore" >>.git/info/attributes &&
+
+ mkdir -p one-level-lower/two-levels-lower/ignored-only-if-dir &&
+ echo ignored by ignored dir >one-level-lower/two-levels-lower/ignored-only-if-dir/ignored-by-ignored-dir &&
+ git add one-level-lower &&
+
+ git commit -m. &&
+
+ git clone --bare . bare &&
+ cp .git/info/attributes bare/info/attributes
+'
+
+test_expect_success 'git archive' '
+ git archive HEAD >archive.tar &&
+ (mkdir archive && cd archive && "$TAR" xf -) <archive.tar
+'
+
+test_expect_missing archive/ignored
+test_expect_missing archive/not-ignored-dir/ignored
+test_expect_exists archive/not-ignored-dir/ignored-only-if-dir
+test_expect_exists archive/not-ignored-dir/
+test_expect_missing archive/ignored-only-if-dir/
+test_expect_missing archive/ignored-ony-if-dir/ignored-by-ignored-dir
+test_expect_missing archive/ignored-without-slash/ &&
+test_expect_missing archive/ignored-without-slash/foo &&
+test_expect_missing archive/wildcard-without-slash/
+test_expect_missing archive/wildcard-without-slash/foo &&
+test_expect_missing archive/deep/and/slashless/ &&
+test_expect_missing archive/deep/and/slashless/foo &&
+test_expect_missing archive/deep/with/wildcard/ &&
+test_expect_missing archive/deep/with/wildcard/foo &&
+test_expect_exists archive/one-level-lower/
+test_expect_missing archive/one-level-lower/two-levels-lower/ignored-only-if-dir/
+test_expect_missing archive/one-level-lower/two-levels-lower/ignored-ony-if-dir/ignored-by-ignored-dir
+
+
+test_done
diff --git a/t/t5003-archive-zip.sh b/t/t5003-archive-zip.sh
new file mode 100755
index 0000000000..4e7b05dd23
--- /dev/null
+++ b/t/t5003-archive-zip.sh
@@ -0,0 +1,131 @@
+#!/bin/sh
+
+test_description='git archive --format=zip test'
+
+. ./test-lib.sh
+
+SUBSTFORMAT=%H%n
+
+test_lazy_prereq UNZIP_SYMLINKS '
+ (
+ mkdir unzip-symlinks &&
+ cd unzip-symlinks &&
+ "$GIT_UNZIP" "$TEST_DIRECTORY"/t5003/infozip-symlinks.zip &&
+ test -h symlink
+ )
+'
+
+check_zip() {
+ zipfile=$1.zip
+ listfile=$1.lst
+ dir=$1
+ dir_with_prefix=$dir/$2
+
+ test_expect_success UNZIP " extract ZIP archive" '
+ (mkdir $dir && cd $dir && "$GIT_UNZIP" ../$zipfile)
+ '
+
+ test_expect_success UNZIP " validate filenames" "
+ (cd ${dir_with_prefix}a && find .) | sort >$listfile &&
+ test_cmp a.lst $listfile
+ "
+
+ test_expect_success UNZIP " validate file contents" "
+ diff -r a ${dir_with_prefix}a
+ "
+}
+
+test_expect_success \
+ 'populate workdir' \
+ 'mkdir a b c &&
+ echo simple textfile >a/a &&
+ mkdir a/bin &&
+ cp /bin/sh a/bin &&
+ printf "A\$Format:%s\$O" "$SUBSTFORMAT" >a/substfile1 &&
+ printf "A not substituted O" >a/substfile2 &&
+ (p=long_path_to_a_file && cd a &&
+ for depth in 1 2 3 4 5; do mkdir $p && cd $p; done &&
+ echo text >file_with_long_path)
+'
+
+test_expect_success SYMLINKS,UNZIP_SYMLINKS 'add symlink' '
+ ln -s a a/symlink_to_a
+'
+
+test_expect_success 'prepare file list' '
+ (cd a && find .) | sort >a.lst
+'
+
+test_expect_success \
+ 'add ignored file' \
+ 'echo ignore me >a/ignored &&
+ echo ignored export-ignore >.git/info/attributes'
+
+test_expect_success \
+ 'add files to repository' \
+ 'find a -type f | xargs git update-index --add &&
+ find a -type l | xargs git update-index --add &&
+ treeid=`git write-tree` &&
+ echo $treeid >treeid &&
+ git update-ref HEAD $(TZ=GMT GIT_COMMITTER_DATE="2005-05-27 22:00:00" \
+ git commit-tree $treeid </dev/null)'
+
+test_expect_success 'setup export-subst' '
+ echo "substfile?" export-subst >>.git/info/attributes &&
+ git log --max-count=1 "--pretty=format:A${SUBSTFORMAT}O" HEAD \
+ >a/substfile1
+'
+
+test_expect_success \
+ 'create bare clone' \
+ 'git clone --bare . bare.git &&
+ cp .git/info/attributes bare.git/info/attributes'
+
+test_expect_success \
+ 'remove ignored file' \
+ 'rm a/ignored'
+
+test_expect_success \
+ 'git archive --format=zip' \
+ 'git archive --format=zip HEAD >d.zip'
+
+check_zip d
+
+test_expect_success \
+ 'git archive --format=zip in a bare repo' \
+ '(cd bare.git && git archive --format=zip HEAD) >d1.zip'
+
+test_expect_success \
+ 'git archive --format=zip vs. the same in a bare repo' \
+ 'test_cmp d.zip d1.zip'
+
+test_expect_success 'git archive --format=zip with --output' \
+ 'git archive --format=zip --output=d2.zip HEAD &&
+ test_cmp d.zip d2.zip'
+
+test_expect_success 'git archive with --output, inferring format' '
+ git archive --output=d3.zip HEAD &&
+ test_cmp d.zip d3.zip
+'
+
+test_expect_success \
+ 'git archive --format=zip with prefix' \
+ 'git archive --format=zip --prefix=prefix/ HEAD >e.zip'
+
+check_zip e prefix/
+
+test_expect_success 'git archive -0 --format=zip on large files' '
+ test_config core.bigfilethreshold 1 &&
+ git archive -0 --format=zip HEAD >large.zip
+'
+
+check_zip large
+
+test_expect_success 'git archive --format=zip on large files' '
+ test_config core.bigfilethreshold 1 &&
+ git archive --format=zip HEAD >large-compressed.zip
+'
+
+check_zip large-compressed
+
+test_done
diff --git a/t/t5003/infozip-symlinks.zip b/t/t5003/infozip-symlinks.zip
new file mode 100644
index 0000000000..065728c631
--- /dev/null
+++ b/t/t5003/infozip-symlinks.zip
Binary files differ
diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh
new file mode 100755
index 0000000000..cdb7d7a7f9
--- /dev/null
+++ b/t/t5004-archive-corner-cases.sh
@@ -0,0 +1,102 @@
+#!/bin/sh
+
+test_description='test corner cases of git-archive'
+. ./test-lib.sh
+
+test_expect_success 'create commit with empty tree' '
+ git commit --allow-empty -m foo
+'
+
+# Make a dir and clean it up afterwards
+make_dir() {
+ mkdir "$1" &&
+ test_when_finished "rm -rf '$1'"
+}
+
+# Check that the dir given in "$1" contains exactly the
+# set of paths given as arguments.
+check_dir() {
+ dir=$1; shift
+ {
+ echo "$dir" &&
+ for i in "$@"; do
+ echo "$dir/$i"
+ done
+ } | sort >expect &&
+ find "$dir" -print | sort >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'tar archive of empty tree is empty' '
+ git archive --format=tar HEAD >empty.tar &&
+ make_dir extract &&
+ "$TAR" xf empty.tar -C extract &&
+ check_dir extract
+'
+
+test_expect_success 'tar archive of empty tree with prefix' '
+ git archive --format=tar --prefix=foo/ HEAD >prefix.tar &&
+ make_dir extract &&
+ "$TAR" xf prefix.tar -C extract &&
+ check_dir extract foo
+'
+
+test_expect_success UNZIP 'zip archive of empty tree is empty' '
+ # Detect the exit code produced when our particular flavor of unzip
+ # sees an empty archive. Infozip will generate a warning and exit with
+ # code 1. But in the name of sanity, we do not expect other unzip
+ # implementations to do the same thing (it would be perfectly
+ # reasonable to exit 0, for example).
+ #
+ # This makes our test less rigorous on some platforms (unzip may not
+ # handle the empty repo at all, making our later check of its exit code
+ # a no-op). But we cannot do anything reasonable except skip the test
+ # on such platforms anyway, and this is the moral equivalent.
+ "$GIT_UNZIP" "$TEST_DIRECTORY"/t5004/empty.zip
+ expect_code=$?
+
+ git archive --format=zip HEAD >empty.zip &&
+ make_dir extract &&
+ (
+ cd extract &&
+ test_expect_code $expect_code "$GIT_UNZIP" ../empty.zip
+ ) &&
+ check_dir extract
+'
+
+test_expect_success UNZIP 'zip archive of empty tree with prefix' '
+ # We do not have to play exit-code tricks here, because our
+ # result should not be empty; it has a directory in it.
+ git archive --format=zip --prefix=foo/ HEAD >prefix.zip &&
+ make_dir extract &&
+ (
+ cd extract &&
+ "$GIT_UNZIP" ../prefix.zip
+ ) &&
+ check_dir extract foo
+'
+
+test_expect_success 'archive complains about pathspec on empty tree' '
+ test_must_fail git archive --format=tar HEAD -- foo >/dev/null
+'
+
+test_expect_success 'create a commit with an empty subtree' '
+ empty_tree=$(git hash-object -t tree /dev/null) &&
+ root_tree=$(printf "040000 tree $empty_tree\tsub\n" | git mktree)
+'
+
+test_expect_success 'archive empty subtree with no pathspec' '
+ git archive --format=tar $root_tree >subtree-all.tar &&
+ make_dir extract &&
+ "$TAR" xf subtree-all.tar -C extract &&
+ check_dir extract sub
+'
+
+test_expect_success 'archive empty subtree by direct pathspec' '
+ git archive --format=tar $root_tree -- sub >subtree-path.tar &&
+ make_dir extract &&
+ "$TAR" xf subtree-path.tar -C extract &&
+ check_dir extract sub
+'
+
+test_done
diff --git a/t/t5004/empty.zip b/t/t5004/empty.zip
new file mode 100644
index 0000000000..1a76bb6005
--- /dev/null
+++ b/t/t5004/empty.zip
Binary files differ
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 6322e8ade8..d574085696 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -130,16 +130,25 @@ test_expect_success 'single given branch clone' '
test_must_fail git --git-dir=branch-a/.git rev-parse origin/B
'
+test_expect_success 'clone shallow depth 1' '
+ git clone --no-single-branch --depth 1 "file://$(pwd)/." shallow0 &&
+ test "`git --git-dir=shallow0/.git rev-list --count HEAD`" = 1
+'
+
test_expect_success 'clone shallow' '
git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow
'
+test_expect_success 'clone shallow depth count' '
+ test "`git --git-dir=shallow/.git rev-list --count HEAD`" = 2
+'
+
test_expect_success 'clone shallow object count' '
(
cd shallow &&
git count-objects -v
) > count.shallow &&
- grep "^in-pack: 18" count.shallow
+ grep "^in-pack: 12" count.shallow
'
test_expect_success 'clone shallow object count (part 2)' '
@@ -256,12 +265,36 @@ test_expect_success 'additional simple shallow deepenings' '
)
'
+test_expect_success 'clone shallow depth count' '
+ test "`git --git-dir=shallow/.git rev-list --count HEAD`" = 11
+'
+
test_expect_success 'clone shallow object count' '
(
cd shallow &&
git count-objects -v
) > count.shallow &&
- grep "^count: 52" count.shallow
+ grep "^count: 55" count.shallow
+'
+
+test_expect_success 'fetch --no-shallow on full repo' '
+ test_must_fail git fetch --noshallow
+'
+
+test_expect_success 'fetch --depth --no-shallow' '
+ (
+ cd shallow &&
+ test_must_fail git fetch --depth=1 --noshallow
+ )
+'
+
+test_expect_success 'turn shallow to complete repository' '
+ (
+ cd shallow &&
+ git fetch --unshallow &&
+ ! test -f .git/shallow &&
+ git fsck --full
+ )
'
test_expect_success 'clone shallow without --no-single-branch' '
@@ -273,7 +306,7 @@ test_expect_success 'clone shallow object count' '
cd shallow2 &&
git count-objects -v
) > count.shallow2 &&
- grep "^in-pack: 6" count.shallow2
+ grep "^in-pack: 3" count.shallow2
'
test_expect_success 'clone shallow with --branch' '
@@ -281,7 +314,7 @@ test_expect_success 'clone shallow with --branch' '
'
test_expect_success 'clone shallow object count' '
- echo "in-pack: 6" > count3.expected &&
+ echo "in-pack: 3" > count3.expected &&
GIT_DIR=shallow3/.git git count-objects -v |
grep "^in-pack" > count3.actual &&
test_cmp count3.expected count3.actual
@@ -310,7 +343,7 @@ EOF
GIT_DIR=shallow6/.git git tag -l >taglist.actual &&
test_cmp taglist.expected taglist.actual &&
- echo "in-pack: 7" > count6.expected &&
+ echo "in-pack: 4" > count6.expected &&
GIT_DIR=shallow6/.git git count-objects -v |
grep "^in-pack" > count6.actual &&
test_cmp count6.expected count6.actual
@@ -325,12 +358,21 @@ EOF
GIT_DIR=shallow7/.git git tag -l >taglist.actual &&
test_cmp taglist.expected taglist.actual &&
- echo "in-pack: 7" > count7.expected &&
+ echo "in-pack: 4" > count7.expected &&
GIT_DIR=shallow7/.git git count-objects -v |
grep "^in-pack" > count7.actual &&
test_cmp count7.expected count7.actual
'
+test_expect_success 'clone shallow with packed refs' '
+ git pack-refs --all &&
+ git clone --depth 1 --branch A "file://$(pwd)/." shallow8 &&
+ echo "in-pack: 4" > count8.expected &&
+ GIT_DIR=shallow8/.git git count-objects -v |
+ grep "^in-pack" > count8.actual &&
+ test_cmp count8.expected count8.actual
+'
+
test_expect_success 'setup tests for the --stdin parameter' '
for head in C D E F
do
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index d16e5d384a..321c3e5234 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -126,4 +126,16 @@ test_expect_success 'Report match with --exit-code' '
test_cmp expect actual
'
+for configsection in transfer uploadpack
+do
+ test_expect_success "Hide some refs with $configsection.hiderefs" '
+ test_config $configsection.hiderefs refs/tags &&
+ git ls-remote . >actual &&
+ test_unconfig $configsection.hiderefs &&
+ git ls-remote . |
+ sed -e "/ refs\/tags\//d" >expect &&
+ test_cmp expect actual
+ '
+done
+
test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index b5417cc951..9a21cd61d7 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -230,10 +230,10 @@ test_expect_success 'push with pushInsteadOf' '
test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' '
mk_empty &&
- TRASH="$(pwd)/" &&
- git config "url.trash2/.pushInsteadOf" trash/ &&
+ git config "url.trash2/.pushInsteadOf" testrepo/ &&
+ git config "url.trash3/.pusnInsteadOf" trash/wrong &&
git config remote.r.url trash/wrong &&
- git config remote.r.pushurl "$TRASH/testrepo" &&
+ git config remote.r.pushurl "testrepo/" &&
git push r refs/heads/master:refs/remotes/origin/master &&
(
cd testrepo &&
@@ -368,7 +368,7 @@ test_expect_success 'push with colon-less refspec (2)' '
git branch -D frotz
fi &&
git tag -f frotz &&
- git push testrepo frotz &&
+ git push -f testrepo frotz &&
check_push_result $the_commit tags/frotz &&
check_push_result $the_first_commit heads/frotz
@@ -929,6 +929,27 @@ test_expect_success 'push into aliased refs (inconsistent)' '
)
'
+test_expect_success 'push requires --force to update lightweight tag' '
+ mk_test heads/master &&
+ mk_child child1 &&
+ mk_child child2 &&
+ (
+ cd child1 &&
+ git tag Tag &&
+ git push ../child2 Tag &&
+ git push ../child2 Tag &&
+ >file1 &&
+ git add file1 &&
+ git commit -m "file1" &&
+ git tag -f Tag &&
+ test_must_fail git push ../child2 Tag &&
+ git push --force ../child2 Tag &&
+ git tag -f Tag &&
+ test_must_fail git push ../child2 Tag HEAD~ &&
+ git push --force ../child2 Tag
+ )
+'
+
test_expect_success 'push --porcelain' '
mk_empty &&
echo >.git/foo "To testrepo" &&
@@ -995,4 +1016,31 @@ test_expect_success 'push --prune refspec' '
! check_push_result $the_first_commit tmp/foo tmp/bar
'
+for configsection in transfer receive
+do
+ test_expect_success "push to update a ref hidden by $configsection.hiderefs" '
+ mk_test heads/master hidden/one hidden/two hidden/three &&
+ (
+ cd testrepo &&
+ git config $configsection.hiderefs refs/hidden
+ ) &&
+
+ # push to unhidden ref succeeds normally
+ git push testrepo master:refs/heads/master &&
+ check_push_result $the_commit heads/master &&
+
+ # push to update a hidden ref should fail
+ test_must_fail git push testrepo master:refs/hidden/one &&
+ check_push_result $the_first_commit hidden/one &&
+
+ # push to delete a hidden ref should fail
+ test_must_fail git push testrepo :refs/hidden/two &&
+ check_push_result $the_first_commit hidden/two &&
+
+ # idempotent push to update a hidden ref should fail
+ test_must_fail git push testrepo $the_first_commit:refs/hidden/three &&
+ check_push_result $the_first_commit hidden/three
+ '
+done
+
test_done
diff --git a/t/t5535-fetch-push-symref.sh b/t/t5535-fetch-push-symref.sh
new file mode 100755
index 0000000000..8ed58d27f2
--- /dev/null
+++ b/t/t5535-fetch-push-symref.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+test_description='avoiding conflicting update thru symref aliasing'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit one &&
+ git clone . src &&
+ git clone src dst1 &&
+ git clone src dst2 &&
+ test_commit two &&
+ ( cd src && git pull )
+'
+
+test_expect_success 'push' '
+ (
+ cd src &&
+ git push ../dst1 "refs/remotes/*:refs/remotes/*"
+ ) &&
+ git ls-remote src "refs/remotes/*" >expect &&
+ git ls-remote dst1 "refs/remotes/*" >actual &&
+ test_cmp expect actual &&
+ ( cd src && git symbolic-ref refs/remotes/origin/HEAD ) >expect &&
+ ( cd dst1 && git symbolic-ref refs/remotes/origin/HEAD ) >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'fetch' '
+ (
+ cd dst2 &&
+ git fetch ../src "refs/remotes/*:refs/remotes/*"
+ ) &&
+ git ls-remote src "refs/remotes/*" >expect &&
+ git ls-remote dst2 "refs/remotes/*" >actual &&
+ test_cmp expect actual &&
+ ( cd src && git symbolic-ref refs/remotes/origin/HEAD ) >expect &&
+ ( cd dst2 && git symbolic-ref refs/remotes/origin/HEAD ) >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh
index 5060879d6d..47eb76921d 100755
--- a/t/t5551-http-fetch.sh
+++ b/t/t5551-http-fetch.sh
@@ -130,6 +130,21 @@ test_expect_success 'clone from auth-only-for-push repository' '
test_cmp expect actual
'
+test_expect_success 'clone from auth-only-for-objects repository' '
+ echo two >expect &&
+ set_askpass user@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 &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-op half-auth fetch does not require a password' '
+ set_askpass wrong &&
+ git --git-dir=half-auth fetch &&
+ expect_askpass none
+'
+
test_expect_success 'disable dumb http on server' '
git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \
config http.getanyfile false
@@ -142,6 +157,11 @@ test_expect_success 'GIT_SMART_HTTP can disable smart http' '
test_must_fail git fetch)
'
+test_expect_success 'invalid Content-Type rejected' '
+ test_must_fail git clone $HTTPD_URL/broken_smart/repo.git 2>actual
+ grep "not valid:" actual
+'
+
test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE
test_expect_success EXPENSIVE 'create 50,000 tags in the repo' '
diff --git a/t/t5571-pre-push-hook.sh b/t/t5571-pre-push-hook.sh
new file mode 100755
index 0000000000..6f9916a390
--- /dev/null
+++ b/t/t5571-pre-push-hook.sh
@@ -0,0 +1,131 @@
+#!/bin/sh
+
+test_description='check pre-push hooks'
+. ./test-lib.sh
+
+# Setup hook that always succeeds
+HOOKDIR="$(git rev-parse --git-dir)/hooks"
+HOOK="$HOOKDIR/pre-push"
+mkdir -p "$HOOKDIR"
+write_script "$HOOK" <<EOF
+cat >/dev/null
+exit 0
+EOF
+
+test_expect_success 'setup' '
+ git config push.default upstream &&
+ git init --bare repo1 &&
+ git remote add parent1 repo1 &&
+ test_commit one &&
+ git push parent1 HEAD:foreign
+'
+write_script "$HOOK" <<EOF
+cat >/dev/null
+exit 1
+EOF
+
+COMMIT1="$(git rev-parse HEAD)"
+export COMMIT1
+
+test_expect_success 'push with failing hook' '
+ test_commit two &&
+ test_must_fail git push parent1 HEAD
+'
+
+test_expect_success '--no-verify bypasses hook' '
+ git push --no-verify parent1 HEAD
+'
+
+COMMIT2="$(git rev-parse HEAD)"
+export COMMIT2
+
+write_script "$HOOK" <<'EOF'
+echo "$1" >actual
+echo "$2" >>actual
+cat >>actual
+EOF
+
+cat >expected <<EOF
+parent1
+repo1
+refs/heads/master $COMMIT2 refs/heads/foreign $COMMIT1
+EOF
+
+test_expect_success 'push with hook' '
+ git push parent1 master:foreign &&
+ diff expected actual
+'
+
+test_expect_success 'add a branch' '
+ git checkout -b other parent1/foreign &&
+ test_commit three
+'
+
+COMMIT3="$(git rev-parse HEAD)"
+export COMMIT3
+
+cat >expected <<EOF
+parent1
+repo1
+refs/heads/other $COMMIT3 refs/heads/foreign $COMMIT2
+EOF
+
+test_expect_success 'push to default' '
+ git push &&
+ diff expected actual
+'
+
+cat >expected <<EOF
+parent1
+repo1
+refs/tags/one $COMMIT1 refs/tags/tag1 $_z40
+HEAD~ $COMMIT2 refs/heads/prev $_z40
+EOF
+
+test_expect_success 'push non-branches' '
+ git push parent1 one:tag1 HEAD~:refs/heads/prev &&
+ diff expected actual
+'
+
+cat >expected <<EOF
+parent1
+repo1
+(delete) $_z40 refs/heads/prev $COMMIT2
+EOF
+
+test_expect_success 'push delete' '
+ git push parent1 :prev &&
+ diff expected actual
+'
+
+cat >expected <<EOF
+repo1
+repo1
+HEAD $COMMIT3 refs/heads/other $_z40
+EOF
+
+test_expect_success 'push to URL' '
+ git push repo1 HEAD &&
+ diff expected actual
+'
+
+# Test that filling pipe buffers doesn't cause failure
+# Too slow to leave enabled for general use
+if false
+then
+ printf 'parent1\nrepo1\n' >expected
+ nr=1000
+ while test $nr -lt 2000
+ do
+ nr=$(( $nr + 1 ))
+ git branch b/$nr $COMMIT3
+ echo "refs/heads/b/$nr $COMMIT3 refs/heads/b/$nr $_z40" >>expected
+ done
+
+ test_expect_success 'push many refs' '
+ git push parent1 "refs/heads/b/*:refs/heads/b/*" &&
+ diff expected actual
+ '
+fi
+
+test_done
diff --git a/t/t5600-clone-fail-cleanup.sh b/t/t5600-clone-fail-cleanup.sh
index ee06d28649..4435693bb2 100755
--- a/t/t5600-clone-fail-cleanup.sh
+++ b/t/t5600-clone-fail-cleanup.sh
@@ -37,6 +37,16 @@ test_expect_success \
test_expect_success \
'successful clone must leave the directory' \
- 'cd bar'
+ 'test -d bar'
+
+test_expect_success 'failed clone --separate-git-dir should not leave any directories' '
+ mkdir foo/.git/objects.bak/ &&
+ mv foo/.git/objects/* foo/.git/objects.bak/ &&
+ test_must_fail git clone --separate-git-dir gitdir foo worktree &&
+ test_must_fail test -e gitdir &&
+ test_must_fail test -e worktree &&
+ mv foo/.git/objects.bak/* foo/.git/objects/ &&
+ rmdir foo/.git/objects.bak
+'
test_done
diff --git a/t/t5704-bundle.sh b/t/t5704-bundle.sh
index 9e43731fe5..a45c31692e 100755
--- a/t/t5704-bundle.sh
+++ b/t/t5704-bundle.sh
@@ -58,4 +58,14 @@ test_expect_success 'ridiculously long subject in boundary' '
grep "^-[0-9a-f]\\{40\\} " boundary
'
+test_expect_success 'prerequisites with an empty commit message' '
+ : >file1 &&
+ git add file1 &&
+ test_tick &&
+ git commit --allow-empty-message -m "" &&
+ test_commit file2 &&
+ git bundle create bundle HEAD^.. &&
+ git bundle verify bundle
+'
+
test_done
diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-testpy.sh
index e7dc668cef..1e683d4220 100755
--- a/t/t5800-remote-helpers.sh
+++ b/t/t5800-remote-testpy.sh
@@ -3,12 +3,12 @@
# Copyright (c) 2010 Sverre Rabbelier
#
-test_description='Test remote-helper import and export commands'
+test_description='Test python remote-helper framework'
. ./test-lib.sh
if ! test_have_prereq PYTHON ; then
- skip_all='skipping git-remote-hg tests, python not available'
+ skip_all='skipping python remote-helper tests, python not available'
test_done
fi
@@ -17,7 +17,7 @@ import sys
if sys.hexversion < 0x02040000:
sys.exit(1)
' || {
- skip_all='skipping git-remote-hg tests, python version < 2.4'
+ skip_all='skipping python remote-helper tests, python version < 2.4'
test_done
}
@@ -38,12 +38,12 @@ test_expect_success 'setup repository' '
'
test_expect_success 'cloning from local repo' '
- git clone "testgit::${PWD}/server" localclone &&
+ git clone "testpy::${PWD}/server" localclone &&
test_cmp public/file localclone/file
'
test_expect_success 'cloning from remote repo' '
- git clone "testgit::file://${PWD}/server" clone &&
+ git clone "testpy::file://${PWD}/server" clone &&
test_cmp public/file clone/file
'
@@ -73,11 +73,11 @@ test_expect_success 'pushing to local repo' '
'
# Generally, skip this test. It demonstrates a now-fixed race in
-# git-remote-testgit, but is too slow to leave in for general use.
+# git-remote-testpy, but is too slow to leave in for general use.
: test_expect_success 'racily pushing to local repo' '
test_when_finished "rm -rf server2 localclone2" &&
cp -R server server2 &&
- git clone "testgit::${PWD}/server2" localclone2 &&
+ git clone "testpy::${PWD}/server2" localclone2 &&
(cd localclone2 &&
echo content >>file &&
git commit -a -m three &&
@@ -145,4 +145,25 @@ test_expect_failure 'push new branch with old:new refspec' '
compare_refs clone HEAD server refs/heads/new-refspec
'
+test_expect_success 'proper failure checks for fetching' '
+ (GIT_REMOTE_TESTGIT_FAILURE=1 &&
+ export GIT_REMOTE_TESTGIT_FAILURE &&
+ cd localclone &&
+ test_must_fail git fetch 2>&1 | \
+ grep "Error while running fast-import"
+ )
+'
+
+# We sleep to give fast-export a chance to catch the SIGPIPE
+test_expect_failure 'proper failure checks for pushing' '
+ (GIT_REMOTE_TESTGIT_FAILURE=1 &&
+ export GIT_REMOTE_TESTGIT_FAILURE &&
+ GIT_REMOTE_TESTGIT_SLEEPY=1 &&
+ export GIT_REMOTE_TESTGIT_SLEEPY &&
+ cd localclone &&
+ test_must_fail git push --all 2>&1 | \
+ grep "Error while running fast-export"
+ )
+'
+
test_done
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
new file mode 100755
index 0000000000..f387027c05
--- /dev/null
+++ b/t/t5801-remote-helpers.sh
@@ -0,0 +1,169 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Sverre Rabbelier
+#
+
+test_description='Test remote-helper import and export commands'
+
+. ./test-lib.sh
+
+if ! type "${BASH-bash}" >/dev/null 2>&1; then
+ skip_all='skipping remote-testgit tests, bash not available'
+ test_done
+fi
+
+compare_refs() {
+ git --git-dir="$1/.git" rev-parse --verify $2 >expect &&
+ git --git-dir="$3/.git" rev-parse --verify $4 >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'setup repository' '
+ git init server &&
+ (cd server &&
+ echo content >file &&
+ git add file &&
+ git commit -m one)
+'
+
+test_expect_success 'cloning from local repo' '
+ git clone "testgit::${PWD}/server" local &&
+ test_cmp server/file local/file
+'
+
+test_expect_success 'create new commit on remote' '
+ (cd server &&
+ echo content >>file &&
+ git commit -a -m two)
+'
+
+test_expect_success 'pulling from local repo' '
+ (cd local && git pull) &&
+ test_cmp server/file local/file
+'
+
+test_expect_success 'pushing to local repo' '
+ (cd local &&
+ echo content >>file &&
+ git commit -a -m three &&
+ git push) &&
+ compare_refs local HEAD server HEAD
+'
+
+test_expect_success 'fetch new branch' '
+ (cd server &&
+ git reset --hard &&
+ git checkout -b new &&
+ echo content >>file &&
+ git commit -a -m five
+ ) &&
+ (cd local &&
+ git fetch origin new
+ ) &&
+ compare_refs server HEAD local FETCH_HEAD
+'
+
+test_expect_success 'fetch multiple branches' '
+ (cd local &&
+ git fetch
+ ) &&
+ compare_refs server master local refs/remotes/origin/master &&
+ compare_refs server new local refs/remotes/origin/new
+'
+
+test_expect_success 'push when remote has extra refs' '
+ (cd local &&
+ git reset --hard origin/master &&
+ echo content >>file &&
+ git commit -a -m six &&
+ git push
+ ) &&
+ compare_refs local master server master
+'
+
+test_expect_success 'push new branch by name' '
+ (cd local &&
+ git checkout -b new-name &&
+ echo content >>file &&
+ git commit -a -m seven &&
+ git push origin new-name
+ ) &&
+ compare_refs local HEAD server refs/heads/new-name
+'
+
+test_expect_failure 'push new branch with old:new refspec' '
+ (cd local &&
+ git push origin new-name:new-refspec
+ ) &&
+ compare_refs local HEAD server refs/heads/new-refspec
+'
+
+test_expect_success 'cloning without refspec' '
+ GIT_REMOTE_TESTGIT_REFSPEC="" \
+ git clone "testgit::${PWD}/server" local2 &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'pulling without refspecs' '
+ (cd local2 &&
+ git reset --hard &&
+ GIT_REMOTE_TESTGIT_REFSPEC="" git pull) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_failure 'pushing without refspecs' '
+ test_when_finished "(cd local2 && git reset --hard origin)" &&
+ (cd local2 &&
+ echo content >>file &&
+ git commit -a -m ten &&
+ GIT_REMOTE_TESTGIT_REFSPEC="" git push) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'pulling with straight refspec' '
+ (cd local2 &&
+ GIT_REMOTE_TESTGIT_REFSPEC="*:*" git pull) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_failure 'pushing with straight refspec' '
+ test_when_finished "(cd local2 && git reset --hard origin)" &&
+ (cd local2 &&
+ echo content >>file &&
+ git commit -a -m eleven &&
+ GIT_REMOTE_TESTGIT_REFSPEC="*:*" git push) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'pulling without marks' '
+ (cd local2 &&
+ GIT_REMOTE_TESTGIT_NO_MARKS=1 git pull) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_failure 'pushing without marks' '
+ test_when_finished "(cd local2 && git reset --hard origin)" &&
+ (cd local2 &&
+ echo content >>file &&
+ git commit -a -m twelve &&
+ GIT_REMOTE_TESTGIT_NO_MARKS=1 git push) &&
+ compare_refs local2 HEAD server HEAD
+'
+
+test_expect_success 'push all with existing object' '
+ (cd local &&
+ git branch dup2 master &&
+ git push origin --all
+ ) &&
+ compare_refs local dup2 server dup2
+'
+
+test_expect_success 'push ref with existing object' '
+ (cd local &&
+ git branch dup master &&
+ git push origin dup
+ ) &&
+ compare_refs local dup server dup
+'
+
+test_done
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index f94f0c48e6..3fc3b74c8e 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -3,6 +3,7 @@
test_description='git rev-list --pretty=format test'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-terminal.sh
test_tick
test_expect_success 'setup' '
@@ -11,12 +12,24 @@ touch foo && git add foo && git commit -m "added foo" &&
'
# usage: test_format name format_string <expected_output
-test_format() {
+test_format () {
cat >expect.$1
test_expect_success "format $1" "
-git rev-list --pretty=format:'$2' master >output.$1 &&
-test_cmp expect.$1 output.$1
-"
+ git rev-list --pretty=format:'$2' master >output.$1 &&
+ test_cmp expect.$1 output.$1
+ "
+}
+
+# Feed to --format to provide predictable colored sequences.
+AUTO_COLOR='%C(auto,red)foo%C(auto,reset)'
+has_color () {
+ printf '\033[31mfoo\033[m\n' >expect &&
+ test_cmp expect "$1"
+}
+
+has_no_color () {
+ echo foo >expect &&
+ test_cmp expect "$1"
}
test_format percent %%h <<'EOF'
@@ -124,6 +137,48 @@ commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
foo
EOF
+test_expect_success '%C(auto) does not enable color by default' '
+ git log --format=$AUTO_COLOR -1 >actual &&
+ has_no_color actual
+'
+
+test_expect_success '%C(auto) enables colors for color.diff' '
+ git -c color.diff=always log --format=$AUTO_COLOR -1 >actual &&
+ has_color actual
+'
+
+test_expect_success '%C(auto) enables colors for color.ui' '
+ git -c color.ui=always log --format=$AUTO_COLOR -1 >actual &&
+ has_color actual
+'
+
+test_expect_success '%C(auto) respects --color' '
+ git log --format=$AUTO_COLOR -1 --color >actual &&
+ has_color actual
+'
+
+test_expect_success '%C(auto) respects --no-color' '
+ git -c color.ui=always log --format=$AUTO_COLOR -1 --no-color >actual &&
+ has_no_color actual
+'
+
+test_expect_success TTY '%C(auto) respects --color=auto (stdout is tty)' '
+ (
+ TERM=vt100 && export TERM &&
+ test_terminal \
+ git log --format=$AUTO_COLOR -1 --color=auto >actual &&
+ has_color actual
+ )
+'
+
+test_expect_success '%C(auto) respects --color=auto (stdout not tty)' '
+ (
+ TERM=vt100 && export TERM &&
+ git log --format=$AUTO_COLOR -1 --color=auto >actual &&
+ has_no_color actual
+ )
+'
+
cat >commit-msg <<'EOF'
Test printing of complex bodies
diff --git a/t/t6009-rev-list-parent.sh b/t/t6009-rev-list-parent.sh
index 30507407ff..66cda17ef3 100755
--- a/t/t6009-rev-list-parent.sh
+++ b/t/t6009-rev-list-parent.sh
@@ -133,4 +133,17 @@ test_expect_success 'dodecapus' '
check_revlist "--min-parents=13" &&
check_revlist "--min-parents=4 --max-parents=11" tetrapus
'
+
+test_expect_success 'ancestors with the same commit time' '
+
+ test_tick_keep=$test_tick &&
+ for i in 1 2 3 4 5 6 7 8; do
+ test_tick=$test_tick_keep
+ test_commit t$i
+ done &&
+ git rev-list t1^! --not t$i >result &&
+ >expect &&
+ test_cmp expect result
+'
+
test_done
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 72e28ee535..8bf99e10a3 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -190,7 +190,7 @@ test_expect_success 'bisect start: no ".git/BISECT_START" if checkout error' '
# $HASH1 is good, $HASH4 is bad, we skip $HASH3
# but $HASH2 is bad,
# so we should find $HASH2 as the first bad commit
-test_expect_success 'bisect skip: successfull result' '
+test_expect_success 'bisect skip: successful result' '
git bisect reset &&
git bisect start $HASH4 $HASH1 &&
git bisect skip &&
@@ -676,9 +676,7 @@ test_expect_success 'bisect fails if tree is broken on trial commit' '
check_same()
{
echo "Checking $1 is the same as $2" &&
- git rev-parse "$1" > expected.same &&
- git rev-parse "$2" > expected.actual &&
- test_cmp expected.same expected.actual
+ test_cmp_rev "$1" "$2"
}
test_expect_success 'bisect: --no-checkout - start commit bad' '
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index 5c87f28e4e..decdc33c52 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -140,6 +140,17 @@ test_expect_success '"git replace" replacing' '
test "$HASH2" = "$(git replace)"
'
+test_expect_success '"git replace" resolves sha1' '
+ SHORTHASH2=$(git rev-parse --short=8 $HASH2) &&
+ git replace -d $SHORTHASH2 &&
+ git replace $SHORTHASH2 $R &&
+ git show $HASH2 | grep "O Thor" &&
+ test_must_fail git replace $HASH2 $R &&
+ git replace -f $HASH2 $R &&
+ test_must_fail git replace -f &&
+ test "$HASH2" = "$(git replace)"
+'
+
# This creates a side branch where the bug in H2
# does not appear because P2 is created by applying
# H2 and squashing H5 into it.
diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh
new file mode 100755
index 0000000000..39ef61994f
--- /dev/null
+++ b/t/t6130-pathspec-noglob.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+
+test_description='test globbing (and noglob) of pathspec limiting'
+. ./test-lib.sh
+
+test_expect_success 'create commits with glob characters' '
+ test_commit unrelated bar &&
+ test_commit vanilla foo &&
+ # insert file "f*" in the commit, but in a way that avoids
+ # the name "f*" in the worktree, because it is not allowed
+ # on Windows (the tests below do not depend on the presence
+ # of the file in the worktree)
+ git update-index --add --cacheinfo 100644 "$(git rev-parse HEAD:foo)" "f*" &&
+ test_tick &&
+ git commit -m star &&
+ test_commit bracket "f[o][o]"
+'
+
+test_expect_success 'vanilla pathspec matches literally' '
+ echo vanilla >expect &&
+ git log --format=%s -- foo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'star pathspec globs' '
+ cat >expect <<-\EOF &&
+ bracket
+ star
+ vanilla
+ EOF
+ git log --format=%s -- "f*" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'bracket pathspec globs and matches literal brackets' '
+ cat >expect <<-\EOF &&
+ bracket
+ vanilla
+ EOF
+ git log --format=%s -- "f[o][o]" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-glob option matches literally (vanilla)' '
+ echo vanilla >expect &&
+ git --literal-pathspecs log --format=%s -- foo >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-glob option matches literally (star)' '
+ echo star >expect &&
+ git --literal-pathspecs log --format=%s -- "f*" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-glob option matches literally (bracket)' '
+ echo bracket >expect &&
+ git --literal-pathspecs log --format=%s -- "f[o][o]" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'no-glob environment variable works' '
+ echo star >expect &&
+ GIT_LITERAL_PATHSPECS=1 git log --format=%s -- "f*" >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh
index 4d13e10de1..9496736a89 100755
--- a/t/t7003-filter-branch.sh
+++ b/t/t7003-filter-branch.sh
@@ -64,6 +64,20 @@ test_expect_success 'correct GIT_DIR while using -d' '
grep drepo "$TRASHDIR/backup-refs"
'
+test_expect_success 'tree-filter works with -d' '
+ git init drepo-tree &&
+ (
+ cd drepo-tree &&
+ test_commit one &&
+ git filter-branch -d "$TRASHDIR/dfoo" \
+ --tree-filter "echo changed >one.t" &&
+ echo changed >expect &&
+ git cat-file blob HEAD:one.t >actual &&
+ test_cmp expect actual &&
+ test_cmp one.t actual
+ )
+'
+
test_expect_success 'Fail if commit filter fails' '
test_must_fail git filter-branch -f --commit-filter "exit 1" HEAD
'
@@ -167,10 +181,11 @@ test_expect_success 'author information is preserved' '
test_tick &&
GIT_AUTHOR_NAME="B V Uips" git commit -m bvuips &&
git branch preserved-author &&
- git filter-branch -f --msg-filter "cat; \
+ (sane_unset GIT_AUTHOR_NAME &&
+ git filter-branch -f --msg-filter "cat; \
test \$GIT_COMMIT != $(git rev-parse master) || \
echo Hallo" \
- preserved-author &&
+ preserved-author) &&
test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l)
'
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index f5a79b13ae..c8d6e9f88c 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -104,6 +104,18 @@ test_expect_success 'creating a tag using HEAD directly should succeed' '
tag_exists myhead
'
+test_expect_success '--force can create a tag with the name of one existing' '
+ tag_exists mytag &&
+ git tag --force mytag &&
+ tag_exists mytag'
+
+test_expect_success '--force is moot with a non-existing tag name' '
+ git tag newtag >expect &&
+ git tag --force forcetag >actual &&
+ test_cmp expect actual
+'
+git tag -d newtag forcetag
+
# deleting tags:
test_expect_success 'trying to delete an unknown tag should fail' '
diff --git a/t/t7060-wtstatus.sh b/t/t7060-wtstatus.sh
index f4f38a5e73..52ef06b000 100755
--- a/t/t7060-wtstatus.sh
+++ b/t/t7060-wtstatus.sh
@@ -5,6 +5,7 @@ test_description='basic work tree status reporting'
. ./test-lib.sh
test_expect_success setup '
+ git config --global advice.statusuoption false &&
test_commit A &&
test_commit B oneside added &&
git checkout A^0 &&
diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh
new file mode 100755
index 0000000000..0da1214bcc
--- /dev/null
+++ b/t/t7061-wtstatus-ignore.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+
+test_description='git-status ignored files'
+
+. ./test-lib.sh
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+?? untracked/
+EOF
+
+test_expect_success 'status untracked directory with --ignored' '
+ echo "ignored" >.gitignore &&
+ mkdir untracked &&
+ : >untracked/ignored &&
+ : >untracked/uncommitted &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+?? untracked/uncommitted
+!! untracked/ignored
+EOF
+
+test_expect_success 'status untracked directory with --ignored -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! ignored/
+EOF
+
+test_expect_success 'status ignored directory with --ignore' '
+ rm -rf untracked &&
+ mkdir ignored &&
+ : >ignored/uncommitted &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! ignored/uncommitted
+EOF
+
+test_expect_success 'status ignored directory with --ignore -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! untracked-ignored/
+EOF
+
+test_expect_success 'status untracked directory with ignored files with --ignore' '
+ rm -rf ignored &&
+ mkdir untracked-ignored &&
+ mkdir untracked-ignored/test &&
+ : >untracked-ignored/ignored &&
+ : >untracked-ignored/test/ignored &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! untracked-ignored/ignored
+!! untracked-ignored/test/ignored
+EOF
+
+test_expect_success 'status untracked directory with ignored files with --ignore -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+EOF
+
+test_expect_success 'status ignored tracked directory with --ignore' '
+ rm -rf untracked-ignored &&
+ mkdir tracked &&
+ : >tracked/committed &&
+ git add tracked/committed &&
+ git commit -m. &&
+ echo "tracked" >.gitignore &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+EOF
+
+test_expect_success 'status ignored tracked directory with --ignore -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! tracked/
+EOF
+
+test_expect_success 'status ignored tracked directory and uncommitted file with --ignore' '
+ : >tracked/uncommitted &&
+ git status --porcelain --ignored >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<\EOF
+?? .gitignore
+?? actual
+?? expected
+!! tracked/uncommitted
+EOF
+
+test_expect_success 'status ignored tracked directory and uncommitted file with --ignore -u' '
+ git status --porcelain --ignored -u >actual &&
+ test_cmp expected actual
+'
+
+test_done
diff --git a/t/t7062-wtstatus-ignorecase.sh b/t/t7062-wtstatus-ignorecase.sh
new file mode 100755
index 0000000000..73709dbeee
--- /dev/null
+++ b/t/t7062-wtstatus-ignorecase.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+test_description='git-status with core.ignorecase=true'
+
+. ./test-lib.sh
+
+test_expect_success 'status with hash collisions' '
+ # note: "V/", "V/XQANY/" and "WURZAUP/" produce the same hash code
+ # in name-hash.c::hash_name
+ mkdir V &&
+ mkdir V/XQANY &&
+ mkdir WURZAUP &&
+ touch V/XQANY/test &&
+ git config core.ignorecase true &&
+ git add . &&
+ # test is successful if git status completes (no endless loop)
+ git status
+'
+
+test_done
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index b096dc88c2..df82ec9dda 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -28,7 +28,8 @@ test_expect_success 'creating initial files and commits' '
echo "1st line 2nd file" >secondfile &&
echo "2nd line 2nd file" >>secondfile &&
- git commit -a -m "modify 2nd file"
+ git commit -a -m "modify 2nd file" &&
+ head5=$(git rev-parse --verify HEAD)
'
# git log --pretty=oneline # to see those SHA1 involved
@@ -56,7 +57,7 @@ test_expect_success 'giving a non existing revision should fail' '
test_must_fail git reset --mixed aaaaaa &&
test_must_fail git reset --soft aaaaaa &&
test_must_fail git reset --hard aaaaaa &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ check_changes $head5
'
test_expect_success 'reset --soft with unmerged index should fail' '
@@ -74,7 +75,7 @@ test_expect_success \
test_must_fail git reset --hard -- first &&
test_must_fail git reset --soft HEAD^ -- first &&
test_must_fail git reset --hard HEAD^ -- first &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ check_changes $head5
'
test_expect_success 'giving unrecognized options should fail' '
@@ -86,7 +87,7 @@ test_expect_success 'giving unrecognized options should fail' '
test_must_fail git reset --soft -o &&
test_must_fail git reset --hard --other &&
test_must_fail git reset --hard -o &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ check_changes $head5
'
test_expect_success \
@@ -110,7 +111,7 @@ test_expect_success \
git checkout master &&
git branch -D branch1 branch2 &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ check_changes $head5
'
test_expect_success \
@@ -133,27 +134,27 @@ test_expect_success \
git checkout master &&
git branch -D branch3 branch4 &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ check_changes $head5
'
test_expect_success \
'resetting to HEAD with no changes should succeed and do nothing' '
git reset --hard &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git reset --hard HEAD &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git reset --soft &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git reset --soft HEAD &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git reset --mixed &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git reset --mixed HEAD &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git reset &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git reset HEAD &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ check_changes $head5
'
>.diff_expect
@@ -176,7 +177,7 @@ test_expect_success '--soft reset only should show changes in diff --cached' '
git reset --soft HEAD^ &&
check_changes d1a4bc3abce4829628ae2dcb0d60ef3d1a78b1c4 &&
test "$(git rev-parse ORIG_HEAD)" = \
- 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ $head5
'
>.diff_expect
@@ -193,7 +194,7 @@ test_expect_success \
git commit -a -C ORIG_HEAD &&
check_changes 3d3b7be011a58ca0c179ae45d94e6c83c0b0cd0d &&
test "$(git rev-parse ORIG_HEAD)" = \
- 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ $head5
'
>.diff_expect
@@ -303,7 +304,7 @@ test_expect_success 'redoing the last two commits should succeed' '
echo "1st line 2nd file" >secondfile &&
echo "2nd line 2nd file" >>secondfile &&
git commit -a -m "modify 2nd file" &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ check_changes $head5
'
>.diff_expect
@@ -341,15 +342,15 @@ EOF
test_expect_success \
'--hard reset to ORIG_HEAD should clear a fast-forward merge' '
git reset --hard HEAD^ &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git pull . branch1 &&
git reset --hard ORIG_HEAD &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc &&
+ check_changes $head5 &&
git checkout master &&
git branch -D branch1 branch2 &&
- check_changes 3ec39651e7f44ea531a5de18a9fa791c0fd370fc
+ check_changes $head5
'
cat > expect << EOF
@@ -388,7 +389,8 @@ test_expect_success 'test --mixed <paths>' '
echo 4 > file4 &&
echo 5 > file1 &&
git add file1 file3 file4 &&
- test_must_fail git reset HEAD -- file1 file2 file3 &&
+ git reset HEAD -- file1 file2 file3 &&
+ test_must_fail git diff --quiet &&
git diff > output &&
test_cmp output expect &&
git diff --cached > output &&
@@ -402,7 +404,8 @@ test_expect_success 'test resetting the index at give paths' '
>sub/file2 &&
git update-index --add sub/file1 sub/file2 &&
T=$(git write-tree) &&
- test_must_fail git reset HEAD sub/file2 &&
+ git reset HEAD sub/file2 &&
+ test_must_fail git diff --quiet &&
U=$(git write-tree) &&
echo "$T" &&
echo "$U" &&
@@ -440,7 +443,8 @@ test_expect_success 'resetting specific path that is unmerged' '
echo "100644 $F3 3 file2"
} | git update-index --index-info &&
git ls-files -u &&
- test_must_fail git reset HEAD file2 &&
+ git reset HEAD file2 &&
+ test_must_fail git diff --quiet &&
git diff-index --exit-code --cached HEAD
'
@@ -449,7 +453,8 @@ test_expect_success 'disambiguation (1)' '
git reset --hard &&
>secondfile &&
git add secondfile &&
- test_must_fail git reset secondfile &&
+ git reset secondfile &&
+ test_must_fail git diff --quiet -- secondfile &&
test -z "$(git diff --cached --name-only)" &&
test -f secondfile &&
test ! -s secondfile
@@ -474,7 +479,8 @@ test_expect_success 'disambiguation (3)' '
>secondfile &&
git add secondfile &&
rm -f secondfile &&
- test_must_fail git reset HEAD secondfile &&
+ git reset HEAD secondfile &&
+ test_must_fail git diff --quiet &&
test -z "$(git diff --cached --name-only)" &&
test ! -f secondfile
@@ -486,9 +492,18 @@ test_expect_success 'disambiguation (4)' '
>secondfile &&
git add secondfile &&
rm -f secondfile &&
- test_must_fail git reset -- secondfile &&
+ git reset -- secondfile &&
+ test_must_fail git diff --quiet &&
test -z "$(git diff --cached --name-only)" &&
test ! -f secondfile
'
+test_expect_success 'reset with paths accepts tree' '
+ # for simpler tests, drop last commit containing added files
+ git reset --hard HEAD^ &&
+ git reset HEAD^^{tree} -- . &&
+ git diff --cached HEAD^ --exit-code &&
+ git diff HEAD --exit-code
+'
+
test_done
diff --git a/t/t7106-reset-unborn-branch.sh b/t/t7106-reset-unborn-branch.sh
new file mode 100755
index 0000000000..8062cf502b
--- /dev/null
+++ b/t/t7106-reset-unborn-branch.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+test_description='git reset should work on unborn branch'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ echo a >a &&
+ echo b >b
+'
+
+test_expect_success 'reset' '
+ git add a b &&
+ git reset &&
+ test "$(git ls-files)" = ""
+'
+
+test_expect_success 'reset HEAD' '
+ rm .git/index &&
+ git add a b &&
+ test_must_fail git reset HEAD
+'
+
+test_expect_success 'reset $file' '
+ rm .git/index &&
+ git add a b &&
+ git reset a &&
+ test "$(git ls-files)" = "b"
+'
+
+test_expect_success 'reset -p' '
+ rm .git/index &&
+ git add a &&
+ echo y | git reset -p &&
+ test "$(git ls-files)" = ""
+'
+
+test_expect_success 'reset --soft is a no-op' '
+ rm .git/index &&
+ git add a &&
+ git reset --soft
+ test "$(git ls-files)" = "a"
+'
+
+test_expect_success 'reset --hard' '
+ rm .git/index &&
+ git add a &&
+ git reset --hard &&
+ test "$(git ls-files)" = "" &&
+ test_path_is_missing a
+'
+
+test_done
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 5397037491..2683cba7e3 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -133,6 +133,7 @@ test_expect_success 'submodule add --branch' '
(
cd addtest &&
git submodule add -b initial "$submodurl" submod-branch &&
+ test "initial" = "$(git config -f .gitmodules submodule.submod-branch.branch)" &&
git submodule init
) &&
@@ -681,4 +682,79 @@ test_expect_success 'moving the superproject does not break submodules' '
)
'
+test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
+ (
+ cd addtest2 &&
+ (
+ cd repo &&
+ echo "$submodurl/repo" >expect &&
+ git config remote.origin.url >actual &&
+ test_cmp expect actual &&
+ echo "gitdir: ../.git/modules/repo" >expect &&
+ test_cmp expect .git
+ ) &&
+ rm -rf repo &&
+ git rm repo &&
+ git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual &&
+ test ! -s actual &&
+ echo "gitdir: ../.git/modules/submod" >expect &&
+ test_cmp expect submod/.git &&
+ (
+ cd repo &&
+ echo "$submodurl/bare.git" >expect &&
+ git config remote.origin.url >actual &&
+ test_cmp expect actual &&
+ echo "gitdir: ../.git/modules/repo_new" >expect &&
+ test_cmp expect .git
+ ) &&
+ echo "repo" >expect &&
+ git config -f .gitmodules submodule.repo.path >actual &&
+ test_cmp expect actual &&
+ git config -f .gitmodules submodule.repo_new.path >actual &&
+ test_cmp expect actual&&
+ echo "$submodurl/repo" >expect &&
+ git config -f .gitmodules submodule.repo.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/bare.git" >expect &&
+ git config -f .gitmodules submodule.repo_new.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/repo" >expect &&
+ git config submodule.repo.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/bare.git" >expect &&
+ git config submodule.repo_new.url >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'submodule add with an existing name fails unless forced' '
+ (
+ cd addtest2 &&
+ rm -rf repo &&
+ git rm repo &&
+ test_must_fail git submodule add -q --name repo_new "$submodurl/repo.git" repo &&
+ test ! -d repo &&
+ echo "repo" >expect &&
+ git config -f .gitmodules submodule.repo_new.path >actual &&
+ test_cmp expect actual&&
+ echo "$submodurl/bare.git" >expect &&
+ git config -f .gitmodules submodule.repo_new.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/bare.git" >expect &&
+ git config submodule.repo_new.url >actual &&
+ test_cmp expect actual &&
+ git submodule add -f -q --name repo_new "$submodurl/repo.git" repo &&
+ test -d repo &&
+ echo "repo" >expect &&
+ git config -f .gitmodules submodule.repo_new.path >actual &&
+ test_cmp expect actual&&
+ echo "$submodurl/repo.git" >expect &&
+ git config -f .gitmodules submodule.repo_new.url >actual &&
+ test_cmp expect actual &&
+ echo "$submodurl/repo.git" >expect &&
+ git config submodule.repo_new.url >actual &&
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t7402-submodule-rebase.sh b/t/t7402-submodule-rebase.sh
index f919c8d34d..8e32f19007 100755
--- a/t/t7402-submodule-rebase.sh
+++ b/t/t7402-submodule-rebase.sh
@@ -3,7 +3,7 @@
# Copyright (c) 2008 Johannes Schindelin
#
-test_description='Test rebasing and stashing with dirty submodules'
+test_description='Test rebasing, stashing, etc. with submodules'
. ./test-lib.sh
@@ -20,7 +20,8 @@ test_expect_success setup '
echo second line >> file &&
(cd submodule && git pull) &&
test_tick &&
- git commit -m file-and-submodule -a
+ git commit -m file-and-submodule -a &&
+ git branch added-submodule
'
@@ -89,4 +90,29 @@ test_expect_success 'stash with a dirty submodule' '
'
+test_expect_success 'rebasing submodule that should conflict' '
+ git reset --hard &&
+ git checkout added-submodule &&
+ git add submodule &&
+ test_tick &&
+ git commit -m third &&
+ (
+ cd submodule &&
+ git commit --allow-empty -m extra
+ ) &&
+ git add submodule &&
+ test_tick &&
+ git commit -m fourth &&
+
+ test_must_fail git rebase --onto HEAD^^ HEAD^ HEAD^0 &&
+ git ls-files -s submodule >actual &&
+ (
+ cd submodule &&
+ echo "160000 $(git rev-parse HEAD^) 1 submodule" &&
+ echo "160000 $(git rev-parse HEAD^^) 2 submodule" &&
+ echo "160000 $(git rev-parse HEAD) 3 submodule"
+ ) >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh
index 524d5c1b21..94e26c47ea 100755
--- a/t/t7403-submodule-sync.sh
+++ b/t/t7403-submodule-sync.sh
@@ -17,18 +17,25 @@ test_expect_success setup '
git commit -m upstream &&
git clone . super &&
git clone super submodule &&
+ (cd submodule &&
+ git submodule add ../submodule sub-submodule &&
+ test_tick &&
+ git commit -m "sub-submodule"
+ ) &&
(cd super &&
git submodule add ../submodule submodule &&
test_tick &&
git commit -m "submodule"
) &&
git clone super super-clone &&
- (cd super-clone && git submodule update --init) &&
+ (cd super-clone && git submodule update --init --recursive) &&
git clone super empty-clone &&
(cd empty-clone && git submodule init) &&
git clone super top-only-clone &&
git clone super relative-clone &&
- (cd relative-clone && git submodule update --init)
+ (cd relative-clone && git submodule update --init --recursive) &&
+ git clone super recursive-clone &&
+ (cd recursive-clone && git submodule update --init --recursive)
'
test_expect_success 'change submodule' '
@@ -46,6 +53,11 @@ test_expect_success 'change submodule url' '
git pull
) &&
mv submodule moved-submodule &&
+ (cd moved-submodule &&
+ git config -f .gitmodules submodule.sub-submodule.url ../moved-submodule &&
+ test_tick &&
+ git commit -a -m moved-sub-submodule
+ ) &&
(cd super &&
git config -f .gitmodules submodule.submodule.url ../moved-submodule &&
test_tick &&
@@ -61,6 +73,9 @@ test_expect_success '"git submodule sync" should update submodule URLs' '
test -d "$(cd super-clone/submodule &&
git config remote.origin.url
)" &&
+ test ! -d "$(cd super-clone/submodule/sub-submodule &&
+ git config remote.origin.url
+ )" &&
(cd super-clone/submodule &&
git checkout master &&
git pull
@@ -70,6 +85,25 @@ test_expect_success '"git submodule sync" should update submodule URLs' '
)
'
+test_expect_success '"git submodule sync --recursive" should update all submodule URLs' '
+ (cd super-clone &&
+ (cd submodule &&
+ git pull --no-recurse-submodules
+ ) &&
+ git submodule sync --recursive
+ ) &&
+ test -d "$(cd super-clone/submodule &&
+ git config remote.origin.url
+ )" &&
+ test -d "$(cd super-clone/submodule/sub-submodule &&
+ git config remote.origin.url
+ )" &&
+ (cd super-clone/submodule/sub-submodule &&
+ git checkout master &&
+ git pull
+ )
+'
+
test_expect_success '"git submodule sync" should update known submodule URLs' '
(cd empty-clone &&
git pull &&
@@ -107,6 +141,23 @@ test_expect_success '"git submodule sync" handles origin URL of the form foo/bar
#actual foo/submodule
test "$(git config remote.origin.url)" = "../foo/submodule"
)
+ (cd submodule/sub-submodule &&
+ test "$(git config remote.origin.url)" != "../../foo/submodule"
+ )
+ )
+'
+
+test_expect_success '"git submodule sync --recursive" propagates changes in origin' '
+ (cd recursive-clone &&
+ git remote set-url origin foo/bar &&
+ git submodule sync --recursive &&
+ (cd submodule &&
+ #actual foo/submodule
+ test "$(git config remote.origin.url)" = "../foo/submodule"
+ )
+ (cd submodule/sub-submodule &&
+ test "$(git config remote.origin.url)" = "../../foo/submodule"
+ )
)
'
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 15426530e4..1a3d20bdc3 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -135,6 +135,37 @@ test_expect_success 'submodule update --force forcibly checks out submodules' '
)
'
+test_expect_success 'submodule update --remote should fetch upstream changes' '
+ (cd submodule &&
+ echo line4 >> file &&
+ git add file &&
+ test_tick &&
+ git commit -m "upstream line4"
+ ) &&
+ (cd super &&
+ git submodule update --remote --force submodule &&
+ cd submodule &&
+ test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline)"
+ )
+'
+
+test_expect_success 'local config should override .gitmodules branch' '
+ (cd submodule &&
+ git checkout -b test-branch &&
+ echo line5 >> file &&
+ git add file &&
+ test_tick &&
+ git commit -m "upstream line5" &&
+ git checkout master
+ ) &&
+ (cd super &&
+ git config submodule.submodule.branch test-branch &&
+ git submodule update --remote --force submodule &&
+ cd submodule &&
+ test "$(git log -1 --oneline)" = "$(GIT_DIR=../../submodule/.git git log -1 --oneline test-branch)"
+ )
+'
+
test_expect_success 'submodule update --rebase staying on master' '
(cd super/submodule &&
git checkout master
@@ -612,7 +643,8 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re
rm -rf super_update_r2 &&
git clone super_update_r super_update_r2 &&
(cd super_update_r2 &&
- git submodule update --init --recursive &&
+ git submodule update --init --recursive >actual &&
+ test_i18ngrep "Submodule path .submodule/subsubmodule.: checked out" actual &&
(cd submodule/subsubmodule &&
git log > ../../expected
) &&
@@ -627,7 +659,7 @@ test_expect_success 'submodule add properly re-creates deeper level submodules'
(cd super &&
git reset --hard master &&
rm -rf deeper/ &&
- git submodule add ../submodule deeper/submodule
+ git submodule add --force ../submodule deeper/submodule
)
'
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 9b69fe2e14..107b4b7c45 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -226,14 +226,14 @@ test_expect_success 'test "status --recursive"' '
test_cmp expect actual
'
-sed -e "/nested1 /s/.*/+$nested1sha1 nested1 (file2~1)/;/sub[1-3]/d" < expect > expect2
+sed -e "/nested2 /s/.*/+$nested2sha1 nested1\/nested2 (file2~1)/;/sub[1-3]/d" < expect > expect2
mv -f expect2 expect
test_expect_success 'ensure "status --cached --recursive" preserves the --cached flag' '
(
cd clone3 &&
(
- cd nested1 &&
+ cd nested1/nested2 &&
test_commit file2
) &&
git submodule status --cached --recursive -- nested1 > ../actual
diff --git a/t/t7500/add-content-and-comment b/t/t7500/add-content-and-comment
new file mode 100755
index 0000000000..c4dccff13a
--- /dev/null
+++ b/t/t7500/add-content-and-comment
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo "commit message" >> "$1"
+echo "# comment" >> "$1"
+exit 0
+
diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh
index deb187eb7b..292bc082b2 100755
--- a/t/t7502-commit.sh
+++ b/t/t7502-commit.sh
@@ -4,6 +4,15 @@ test_description='git commit porcelain-ish'
. ./test-lib.sh
+commit_msg_is () {
+ expect=commit_msg_is.expect
+ actual=commit_msg_is.actual
+
+ printf "%s" "$(git log --pretty=format:%s%b -1)" >$actual &&
+ printf "%s" "$1" >$expect &&
+ test_i18ncmp $expect $actual
+}
+
# Arguments: [<prefix] [<commit message>] [<commit options>]
check_summary_oneline() {
test_tick &&
@@ -168,17 +177,25 @@ test_expect_success 'verbose respects diff config' '
git config --unset color.diff
'
-test_expect_success 'cleanup commit messages (verbatim,-t)' '
+mesg_with_comment_and_newlines='
+# text
+
+'
+
+test_expect_success 'prepare file with comment line and trailing newlines' '
+ printf "%s" "$mesg_with_comment_and_newlines" >expect
+'
+
+test_expect_success 'cleanup commit messages (verbatim option,-t)' '
echo >>negative &&
- { echo;echo "# text";echo; } >expect &&
- git commit --cleanup=verbatim -t expect -a &&
- git cat-file -p HEAD |sed -e "1,/^\$/d" |head -n 3 >actual &&
+ git commit --cleanup=verbatim --no-status -t expect -a &&
+ git cat-file -p HEAD |sed -e "1,/^\$/d" >actual &&
test_cmp expect actual
'
-test_expect_success 'cleanup commit messages (verbatim,-F)' '
+test_expect_success 'cleanup commit messages (verbatim option,-F)' '
echo >>negative &&
git commit --cleanup=verbatim -F expect -a &&
@@ -187,16 +204,16 @@ test_expect_success 'cleanup commit messages (verbatim,-F)' '
'
-test_expect_success 'cleanup commit messages (verbatim,-m)' '
+test_expect_success 'cleanup commit messages (verbatim option,-m)' '
echo >>negative &&
- git commit --cleanup=verbatim -m "$(cat expect)" -a &&
+ git commit --cleanup=verbatim -m "$mesg_with_comment_and_newlines" -a &&
git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
test_cmp expect actual
'
-test_expect_success 'cleanup commit messages (whitespace,-F)' '
+test_expect_success 'cleanup commit messages (whitespace option,-F)' '
echo >>negative &&
{ echo;echo "# text";echo; } >text &&
@@ -207,7 +224,7 @@ test_expect_success 'cleanup commit messages (whitespace,-F)' '
'
-test_expect_success 'cleanup commit messages (strip,-F)' '
+test_expect_success 'cleanup commit messages (strip option,-F)' '
echo >>negative &&
{ echo;echo "# text";echo sample;echo; } >text &&
@@ -218,7 +235,7 @@ test_expect_success 'cleanup commit messages (strip,-F)' '
'
-test_expect_success 'cleanup commit messages (strip,-F,-e)' '
+test_expect_success 'cleanup commit messages (strip option,-F,-e)' '
echo >>negative &&
{ echo;echo sample;echo; } >text &&
@@ -231,10 +248,71 @@ echo "sample
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit." >expect
-test_expect_success 'cleanup commit messages (strip,-F,-e): output' '
+test_expect_success 'cleanup commit messages (strip option,-F,-e): output' '
test_i18ncmp expect actual
'
+test_expect_success 'cleanup commit message (fail on invalid cleanup mode option)' '
+ test_must_fail git commit --cleanup=non-existent
+'
+
+test_expect_success 'cleanup commit message (fail on invalid cleanup mode configuration)' '
+ test_must_fail git -c commit.cleanup=non-existent commit
+'
+
+test_expect_success 'cleanup commit message (no config and no option uses default)' '
+ echo content >>file &&
+ git add file &&
+ test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
+ git commit --no-status &&
+ commit_msg_is "commit message"
+'
+
+test_expect_success 'cleanup commit message (option overrides default)' '
+ echo content >>file &&
+ git add file &&
+ test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
+ git commit --cleanup=whitespace --no-status &&
+ commit_msg_is "commit message # comment"
+'
+
+test_expect_success 'cleanup commit message (config overrides default)' '
+ echo content >>file &&
+ git add file &&
+ test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
+ git -c commit.cleanup=whitespace commit --no-status &&
+ commit_msg_is "commit message # comment"
+'
+
+test_expect_success 'cleanup commit message (option overrides config)' '
+ echo content >>file &&
+ git add file &&
+ test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment &&
+ git -c commit.cleanup=whitespace commit --cleanup=default &&
+ commit_msg_is "commit message"
+'
+
+test_expect_success 'cleanup commit message (default, -m)' '
+ echo content >>file &&
+ git add file &&
+ git commit -m "message #comment " &&
+ commit_msg_is "message #comment"
+'
+
+test_expect_success 'cleanup commit message (whitespace option, -m)' '
+ echo content >>file &&
+ git add file &&
+ git commit --cleanup=whitespace --no-status -m "message #comment " &&
+ commit_msg_is "message #comment"
+'
+
+test_expect_success 'cleanup commit message (whitespace config, -m)' '
+ echo content >>file &&
+ git add file &&
+ git -c commit.cleanup=whitespace commit --no-status -m "message #comment " &&
+ commit_msg_is "message #comment"
+'
+
test_expect_success 'message shows author when it is not equal to committer' '
echo >>negative &&
git commit -e -m "sample" -a &&
@@ -243,16 +321,6 @@ test_expect_success 'message shows author when it is not equal to committer' '
.git/COMMIT_EDITMSG
'
-test_expect_success 'setup auto-ident prerequisite' '
- if (sane_unset GIT_COMMITTER_EMAIL &&
- sane_unset GIT_COMMITTER_NAME &&
- git var GIT_COMMITTER_IDENT); then
- test_set_prereq AUTOIDENT
- else
- test_set_prereq NOAUTOIDENT
- fi
-'
-
test_expect_success AUTOIDENT 'message shows committer when it is automatic' '
echo >>negative &&
@@ -271,7 +339,7 @@ echo editor started > "$(pwd)/.git/result"
exit 0
EOF
-test_expect_success NOAUTOIDENT 'do not fire editor when committer is bogus' '
+test_expect_success !AUTOIDENT 'do not fire editor when committer is bogus' '
>.git/result
>expect &&
@@ -457,4 +525,11 @@ use_template="-t template"
try_commit_status_combo
+test_expect_success 'commit --status with custom comment character' '
+ test_when_finished "git config --unset core.commentchar" &&
+ git config core.commentchar ";" &&
+ try_commit --status &&
+ test_i18ngrep "^; Changes to be committed:" .git/COMMIT_EDITMSG
+'
+
test_done
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index 5b4b694f18..357375151d 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -167,5 +167,19 @@ test_expect_success 'with failing hook (--no-verify)' '
'
+test_expect_success 'with failing hook (merge)' '
+
+ git checkout -B other HEAD@{1} &&
+ echo "more" >> file &&
+ git add file &&
+ rm -f "$HOOK" &&
+ git commit -m other &&
+ write_script "$HOOK" <<-EOF
+ exit 1
+ EOF
+ git checkout - &&
+ test_must_fail git merge other
+
+'
test_done
diff --git a/t/t7508-status.sh b/t/t7508-status.sh
index e313ef196e..aecb4d1e5f 100755
--- a/t/t7508-status.sh
+++ b/t/t7508-status.sh
@@ -8,6 +8,7 @@ test_description='git status'
. ./test-lib.sh
test_expect_success 'status -h in broken repository' '
+ git config --global advice.statusuoption false &&
mkdir broken &&
test_when_finished "rm -fr broken" &&
(
@@ -1254,6 +1255,56 @@ test_expect_success ".git/config ignore=dirty doesn't suppress submodule summary
'
cat > expect << EOF
+; On branch master
+; Changes to be committed:
+; (use "git reset HEAD <file>..." to unstage)
+;
+; modified: sm
+;
+; Changes not staged for commit:
+; (use "git add <file>..." to update what will be committed)
+; (use "git checkout -- <file>..." to discard changes in working directory)
+;
+; modified: dir1/modified
+; modified: sm (new commits)
+;
+; Submodule changes to be committed:
+;
+; * sm $head...$new_head (1):
+; > Add bar
+;
+; Submodules changed but not updated:
+;
+; * sm $new_head...$head2 (1):
+; > 2nd commit
+;
+; Untracked files:
+; (use "git add <file>..." to include in what will be committed)
+;
+; .gitmodules
+; dir1/untracked
+; dir2/modified
+; dir2/untracked
+; expect
+; output
+; untracked
+EOF
+
+test_expect_success "status (core.commentchar with submodule summary)" '
+ test_when_finished "git config --unset core.commentchar" &&
+ git config core.commentchar ";" &&
+ git status >output &&
+ test_i18ncmp expect output
+'
+
+test_expect_success "status (core.commentchar with two chars with submodule summary)" '
+ test_when_finished "git config --unset core.commentchar" &&
+ git config core.commentchar ";;" &&
+ git status >output &&
+ test_i18ncmp expect output
+'
+
+cat > expect << EOF
# On branch master
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh
index b3f6eb9c68..9d4610629d 100755
--- a/t/t7512-status-help.sh
+++ b/t/t7512-status-help.sh
@@ -5,7 +5,7 @@
# Grenoble INP Ensimag
#
-test_description='git status advices'
+test_description='git status advice'
. ./test-lib.sh
@@ -14,6 +14,7 @@ test_description='git status advices'
set_fake_editor
test_expect_success 'prepare for conflicts' '
+ git config --global advice.statusuoption false &&
test_commit init main.txt init &&
git branch conflicts &&
test_commit on_master main.txt on_master &&
@@ -73,10 +74,11 @@ test_expect_success 'prepare for rebase conflicts' '
test_expect_success 'status when rebase in progress before resolving conflicts' '
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD^^) &&
test_must_fail git rebase HEAD^ --onto HEAD^^ &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently rebasing.
+ # You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
# (fix conflicts and then run "git rebase --continue")
# (use "git rebase --skip" to skip this patch)
# (use "git rebase --abort" to check out the original branch)
@@ -97,12 +99,13 @@ test_expect_success 'status when rebase in progress before resolving conflicts'
test_expect_success 'status when rebase in progress before rebase --continue' '
git reset --hard rebase_conflicts &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD^^) &&
test_must_fail git rebase HEAD^ --onto HEAD^^ &&
echo three >main.txt &&
git add main.txt &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently rebasing.
+ # You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''.
# (all conflicts fixed: run "git rebase --continue")
#
# Changes to be committed:
@@ -130,10 +133,11 @@ test_expect_success 'prepare for rebase_i_conflicts' '
test_expect_success 'status during rebase -i when conflicts unresolved' '
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short rebase_i_conflicts) &&
test_must_fail git rebase -i rebase_i_conflicts &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently rebasing.
+ # You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
# (fix conflicts and then run "git rebase --continue")
# (use "git rebase --skip" to skip this patch)
# (use "git rebase --abort" to check out the original branch)
@@ -154,11 +158,12 @@ test_expect_success 'status during rebase -i when conflicts unresolved' '
test_expect_success 'status during rebase -i after resolving conflicts' '
git reset --hard rebase_i_conflicts_second &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short rebase_i_conflicts) &&
test_must_fail git rebase -i rebase_i_conflicts &&
git add main.txt &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently rebasing.
+ # You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''.
# (all conflicts fixed: run "git rebase --continue")
#
# Changes to be committed:
@@ -182,10 +187,11 @@ test_expect_success 'status when rebasing -i in edit mode' '
FAKE_LINES="1 edit 2" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~2) &&
git rebase -i HEAD~2 &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently editing a commit during a rebase.
+ # You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
@@ -206,11 +212,12 @@ test_expect_success 'status when splitting a commit' '
FAKE_LINES="1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently splitting a commit during a rebase.
+ # You are currently splitting a commit while rebasing branch '\''split_commit'\'' on '\''$ONTO'\''.
# (Once your working directory is clean, run "git rebase --continue")
#
# Changes not staged for commit:
@@ -236,11 +243,12 @@ test_expect_success 'status after editing the last commit with --amend during a
FAKE_LINES="1 2 edit 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git commit --amend -m "foo" &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently editing a commit during a rebase.
+ # You are currently editing a commit while rebasing branch '\''amend_last'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
@@ -265,11 +273,12 @@ test_expect_success 'status: (continue first edit) second edit' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git rebase --continue &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently editing a commit during a rebase.
+ # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
@@ -285,12 +294,13 @@ test_expect_success 'status: (continue first edit) second edit and split' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git rebase --continue &&
git reset HEAD^ &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently splitting a commit during a rebase.
+ # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (Once your working directory is clean, run "git rebase --continue")
#
# Changes not staged for commit:
@@ -311,12 +321,13 @@ test_expect_success 'status: (continue first edit) second edit and amend' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git rebase --continue &&
git commit --amend -m "foo" &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently editing a commit during a rebase.
+ # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
@@ -332,12 +343,13 @@ test_expect_success 'status: (amend first edit) second edit' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git commit --amend -m "a" &&
git rebase --continue &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently editing a commit during a rebase.
+ # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
@@ -353,13 +365,14 @@ test_expect_success 'status: (amend first edit) second edit and split' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git commit --amend -m "b" &&
git rebase --continue &&
git reset HEAD^ &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently splitting a commit during a rebase.
+ # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (Once your working directory is clean, run "git rebase --continue")
#
# Changes not staged for commit:
@@ -380,13 +393,14 @@ test_expect_success 'status: (amend first edit) second edit and amend' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git commit --amend -m "c" &&
git rebase --continue &&
git commit --amend -m "d" &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently editing a commit during a rebase.
+ # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
@@ -402,14 +416,15 @@ test_expect_success 'status: (split first edit) second edit' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
git add main.txt &&
git commit -m "e" &&
git rebase --continue &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently editing a commit during a rebase.
+ # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
@@ -425,15 +440,16 @@ test_expect_success 'status: (split first edit) second edit and split' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
git add main.txt &&
git commit --amend -m "f" &&
git rebase --continue &&
git reset HEAD^ &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently splitting a commit during a rebase.
+ # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (Once your working directory is clean, run "git rebase --continue")
#
# Changes not staged for commit:
@@ -454,15 +470,16 @@ test_expect_success 'status: (split first edit) second edit and amend' '
FAKE_LINES="edit 1 edit 2 3" &&
export FAKE_LINES &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD~3) &&
git rebase -i HEAD~3 &&
git reset HEAD^ &&
git add main.txt &&
git commit --amend -m "g" &&
git rebase --continue &&
git commit --amend -m "h" &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently editing a commit during a rebase.
+ # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''.
# (use "git commit --amend" to amend the current commit)
# (use "git rebase --continue" once you are satisfied with your changes)
#
@@ -558,7 +575,7 @@ test_expect_success 'status when bisecting' '
git bisect good one_bisect &&
cat >expected <<-\EOF &&
# Not currently on any branch.
- # You are currently bisecting.
+ # You are currently bisecting branch '\''bisect'\''.
# (use "git bisect reset" to get back to the original branch)
#
nothing to commit (use -u to show untracked files)
@@ -577,10 +594,11 @@ test_expect_success 'status when rebase conflicts with statushints disabled' '
test_commit two_statushints main.txt two &&
test_commit three_statushints main.txt three &&
test_when_finished "git rebase --abort" &&
+ ONTO=$(git rev-parse --short HEAD^^) &&
test_must_fail git rebase HEAD^ --onto HEAD^^ &&
- cat >expected <<-\EOF &&
+ cat >expected <<-EOF &&
# Not currently on any branch.
- # You are currently rebasing.
+ # You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''.
#
# Unmerged paths:
# both modified: main.txt
diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh
index b44b293950..25dac79889 100755
--- a/t/t7601-merge-pull-config.sh
+++ b/t/t7601-merge-pull-config.sh
@@ -109,7 +109,7 @@ test_expect_success 'setup conflicted merge' '
'
# First do the merge with resolve and recursive then verify that
-# recusive is choosen.
+# recusive is chosen.
test_expect_success 'merge picks up the best result' '
git config --unset-all pull.twohead &&
diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index bc38737b2a..d526b1d96a 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -237,7 +237,7 @@ test_expect_success 'mergetool takes partial path' '
git submodule update -N &&
test_must_fail git merge master &&
- #shouldnt need these lines
+ #should not need these lines
#( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
#( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
#( yes "l" | git mergetool submod >/dev/null 2>&1 ) &&
diff --git a/t/t7811-grep-open.sh b/t/t7811-grep-open.sh
index a8957782cf..e1951a5cbb 100755
--- a/t/t7811-grep-open.sh
+++ b/t/t7811-grep-open.sh
@@ -125,11 +125,6 @@ test_expect_success 'modified file' '
test_cmp empty out
'
-test_config() {
- git config "$1" "$2" &&
- test_when_finished "git config --unset $1"
-}
-
test_expect_success 'copes with color settings' '
rm -f actual &&
echo grep.h >expect &&
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 035122808b..ebd5c5db45 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -101,7 +101,7 @@ test_expect_success $PREREQ \
test_expect_success $PREREQ 'Send patches with --envelope-sender' '
clean_fake_sendmail &&
- git send-email --envelope-sender="Patch Contributer <patch@example.com>" --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
+ git send-email --envelope-sender="Patch Contributor <patch@example.com>" --suppress-cc=sob --from="Example <nobody@example.com>" --to=nobody@example.com --smtp-server="$(pwd)/fake.sendmail" $patches 2>errors
'
test_expect_success $PREREQ 'setup expect' '
@@ -191,17 +191,44 @@ test_expect_success $PREREQ 'Show all headers' '
test_expect_success $PREREQ 'Prompting works' '
clean_fake_sendmail &&
- (echo "Example <from@example.com>"
- echo "to@example.com"
+ (echo "to@example.com"
echo ""
) | GIT_SEND_EMAIL_NOTTY=1 git send-email \
--smtp-server="$(pwd)/fake.sendmail" \
$patches \
2>errors &&
- grep "^From: Example <from@example.com>\$" msgtxt1 &&
+ grep "^From: A U Thor <author@example.com>\$" msgtxt1 &&
grep "^To: to@example.com\$" msgtxt1
'
+test_expect_success $PREREQ,AUTOIDENT 'implicit ident is allowed' '
+ clean_fake_sendmail &&
+ (sane_unset GIT_AUTHOR_NAME &&
+ sane_unset GIT_AUTHOR_EMAIL &&
+ sane_unset GIT_COMMITTER_NAME &&
+ sane_unset GIT_COMMITTER_EMAIL &&
+ GIT_SEND_EMAIL_NOTTY=1 git send-email \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --to=to@example.com \
+ $patches </dev/null 2>errors
+ )
+'
+
+test_expect_success $PREREQ,!AUTOIDENT 'broken implicit ident aborts send-email' '
+ clean_fake_sendmail &&
+ (sane_unset GIT_AUTHOR_NAME &&
+ sane_unset GIT_AUTHOR_EMAIL &&
+ sane_unset GIT_COMMITTER_NAME &&
+ sane_unset GIT_COMMITTER_EMAIL &&
+ GIT_SEND_EMAIL_NOTTY=1 && export GIT_SEND_EMAIL_NOTTY &&
+ test_must_fail git send-email \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --to=to@example.com \
+ $patches </dev/null 2>errors &&
+ test_i18ngrep "tell me who you are" errors
+ )
+'
+
test_expect_success $PREREQ 'tocmd works' '
clean_fake_sendmail &&
cp $patches tocmd.patch &&
@@ -760,7 +787,7 @@ test_expect_success $PREREQ 'confirm detects EOF (auto causes failure)' '
test $ret = "0"
'
-test_expect_success $PREREQ 'confirm doesnt loop forever' '
+test_expect_success $PREREQ 'confirm does not loop forever' '
CONFIRM=$(git config --get sendemail.confirm) &&
git config sendemail.confirm auto &&
GIT_SEND_EMAIL_NOTTY=1 &&
@@ -854,6 +881,75 @@ test_expect_success $PREREQ 'utf8 author is correctly passed on' '
grep "^From: Füñný Nâmé <odd_?=mail@example.com>" msgtxt1
'
+test_expect_success $PREREQ 'sendemail.composeencoding works' '
+ clean_fake_sendmail &&
+ git config sendemail.composeencoding iso-8859-1 &&
+ (echo "#!$SHELL_PATH" &&
+ echo "echo utf8 body: àéìöú >>\"\$1\""
+ ) >fake-editor-utf8 &&
+ chmod +x fake-editor-utf8 &&
+ GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
+ git send-email \
+ --compose --subject foo \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ grep "^utf8 body" msgtxt1 &&
+ grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
+'
+
+test_expect_success $PREREQ '--compose-encoding works' '
+ clean_fake_sendmail &&
+ (echo "#!$SHELL_PATH" &&
+ echo "echo utf8 body: àéìöú >>\"\$1\""
+ ) >fake-editor-utf8 &&
+ chmod +x fake-editor-utf8 &&
+ GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
+ git send-email \
+ --compose-encoding iso-8859-1 \
+ --compose --subject foo \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ grep "^utf8 body" msgtxt1 &&
+ grep "^Content-Type: text/plain; charset=iso-8859-1" msgtxt1
+'
+
+test_expect_success $PREREQ '--compose-encoding overrides sendemail.composeencoding' '
+ clean_fake_sendmail &&
+ git config sendemail.composeencoding iso-8859-1 &&
+ (echo "#!$SHELL_PATH" &&
+ echo "echo utf8 body: àéìöú >>\"\$1\""
+ ) >fake-editor-utf8 &&
+ chmod +x fake-editor-utf8 &&
+ GIT_EDITOR="\"$(pwd)/fake-editor-utf8\"" \
+ git send-email \
+ --compose-encoding iso-8859-2 \
+ --compose --subject foo \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ grep "^utf8 body" msgtxt1 &&
+ grep "^Content-Type: text/plain; charset=iso-8859-2" msgtxt1
+'
+
+test_expect_success $PREREQ '--compose-encoding adds correct MIME for subject' '
+ clean_fake_sendmail &&
+ GIT_EDITOR="\"$(pwd)/fake-editor\"" \
+ git send-email \
+ --compose-encoding iso-8859-2 \
+ --compose --subject utf8-sübjëct \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ $patches &&
+ grep "^fake edit" msgtxt1 &&
+ grep "^Subject: =?iso-8859-2?q?utf8-s=C3=BCbj=C3=ABct?=" msgtxt1
+'
+
test_expect_success $PREREQ 'detects ambiguous reference/file conflict' '
echo master > master &&
git add master &&
@@ -1074,6 +1170,23 @@ EOF
'
test_expect_success $PREREQ 'setup expect' '
+cat >expected <<EOF
+Subject: subject goes here
+EOF
+'
+
+test_expect_success $PREREQ 'ASCII subject is not RFC2047 quoted' '
+ clean_fake_sendmail &&
+ echo bogus |
+ git send-email --from=author@example.com --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --8bit-encoding=UTF-8 \
+ email-using-8bit >stdout &&
+ grep "Subject" msgtxt1 >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success $PREREQ 'setup expect' '
cat >content-type-decl <<EOF
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
index b7eed2489f..6dafe7e99a 100755
--- a/t/t9010-svn-fe.sh
+++ b/t/t9010-svn-fe.sh
@@ -54,14 +54,6 @@ text_no_props () {
>empty
-test_expect_success 'setup: have pipes?' '
- rm -f frob &&
- if mkfifo frob
- then
- test_set_prereq PIPE
- fi
-'
-
test_expect_success PIPE 'empty dump' '
reinit_git &&
echo "SVN-fs-dump-format-version: 2" >input &&
diff --git a/t/t9020-remote-svn.sh b/t/t9020-remote-svn.sh
new file mode 100755
index 0000000000..2d2f016f6f
--- /dev/null
+++ b/t/t9020-remote-svn.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+test_description='tests remote-svn'
+
+. ./test-lib.sh
+
+MARKSPATH=.git/info/fast-import/remote-svn
+
+if ! test_have_prereq PYTHON
+then
+ skip_all='skipping remote-svn tests, python not available'
+ test_done
+fi
+
+# Override svnrdump with our simulator
+PATH="$HOME:$PATH"
+export PATH PYTHON_PATH GIT_BUILD_DIR
+
+write_script "$HOME/svnrdump" <<\EOF
+exec "$PYTHON_PATH" "$GIT_BUILD_DIR/contrib/svn-fe/svnrdump_sim.py" "$@"
+EOF
+
+init_git () {
+ rm -fr .git &&
+ git init &&
+ #git remote add svnsim testsvn::sim:///$TEST_DIRECTORY/t9020/example.svnrdump
+ # let's reuse an exisiting dump file!?
+ git remote add svnsim testsvn::sim://$TEST_DIRECTORY/t9154/svn.dump
+ git remote add svnfile testsvn::file://$TEST_DIRECTORY/t9154/svn.dump
+}
+
+if test -e "$GIT_BUILD_DIR/git-remote-testsvn"
+then
+ test_set_prereq REMOTE_SVN
+fi
+
+test_debug '
+ git --version
+ type git
+ type svnrdump
+'
+
+test_expect_success REMOTE_SVN 'simple fetch' '
+ init_git &&
+ git fetch svnsim &&
+ test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master &&
+ cp .git/refs/remotes/svnsim/master master.good
+'
+
+test_debug '
+ cat .git/refs/svn/svnsim/master
+ cat .git/refs/remotes/svnsim/master
+'
+
+test_expect_success REMOTE_SVN 'repeated fetch, nothing shall change' '
+ git fetch svnsim &&
+ test_cmp master.good .git/refs/remotes/svnsim/master
+'
+
+test_expect_success REMOTE_SVN 'fetch from a file:// url gives the same result' '
+ git fetch svnfile
+'
+
+test_expect_failure REMOTE_SVN 'the sha1 differ because the git-svn-id line in the commit msg contains the url' '
+ test_cmp .git/refs/remotes/svnfile/master .git/refs/remotes/svnsim/master
+'
+
+test_expect_success REMOTE_SVN 'mark-file regeneration' '
+ # filter out any other marks, that can not be regenerated. Only up to 3 digit revisions are allowed here
+ grep ":[0-9]\{1,3\} " $MARKSPATH/svnsim.marks > $MARKSPATH/svnsim.marks.old &&
+ rm $MARKSPATH/svnsim.marks &&
+ git fetch svnsim &&
+ test_cmp $MARKSPATH/svnsim.marks.old $MARKSPATH/svnsim.marks
+'
+
+test_expect_success REMOTE_SVN 'incremental imports must lead to the same head' '
+ export SVNRMAX=3 &&
+ init_git &&
+ git fetch svnsim &&
+ test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master &&
+ unset SVNRMAX &&
+ git fetch svnsim &&
+ test_cmp master.good .git/refs/remotes/svnsim/master
+'
+
+test_debug 'git branch -a'
+
+test_done
diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh
index 749b75e8d4..4fea8d901b 100755
--- a/t/t9100-git-svn-basic.sh
+++ b/t/t9100-git-svn-basic.sh
@@ -306,5 +306,13 @@ test_expect_success 'git-svn works in a bare repository' '
git svn fetch ) &&
rm -rf bare-repo
'
+test_expect_success 'git-svn works in in a repository with a gitdir: link' '
+ mkdir worktree gitdir &&
+ ( cd worktree &&
+ git svn init "$svnrepo" &&
+ git init --separate-git-dir ../gitdir &&
+ git svn fetch ) &&
+ rm -rf worktree gitdir
+ '
test_done
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index b59be9a894..3fb3368903 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -19,14 +19,15 @@ then
test_done
fi
-CVSROOT=$PWD/cvsroot
+CVSROOT=$PWD/tmpcvsroot
CVSWORK=$PWD/cvswork
GIT_DIR=$PWD/.git
export CVSROOT CVSWORK GIT_DIR
rm -rf "$CVSROOT" "$CVSWORK"
-mkdir "$CVSROOT" &&
+
cvs init &&
+test -d "$CVSROOT" &&
cvs -Q co -d "$CVSWORK" . &&
echo >empty &&
git add empty &&
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 2fcf269469..ac6f3b6af2 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -49,14 +49,6 @@ echo "$@"'
>empty
-test_expect_success 'setup: have pipes?' '
- rm -f frob &&
- if mkfifo frob
- then
- test_set_prereq PIPE
- fi
-'
-
###
### series A
###
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 3e821f958b..9320b4f94c 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -303,7 +303,7 @@ test_expect_success 'dropping tag of filtered out object' '
(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=drop mytag -- there > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -320,7 +320,7 @@ test_expect_success 'rewriting tag of filtered out object' '
(
cd limit-by-paths &&
git fast-export --tag-of-filtered-object=rewrite mytag -- there > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -351,7 +351,7 @@ test_expect_failure 'no exact-ref revisions included' '
(
cd limit-by-paths &&
git fast-export master~2..master~1 > output &&
- test_cmp output expected
+ test_cmp expected output
)
'
@@ -440,4 +440,63 @@ test_expect_success 'fast-export quotes pathnames' '
)
'
+test_expect_success 'test bidirectionality' '
+ >marks-cur &&
+ >marks-new &&
+ git init marks-test &&
+ git fast-export --export-marks=marks-cur --import-marks=marks-cur --branches | \
+ git --git-dir=marks-test/.git fast-import --export-marks=marks-new --import-marks=marks-new &&
+ (cd marks-test &&
+ git reset --hard &&
+ echo Wohlauf > file &&
+ git commit -a -m "back in time") &&
+ git --git-dir=marks-test/.git fast-export --export-marks=marks-new --import-marks=marks-new --branches | \
+ git fast-import --export-marks=marks-cur --import-marks=marks-cur
+'
+
+cat > expected << EOF
+blob
+mark :13
+data 5
+bump
+
+commit refs/heads/master
+mark :14
+author A U Thor <author@example.com> 1112912773 -0700
+committer C O Mitter <committer@example.com> 1112912773 -0700
+data 5
+bump
+from :12
+M 100644 :13 file
+
+EOF
+
+test_expect_success 'avoid uninteresting refs' '
+ > tmp-marks &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > /dev/null &&
+ git tag v1.0 &&
+ git branch uninteresting &&
+ echo bump > file &&
+ git commit -a -m bump &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks ^uninteresting ^v1.0 master > actual &&
+ test_cmp expected actual
+'
+
+cat > expected << EOF
+reset refs/heads/master
+from :14
+
+EOF
+
+test_expect_success 'refs are updated even if no commits need to be exported' '
+ > tmp-marks &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > /dev/null &&
+ git fast-export --import-marks=tmp-marks \
+ --export-marks=tmp-marks master > actual &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 806623e885..9502f2438a 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -400,7 +400,7 @@ cat >expected.C <<EOF
Line 0
=======
LINE 0
->>>>>>> merge.3
+>>>>>>> merge.1.3
EOF
for i in 1 2 3 4 5 6 7 8
@@ -505,6 +505,76 @@ test_expect_success 'cvs co -c (shows module database)' '
'
#------------
+# CVS LOG
+#------------
+
+# Known issues with git-cvsserver current log output:
+# - Hard coded "lines: +2 -3" placeholder, instead of real numbers.
+# - CVS normally does not internally add a blank first line
+# nor a last line with nothing but a space to log messages.
+# - The latest cvs 1.12.x server sends +0000 timezone (with some hidden "MT"
+# tagging in the protocol), and if cvs 1.12.x client sees the MT tags,
+# it converts to local time zone. git-cvsserver doesn't do the +0000
+# or the MT tags...
+# - The latest 1.12.x releases add a "commitid:" field on to the end of the
+# "date:" line (after "lines:"). Maybe we could stick git's commit id
+# in it? Or does CVS expect a certain number of bits (too few for
+# a full sha1)?
+#
+# Given the above, expect the following test to break if git-cvsserver's
+# log output is improved. The test is just to ensure it doesn't
+# accidentally get worse.
+
+sed -e 's/^x//' -e 's/SP$/ /' > "$WORKDIR/expect" <<EOF
+x
+xRCS file: $WORKDIR/gitcvs.git/master/merge,v
+xWorking file: merge
+xhead: 1.4
+xbranch:
+xlocks: strict
+xaccess list:
+xsymbolic names:
+xkeyword substitution: kv
+xtotal revisions: 4; selected revisions: 4
+xdescription:
+x----------------------------
+xrevision 1.4
+xdate: __DATE__; author: author; state: Exp; lines: +2 -3
+x
+xMerge test (no-op)
+xSP
+x----------------------------
+xrevision 1.3
+xdate: __DATE__; author: author; state: Exp; lines: +2 -3
+x
+xMerge test (conflict)
+xSP
+x----------------------------
+xrevision 1.2
+xdate: __DATE__; author: author; state: Exp; lines: +2 -3
+x
+xMerge test (merge)
+xSP
+x----------------------------
+xrevision 1.1
+xdate: __DATE__; author: author; state: Exp; lines: +2 -3
+x
+xMerge test (pre-merge)
+xSP
+x=============================================================================
+EOF
+expectStat="$?"
+
+cd "$WORKDIR"
+test_expect_success 'cvs log' '
+ cd cvswork &&
+ test x"$expectStat" = x"0" &&
+ GIT_CONFIG="$git_config" cvs log merge >../out &&
+ sed -e "s%2[0-9][0-9][0-9]/[01][0-9]/[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]%__DATE__%" ../out > ../actual &&
+ test_cmp ../expect ../actual
+'
+
+#------------
# CVS ANNOTATE
#------------
diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh
index ff6d6fb473..1c5bc84fa7 100755
--- a/t/t9401-git-cvsserver-crlf.sh
+++ b/t/t9401-git-cvsserver-crlf.sh
@@ -38,6 +38,25 @@ not_present() {
fi
}
+check_status_options() {
+ (cd "$1" &&
+ GIT_CONFIG="$git_config" cvs -Q status "$2" > "${WORKDIR}/status.out" 2>&1
+ )
+ if [ x"$?" != x"0" ] ; then
+ echo "Error from cvs status: $1 $2" >> "${WORKDIR}/marked.log"
+ return 1;
+ fi
+ got="$(sed -n -e 's/^[ ]*Sticky Options:[ ]*//p' "${WORKDIR}/status.out")"
+ expect="$3"
+ if [ x"$expect" = x"" ] ; then
+ expect="(none)"
+ fi
+ test x"$got" = x"$expect"
+ stat=$?
+ echo "cvs status: $1 $2 $stat '$3' '$got'" >> "${WORKDIR}/marked.log"
+ return $stat
+}
+
cvs >/dev/null 2>&1
if test $? -ne 1
then
@@ -233,6 +252,22 @@ test_expect_success 'cvs co another copy (guess)' '
marked_as cvswork2/subdir newfile.c ""
'
+test_expect_success 'cvs status - sticky options' '
+ check_status_options cvswork2 textfile.c "" &&
+ check_status_options cvswork2 binfile.bin -kb &&
+ check_status_options cvswork2 .gitattributes "" &&
+ check_status_options cvswork2 mixedUp.c -kb &&
+ check_status_options cvswork2 multiline.c -kb &&
+ check_status_options cvswork2 multilineTxt.c "" &&
+ check_status_options cvswork2/subdir withCr.bin -kb &&
+ check_status_options cvswork2 subdir/withCr.bin -kb &&
+ check_status_options cvswork2/subdir file.h "" &&
+ check_status_options cvswork2 subdir/file.h "" &&
+ check_status_options cvswork2/subdir unspecified.other "" &&
+ check_status_options cvswork2/subdir newfile.bin "" &&
+ check_status_options cvswork2/subdir newfile.c ""
+'
+
test_expect_success 'add text (guess)' '
(cd cvswork &&
echo "simpleText" > simpleText.c &&
diff --git a/t/t9402-git-cvsserver-refs.sh b/t/t9402-git-cvsserver-refs.sh
new file mode 100755
index 0000000000..735a018ecc
--- /dev/null
+++ b/t/t9402-git-cvsserver-refs.sh
@@ -0,0 +1,551 @@
+#!/bin/sh
+
+test_description='git-cvsserver and git refspecs
+
+tests ability for git-cvsserver to switch between and compare
+tags, branches and other git refspecs'
+
+. ./test-lib.sh
+
+#########
+
+check_start_tree() {
+ rm -f "$WORKDIR/list.expected"
+ echo "start $1" >>"${WORKDIR}/check.log"
+}
+
+check_file() {
+ sandbox="$1"
+ file="$2"
+ ver="$3"
+ GIT_DIR=$SERVERDIR git show "${ver}:${file}" \
+ >"$WORKDIR/check.got" 2>"$WORKDIR/check.stderr"
+ test_cmp "$WORKDIR/check.got" "$sandbox/$file"
+ stat=$?
+ echo "check_file $sandbox $file $ver : $stat" >>"$WORKDIR/check.log"
+ echo "$file" >>"$WORKDIR/list.expected"
+ return $stat
+}
+
+check_end_tree() {
+ sandbox="$1" &&
+ find "$sandbox" -name CVS -prune -o -type f -print >"$WORKDIR/list.actual" &&
+ sort <"$WORKDIR/list.expected" >expected &&
+ sort <"$WORKDIR/list.actual" | sed -e "s%cvswork/%%" >actual &&
+ test_cmp expected actual &&
+ rm expected actual
+}
+
+check_end_full_tree() {
+ sandbox="$1" &&
+ sort <"$WORKDIR/list.expected" >expected &&
+ find "$sandbox" -name CVS -prune -o -type f -print |
+ sed -e "s%$sandbox/%%" | sort >act1 &&
+ test_cmp expected act1 &&
+ git ls-tree --name-only -r "$2" | sort >act2 &&
+ test_cmp expected act2 &&
+ rm expected act1 act2
+}
+
+#########
+
+check_diff() {
+ diffFile="$1"
+ vOld="$2"
+ vNew="$3"
+ rm -rf diffSandbox
+ git clone -q -n . diffSandbox &&
+ (
+ cd diffSandbox &&
+ git checkout "$vOld" &&
+ git apply -p0 --index <"../$diffFile" &&
+ git diff --exit-code "$vNew"
+ ) >check_diff_apply.out 2>&1
+}
+
+#########
+
+cvs >/dev/null 2>&1
+if test $? -ne 1
+then
+ skip_all='skipping git-cvsserver tests, cvs not found'
+ test_done
+fi
+if ! test_have_prereq PERL
+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 || {
+ skip_all='skipping git-cvsserver tests, Perl SQLite interface unavailable'
+ test_done
+}
+
+unset GIT_DIR GIT_CONFIG
+WORKDIR=$(pwd)
+SERVERDIR=$(pwd)/gitcvs.git
+git_config="$SERVERDIR/config"
+CVSROOT=":fork:$SERVERDIR"
+CVSWORK="$(pwd)/cvswork"
+CVS_SERVER=git-cvsserver
+export CVSROOT CVS_SERVER
+
+rm -rf "$CVSWORK" "$SERVERDIR"
+test_expect_success 'setup v1, b1' '
+ echo "Simple text file" >textfile.c &&
+ echo "t2" >t2 &&
+ mkdir adir &&
+ echo "adir/afile line1" >adir/afile &&
+ echo "adir/afile line2" >>adir/afile &&
+ echo "adir/afile line3" >>adir/afile &&
+ echo "adir/afile line4" >>adir/afile &&
+ echo "adir/a2file" >>adir/a2file &&
+ mkdir adir/bdir &&
+ echo "adir/bdir/bfile line 1" >adir/bdir/bfile &&
+ echo "adir/bdir/bfile line 2" >>adir/bdir/bfile &&
+ echo "adir/bdir/b2file" >adir/bdir/b2file &&
+ git add textfile.c t2 adir &&
+ git commit -q -m "First Commit (v1)" &&
+ git tag v1 &&
+ git branch b1 &&
+ git clone -q --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 &&
+ GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
+ GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log"
+'
+
+rm -rf cvswork
+test_expect_success 'cvs co v1' '
+ cvs -f -Q co -r v1 -d cvswork master >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_tree cvswork
+'
+
+rm -rf cvswork
+test_expect_success 'cvs co b1' '
+ cvs -f co -r b1 -d cvswork master >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_tree cvswork
+'
+
+test_expect_success 'cvs co b1 [cvswork3]' '
+ cvs -f co -r b1 -d cvswork3 master >cvs.log 2>&1 &&
+ check_start_tree cvswork3 &&
+ check_file cvswork3 textfile.c v1 &&
+ check_file cvswork3 t2 v1 &&
+ check_file cvswork3 adir/afile v1 &&
+ check_file cvswork3 adir/a2file v1 &&
+ check_file cvswork3 adir/bdir/bfile v1 &&
+ check_file cvswork3 adir/bdir/b2file v1 &&
+ check_end_full_tree cvswork3 v1
+'
+
+test_expect_success 'edit cvswork3 and save diff' '
+ (
+ cd cvswork3 &&
+ sed -e "s/line1/line1 - data/" adir/afile >adir/afileNEW &&
+ mv -f adir/afileNEW adir/afile &&
+ echo "afile5" >adir/afile5 &&
+ rm t2 &&
+ cvs -f add adir/afile5 &&
+ cvs -f rm t2 &&
+ ! cvs -f diff -N -u >"$WORKDIR/cvswork3edit.diff"
+ )
+'
+
+test_expect_success 'setup v1.2 on b1' '
+ git checkout b1 &&
+ echo "new v1.2" >t3 &&
+ rm t2 &&
+ sed -e "s/line3/line3 - more data/" adir/afile >adir/afileNEW &&
+ mv -f adir/afileNEW adir/afile &&
+ rm adir/a2file &&
+ echo "a3file" >>adir/a3file &&
+ echo "bfile line 3" >>adir/bdir/bfile &&
+ rm adir/bdir/b2file &&
+ echo "b3file" >adir/bdir/b3file &&
+ mkdir cdir &&
+ echo "cdir/cfile" >cdir/cfile &&
+ git add -A cdir adir t3 t2 &&
+ git commit -q -m 'v1.2' &&
+ git tag v1.2 &&
+ git push --tags gitcvs.git b1:b1
+'
+
+test_expect_success 'cvs -f up (on b1 adir)' '
+ ( cd cvswork/adir && cvs -f up -d ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1.2 &&
+ check_file cvswork adir/a3file v1.2 &&
+ check_file cvswork adir/bdir/bfile v1.2 &&
+ check_file cvswork adir/bdir/b3file v1.2 &&
+ check_end_tree cvswork
+'
+
+test_expect_success 'cvs up (on b1 /)' '
+ ( cd cvswork && cvs -f up -d ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1.2 &&
+ check_file cvswork t3 v1.2 &&
+ check_file cvswork adir/afile v1.2 &&
+ check_file cvswork adir/a3file v1.2 &&
+ check_file cvswork adir/bdir/bfile v1.2 &&
+ check_file cvswork adir/bdir/b3file v1.2 &&
+ check_file cvswork cdir/cfile v1.2 &&
+ check_end_tree cvswork
+'
+
+# Make sure "CVS/Tag" files didn't get messed up:
+test_expect_success 'cvs up (on b1 /) (again; check CVS/Tag files)' '
+ ( cd cvswork && cvs -f up -d ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1.2 &&
+ check_file cvswork t3 v1.2 &&
+ check_file cvswork adir/afile v1.2 &&
+ check_file cvswork adir/a3file v1.2 &&
+ check_file cvswork adir/bdir/bfile v1.2 &&
+ check_file cvswork adir/bdir/b3file v1.2 &&
+ check_file cvswork cdir/cfile v1.2 &&
+ check_end_tree cvswork
+'
+
+# update to another version:
+test_expect_success 'cvs up -r v1' '
+ ( cd cvswork && cvs -f up -r v1 ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_tree cvswork
+'
+
+test_expect_success 'cvs up' '
+ ( cd cvswork && cvs -f up ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_tree cvswork
+'
+
+test_expect_success 'cvs up (again; check CVS/Tag files)' '
+ ( cd cvswork && cvs -f up -d ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_tree cvswork
+'
+
+test_expect_success 'setup simple b2' '
+ git branch b2 v1 &&
+ git push --tags gitcvs.git b2:b2
+'
+
+test_expect_success 'cvs co b2 [into cvswork2]' '
+ cvs -f co -r b2 -d cvswork2 master >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_tree cvswork
+'
+
+test_expect_success 'root dir edit [cvswork2]' '
+ (
+ cd cvswork2 && echo "Line 2" >>textfile.c &&
+ ! cvs -f diff -u >"$WORKDIR/cvsEdit1.diff" &&
+ cvs -f commit -m "edit textfile.c" textfile.c
+ ) >cvsEdit1.log 2>&1
+'
+
+test_expect_success 'root dir rm file [cvswork2]' '
+ (
+ cd cvswork2 &&
+ cvs -f rm -f t2 &&
+ cvs -f diff -u >../cvsEdit2-empty.diff &&
+ ! cvs -f diff -N -u >"$WORKDIR/cvsEdit2-N.diff" &&
+ cvs -f commit -m "rm t2"
+ ) >cvsEdit2.log 2>&1
+'
+
+test_expect_success 'subdir edit/add/rm files [cvswork2]' '
+ (
+ cd cvswork2 &&
+ sed -e "s/line 1/line 1 (v2)/" adir/bdir/bfile >adir/bdir/bfileNEW &&
+ mv -f adir/bdir/bfileNEW adir/bdir/bfile &&
+ rm adir/bdir/b2file &&
+ cd adir &&
+ cvs -f rm bdir/b2file &&
+ echo "4th file" >bdir/b4file &&
+ cvs -f add bdir/b4file &&
+ ! cvs -f diff -N -u >"$WORKDIR/cvsEdit3.diff" &&
+ git fetch gitcvs.git b2:b2 &&
+ (
+ cd .. &&
+ ! cvs -f diff -u -N -r v1.2 >"$WORKDIR/cvsEdit3-v1.2.diff" &&
+ ! cvs -f diff -u -N -r v1.2 -r v1 >"$WORKDIR/cvsEdit3-v1.2-v1.diff"
+ ) &&
+ cvs -f commit -m "various add/rm/edit"
+ ) >cvs.log 2>&1
+'
+
+test_expect_success 'validate result of edits [cvswork2]' '
+ git fetch gitcvs.git b2:b2 &&
+ git tag v2 b2 &&
+ git push --tags gitcvs.git b2:b2 &&
+ check_start_tree cvswork2 &&
+ check_file cvswork2 textfile.c v2 &&
+ check_file cvswork2 adir/afile v2 &&
+ check_file cvswork2 adir/a2file v2 &&
+ check_file cvswork2 adir/bdir/bfile v2 &&
+ check_file cvswork2 adir/bdir/b4file v2 &&
+ check_end_full_tree cvswork2 v2
+'
+
+test_expect_success 'validate basic diffs saved during above cvswork2 edits' '
+ test $(grep Index: cvsEdit1.diff | wc -l) = 1 &&
+ test ! -s cvsEdit2-empty.diff &&
+ test $(grep Index: cvsEdit2-N.diff | wc -l) = 1 &&
+ test $(grep Index: cvsEdit3.diff | wc -l) = 3 &&
+ rm -rf diffSandbox &&
+ git clone -q -n . diffSandbox &&
+ (
+ cd diffSandbox &&
+ git checkout v1 &&
+ git apply -p0 --index <"$WORKDIR/cvsEdit1.diff" &&
+ git apply -p0 --index <"$WORKDIR/cvsEdit2-N.diff" &&
+ git apply -p0 --directory=adir --index <"$WORKDIR/cvsEdit3.diff" &&
+ git diff --exit-code v2
+ ) >"check_diff_apply.out" 2>&1
+'
+
+test_expect_success 'validate v1.2 diff saved during last cvswork2 edit' '
+ test $(grep Index: cvsEdit3-v1.2.diff | wc -l) = 9 &&
+ check_diff cvsEdit3-v1.2.diff v1.2 v2
+'
+
+test_expect_success 'validate v1.2 v1 diff saved during last cvswork2 edit' '
+ test $(grep Index: cvsEdit3-v1.2-v1.diff | wc -l) = 9 &&
+ check_diff cvsEdit3-v1.2-v1.diff v1.2 v1
+'
+
+test_expect_success 'cvs up [cvswork2]' '
+ ( cd cvswork2 && cvs -f up ) >cvs.log 2>&1 &&
+ check_start_tree cvswork2 &&
+ check_file cvswork2 textfile.c v2 &&
+ check_file cvswork2 adir/afile v2 &&
+ check_file cvswork2 adir/a2file v2 &&
+ check_file cvswork2 adir/bdir/bfile v2 &&
+ check_file cvswork2 adir/bdir/b4file v2 &&
+ check_end_full_tree cvswork2 v2
+'
+
+test_expect_success 'cvs up -r b2 [back to cvswork]' '
+ ( cd cvswork && cvs -f up -r b2 ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v2 &&
+ check_file cvswork adir/afile v2 &&
+ check_file cvswork adir/a2file v2 &&
+ check_file cvswork adir/bdir/bfile v2 &&
+ check_file cvswork adir/bdir/b4file v2 &&
+ check_end_full_tree cvswork v2
+'
+
+test_expect_success 'cvs up -r b1' '
+ ( cd cvswork && cvs -f up -r b1 ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1.2 &&
+ check_file cvswork t3 v1.2 &&
+ check_file cvswork adir/afile v1.2 &&
+ check_file cvswork adir/a3file v1.2 &&
+ check_file cvswork adir/bdir/bfile v1.2 &&
+ check_file cvswork adir/bdir/b3file v1.2 &&
+ check_file cvswork cdir/cfile v1.2 &&
+ check_end_full_tree cvswork v1.2
+'
+
+test_expect_success 'cvs up -A' '
+ ( cd cvswork && cvs -f up -A ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_full_tree cvswork v1
+'
+
+test_expect_success 'cvs up (check CVS/Tag files)' '
+ ( cd cvswork && cvs -f up ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_full_tree cvswork v1
+'
+
+# This is not really legal CVS, but it seems to work anyway:
+test_expect_success 'cvs up -r heads/b1' '
+ ( cd cvswork && cvs -f up -r heads/b1 ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1.2 &&
+ check_file cvswork t3 v1.2 &&
+ check_file cvswork adir/afile v1.2 &&
+ check_file cvswork adir/a3file v1.2 &&
+ check_file cvswork adir/bdir/bfile v1.2 &&
+ check_file cvswork adir/bdir/b3file v1.2 &&
+ check_file cvswork cdir/cfile v1.2 &&
+ check_end_full_tree cvswork v1.2
+'
+
+# But this should work even if CVS client checks -r more carefully:
+test_expect_success 'cvs up -r heads_-s-b2 (cvsserver escape mechanism)' '
+ ( cd cvswork && cvs -f up -r heads_-s-b2 ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v2 &&
+ check_file cvswork adir/afile v2 &&
+ check_file cvswork adir/a2file v2 &&
+ check_file cvswork adir/bdir/bfile v2 &&
+ check_file cvswork adir/bdir/b4file v2 &&
+ check_end_full_tree cvswork v2
+'
+
+v1hash=$(git rev-parse v1)
+test_expect_success 'cvs up -r $(git rev-parse v1)' '
+ test -n "$v1hash" &&
+ ( cd cvswork && cvs -f up -r "$v1hash" ) >cvs.log 2>&1 &&
+ check_start_tree cvswork &&
+ check_file cvswork textfile.c v1 &&
+ check_file cvswork t2 v1 &&
+ check_file cvswork adir/afile v1 &&
+ check_file cvswork adir/a2file v1 &&
+ check_file cvswork adir/bdir/bfile v1 &&
+ check_file cvswork adir/bdir/b2file v1 &&
+ check_end_full_tree cvswork v1
+'
+
+test_expect_success 'cvs diff -r v1 -u' '
+ ( cd cvswork && cvs -f diff -r v1 -u ) >cvsDiff.out 2>cvs.log &&
+ test ! -s cvsDiff.out &&
+ test ! -s cvs.log
+'
+
+test_expect_success 'cvs diff -N -r v2 -u' '
+ ( cd cvswork && ! cvs -f diff -N -r v2 -u ) >cvsDiff.out 2>cvs.log &&
+ test ! -s cvs.log &&
+ test -s cvsDiff.out &&
+ check_diff cvsDiff.out v2 v1 >check_diff.out 2>&1
+'
+
+test_expect_success 'cvs diff -N -r v2 -r v1.2' '
+ ( cd cvswork && ! cvs -f diff -N -r v2 -r v1.2 -u ) >cvsDiff.out 2>cvs.log &&
+ test ! -s cvs.log &&
+ test -s cvsDiff.out &&
+ check_diff cvsDiff.out v2 v1.2 >check_diff.out 2>&1
+'
+
+test_expect_success 'apply early [cvswork3] diff to b3' '
+ git clone -q . gitwork3 &&
+ (
+ cd gitwork3 &&
+ git checkout -b b3 v1 &&
+ git apply -p0 --index <"$WORKDIR/cvswork3edit.diff" &&
+ git commit -m "cvswork3 edits applied"
+ ) &&
+ git fetch gitwork3 b3:b3 &&
+ git tag v3 b3
+'
+
+test_expect_success 'check [cvswork3] diff' '
+ ( cd cvswork3 && ! cvs -f diff -N -u ) >"$WORKDIR/cvsDiff.out" 2>cvs.log &&
+ test ! -s cvs.log &&
+ test -s cvsDiff.out &&
+ test $(grep Index: cvsDiff.out | wc -l) = 3 &&
+ test_cmp cvsDiff.out cvswork3edit.diff &&
+ check_diff cvsDiff.out v1 v3 >check_diff.out 2>&1
+'
+
+test_expect_success 'merge early [cvswork3] b3 with b1' '
+ ( cd gitwork3 && git merge "message" HEAD b1 ) &&
+ git fetch gitwork3 b3:b3 &&
+ git tag v3merged b3 &&
+ git push --tags gitcvs.git b3:b3
+'
+
+# This test would fail if cvsserver properly created a ".#afile"* file
+# for the merge.
+# TODO: Validate that the .# file was saved properly, and then
+# delete/ignore it when checking the tree.
+test_expect_success 'cvs up dirty [cvswork3]' '
+ (
+ cd cvswork3 &&
+ cvs -f up &&
+ ! cvs -f diff -N -u >"$WORKDIR/cvsDiff.out"
+ ) >cvs.log 2>&1 &&
+ test -s cvsDiff.out &&
+ test $(grep Index: cvsDiff.out | wc -l) = 2 &&
+ check_start_tree cvswork3 &&
+ check_file cvswork3 textfile.c v3merged &&
+ check_file cvswork3 t3 v3merged &&
+ check_file cvswork3 adir/afile v3merged &&
+ check_file cvswork3 adir/a3file v3merged &&
+ check_file cvswork3 adir/afile5 v3merged &&
+ check_file cvswork3 adir/bdir/bfile v3merged &&
+ check_file cvswork3 adir/bdir/b3file v3merged &&
+ check_file cvswork3 cdir/cfile v3merged &&
+ check_end_full_tree cvswork3 v3merged
+'
+
+# TODO: test cvs status
+
+test_expect_success 'cvs commit [cvswork3]' '
+ (
+ cd cvswork3 &&
+ cvs -f commit -m "dirty sandbox after auto-merge"
+ ) >cvs.log 2>&1 &&
+ check_start_tree cvswork3 &&
+ check_file cvswork3 textfile.c v3merged &&
+ check_file cvswork3 t3 v3merged &&
+ check_file cvswork3 adir/afile v3merged &&
+ check_file cvswork3 adir/a3file v3merged &&
+ check_file cvswork3 adir/afile5 v3merged &&
+ check_file cvswork3 adir/bdir/bfile v3merged &&
+ check_file cvswork3 adir/bdir/b3file v3merged &&
+ check_file cvswork3 cdir/cfile v3merged &&
+ check_end_full_tree cvswork3 v3merged &&
+ git fetch gitcvs.git b3:b4 &&
+ git tag v4.1 b4 &&
+ git diff --exit-code v4.1 v3merged >check_diff_apply.out 2>&1
+'
+
+test_done
diff --git a/t/t9502-gitweb-standalone-parse-output.sh b/t/t9502-gitweb-standalone-parse-output.sh
index 3a8e7d3f5a..86dfee2e4f 100755
--- a/t/t9502-gitweb-standalone-parse-output.sh
+++ b/t/t9502-gitweb-standalone-parse-output.sh
@@ -40,7 +40,7 @@ check_snapshot () {
echo "basename=$basename"
grep "filename=.*$basename.tar" gitweb.headers >/dev/null 2>&1 &&
"$TAR" tf gitweb.body >file_list &&
- ! grep -v "^$prefix/" file_list
+ ! grep -v -e "^$prefix$" -e "^$prefix/" -e "^pax_global_header$" file_list
}
test_expect_success setup '
diff --git a/t/t9604-cvsimport-timestamps.sh b/t/t9604-cvsimport-timestamps.sh
new file mode 100755
index 0000000000..1fd51423ee
--- /dev/null
+++ b/t/t9604-cvsimport-timestamps.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+test_description='git cvsimport timestamps'
+. ./lib-cvs.sh
+
+setup_cvs_test_repository t9604
+
+test_expect_success 'check timestamps are UTC (TZ=CST6CDT)' '
+
+ TZ=CST6CDT git cvsimport -p"-x" -C module-1 module &&
+ git cvsimport -p"-x" -C module-1 module &&
+ (
+ cd module-1 &&
+ git log --format="%s %ai"
+ ) >actual-1 &&
+ cat >expect-1 <<-EOF &&
+ Rev 16 2006-10-29 07:00:01 +0000
+ Rev 15 2006-10-29 06:59:59 +0000
+ Rev 14 2006-04-02 08:00:01 +0000
+ Rev 13 2006-04-02 07:59:59 +0000
+ Rev 12 2005-12-01 00:00:00 +0000
+ Rev 11 2005-11-01 00:00:00 +0000
+ Rev 10 2005-10-01 00:00:00 +0000
+ Rev 9 2005-09-01 00:00:00 +0000
+ Rev 8 2005-08-01 00:00:00 +0000
+ Rev 7 2005-07-01 00:00:00 +0000
+ Rev 6 2005-06-01 00:00:00 +0000
+ Rev 5 2005-05-01 00:00:00 +0000
+ Rev 4 2005-04-01 00:00:00 +0000
+ Rev 3 2005-03-01 00:00:00 +0000
+ Rev 2 2005-02-01 00:00:00 +0000
+ Rev 1 2005-01-01 00:00:00 +0000
+ EOF
+ test_cmp actual-1 expect-1
+'
+
+test_expect_success 'check timestamps with author-specific timezones' '
+
+ cat >cvs-authors <<-EOF &&
+ user1=User One <user1@domain.org>
+ user2=User Two <user2@domain.org> CST6CDT
+ user3=User Three <user3@domain.org> EST5EDT
+ user4=User Four <user4@domain.org> MST7MDT
+ EOF
+ git cvsimport -p"-x" -A cvs-authors -C module-2 module &&
+ (
+ cd module-2 &&
+ git log --format="%s %ai %an"
+ ) >actual-2 &&
+ cat >expect-2 <<-EOF &&
+ Rev 16 2006-10-29 01:00:01 -0600 User Two
+ Rev 15 2006-10-29 01:59:59 -0500 User Two
+ Rev 14 2006-04-02 03:00:01 -0500 User Two
+ Rev 13 2006-04-02 01:59:59 -0600 User Two
+ Rev 12 2005-11-30 17:00:00 -0700 User Four
+ Rev 11 2005-10-31 19:00:00 -0500 User Three
+ Rev 10 2005-09-30 19:00:00 -0500 User Two
+ Rev 9 2005-09-01 00:00:00 +0000 User One
+ Rev 8 2005-07-31 18:00:00 -0600 User Four
+ Rev 7 2005-06-30 20:00:00 -0400 User Three
+ Rev 6 2005-05-31 19:00:00 -0500 User Two
+ Rev 5 2005-05-01 00:00:00 +0000 User One
+ Rev 4 2005-03-31 17:00:00 -0700 User Four
+ Rev 3 2005-02-28 19:00:00 -0500 User Three
+ Rev 2 2005-01-31 18:00:00 -0600 User Two
+ Rev 1 2005-01-01 00:00:00 +0000 User One
+ EOF
+ test_cmp actual-2 expect-2
+'
+
+test_done
diff --git a/t/t9604/cvsroot/.gitattributes b/t/t9604/cvsroot/.gitattributes
new file mode 100644
index 0000000000..562b12e16e
--- /dev/null
+++ b/t/t9604/cvsroot/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/t/t9604/cvsroot/CVSROOT/.gitignore b/t/t9604/cvsroot/CVSROOT/.gitignore
new file mode 100644
index 0000000000..3bb9b34173
--- /dev/null
+++ b/t/t9604/cvsroot/CVSROOT/.gitignore
@@ -0,0 +1,2 @@
+history
+val-tags
diff --git a/t/t9604/cvsroot/module/a,v b/t/t9604/cvsroot/module/a,v
new file mode 100644
index 0000000000..80658c3c8d
--- /dev/null
+++ b/t/t9604/cvsroot/module/a,v
@@ -0,0 +1,264 @@
+head 1.16;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.16
+date 2006.10.29.07.00.01; author user2; state Exp;
+branches;
+next 1.15;
+
+1.15
+date 2006.10.29.06.59.59; author user2; state Exp;
+branches;
+next 1.14;
+
+1.14
+date 2006.04.02.08.00.01; author user2; state Exp;
+branches;
+next 1.13;
+
+1.13
+date 2006.04.02.07.59.59; author user2; state Exp;
+branches;
+next 1.12;
+
+1.12
+date 2005.12.01.00.00.00; author user4; state Exp;
+branches;
+next 1.11;
+
+1.11
+date 2005.11.01.00.00.00; author user3; state Exp;
+branches;
+next 1.10;
+
+1.10
+date 2005.10.01.00.00.00; author user2; state Exp;
+branches;
+next 1.9;
+
+1.9
+date 2005.09.01.00.00.00; author user1; state Exp;
+branches;
+next 1.8;
+
+1.8
+date 2005.08.01.00.00.00; author user4; state Exp;
+branches;
+next 1.7;
+
+1.7
+date 2005.07.01.00.00.00; author user3; state Exp;
+branches;
+next 1.6;
+
+1.6
+date 2005.06.01.00.00.00; author user2; state Exp;
+branches;
+next 1.5;
+
+1.5
+date 2005.05.01.00.00.00; author user1; state Exp;
+branches;
+next 1.4;
+
+1.4
+date 2005.04.01.00.00.00; author user4; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 2005.03.01.00.00.00; author user3; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 2005.02.01.00.00.00; author user2; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 2005.01.01.00.00.00; author user1; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.16
+log
+@Rev 16
+@
+text
+@Rev 16
+@
+
+
+1.15
+log
+@Rev 15
+@
+text
+@d1 1
+a1 1
+Rev 15
+@
+
+
+1.14
+log
+@Rev 14
+@
+text
+@d1 1
+a1 1
+Rev 14
+@
+
+
+1.13
+log
+@Rev 13
+@
+text
+@d1 1
+a1 1
+Rev 13
+@
+
+
+1.12
+log
+@Rev 12
+@
+text
+@d1 1
+a1 1
+Rev 12
+@
+
+
+1.11
+log
+@Rev 11
+@
+text
+@d1 1
+a1 1
+Rev 11
+@
+
+
+1.10
+log
+@Rev 10
+@
+text
+@d1 1
+a1 1
+Rev 10
+@
+
+
+1.9
+log
+@Rev 9
+@
+text
+@d1 1
+a1 1
+Rev 9
+@
+
+
+1.8
+log
+@Rev 8
+@
+text
+@d1 1
+a1 1
+Rev 8
+@
+
+
+1.7
+log
+@Rev 7
+@
+text
+@d1 1
+a1 1
+Rev 7
+@
+
+
+1.6
+log
+@Rev 6
+@
+text
+@d1 1
+a1 1
+Rev 6
+@
+
+
+1.5
+log
+@Rev 5
+@
+text
+@d1 1
+a1 1
+Rev 5
+@
+
+
+1.4
+log
+@Rev 4
+@
+text
+@d1 1
+a1 1
+Rev 4
+@
+
+
+1.3
+log
+@Rev 3
+@
+text
+@d1 1
+a1 1
+Rev 3
+@
+
+
+1.2
+log
+@Rev 2
+@
+text
+@d1 1
+a1 1
+Rev 2
+@
+
+
+1.1
+log
+@Rev 1
+@
+text
+@d1 1
+a1 1
+Rev 1
+@
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index 3b9b48408a..1140767b50 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -45,9 +45,9 @@ is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color");
# Failure cases for config:
# Save and restore STDERR; we will probably extract this into a
# "dies_ok" method and possibly move the STDERR handling to Git.pm.
-open our $tmpstderr, ">&STDERR" or die "cannot save STDERR"; close STDERR;
-eval { $r->config("test.dupstring") };
-ok($@, "config: duplicate entry in scalar context fails");
+open our $tmpstderr, ">&STDERR" or die "cannot save STDERR";
+open STDERR, ">", "/dev/null" or die "cannot redirect STDERR to /dev/null";
+is($r->config("test.dupstring"), "value2", "config: multivar");
eval { $r->config_bool("test.boolother") };
ok($@, "config_bool: non-boolean values fail");
open STDERR, ">&", $tmpstderr or die "cannot restore STDERR";
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index b7ad716b09..665607c9cb 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -30,6 +30,11 @@ test_expect_success 'basic git p4 clone' '
)
'
+test_expect_success 'depot typo error' '
+ test_must_fail git p4 clone --dest="$git" /depot 2>errs &&
+ grep "Depot paths must start with" errs
+'
+
test_expect_success 'git p4 clone @all' '
git p4 clone --dest="$git" //depot@all &&
test_when_finished cleanup_git &&
@@ -143,15 +148,29 @@ test_expect_success 'exit when p4 fails to produce marshaled output' '
! test_i18ngrep Traceback errs
'
-test_expect_success 'clone bare' '
+# Hide a file from p4d, make sure we catch its complaint. This won't fail in
+# p4 changes, files, or describe; just in p4 print. If P4CLIENT is unset, the
+# message will include "Librarian checkout".
+test_expect_success 'exit gracefully for p4 server errors' '
+ test_when_finished "mv \"$db\"/depot/file1,v,hidden \"$db\"/depot/file1,v" &&
+ mv "$db"/depot/file1,v "$db"/depot/file1,v,hidden &&
+ test_when_finished cleanup_git &&
+ test_expect_code 1 git p4 clone --dest="$git" //depot@1 >out 2>err &&
+ test_i18ngrep "Error from p4 print" err
+'
+
+test_expect_success 'clone --bare should make a bare repository' '
rm -rf "$git" &&
git p4 clone --dest="$git" --bare //depot &&
test_when_finished cleanup_git &&
(
cd "$git" &&
- test ! -d .git &&
- bare=`git config --get core.bare` &&
- test "$bare" = true
+ test_path_is_missing .git &&
+ git config --get --bool core.bare true &&
+ git rev-parse --verify refs/remotes/p4/master &&
+ git rev-parse --verify refs/remotes/p4/HEAD &&
+ git rev-parse --verify refs/heads/master &&
+ git rev-parse --verify HEAD
)
'
@@ -172,6 +191,18 @@ test_expect_success 'initial import time from top change time' '
)
'
+test_expect_success 'unresolvable host in P4PORT should display error' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ P4PORT=nosuchhost:65537 &&
+ export P4PORT &&
+ test_expect_code 1 git p4 sync >out 2>err &&
+ grep "connect to nosuchhost" err
+ )
+'
+
test_expect_success 'kill p4d' '
kill_p4d
'
diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh
index 21924dfd7d..eeefa67904 100755
--- a/t/t9802-git-p4-filetype.sh
+++ b/t/t9802-git-p4-filetype.sh
@@ -8,6 +8,123 @@ test_expect_success 'start p4d' '
start_p4d
'
+#
+# This series of tests checks newline handling Both p4 and
+# git store newlines as \n, and have options to choose how
+# newlines appear in checked-out files.
+#
+test_expect_success 'p4 client newlines, unix' '
+ (
+ cd "$cli" &&
+ p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
+ printf "unix\ncrlf\n" >f-unix &&
+ printf "unix\r\ncrlf\r\n" >f-unix-as-crlf &&
+ p4 add -t text f-unix &&
+ p4 submit -d f-unix &&
+
+ # LineEnd: unix; should be no change after sync
+ cp f-unix f-unix-orig &&
+ p4 sync -f &&
+ test_cmp f-unix-orig f-unix &&
+
+ # make sure stored in repo as unix newlines
+ # use sed to eat python-appened newline
+ p4 -G print //depot/f-unix | marshal_dump data 2 |\
+ sed \$d >f-unix-p4-print &&
+ test_cmp f-unix-orig f-unix-p4-print &&
+
+ # switch to win, make sure lf -> crlf
+ p4 client -o | sed "/LineEnd/s/:.*/:win/" | p4 client -i &&
+ p4 sync -f &&
+ test_cmp f-unix-as-crlf f-unix
+ )
+'
+
+test_expect_success 'p4 client newlines, win' '
+ (
+ cd "$cli" &&
+ p4 client -o | sed "/LineEnd/s/:.*/:win/" | p4 client -i &&
+ printf "win\r\ncrlf\r\n" >f-win &&
+ printf "win\ncrlf\n" >f-win-as-lf &&
+ p4 add -t text f-win &&
+ p4 submit -d f-win &&
+
+ # LineEnd: win; should be no change after sync
+ cp f-win f-win-orig &&
+ p4 sync -f &&
+ test_cmp f-win-orig f-win &&
+
+ # make sure stored in repo as unix newlines
+ # use sed to eat python-appened newline
+ p4 -G print //depot/f-win | marshal_dump data 2 |\
+ sed \$d >f-win-p4-print &&
+ test_cmp f-win-as-lf f-win-p4-print &&
+
+ # switch to unix, make sure lf -> crlf
+ p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
+ p4 sync -f &&
+ test_cmp f-win-as-lf f-win
+ )
+'
+
+test_expect_success 'ensure blobs store only lf newlines' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git init &&
+ git p4 sync //depot@all &&
+
+ # verify the files in .git are stored only with newlines
+ o=$(git ls-tree p4/master -- f-unix | cut -f1 | cut -d\ -f3) &&
+ git cat-file blob $o >f-unix-blob &&
+ test_cmp "$cli"/f-unix-orig f-unix-blob &&
+
+ o=$(git ls-tree p4/master -- f-win | cut -f1 | cut -d\ -f3) &&
+ git cat-file blob $o >f-win-blob &&
+ test_cmp "$cli"/f-win-as-lf f-win-blob &&
+
+ rm f-unix-blob f-win-blob
+ )
+'
+
+test_expect_success 'gitattributes setting eol=lf produces lf newlines' '
+ test_when_finished cleanup_git &&
+ (
+ # checkout the files and make sure core.eol works as planned
+ cd "$git" &&
+ git init &&
+ echo "* eol=lf" >.gitattributes &&
+ git p4 sync //depot@all &&
+ git checkout master &&
+ test_cmp "$cli"/f-unix-orig f-unix &&
+ test_cmp "$cli"/f-win-as-lf f-win
+ )
+'
+
+test_expect_success 'gitattributes setting eol=crlf produces crlf newlines' '
+ test_when_finished cleanup_git &&
+ (
+ # checkout the files and make sure core.eol works as planned
+ cd "$git" &&
+ git init &&
+ echo "* eol=crlf" >.gitattributes &&
+ git p4 sync //depot@all &&
+ git checkout master &&
+ test_cmp "$cli"/f-unix-as-crlf f-unix &&
+ test_cmp "$cli"/f-win-orig f-win
+ )
+'
+
+test_expect_success 'crlf cleanup' '
+ (
+ cd "$cli" &&
+ rm f-unix-orig f-unix-as-crlf &&
+ rm f-win-orig f-win-as-lf &&
+ p4 client -o | sed "/LineEnd/s/:.*/:unix/" | p4 client -i &&
+ p4 sync -f
+ )
+'
+
test_expect_success 'utf-16 file create' '
(
cd "$cli" &&
@@ -105,12 +222,13 @@ build_gendouble() {
cat >gendouble.py <<-\EOF
import sys
import struct
- import array
- s = array.array("c", '\0' * 26)
- struct.pack_into(">L", s, 0, 0x00051607) # AppleDouble
- struct.pack_into(">L", s, 4, 0x00020000) # version 2
- s.tofile(sys.stdout)
+ s = struct.pack(">LL18s",
+ 0x00051607, # AppleDouble
+ 0x00020000, # version 2
+ "" # pad to 26 bytes
+ )
+ sys.stdout.write(s)
EOF
}
diff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh
index fa40cc8bb5..254d428b73 100755
--- a/t/t9806-git-p4-options.sh
+++ b/t/t9806-git-p4-options.sh
@@ -27,14 +27,102 @@ test_expect_success 'clone no --git-dir' '
test_must_fail git p4 clone --git-dir=xx //depot
'
-test_expect_success 'clone --branch' '
+test_expect_success 'clone --branch should checkout master' '
git p4 clone --branch=refs/remotes/p4/sb --dest="$git" //depot &&
test_when_finished cleanup_git &&
(
cd "$git" &&
- git ls-files >files &&
- test_line_count = 0 files &&
- test_path_is_file .git/refs/remotes/p4/sb
+ git rev-parse refs/remotes/p4/sb >sb &&
+ git rev-parse refs/heads/master >master &&
+ test_cmp sb master &&
+ git rev-parse HEAD >head &&
+ test_cmp sb head
+ )
+'
+
+test_expect_success 'sync when no master branch prints a nice error' '
+ test_when_finished cleanup_git &&
+ git p4 clone --branch=refs/remotes/p4/sb --dest="$git" //depot@2 &&
+ (
+ cd "$git" &&
+ test_must_fail git p4 sync 2>err &&
+ grep "Error: no branch refs/remotes/p4/master" err
+ )
+'
+
+test_expect_success 'sync --branch builds the full ref name correctly' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git init &&
+
+ git p4 sync --branch=b1 //depot &&
+ git rev-parse --verify refs/remotes/p4/b1 &&
+ git p4 sync --branch=p4/b2 //depot &&
+ git rev-parse --verify refs/remotes/p4/b2 &&
+
+ git p4 sync --import-local --branch=h1 //depot &&
+ git rev-parse --verify refs/heads/p4/h1 &&
+ git p4 sync --import-local --branch=p4/h2 //depot &&
+ git rev-parse --verify refs/heads/p4/h2 &&
+
+ git p4 sync --branch=refs/stuff //depot &&
+ git rev-parse --verify refs/stuff
+ )
+'
+
+# engages --detect-branches code, which will do filename filtering so
+# no sync to either b1 or b2
+test_expect_success 'sync when two branches but no master should noop' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git init &&
+ git p4 sync --branch=refs/remotes/p4/b1 //depot@2 &&
+ git p4 sync --branch=refs/remotes/p4/b2 //depot@2 &&
+ git p4 sync &&
+ git show -s --format=%s refs/remotes/p4/b1 >show &&
+ grep "Initial import" show &&
+ git show -s --format=%s refs/remotes/p4/b2 >show &&
+ grep "Initial import" show
+ )
+'
+
+test_expect_success 'sync --branch updates specific branch, no detection' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git init &&
+ git p4 sync --branch=b1 //depot@2 &&
+ git p4 sync --branch=b2 //depot@2 &&
+ git p4 sync --branch=b2 &&
+ git show -s --format=%s refs/remotes/p4/b1 >show &&
+ grep "Initial import" show &&
+ git show -s --format=%s refs/remotes/p4/b2 >show &&
+ grep "change 3" show
+ )
+'
+
+# allows using the refname "p4" as a short name for p4/master
+test_expect_success 'clone creates HEAD symbolic reference' '
+ git p4 clone --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git rev-parse --verify refs/remotes/p4/master >master &&
+ git rev-parse --verify p4 >p4 &&
+ test_cmp master p4
+ )
+'
+
+test_expect_success 'clone --branch creates HEAD symbolic reference' '
+ git p4 clone --branch=refs/remotes/p4/sb --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git rev-parse --verify refs/remotes/p4/sb >sb &&
+ git rev-parse --verify p4 >p4 &&
+ test_cmp sb p4
)
'
@@ -126,37 +214,58 @@ test_expect_success 'clone --use-client-spec' '
exec >/dev/null &&
test_must_fail git p4 clone --dest="$git" --use-client-spec
) &&
- cli2=$(test-path-utils real_path "$TRASH_DIRECTORY/cli2") &&
+ # build a different client
+ cli2="$TRASH_DIRECTORY/cli2" &&
mkdir -p "$cli2" &&
test_when_finished "rmdir \"$cli2\"" &&
+ test_when_finished cleanup_git &&
(
- cd "$cli2" &&
- p4 client -i <<-EOF
- Client: client2
- Description: client2
- Root: $cli2
- View: //depot/sub/... //client2/bus/...
- EOF
- ) &&
- P4CLIENT=client2 &&
+ # group P4CLIENT and cli changes in a sub-shell
+ P4CLIENT=client2 &&
+ cli="$cli2" &&
+ client_view "//depot/sub/... //client2/bus/..." &&
+ git p4 clone --dest="$git" --use-client-spec //depot/... &&
+ (
+ cd "$git" &&
+ test_path_is_file bus/dir/f4 &&
+ test_path_is_missing file1
+ ) &&
+ cleanup_git &&
+ # same thing again, this time with variable instead of option
+ (
+ cd "$git" &&
+ git init &&
+ git config git-p4.useClientSpec true &&
+ git p4 sync //depot/... &&
+ git checkout -b master p4/master &&
+ test_path_is_file bus/dir/f4 &&
+ test_path_is_missing file1
+ )
+ )
+'
+
+test_expect_success 'submit works with no p4/master' '
test_when_finished cleanup_git &&
- git p4 clone --dest="$git" --use-client-spec //depot/... &&
+ git p4 clone --branch=b1 //depot@1,2 --destination="$git" &&
(
cd "$git" &&
- test_path_is_file bus/dir/f4 &&
- test_path_is_missing file1
- ) &&
- cleanup_git &&
+ test_commit submit-1-branch &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit --branch=b1
+ )
+'
- # same thing again, this time with variable instead of option
+# The sync/rebase part post-submit will engage detect-branches
+# machinery which will not do anything in this particular test.
+test_expect_success 'submit works with two branches' '
+ test_when_finished cleanup_git &&
+ git p4 clone --branch=b1 //depot@1,2 --destination="$git" &&
(
cd "$git" &&
- git init &&
- git config git-p4.useClientSpec true &&
- git p4 sync //depot/... &&
- git checkout -b master p4/master &&
- test_path_is_file bus/dir/f4 &&
- test_path_is_missing file1
+ git p4 sync --branch=b2 //depot@1,3 &&
+ test_commit submit-2-branches &&
+ git config git-p4.skipSubmitEdit true &&
+ git p4 submit
)
'
diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh
index 0ae048f29f..1fb7bc7cf9 100755
--- a/t/t9807-git-p4-submit.sh
+++ b/t/t9807-git-p4-submit.sh
@@ -17,6 +17,16 @@ test_expect_success 'init depot' '
)
'
+test_expect_failure 'is_cli_file_writeable function' '
+ (
+ cd "$cli" &&
+ echo a >a &&
+ is_cli_file_writeable a &&
+ ! is_cli_file_writeable file1 &&
+ rm a
+ )
+'
+
test_expect_success 'submit with no client dir' '
test_when_finished cleanup_git &&
git p4 clone --dest="$git" //depot &&
@@ -200,7 +210,7 @@ test_expect_success 'submit copy' '
(
cd "$cli" &&
test_path_is_file file5.ta &&
- test ! -w file5.ta
+ ! is_cli_file_writeable file5.ta
)
'
@@ -219,7 +229,7 @@ test_expect_success 'submit rename' '
cd "$cli" &&
test_path_is_missing file6.t &&
test_path_is_file file6.ta &&
- test ! -w file6.ta
+ ! is_cli_file_writeable file6.ta
)
'
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 281be29174..77f63492d9 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -196,7 +196,7 @@ test_expect_success 'exclusion single file' '
test_expect_success 'overlay wildcard' '
client_view "//depot/dir1/... //client/cli/..." \
- "+//depot/dir2/... //client/cli/...\n" &&
+ "+//depot/dir2/... //client/cli/..." &&
files="cli/file11 cli/file12 cli/file21 cli/file22" &&
client_verify $files &&
test_when_finished cleanup_git &&
@@ -333,7 +333,7 @@ test_expect_success 'subdir clone, submit copy' '
(
cd "$cli" &&
test_path_is_file dir1/file11a &&
- test ! -w dir1/file11a
+ ! is_cli_file_writeable dir1/file11a
)
'
@@ -353,7 +353,7 @@ test_expect_success 'subdir clone, submit rename' '
cd "$cli" &&
test_path_is_missing dir1/file13 &&
test_path_is_file dir1/file13a &&
- test ! -w dir1/file13a
+ ! is_cli_file_writeable dir1/file13a
)
'
@@ -365,7 +365,10 @@ test_expect_success 'wildcard files submit back to p4, client-spec case' '
(
cd "$git" &&
echo git-wild-hash >dir1/git-wild#hash &&
- echo git-wild-star >dir1/git-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ echo git-wild-star >dir1/git-wild\*star
+ fi &&
echo git-wild-at >dir1/git-wild@at &&
echo git-wild-percent >dir1/git-wild%percent &&
git add dir1/git-wild* &&
@@ -376,7 +379,10 @@ test_expect_success 'wildcard files submit back to p4, client-spec case' '
(
cd "$cli" &&
test_path_is_file dir1/git-wild#hash &&
- test_path_is_file dir1/git-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ test_path_is_file dir1/git-wild\*star
+ fi &&
test_path_is_file dir1/git-wild@at &&
test_path_is_file dir1/git-wild%percent
) &&
diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh
index 0c2fc3ea1a..34fbc90005 100755
--- a/t/t9810-git-p4-rcs.sh
+++ b/t/t9810-git-p4-rcs.sh
@@ -26,10 +26,8 @@ test_expect_success 'init depot' '
line7
line8
EOF
- cp filek fileko &&
- sed -i "s/Revision/Revision: do not scrub me/" fileko
- cp fileko file_text &&
- sed -i "s/Id/Id: do not scrub me/" file_text
+ sed "s/Revision/Revision: do not scrub me/" <filek >fileko &&
+ sed "s/Id/Id: do not scrub me/" <fileko >file_text &&
p4 add -t text+k filek &&
p4 submit -d "filek" &&
p4 add -t text+ko fileko &&
@@ -88,7 +86,8 @@ test_expect_success 'edit far away from RCS lines' '
(
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
- sed -i "s/^line7/line7 edit/" filek &&
+ sed "s/^line7/line7 edit/" <filek >filek.tmp &&
+ mv -f filek.tmp filek &&
git commit -m "filek line7 edit" filek &&
git p4 submit &&
scrub_k_check filek
@@ -105,7 +104,8 @@ test_expect_success 'edit near RCS lines' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- sed -i "s/^line4/line4 edit/" filek &&
+ sed "s/^line4/line4 edit/" <filek >filek.tmp &&
+ mv -f filek.tmp filek &&
git commit -m "filek line4 edit" filek &&
git p4 submit &&
scrub_k_check filek
@@ -122,7 +122,8 @@ test_expect_success 'edit keyword lines' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- sed -i "/Revision/d" filek &&
+ sed "/Revision/d" <filek >filek.tmp &&
+ mv -f filek.tmp filek &&
git commit -m "filek remove Revision line" filek &&
git p4 submit &&
scrub_k_check filek
@@ -139,7 +140,8 @@ test_expect_success 'scrub ko files differently' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- sed -i "s/^line4/line4 edit/" fileko &&
+ sed "s/^line4/line4 edit/" <fileko >fileko.tmp &&
+ mv -f fileko.tmp fileko &&
git commit -m "fileko line4 edit" fileko &&
git p4 submit &&
scrub_ko_check fileko &&
@@ -189,12 +191,14 @@ test_expect_success 'do not scrub plain text' '
cd "$git" &&
git config git-p4.skipSubmitEdit true &&
git config git-p4.attemptRCSCleanup true &&
- sed -i "s/^line4/line4 edit/" file_text &&
+ sed "s/^line4/line4 edit/" <file_text >file_text.tmp &&
+ mv -f file_text.tmp file_text &&
git commit -m "file_text line4 edit" file_text &&
(
cd "$cli" &&
p4 open file_text &&
- sed -i "s/^line5/line5 p4 edit/" file_text &&
+ sed "s/^line5/line5 p4 edit/" <file_text >file_text.tmp &&
+ mv -f file_text.tmp file_text &&
p4 submit -d "file5 p4 edit"
) &&
echo s | test_expect_code 1 git p4 submit &&
diff --git a/t/t9812-git-p4-wildcards.sh b/t/t9812-git-p4-wildcards.sh
index 143d413057..67633257f3 100755
--- a/t/t9812-git-p4-wildcards.sh
+++ b/t/t9812-git-p4-wildcards.sh
@@ -14,7 +14,10 @@ test_expect_success 'add p4 files with wildcards in the names' '
printf "file2\nhas\nsome\nrandom\ntext\n" >file2 &&
p4 add file2 &&
echo file-wild-hash >file-wild#hash &&
- echo file-wild-star >file-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ echo file-wild-star >file-wild\*star
+ fi &&
echo file-wild-at >file-wild@at &&
echo file-wild-percent >file-wild%percent &&
p4 add -f file-wild* &&
@@ -28,7 +31,10 @@ test_expect_success 'wildcard files git p4 clone' '
(
cd "$git" &&
test -f file-wild#hash &&
- test -f file-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ test -f file-wild\*star
+ fi &&
test -f file-wild@at &&
test -f file-wild%percent
)
@@ -40,7 +46,10 @@ test_expect_success 'wildcard files submit back to p4, add' '
(
cd "$git" &&
echo git-wild-hash >git-wild#hash &&
- echo git-wild-star >git-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ echo git-wild-star >git-wild\*star
+ fi &&
echo git-wild-at >git-wild@at &&
echo git-wild-percent >git-wild%percent &&
git add git-wild* &&
@@ -51,7 +60,10 @@ test_expect_success 'wildcard files submit back to p4, add' '
(
cd "$cli" &&
test_path_is_file git-wild#hash &&
- test_path_is_file git-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ test_path_is_file git-wild\*star
+ fi &&
test_path_is_file git-wild@at &&
test_path_is_file git-wild%percent
)
@@ -63,7 +75,10 @@ test_expect_success 'wildcard files submit back to p4, modify' '
(
cd "$git" &&
echo new-line >>git-wild#hash &&
- echo new-line >>git-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ echo new-line >>git-wild\*star
+ fi &&
echo new-line >>git-wild@at &&
echo new-line >>git-wild%percent &&
git add git-wild* &&
@@ -74,7 +89,10 @@ test_expect_success 'wildcard files submit back to p4, modify' '
(
cd "$cli" &&
test_line_count = 2 git-wild#hash &&
- test_line_count = 2 git-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ test_line_count = 2 git-wild\*star
+ fi &&
test_line_count = 2 git-wild@at &&
test_line_count = 2 git-wild%percent
)
@@ -87,7 +105,7 @@ test_expect_success 'wildcard files submit back to p4, copy' '
cd "$git" &&
cp file2 git-wild-cp#hash &&
git add git-wild-cp#hash &&
- cp git-wild\*star file-wild-3 &&
+ cp git-wild#hash file-wild-3 &&
git add file-wild-3 &&
git commit -m "wildcard copies" &&
git config git-p4.detectCopies true &&
@@ -134,7 +152,10 @@ test_expect_success 'wildcard files submit back to p4, delete' '
(
cd "$cli" &&
test_path_is_missing git-wild#hash &&
- test_path_is_missing git-wild\*star &&
+ if test_have_prereq NOT_MINGW NOT_CYGWIN
+ then
+ test_path_is_missing git-wild\*star
+ fi &&
test_path_is_missing git-wild@at &&
test_path_is_missing git-wild%percent
)
diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh
index 3bf1224ae0..be802e0e16 100755
--- a/t/t9814-git-p4-rename.sh
+++ b/t/t9814-git-p4-rename.sh
@@ -199,6 +199,41 @@ test_expect_success 'detect copies' '
)
'
+# See if configurables can be set, and in particular if the run.move.allow
+# variable exists, which allows admins to disable the "p4 move" command.
+test_expect_success 'p4 configure command and run.move.allow are available' '
+ p4 configure show run.move.allow >out ; retval=$? &&
+ test $retval = 0 &&
+ {
+ egrep ^run.move.allow: out &&
+ test_set_prereq P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW ||
+ true
+ } || true
+'
+
+# If move can be disabled, turn it off and test p4 move handling
+test_expect_success P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW \
+ 'do not use p4 move when administratively disabled' '
+ test_when_finished "p4 configure set run.move.allow=1" &&
+ p4 configure set run.move.allow=0 &&
+ (
+ cd "$cli" &&
+ echo move-disallow-file >move-disallow-file &&
+ p4 add move-disallow-file &&
+ p4 submit -d "add move-disallow-file"
+ ) &&
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.detectRenames true &&
+ git mv move-disallow-file move-disallow-file-moved &&
+ git commit -m "move move-disallow-file" &&
+ git p4 submit
+ )
+'
+
test_expect_success 'kill p4d' '
kill_p4d
'
diff --git a/t/t9815-git-p4-submit-fail.sh b/t/t9815-git-p4-submit-fail.sh
index d2b7b3d98d..1243d96092 100755
--- a/t/t9815-git-p4-submit-fail.sh
+++ b/t/t9815-git-p4-submit-fail.sh
@@ -405,8 +405,8 @@ test_expect_success 'cleanup chmod after submit cancel' '
git p4 clone --dest="$git" //depot &&
(
cd "$git" &&
- chmod u+x text &&
- chmod u-x text+x &&
+ test_chmod +x text &&
+ test_chmod -x text+x &&
git add text text+x &&
git commit -m "chmod texts" &&
echo n | test_expect_code 1 git p4 submit
@@ -415,10 +415,13 @@ test_expect_success 'cleanup chmod after submit cancel' '
cd "$cli" &&
test_path_is_file text &&
! p4 fstat -T action text &&
- stat --format=%A text | egrep ^-r-- &&
test_path_is_file text+x &&
! p4 fstat -T action text+x &&
- stat --format=%A text+x | egrep ^-r-x
+ if test_have_prereq NOT_CYGWIN
+ then
+ stat --format=%A text | egrep ^-r-- &&
+ stat --format=%A text+x | egrep ^-r-x
+ fi
)
'
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index cbd0fb66f9..adc1372b3c 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -13,6 +13,25 @@ complete ()
return 0
}
+# Be careful when updating this list:
+#
+# (1) The build tree may have build artifact from different branch, or
+# the user's $PATH may have a random executable that may begin
+# with "git-check" that are not part of the subcommands this build
+# will ship, e.g. "check-ignore". The tests for completion for
+# subcommand names tests how "check" is expanded; we limit the
+# possible candidates to "checkout" and "check-attr" to make sure
+# "check-attr", which is known by the filter function as a
+# subcommand to be thrown out, while excluding other random files
+# that happen to begin with "check" to avoid letting them get in
+# the way.
+#
+# (2) A test makes sure that common subcommands are included in the
+# completion for "git <TAB>", and a plumbing is excluded. "add",
+# "filter-branch" and "ls-files" are listed for this.
+
+GIT_TESTING_COMMAND_COMPLETION='add checkout check-attr filter-branch ls-files'
+
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
# We don't need this function to actually join words or do anything special.
@@ -54,105 +73,78 @@ run_completion ()
__git_wrap__git_main && print_comp
}
+# Test high-level completion
+# Arguments are:
+# 1: typed text so far (cur)
+# 2: expected completion
test_completion ()
{
- test $# -gt 1 && echo "$2" > expected
- run_completion "$@" &&
+ if test $# -gt 1
+ then
+ printf '%s\n' "$2" >expected
+ else
+ sed -e 's/Z$//' >expected
+ fi &&
+ run_completion "$1" &&
test_cmp expected out
}
-# Like test_completion, but reads expectation from stdin,
-# which is convenient when it is multiline. We also process "_" into
-# spaces to make test vectors more readable.
-test_completion_long ()
+# Test __gitcomp.
+# The first argument is the typed text so far (cur); the rest are
+# passed to __gitcomp. Expected output comes is read from the
+# standard input, like test_completion().
+test_gitcomp ()
{
- tr _ " " >expected &&
- test_completion "$1"
+ local -a COMPREPLY &&
+ sed -e 's/Z$//' >expected &&
+ cur="$1" &&
+ shift &&
+ __gitcomp "$@" &&
+ print_comp &&
+ test_cmp expected out
}
-newline=$'\n'
-
test_expect_success '__gitcomp - trailing space - options' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
+ --reset-author" <<-EOF
--reuse-message=Z
--reedit-message=Z
--reset-author Z
EOF
- (
- local -a COMPREPLY &&
- cur="--re" &&
- __gitcomp "--dry-run --reuse-message= --reedit-message=
- --reset-author" &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success '__gitcomp - trailing space - config keys' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "br" "branch. branch.autosetupmerge
+ branch.autosetuprebase browser." <<-\EOF
branch.Z
branch.autosetupmerge Z
branch.autosetuprebase Z
browser.Z
EOF
- (
- local -a COMPREPLY &&
- cur="br" &&
- __gitcomp "branch. branch.autosetupmerge
- branch.autosetuprebase browser." &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success '__gitcomp - option parameter' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
+ "" "re" <<-\EOF
recursive Z
resolve Z
EOF
- (
- local -a COMPREPLY &&
- cur="--strategy=re" &&
- __gitcomp "octopus ours recursive resolve subtree
- " "" "re" &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success '__gitcomp - prefix' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
+ "branch.maint." "me" <<-\EOF
branch.maint.merge Z
branch.maint.mergeoptions Z
EOF
- (
- local -a COMPREPLY &&
- cur="branch.me" &&
- __gitcomp "remote merge mergeoptions rebase
- " "branch.maint." "me" &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success '__gitcomp - suffix' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_gitcomp "branch.me" "master maint next pu" "branch." \
+ "ma" "." <<-\EOF
branch.master.Z
branch.maint.Z
EOF
- (
- local -a COMPREPLY &&
- cur="branch.me" &&
- __gitcomp "master maint next pu
- " "branch." "ma" "." &&
- IFS="$newline" &&
- echo "${COMPREPLY[*]}" > out
- ) &&
- test_cmp expected out
'
test_expect_success 'basic' '
@@ -169,7 +161,7 @@ test_expect_success 'basic' '
'
test_expect_success 'double dash "git" itself' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_completion "git --" <<-\EOF
--paginate Z
--no-pager Z
--git-dir=
@@ -184,11 +176,10 @@ test_expect_success 'double dash "git" itself' '
--no-replace-objects Z
--help Z
EOF
- test_completion "git --"
'
test_expect_success 'double dash "git checkout"' '
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_completion "git checkout --" <<-\EOF
--quiet Z
--ours Z
--theirs Z
@@ -199,17 +190,15 @@ test_expect_success 'double dash "git checkout"' '
--orphan Z
--patch Z
EOF
- test_completion "git checkout --"
'
test_expect_success 'general options' '
test_completion "git --ver" "--version " &&
test_completion "git --hel" "--help " &&
- sed -e "s/Z$//" >expected <<-\EOF &&
+ test_completion "git --exe" <<-\EOF &&
--exec-path Z
--exec-path=
EOF
- test_completion "git --exe" &&
test_completion "git --htm" "--html-path " &&
test_completion "git --pag" "--paginate " &&
test_completion "git --no-p" "--no-pager " &&
@@ -226,7 +215,6 @@ test_expect_success 'general options plus command' '
test_completion "git --paginate check" "checkout " &&
test_completion "git --git-dir=foo check" "checkout " &&
test_completion "git --bare check" "checkout " &&
- test_completion "git --help des" "describe " &&
test_completion "git --exec-path=foo check" "checkout " &&
test_completion "git --html-path check" "checkout " &&
test_completion "git --no-pager check" "checkout " &&
@@ -237,6 +225,11 @@ test_expect_success 'general options plus command' '
test_completion "git --no-replace-objects check" "checkout "
'
+test_expect_success 'git --help completion' '
+ test_completion "git --help ad" "add " &&
+ test_completion "git --help core" "core-tutorial "
+'
+
test_expect_success 'setup for ref completion' '
echo content >file1 &&
echo more >file2 &&
@@ -247,25 +240,25 @@ test_expect_success 'setup for ref completion' '
'
test_expect_success 'checkout completes ref names' '
- test_completion_long "git checkout m" <<-\EOF
- master_
- mybranch_
- mytag_
+ test_completion "git checkout m" <<-\EOF
+ master Z
+ mybranch Z
+ mytag Z
EOF
'
test_expect_success 'show completes all refs' '
- test_completion_long "git show m" <<-\EOF
- master_
- mybranch_
- mytag_
+ test_completion "git show m" <<-\EOF
+ master Z
+ mybranch Z
+ mytag Z
EOF
'
test_expect_success '<ref>: completes paths' '
- test_completion_long "git show mytag:f" <<-\EOF
- file1_
- file2_
+ test_completion "git show mytag:f" <<-\EOF
+ file1 Z
+ file2 Z
EOF
'
@@ -273,8 +266,8 @@ test_expect_success 'complete tree filename with spaces' '
echo content >"name with spaces" &&
git add . &&
git commit -m spaces &&
- test_completion_long "git show HEAD:nam" <<-\EOF
- name with spaces_
+ test_completion "git show HEAD:nam" <<-\EOF
+ name with spaces Z
EOF
'
@@ -282,10 +275,15 @@ test_expect_failure 'complete tree filename with metacharacters' '
echo content >"name with \${meta}" &&
git add . &&
git commit -m meta &&
- test_completion_long "git show HEAD:nam" <<-\EOF
- name with ${meta}_
- name with spaces_
+ test_completion "git show HEAD:nam" <<-\EOF
+ name with ${meta} Z
+ name with spaces Z
EOF
'
+test_expect_success 'send-email' '
+ test_completion "git send-email --cov" "--cover-letter " &&
+ test_completion "git send-email ma" "master "
+'
+
test_done
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index f17c1f8b85..2101d914f2 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -360,7 +360,31 @@ test_expect_success 'prompt - dirty status indicator - before root commit' '
test_cmp expected "$actual"
'
-test_expect_success 'prompt - dirty status indicator - disabled by config' '
+test_expect_success 'prompt - dirty status indicator - shell variable unset with config disabled' '
+ printf " (master)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ test_config bash.showDirtyState false &&
+ (
+ sane_unset GIT_PS1_SHOWDIRTYSTATE &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - shell variable unset with config enabled' '
+ printf " (master)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ test_config bash.showDirtyState true &&
+ (
+ sane_unset GIT_PS1_SHOWDIRTYSTATE &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - dirty status indicator - shell variable set with config disabled' '
printf " (master)" > expected &&
echo "dirty" > file &&
test_when_finished "git reset --hard" &&
@@ -372,6 +396,18 @@ test_expect_success 'prompt - dirty status indicator - disabled by config' '
test_cmp expected "$actual"
'
+test_expect_success 'prompt - dirty status indicator - shell variable set with config enabled' '
+ printf " (master *)" > expected &&
+ echo "dirty" > file &&
+ test_when_finished "git reset --hard" &&
+ test_config bash.showDirtyState true &&
+ (
+ GIT_PS1_SHOWDIRTYSTATE=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
test_expect_success 'prompt - dirty status indicator - not shown inside .git directory' '
printf " (GIT_DIR!)" > expected &&
echo "dirty" > file &&
@@ -437,6 +473,46 @@ test_expect_success 'prompt - untracked files status indicator - untracked files
test_cmp expected "$actual"
'
+test_expect_success 'prompt - untracked files status indicator - shell variable unset with config disabled' '
+ printf " (master)" > expected &&
+ test_config bash.showUntrackedFiles false &&
+ (
+ sane_unset GIT_PS1_SHOWUNTRACKEDFILES &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - shell variable unset with config enabled' '
+ printf " (master)" > expected &&
+ test_config bash.showUntrackedFiles true &&
+ (
+ sane_unset GIT_PS1_SHOWUNTRACKEDFILES &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - shell variable set with config disabled' '
+ printf " (master)" > expected &&
+ test_config bash.showUntrackedFiles false &&
+ (
+ GIT_PS1_SHOWUNTRACKEDFILES=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
+test_expect_success 'prompt - untracked files status indicator - shell variable set with config enabled' '
+ printf " (master %%)" > expected &&
+ test_config bash.showUntrackedFiles true &&
+ (
+ GIT_PS1_SHOWUNTRACKEDFILES=y &&
+ __git_ps1 > "$actual"
+ ) &&
+ test_cmp expected "$actual"
+'
+
test_expect_success 'prompt - untracked files status indicator - not shown inside .git directory' '
printf " (GIT_DIR!)" > expected &&
(
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 8889ba5104..3fc9cc9288 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -91,6 +91,10 @@ q_to_tab () {
tr Q '\011'
}
+qz_to_tab_space () {
+ tr QZ '\011\040'
+}
+
append_cr () {
sed -e 's/$/Q/' | tr Q '\015'
}
@@ -275,6 +279,15 @@ test_have_prereq () {
for prerequisite
do
+ case "$prerequisite" in
+ !*)
+ negative_prereq=t
+ prerequisite=${prerequisite#!}
+ ;;
+ *)
+ negative_prereq=
+ esac
+
case " $lazily_tested_prereq " in
*" $prerequisite "*)
;;
@@ -294,10 +307,20 @@ test_have_prereq () {
total_prereq=$(($total_prereq + 1))
case "$satisfied_prereq" in
*" $prerequisite "*)
+ satisfied_this_prereq=t
+ ;;
+ *)
+ satisfied_this_prereq=
+ esac
+
+ case "$satisfied_this_prereq,$negative_prereq" in
+ t,|,t)
ok_prereq=$(($ok_prereq + 1))
;;
*)
- # Keep a list of missing prerequisites
+ # Keep a list of missing prerequisites; restore
+ # the negative marker if necessary.
+ prerequisite=${negative_prereq:+!}$prerequisite
if test -z "$missing_prereq"
then
missing_prereq=$prerequisite
@@ -583,6 +606,13 @@ test_cmp() {
$GIT_TEST_CMP "$@"
}
+# Tests that its two parameters refer to the same revision
+test_cmp_rev () {
+ git rev-parse --verify "$1" >expect.rev &&
+ git rev-parse --verify "$2" >actual.rev &&
+ test_cmp expect.rev actual.rev
+}
+
# Print a sequence of numbers or letters in increasing order. This is
# similar to GNU seq(1), but the latter might not be available
# everywhere (and does not do letters). It may be used like:
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 489bc80fc1..8d76cf23d4 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -85,7 +85,8 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
.*_TEST
PROVE
VALGRIND
- PERF_AGGREGATING_LATER
+ UNZIP
+ PERF_
));
my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env);
print join("\n", @vars);
@@ -128,6 +129,7 @@ fi
unset CDPATH
unset GREP_OPTIONS
+unset UNZIP
case $(echo $GIT_TRACE |tr "[A-Z]" "[a-z]") in
1|2|true)
@@ -212,11 +214,13 @@ then
error)
tput bold; tput setaf 1;; # bold red
skip)
- tput bold; tput setaf 2;; # bold green
+ tput setaf 4;; # blue
+ warn)
+ tput setaf 3;; # brown/yellow
pass)
- tput setaf 2;; # green
+ tput setaf 2;; # green
info)
- tput setaf 3;; # brown
+ tput setaf 6;; # cyan
*)
test -n "$quiet" && return;;
esac
@@ -298,7 +302,7 @@ test_ok_ () {
test_failure_ () {
test_failure=$(($test_failure + 1))
- say_color error "not ok - $test_count $1"
+ say_color error "not ok $test_count - $1"
shift
echo "$@" | sed -e 's/^/# /'
test "$immediate" = "" || { GIT_EXIT_OK=t; exit 1; }
@@ -306,12 +310,12 @@ test_failure_ () {
test_known_broken_ok_ () {
test_fixed=$(($test_fixed+1))
- say_color "" "ok $test_count - $@ # TODO known breakage"
+ say_color error "ok $test_count - $@ # TODO known breakage vanished"
}
test_known_broken_failure_ () {
test_broken=$(($test_broken+1))
- say_color skip "not ok $test_count - $@ # TODO known breakage"
+ say_color warn "not ok $test_count - $@ # TODO known breakage"
}
test_debug () {
@@ -389,7 +393,8 @@ test_done () {
then
test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
mkdir -p "$test_results_dir"
- test_results_path="$test_results_dir/${0%.sh}-$$.counts"
+ base=${0##*/}
+ test_results_path="$test_results_dir/${base%.sh}-$$.counts"
cat >>"$test_results_path" <<-EOF
total $test_count
@@ -403,13 +408,18 @@ test_done () {
if test "$test_fixed" != 0
then
- say_color pass "# fixed $test_fixed known breakage(s)"
+ say_color error "# $test_fixed known breakage(s) vanished; please update test(s)"
fi
if test "$test_broken" != 0
then
- say_color error "# still have $test_broken known breakage(s)"
- msg="remaining $(($test_count-$test_broken)) test(s)"
+ say_color warn "# still have $test_broken known breakage(s)"
+ fi
+ if test "$test_broken" != 0 || test "$test_fixed" != 0
+ then
+ test_remaining=$(( $test_count - $test_broken - $test_fixed ))
+ msg="remaining $test_remaining test(s)"
else
+ test_remaining=$test_count
msg="$test_count test(s)"
fi
case "$test_failure" in
@@ -423,7 +433,7 @@ test_done () {
if test $test_external_has_tap -eq 0
then
- if test $test_count -gt 0
+ if test $test_remaining -gt 0
then
say_color pass "# passed all $msg"
fi
@@ -614,7 +624,7 @@ for skp in $GIT_SKIP_TESTS
do
case "$this_test" in
$skp)
- say_color skip >&3 "skipping test $this_test altogether"
+ say_color info >&3 "skipping test $this_test altogether"
skip_all="skip all tests in $this_test"
test_done
esac
@@ -656,12 +666,14 @@ case $(uname -s) in
# backslashes in pathspec are converted to '/'
# exec does not inherit the PID
test_set_prereq MINGW
+ test_set_prereq NOT_CYGWIN
test_set_prereq SED_STRIPS_CR
;;
*CYGWIN*)
test_set_prereq POSIXPERM
test_set_prereq EXECKEEPSPID
test_set_prereq NOT_MINGW
+ test_set_prereq CYGWIN
test_set_prereq SED_STRIPS_CR
;;
*)
@@ -669,6 +681,7 @@ case $(uname -s) in
test_set_prereq BSLASHPSPEC
test_set_prereq EXECKEEPSPID
test_set_prereq NOT_MINGW
+ test_set_prereq NOT_CYGWIN
;;
esac
@@ -714,6 +727,11 @@ test_i18ngrep () {
fi
}
+test_lazy_prereq PIPE '
+ # test whether the filesystem supports FIFOs
+ rm -f testfifo && mkfifo testfifo
+'
+
test_lazy_prereq SYMLINKS '
# test whether the filesystem supports symbolic links
ln -s x y && test -h y
@@ -738,6 +756,18 @@ test_lazy_prereq UTF8_NFD_TO_NFC '
esac
'
+test_lazy_prereq AUTOIDENT '
+ sane_unset GIT_AUTHOR_NAME &&
+ sane_unset GIT_AUTHOR_EMAIL &&
+ git var GIT_AUTHOR_IDENT
+'
+
# When the tests are run as root, permission tests will report that
# things are writable when they shouldn't be.
test -w / || test_set_prereq SANITY
+
+GIT_UNZIP=${GIT_UNZIP:-unzip}
+test_lazy_prereq UNZIP '
+ "$GIT_UNZIP" -v
+ test $? -ne 127
+'
diff --git a/t/test-terminal.perl b/t/test-terminal.perl
index 10172aee18..1fb373f25b 100755
--- a/t/test-terminal.perl
+++ b/t/test-terminal.perl
@@ -31,7 +31,7 @@ sub finish_child {
} elsif ($? & 127) {
my $code = $? & 127;
warn "died of signal $code";
- return $code - 128;
+ return $code + 128;
} else {
return $? >> 8;
}