summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/Makefile6
-rw-r--r--t/README13
-rw-r--r--t/lib-git-daemon.sh69
-rwxr-xr-xt/t0003-attributes.sh10
-rwxr-xr-xt/t0090-cache-tree.sh6
-rwxr-xr-xt/t2023-checkout-m.sh4
-rwxr-xr-xt/t2203-add-intent.sh2
-rwxr-xr-xt/t3502-cherry-pick-merge.sh2
-rwxr-xr-xt/t3510-cherry-pick-sequence.sh89
-rwxr-xr-xt/t3900-i18n-commit.sh6
-rwxr-xr-xt/t3903-stash.sh24
-rwxr-xr-xt/t3904-stash-patch.sh47
-rwxr-xr-xt/t3905-stash-include-untracked.sh33
-rwxr-xr-xt/t4010-diff-pathspec.sh8
-rwxr-xr-xt/t4015-diff-whitespace.sh14
-rwxr-xr-xt/t4034-diff-words.sh14
-rwxr-xr-xt/t4150-am.sh14
-rwxr-xr-xt/t5150-request-pull.sh3
-rwxr-xr-xt/t5500-fetch-pack.sh80
-rwxr-xr-xt/t5510-fetch.sh2
-rw-r--r--t/t5515/fetch.br-branches-default-merge2
-rw-r--r--t/t5515/fetch.br-branches-default-merge_branches-default2
-rw-r--r--t/t5515/fetch.br-branches-default-octopus2
-rw-r--r--t/t5515/fetch.br-branches-default-octopus_branches-default2
-rw-r--r--t/t5515/fetch.br-branches-one-merge2
-rw-r--r--t/t5515/fetch.br-branches-one-merge_branches-one2
-rw-r--r--t/t5515/fetch.br-config-explicit-merge2
-rw-r--r--t/t5515/fetch.br-config-explicit-merge_config-explicit2
-rw-r--r--t/t5515/fetch.br-config-explicit-octopus2
-rw-r--r--t/t5515/fetch.br-config-explicit-octopus_config-explicit2
-rw-r--r--t/t5515/fetch.br-config-glob-merge2
-rw-r--r--t/t5515/fetch.br-config-glob-merge_config-glob2
-rw-r--r--t/t5515/fetch.br-config-glob-octopus4
-rw-r--r--t/t5515/fetch.br-config-glob-octopus_config-glob4
-rw-r--r--t/t5515/fetch.br-remote-explicit-merge2
-rw-r--r--t/t5515/fetch.br-remote-explicit-merge_remote-explicit2
-rw-r--r--t/t5515/fetch.br-remote-explicit-octopus2
-rw-r--r--t/t5515/fetch.br-remote-explicit-octopus_remote-explicit2
-rw-r--r--t/t5515/fetch.br-remote-glob-merge2
-rw-r--r--t/t5515/fetch.br-remote-glob-merge_remote-glob2
-rw-r--r--t/t5515/fetch.br-remote-glob-octopus4
-rw-r--r--t/t5515/fetch.br-remote-glob-octopus_remote-glob4
-rwxr-xr-xt/t5523-push-upstream.sh7
-rwxr-xr-xt/t5541-http-push.sh68
-rwxr-xr-xt/t5550-http-fetch.sh3
-rwxr-xr-xt/t5570-git-daemon.sh148
-rwxr-xr-xt/t5601-clone.sh40
-rwxr-xr-xt/t5704-bundle.sh6
-rwxr-xr-xt/t5706-clone-branch.sh8
-rwxr-xr-xt/t6006-rev-list-format.sh6
-rwxr-xr-xt/t6012-rev-list-simplify.sh1
-rwxr-xr-xt/t7006-pager.sh73
-rwxr-xr-xt/t7406-submodule-update.sh8
-rwxr-xr-xt/t7510-signed-commit.sh80
-rwxr-xr-xt/t7610-mergetool.sh28
-rwxr-xr-xt/t7810-grep.sh36
-rwxr-xr-xt/t8006-blame-textconv.sh2
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh6
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh8
-rwxr-xr-xt/t9800-git-p4-basic.sh (renamed from t/t9800-git-p4.sh)60
-rwxr-xr-xt/t9801-git-p4-branch.sh94
-rwxr-xr-xt/t9803-git-p4-shell-metachars.sh (renamed from t/t9803-git-shell-metachars.sh)48
-rwxr-xr-xt/t9804-git-p4-label.sh113
-rwxr-xr-xt/t9805-git-p4-skip-submit-edit.sh (renamed from t/t9805-skip-submit-edit.sh)0
-rwxr-xr-xt/t9806-git-p4-options.sh170
-rwxr-xr-xt/t9807-git-p4-submit.sh92
-rwxr-xr-xt/t9807-submit.sh38
-rwxr-xr-xt/t9808-git-p4-chdir.sh (renamed from t/t9808-chdir.sh)0
-rwxr-xr-xt/t9809-git-p4-client-view.sh683
-rw-r--r--t/test-lib.sh16
-rwxr-xr-xt/test-terminal.perl4
71 files changed, 2125 insertions, 219 deletions
diff --git a/t/Makefile b/t/Makefile
index 9046ec9816..66ceefefcc 100644
--- a/t/Makefile
+++ b/t/Makefile
@@ -17,9 +17,9 @@ DEFAULT_TEST_TARGET ?= test
# Shell quote;
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
-T = $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)
-TSVN = $(wildcard t91[0-9][0-9]-*.sh)
-TGITWEB = $(wildcard t95[0-9][0-9]-*.sh)
+T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh))
+TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh))
+TGITWEB = $(sort $(wildcard t95[0-9][0-9]-*.sh))
all: $(DEFAULT_TEST_TARGET)
diff --git a/t/README b/t/README
index c85abaffb3..c09c582c16 100644
--- a/t/README
+++ b/t/README
@@ -548,6 +548,19 @@ library for your script to use.
...
'
+ - test_pause
+
+ This command is useful for writing and debugging tests and must be
+ removed before submitting. It halts the execution of the test and
+ spawns a shell in the trash directory. Exit the shell to continue
+ the test. Example:
+
+ test_expect_success 'test' '
+ git do-something >actual &&
+ test_pause &&
+ test_cmp expected actual
+ '
+
Prerequisites
-------------
diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
new file mode 100644
index 0000000000..ef2d01f369
--- /dev/null
+++ b/t/lib-git-daemon.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+if test -z "$GIT_TEST_GIT_DAEMON"
+then
+ skip_all="git-daemon testing disabled (define GIT_TEST_GIT_DAEMON to enable)"
+ test_done
+fi
+
+LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-'8121'}
+
+GIT_DAEMON_PID=
+GIT_DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo
+GIT_DAEMON_URL=git://127.0.0.1:$LIB_GIT_DAEMON_PORT
+
+start_git_daemon() {
+ if test -n "$GIT_DAEMON_PID"
+ then
+ error "start_git_daemon already called"
+ fi
+
+ mkdir -p "$GIT_DAEMON_DOCUMENT_ROOT_PATH"
+
+ trap 'code=$?; stop_git_daemon; (exit $code); die' EXIT
+
+ say >&3 "Starting git daemon ..."
+ mkfifo git_daemon_output
+ git daemon --listen=127.0.0.1 --port="$LIB_GIT_DAEMON_PORT" \
+ --reuseaddr --verbose \
+ --base-path="$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
+ "$@" "$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
+ >&3 2>git_daemon_output &
+ GIT_DAEMON_PID=$!
+ {
+ read line
+ echo >&4 "$line"
+ cat >&4 &
+
+ # Check expected output
+ if test x"$(expr "$line" : "\[[0-9]*\] \(.*\)")" != x"Ready to rumble"
+ then
+ kill "$GIT_DAEMON_PID"
+ wait "$GIT_DAEMON_PID"
+ trap 'die' EXIT
+ error "git daemon failed to start"
+ fi
+ } <git_daemon_output
+}
+
+stop_git_daemon() {
+ if test -z "$GIT_DAEMON_PID"
+ then
+ return
+ fi
+
+ trap 'die' EXIT
+
+ # kill git-daemon child of git
+ say >&3 "Stopping git daemon ..."
+ kill "$GIT_DAEMON_PID"
+ wait "$GIT_DAEMON_PID" >&3 2>&4
+ ret=$?
+ # expect exit with status 143 = 128+15 for signal TERM=15
+ if test $ret -ne 143
+ then
+ error "git daemon exited with status: $ret"
+ fi
+ GIT_DAEMON_PID=
+ rm -f git_daemon_output
+}
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index dbb2623d93..51f3045ba4 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -159,6 +159,16 @@ test_expect_success 'relative paths' '
(cd b && attr_check ../a/b/g a/b/g)
'
+test_expect_success 'prefixes are not confused with leading directories' '
+ attr_check a_plus/g unspecified &&
+ cat >expect <<-\EOF &&
+ a/g: test: a/g
+ a_plus/g: test: unspecified
+ EOF
+ git check-attr test a/g a_plus/g >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'core.attributesfile' '
attr_check global unspecified &&
git config core.attributesfile "$HOME/global-gitattributes" &&
diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh
index f97256292e..6c33e28ee8 100755
--- a/t/t0090-cache-tree.sh
+++ b/t/t0090-cache-tree.sh
@@ -17,15 +17,13 @@ cmp_cache_tree () {
# test-dump-cache-tree already verifies that all existing data is
# correct.
test_shallow_cache_tree () {
- echo "SHA " \
- "($(git ls-files|wc -l) entries, 0 subtrees)" >expect &&
+ printf "SHA (%d entries, 0 subtrees)\n" $(git ls-files|wc -l) >expect &&
cmp_cache_tree expect
}
test_invalid_cache_tree () {
echo "invalid (0 subtrees)" >expect &&
- echo "SHA #(ref) " \
- "($(git ls-files|wc -l) entries, 0 subtrees)" >>expect &&
+ printf "SHA #(ref) (%d entries, 0 subtrees)\n" $(git ls-files|wc -l) >>expect &&
cmp_cache_tree expect
}
diff --git a/t/t2023-checkout-m.sh b/t/t2023-checkout-m.sh
index 1a40ce02e5..7e18985134 100755
--- a/t/t2023-checkout-m.sh
+++ b/t/t2023-checkout-m.sh
@@ -17,7 +17,9 @@ test_expect_success setup '
test_commit added_in_topic each.txt in_topic
'
-test_must_fail git merge master
+test_expect_success 'git merge master' '
+ test_must_fail git merge master
+'
clean_branchnames () {
# Remove branch names after conflict lines
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index 58a329961e..25435290a7 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -41,7 +41,7 @@ test_expect_success 'cannot commit with i-t-a entry' '
echo frotz >nitfol &&
git add rezrov &&
git add -N nitfol &&
- test_must_fail git commit
+ test_must_fail git commit -m initial
'
test_expect_success 'can commit with an unrelated i-t-a entry in index' '
diff --git a/t/t3502-cherry-pick-merge.sh b/t/t3502-cherry-pick-merge.sh
index 0ab52da902..e37547f41a 100755
--- a/t/t3502-cherry-pick-merge.sh
+++ b/t/t3502-cherry-pick-merge.sh
@@ -35,7 +35,7 @@ test_expect_success 'cherry-pick a non-merge with -m should fail' '
git reset --hard &&
git checkout a^0 &&
- test_must_fail git cherry-pick -m 1 b &&
+ test_expect_code 128 git cherry-pick -m 1 b &&
git diff --exit-code a --
'
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index e80050e1fe..97f3710700 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -14,6 +14,9 @@ test_description='Test cherry-pick continuation features
. ./test-lib.sh
+# Repeat first match 10 times
+_r10='\1\1\1\1\1\1\1\1\1\1'
+
pristine_detach () {
git cherry-pick --quit &&
git checkout -f "$1^0" &&
@@ -43,7 +46,7 @@ test_expect_success setup '
test_expect_success 'cherry-pick persists data on failure' '
pristine_detach initial &&
- test_must_fail git cherry-pick -s base..anotherpick &&
+ test_expect_code 1 git cherry-pick -s base..anotherpick &&
test_path_is_dir .git/sequencer &&
test_path_is_file .git/sequencer/head &&
test_path_is_file .git/sequencer/todo &&
@@ -64,7 +67,7 @@ test_expect_success 'cherry-pick mid-cherry-pick-sequence' '
test_expect_success 'cherry-pick persists opts correctly' '
pristine_detach initial &&
- test_must_fail git cherry-pick -s -m 1 --strategy=recursive -X patience -X ours base..anotherpick &&
+ test_expect_code 128 git cherry-pick -s -m 1 --strategy=recursive -X patience -X ours initial..anotherpick &&
test_path_is_dir .git/sequencer &&
test_path_is_file .git/sequencer/head &&
test_path_is_file .git/sequencer/todo &&
@@ -104,7 +107,7 @@ test_expect_success '--abort requires cherry-pick in progress' '
test_expect_success '--quit cleans up sequencer state' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..picked &&
+ test_expect_code 1 git cherry-pick base..picked &&
git cherry-pick --quit &&
test_path_is_missing .git/sequencer
'
@@ -118,7 +121,7 @@ test_expect_success '--quit keeps HEAD and conflicted index intact' '
:000000 100644 OBJID OBJID A foo
:000000 100644 OBJID OBJID A unrelated
EOF
- test_must_fail git cherry-pick base..picked &&
+ test_expect_code 1 git cherry-pick base..picked &&
git cherry-pick --quit &&
test_path_is_missing .git/sequencer &&
test_must_fail git update-index --refresh &&
@@ -132,7 +135,7 @@ test_expect_success '--quit keeps HEAD and conflicted index intact' '
test_expect_success '--abort to cancel multiple cherry-pick' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..anotherpick &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
git cherry-pick --abort &&
test_path_is_missing .git/sequencer &&
test_cmp_rev initial HEAD &&
@@ -142,7 +145,7 @@ test_expect_success '--abort to cancel multiple cherry-pick' '
test_expect_success '--abort to cancel single cherry-pick' '
pristine_detach initial &&
- test_must_fail git cherry-pick picked &&
+ test_expect_code 1 git cherry-pick picked &&
git cherry-pick --abort &&
test_path_is_missing .git/sequencer &&
test_cmp_rev initial HEAD &&
@@ -152,7 +155,7 @@ test_expect_success '--abort to cancel single cherry-pick' '
test_expect_success 'cherry-pick --abort to cancel multiple revert' '
pristine_detach anotherpick &&
- test_must_fail git revert base..picked &&
+ test_expect_code 1 git revert base..picked &&
git cherry-pick --abort &&
test_path_is_missing .git/sequencer &&
test_cmp_rev anotherpick HEAD &&
@@ -162,7 +165,7 @@ test_expect_success 'cherry-pick --abort to cancel multiple revert' '
test_expect_success 'revert --abort works, too' '
pristine_detach anotherpick &&
- test_must_fail git revert base..picked &&
+ test_expect_code 1 git revert base..picked &&
git revert --abort &&
test_path_is_missing .git/sequencer &&
test_cmp_rev anotherpick HEAD
@@ -170,7 +173,7 @@ test_expect_success 'revert --abort works, too' '
test_expect_success '--abort to cancel single revert' '
pristine_detach anotherpick &&
- test_must_fail git revert picked &&
+ test_expect_code 1 git revert picked &&
git revert --abort &&
test_path_is_missing .git/sequencer &&
test_cmp_rev anotherpick HEAD &&
@@ -181,7 +184,7 @@ test_expect_success '--abort to cancel single revert' '
test_expect_success '--abort keeps unrelated change, easy case' '
pristine_detach unrelatedpick &&
echo changed >expect &&
- test_must_fail git cherry-pick picked..yetanotherpick &&
+ test_expect_code 1 git cherry-pick picked..yetanotherpick &&
echo changed >unrelated &&
git cherry-pick --abort &&
test_cmp expect unrelated
@@ -190,7 +193,7 @@ test_expect_success '--abort keeps unrelated change, easy case' '
test_expect_success '--abort refuses to clobber unrelated change, harder case' '
pristine_detach initial &&
echo changed >expect &&
- test_must_fail git cherry-pick base..anotherpick &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
echo changed >unrelated &&
test_must_fail git cherry-pick --abort &&
test_cmp expect unrelated &&
@@ -205,7 +208,7 @@ test_expect_success '--abort refuses to clobber unrelated change, harder case' '
test_expect_success 'cherry-pick still writes sequencer state when one commit is left' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..picked &&
+ test_expect_code 1 git cherry-pick base..picked &&
test_path_is_dir .git/sequencer &&
echo "resolved" >foo &&
git add foo &&
@@ -229,7 +232,7 @@ test_expect_success 'cherry-pick still writes sequencer state when one commit is
test_expect_success '--abort after last commit in sequence' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..picked &&
+ test_expect_code 1 git cherry-pick base..picked &&
git cherry-pick --abort &&
test_path_is_missing .git/sequencer &&
test_cmp_rev initial HEAD &&
@@ -239,22 +242,22 @@ test_expect_success '--abort after last commit in sequence' '
test_expect_success 'cherry-pick does not implicitly stomp an existing operation' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..anotherpick &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
test-chmtime -v +0 .git/sequencer >expect &&
- test_must_fail git cherry-pick unrelatedpick &&
+ test_expect_code 128 git cherry-pick unrelatedpick &&
test-chmtime -v +0 .git/sequencer >actual &&
test_cmp expect actual
'
test_expect_success '--continue complains when no cherry-pick is in progress' '
pristine_detach initial &&
- test_must_fail git cherry-pick --continue
+ test_expect_code 128 git cherry-pick --continue
'
test_expect_success '--continue complains when there are unresolved conflicts' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..anotherpick &&
- test_must_fail git cherry-pick --continue
+ test_expect_code 1 git cherry-pick base..anotherpick &&
+ test_expect_code 128 git cherry-pick --continue
'
test_expect_success '--continue of single cherry-pick' '
@@ -318,7 +321,7 @@ test_expect_success '--continue after resolving conflicts' '
test_expect_success '--continue after resolving conflicts and committing' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..anotherpick &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
echo "c" >foo &&
git add foo &&
git commit &&
@@ -368,7 +371,7 @@ test_expect_success 'follow advice and skip nil patch' '
test_expect_success '--continue respects opts' '
pristine_detach initial &&
- test_must_fail git cherry-pick -x base..anotherpick &&
+ test_expect_code 1 git cherry-pick -x base..anotherpick &&
echo "c" >foo &&
git add foo &&
git commit &&
@@ -409,7 +412,7 @@ test_expect_success '--continue respects -x in first commit in multi-pick' '
test_expect_success '--signoff is not automatically propagated to resolved conflict' '
pristine_detach initial &&
- test_must_fail git cherry-pick --signoff base..anotherpick &&
+ test_expect_code 1 git cherry-pick --signoff base..anotherpick &&
echo "c" >foo &&
git add foo &&
git commit &&
@@ -453,24 +456,24 @@ test_expect_success 'sign-off needs to be reaffirmed after conflict resolution,
test_expect_success 'malformed instruction sheet 1' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..anotherpick &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
echo "resolved" >foo &&
git add foo &&
git commit &&
sed "s/pick /pick/" .git/sequencer/todo >new_sheet &&
cp new_sheet .git/sequencer/todo &&
- test_must_fail git cherry-pick --continue
+ test_expect_code 128 git cherry-pick --continue
'
test_expect_success 'malformed instruction sheet 2' '
pristine_detach initial &&
- test_must_fail git cherry-pick base..anotherpick &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
echo "resolved" >foo &&
git add foo &&
git commit &&
sed "s/pick/revert/" .git/sequencer/todo >new_sheet &&
cp new_sheet .git/sequencer/todo &&
- test_must_fail git cherry-pick --continue
+ test_expect_code 128 git cherry-pick --continue
'
test_expect_success 'empty commit set' '
@@ -478,4 +481,40 @@ test_expect_success 'empty commit set' '
test_expect_code 128 git cherry-pick base..base
'
+test_expect_success 'malformed instruction sheet 3' '
+ pristine_detach initial &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
+ echo "resolved" >foo &&
+ git add foo &&
+ git commit &&
+ sed "s/pick \([0-9a-f]*\)/pick $_r10/" .git/sequencer/todo >new_sheet &&
+ cp new_sheet .git/sequencer/todo &&
+ test_expect_code 128 git cherry-pick --continue
+'
+
+test_expect_success 'instruction sheet, fat-fingers version' '
+ pristine_detach initial &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
+ echo "c" >foo &&
+ git add foo &&
+ git commit &&
+ sed "s/pick \([0-9a-f]*\)/pick \1 /" .git/sequencer/todo >new_sheet &&
+ cp new_sheet .git/sequencer/todo &&
+ git cherry-pick --continue
+'
+
+test_expect_success 'commit descriptions in insn sheet are optional' '
+ pristine_detach initial &&
+ test_expect_code 1 git cherry-pick base..anotherpick &&
+ echo "c" >foo &&
+ git add foo &&
+ git commit &&
+ cut -d" " -f1,2 .git/sequencer/todo >new_sheet &&
+ cp new_sheet .git/sequencer/todo &&
+ git cherry-pick --continue &&
+ test_path_is_missing .git/sequencer &&
+ git rev-list HEAD >commits &&
+ test_line_count = 4 commits
+'
+
test_done
diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh
index 1f62c151b0..d48a7c002d 100755
--- a/t/t3900-i18n-commit.sh
+++ b/t/t3900-i18n-commit.sh
@@ -34,6 +34,12 @@ test_expect_success 'no encoding header for base case' '
test z = "z$E"
'
+test_expect_failure 'UTF-16 refused because of NULs' '
+ echo UTF-16 >F &&
+ git commit -a -F "$TEST_DIRECTORY"/t3900/UTF-16.txt
+'
+
+
for H in ISO8859-1 eucJP ISO-2022-JP
do
test_expect_success "$H setup" '
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index fcdb18217a..dbe2ac179d 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -601,4 +601,28 @@ test_expect_success 'stash apply shows status same as git status (relative to cu
test_cmp expect actual
'
+cat > expect << EOF
+diff --git a/HEAD b/HEAD
+new file mode 100644
+index 0000000..fe0cbee
+--- /dev/null
++++ b/HEAD
+@@ -0,0 +1 @@
++file-not-a-ref
+EOF
+
+test_expect_success 'stash where working directory contains "HEAD" file' '
+ git stash clear &&
+ git reset --hard &&
+ echo file-not-a-ref > HEAD &&
+ git add HEAD &&
+ test_tick &&
+ git stash &&
+ git diff-files --quiet &&
+ git diff-index --cached --quiet HEAD &&
+ test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
+ git diff stash^..stash > output &&
+ test_cmp output expect
+'
+
test_done
diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh
index 781fd71681..70655c1848 100755
--- a/t/t3904-stash-patch.sh
+++ b/t/t3904-stash-patch.sh
@@ -7,7 +7,8 @@ test_expect_success PERL 'setup' '
mkdir dir &&
echo parent > dir/foo &&
echo dummy > bar &&
- git add bar dir/foo &&
+ echo committed > HEAD &&
+ git add bar dir/foo HEAD &&
git commit -m initial &&
test_tick &&
test_commit second dir/foo head &&
@@ -17,47 +18,57 @@ test_expect_success PERL 'setup' '
save_head
'
-# note: bar sorts before dir, so the first 'n' is always to skip 'bar'
+# note: order of files with unstaged changes: HEAD bar dir/foo
test_expect_success PERL 'saying "n" does nothing' '
+ set_state HEAD HEADfile_work HEADfile_index &&
set_state dir/foo work index &&
- (echo n; echo n) | test_must_fail git stash save -p &&
- verify_state dir/foo work index &&
- verify_saved_state bar
+ (echo n; echo n; echo n) | test_must_fail git stash save -p &&
+ verify_state HEAD HEADfile_work HEADfile_index &&
+ verify_saved_state bar &&
+ verify_state dir/foo work index
'
test_expect_success PERL 'git stash -p' '
- (echo n; echo y) | git stash save -p &&
- verify_state dir/foo head index &&
+ (echo y; echo n; echo y) | git stash save -p &&
+ verify_state HEAD committed HEADfile_index &&
verify_saved_state bar &&
+ verify_state dir/foo head index &&
git reset --hard &&
git stash apply &&
- verify_state dir/foo work head &&
- verify_state bar dummy dummy
+ verify_state HEAD HEADfile_work committed &&
+ verify_state bar dummy dummy &&
+ verify_state dir/foo work head
'
test_expect_success PERL 'git stash -p --no-keep-index' '
- set_state dir/foo work index &&
+ set_state HEAD HEADfile_work HEADfile_index &&
set_state bar bar_work bar_index &&
- (echo n; echo y) | git stash save -p --no-keep-index &&
- verify_state dir/foo head head &&
+ set_state dir/foo work index &&
+ (echo y; echo n; echo y) | git stash save -p --no-keep-index &&
+ verify_state HEAD committed committed &&
verify_state bar bar_work dummy &&
+ verify_state dir/foo head head &&
git reset --hard &&
git stash apply --index &&
- verify_state dir/foo work index &&
- verify_state bar dummy bar_index
+ verify_state HEAD HEADfile_work HEADfile_index &&
+ verify_state bar dummy bar_index &&
+ verify_state dir/foo work index
'
test_expect_success PERL 'git stash --no-keep-index -p' '
- set_state dir/foo work index &&
+ set_state HEAD HEADfile_work HEADfile_index &&
set_state bar bar_work bar_index &&
- (echo n; echo y) | git stash save --no-keep-index -p &&
+ set_state dir/foo work index &&
+ (echo y; echo n; echo y) | git stash save --no-keep-index -p &&
+ verify_state HEAD committed committed &&
verify_state dir/foo head head &&
verify_state bar bar_work dummy &&
git reset --hard &&
git stash apply --index &&
- verify_state dir/foo work index &&
- verify_state bar dummy bar_index
+ verify_state HEAD HEADfile_work HEADfile_index &&
+ verify_state bar dummy bar_index &&
+ verify_state dir/foo work index
'
test_expect_success PERL 'none of this moved HEAD' '
diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh
index ef44fb2260..a5e7e6b2ba 100755
--- a/t/t3905-stash-include-untracked.sh
+++ b/t/t3905-stash-include-untracked.sh
@@ -17,6 +17,7 @@ test_expect_success 'stash save --include-untracked some dirty working directory
echo 3 > file &&
test_tick &&
echo 1 > file2 &&
+ echo 1 > HEAD &&
mkdir untracked &&
echo untracked >untracked/untracked &&
git stash --include-untracked &&
@@ -35,6 +36,13 @@ test_expect_success 'stash save --include-untracked cleaned the untracked files'
'
cat > expect.diff <<EOF
+diff --git a/HEAD b/HEAD
+new file mode 100644
+index 0000000..d00491f
+--- /dev/null
++++ b/HEAD
+@@ -0,0 +1 @@
++1
diff --git a/file2 b/file2
new file mode 100644
index 0000000..d00491f
@@ -51,14 +59,16 @@ index 0000000..5a72eb2
+untracked
EOF
cat > expect.lstree <<EOF
+HEAD
file2
untracked
EOF
test_expect_success 'stash save --include-untracked stashed the untracked files' '
- test "!" -f file2 &&
- test ! -e untracked &&
- git diff HEAD stash^3 -- file2 untracked >actual &&
+ test_path_is_missing file2 &&
+ test_path_is_missing untracked &&
+ test_path_is_missing HEAD &&
+ git diff HEAD stash^3 -- HEAD file2 untracked >actual &&
test_cmp expect.diff actual &&
git ls-tree --name-only stash^3: >actual &&
test_cmp expect.lstree actual
@@ -75,6 +85,7 @@ git clean --force --quiet
cat > expect <<EOF
M file
+?? HEAD
?? actual
?? expect
?? file2
@@ -116,10 +127,12 @@ test_expect_success 'stash save --include-untracked dirty index got stashed' '
git reset > /dev/null
+# Must direct output somewhere where it won't be considered an untracked file
test_expect_success 'stash save --include-untracked -q is quiet' '
echo 1 > file5 &&
- git stash save --include-untracked --quiet > output.out 2>&1 &&
- test ! -s output.out
+ git stash save --include-untracked --quiet > .git/stash-output.out 2>&1 &&
+ test_line_count = 0 .git/stash-output.out &&
+ rm -f .git/stash-output.out
'
test_expect_success 'stash save --include-untracked removed files' '
@@ -133,7 +146,7 @@ rm -f expect
test_expect_success 'stash save --include-untracked removed files got stashed' '
git stash pop &&
- test ! -f file
+ test_path_is_missing file
'
cat > .gitignore <<EOF
@@ -155,14 +168,14 @@ test_expect_success 'stash save --include-untracked respects .gitignore' '
test_expect_success 'stash save -u can stash with only untracked files different' '
echo 4 > file4 &&
git stash -u &&
- test "!" -f file4
+ test_path_is_missing file4
'
test_expect_success 'stash save --all does not respect .gitignore' '
git stash -a &&
- test "!" -f ignored &&
- test "!" -e ignored.d &&
- test "!" -f .gitignore
+ test_path_is_missing ignored &&
+ test_path_is_missing ignored.d &&
+ test_path_is_missing .gitignore
'
test_expect_success 'stash save --all is stash poppable' '
diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh
index fbc8cd8f05..af5134b70c 100755
--- a/t/t4010-diff-pathspec.sh
+++ b/t/t4010-diff-pathspec.sh
@@ -48,6 +48,14 @@ test_expect_success \
compare_diff_raw current expected'
cat >expected <<\EOF
+:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M path1/file1
+EOF
+test_expect_success \
+ '"*file1" should show path1/file1' \
+ 'git diff-index --cached $tree -- "*file1" >current &&
+ compare_diff_raw current expected'
+
+cat >expected <<\EOF
:100644 100644 766498d93a4b06057a8e49d23f4068f1170ff38f 0a41e115ab61be0328a19b29f18cdcb49338d516 M file0
EOF
test_expect_success \
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index 9059bcd69e..cc3db1304e 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -103,7 +103,7 @@ test_expect_success 'another test, with -w --ignore-space-at-eol' 'test_cmp expe
git diff -w -b --ignore-space-at-eol > out
test_expect_success 'another test, with -w -b --ignore-space-at-eol' 'test_cmp expect out'
-tr 'Q' '\015' << EOF > expect
+tr 'Q_' '\015 ' << EOF > expect
diff --git a/x b/x
index d99af23..8b32fb5 100644
--- a/x
@@ -111,19 +111,19 @@ index d99af23..8b32fb5 100644
@@ -1,6 +1,6 @@
-whitespace at beginning
+ whitespace at beginning
- whitespace change
+ whitespace change
-whitespace in the middle
+white space in the middle
- whitespace at end
+ whitespace at end__
unchanged line
- CR at endQ
+ CR at end
EOF
git diff -b > out
test_expect_success 'another test, with -b' 'test_cmp expect out'
git diff -b --ignore-space-at-eol > out
test_expect_success 'another test, with -b --ignore-space-at-eol' 'test_cmp expect out'
-tr 'Q' '\015' << EOF > expect
+tr 'Q_' '\015 ' << EOF > expect
diff --git a/x b/x
index d99af23..8b32fb5 100644
--- a/x
@@ -135,9 +135,9 @@ index d99af23..8b32fb5 100644
+ whitespace at beginning
+whitespace change
+white space in the middle
- whitespace at end
+ whitespace at end__
unchanged line
- CR at endQ
+ CR at end
EOF
git diff --ignore-space-at-eol > out
test_expect_success 'another test, with --ignore-space-at-eol' 'test_cmp expect out'
diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh
index 6f1e5a2a15..5c2012111c 100755
--- a/t/t4034-diff-words.sh
+++ b/t/t4034-diff-words.sh
@@ -334,4 +334,18 @@ test_expect_success 'word-diff with diff.sbe' '
word_diff --word-diff=plain
'
+test_expect_success 'word-diff with no newline at EOF' '
+ cat >expect <<-\EOF &&
+ diff --git a/pre b/post
+ index 7bf316e..3dd0303 100644
+ --- a/pre
+ +++ b/post
+ @@ -1 +1 @@
+ a a [-a-]{+ab+} a a
+ EOF
+ printf "%s" "a a a a a" >pre &&
+ printf "%s" "a a ab a a" >post &&
+ word_diff --word-diff=plain
+'
+
test_done
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index d7d9ccc1c8..8807b602a5 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -237,7 +237,7 @@ test_expect_success 'am stays in branch' '
test_expect_success 'am --signoff does not add Signed-off-by: line if already there' '
git format-patch --stdout HEAD^ >patch3 &&
- sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4 &&
+ sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2] [foo," patch3 >patch4 &&
rm -fr .git/rebase-apply &&
git reset --hard &&
git checkout HEAD^ &&
@@ -259,7 +259,17 @@ test_expect_success 'am --keep really keeps the subject' '
git am --keep patch4 &&
! test -d .git/rebase-apply &&
git cat-file commit HEAD >actual &&
- grep "Re: Re: Re: \[PATCH 1/5 v2\] third" actual
+ grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual
+'
+
+test_expect_success 'am --keep-non-patch really keeps the non-patch part' '
+ rm -fr .git/rebase-apply &&
+ git reset --hard &&
+ git checkout HEAD^ &&
+ git am --keep-non-patch patch4 &&
+ ! test -d .git/rebase-apply &&
+ git cat-file commit HEAD >actual &&
+ grep "^\[foo\] third" actual
'
test_expect_success 'am -3 falls back to 3-way merge' '
diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh
index ea6f692baf..da25bc2d1f 100755
--- a/t/t5150-request-pull.sh
+++ b/t/t5150-request-pull.sh
@@ -67,9 +67,11 @@ test_expect_success 'setup: two scripts for reading pull requests' '
cat <<-\EOT >read-request.sed &&
#!/bin/sed -nf
+ # Note that a request could ask for "tag $tagname"
/ in the git repository at:$/!d
n
/^$/ n
+ s/ tag \([^ ]*\)$/ tag--\1/
s/^[ ]*\(.*\) \([^ ]*\)/please pull\
\1\
\2/p
@@ -178,6 +180,7 @@ test_expect_success 'request names an appropriate branch' '
read branch
} <digest &&
{
+ test "$branch" = full ||
test "$branch" = master ||
test "$branch" = for-upstream
}
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 9bf69e9a0f..ce51692bb2 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -114,8 +114,19 @@ pull_to_client 2nd "refs/heads/B" $((64*3))
pull_to_client 3rd "refs/heads/A" $((1*3))
+test_expect_success 'single branch clone' '
+ git clone --single-branch "file://$(pwd)/." singlebranch
+'
+
+test_expect_success 'single branch object count' '
+ GIT_DIR=singlebranch/.git git count-objects -v |
+ grep "^in-pack:" > count.singlebranch &&
+ echo "in-pack: 198" >expected &&
+ test_cmp expected count.singlebranch
+'
+
test_expect_success 'clone shallow' '
- git clone --depth 2 "file://$(pwd)/." shallow
+ git clone --no-single-branch --depth 2 "file://$(pwd)/." shallow
'
test_expect_success 'clone shallow object count' '
@@ -248,4 +259,71 @@ test_expect_success 'clone shallow object count' '
grep "^count: 52" count.shallow
'
+test_expect_success 'clone shallow without --no-single-branch' '
+ git clone --depth 1 "file://$(pwd)/." shallow2
+'
+
+test_expect_success 'clone shallow object count' '
+ (
+ cd shallow2 &&
+ git count-objects -v
+ ) > count.shallow2 &&
+ grep "^in-pack: 6" count.shallow2
+'
+
+test_expect_success 'clone shallow with --branch' '
+ git clone --depth 1 --branch A "file://$(pwd)/." shallow3
+'
+
+test_expect_success 'clone shallow object count' '
+ echo "in-pack: 12" > count3.expected &&
+ GIT_DIR=shallow3/.git git count-objects -v |
+ grep "^in-pack" > count3.actual &&
+ test_cmp count3.expected count3.actual
+'
+
+test_expect_success 'clone shallow with detached HEAD' '
+ git checkout HEAD^ &&
+ git clone --depth 1 "file://$(pwd)/." shallow5 &&
+ git checkout - &&
+ GIT_DIR=shallow5/.git git rev-parse HEAD >actual &&
+ git rev-parse HEAD^ >expected &&
+ test_cmp expected actual
+'
+
+test_expect_success 'shallow clone pulling tags' '
+ git tag -a -m A TAGA1 A &&
+ git tag -a -m B TAGB1 B &&
+ git tag TAGA2 A &&
+ git tag TAGB2 B &&
+ git clone --depth 1 "file://$(pwd)/." shallow6 &&
+
+ cat >taglist.expected <<\EOF &&
+TAGB1
+TAGB2
+EOF
+ GIT_DIR=shallow6/.git git tag -l >taglist.actual &&
+ test_cmp taglist.expected taglist.actual &&
+
+ echo "in-pack: 7" > count6.expected &&
+ GIT_DIR=shallow6/.git git count-objects -v |
+ grep "^in-pack" > count6.actual &&
+ test_cmp count6.expected count6.actual
+'
+
+test_expect_success 'shallow cloning single tag' '
+ git clone --depth 1 --branch=TAGB1 "file://$(pwd)/." shallow7 &&
+ cat >taglist.expected <<\EOF &&
+TAGB1
+TAGB2
+EOF
+ GIT_DIR=shallow7/.git git tag -l >taglist.actual &&
+ test_cmp taglist.expected taglist.actual &&
+
+ echo "in-pack: 7" > count7.expected &&
+ GIT_DIR=shallow7/.git git count-objects -v |
+ grep "^in-pack" > count7.actual &&
+ test_cmp count7.expected count7.actual
+'
+
test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index e88dbd50f3..79ee913130 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -70,8 +70,8 @@ test_expect_success "fetch test for-merge" '
master_in_two=`cd ../two && git rev-parse master` &&
one_in_two=`cd ../two && git rev-parse one` &&
{
- echo "$master_in_two not-for-merge"
echo "$one_in_two "
+ echo "$master_in_two not-for-merge"
} >expected &&
cut -f -2 .git/FETCH_HEAD >actual &&
test_cmp expected actual'
diff --git a/t/t5515/fetch.br-branches-default-merge b/t/t5515/fetch.br-branches-default-merge
index e3a41ae811..12ab08e8ac 100644
--- a/t/t5515/fetch.br-branches-default-merge
+++ b/t/t5515/fetch.br-branches-default-merge
@@ -1,6 +1,6 @@
# br-branches-default-merge
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-branches-default-merge_branches-default b/t/t5515/fetch.br-branches-default-merge_branches-default
index 1f60561cb1..54427522dd 100644
--- a/t/t5515/fetch.br-branches-default-merge_branches-default
+++ b/t/t5515/fetch.br-branches-default-merge_branches-default
@@ -1,6 +1,6 @@
# br-branches-default-merge branches-default
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-branches-default-octopus b/t/t5515/fetch.br-branches-default-octopus
index f31e1b3080..498a761aae 100644
--- a/t/t5515/fetch.br-branches-default-octopus
+++ b/t/t5515/fetch.br-branches-default-octopus
@@ -1,7 +1,7 @@
# br-branches-default-octopus
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-branches-default-octopus_branches-default b/t/t5515/fetch.br-branches-default-octopus_branches-default
index 7060bd9ae5..0857f134e1 100644
--- a/t/t5515/fetch.br-branches-default-octopus_branches-default
+++ b/t/t5515/fetch.br-branches-default-octopus_branches-default
@@ -1,7 +1,7 @@
# br-branches-default-octopus branches-default
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-branches-one-merge b/t/t5515/fetch.br-branches-one-merge
index aa1c8a937e..54a77420d5 100644
--- a/t/t5515/fetch.br-branches-one-merge
+++ b/t/t5515/fetch.br-branches-one-merge
@@ -1,6 +1,6 @@
# br-branches-one-merge
-8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
+8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-branches-one-merge_branches-one b/t/t5515/fetch.br-branches-one-merge_branches-one
index c93310a730..b4d1bb0b0b 100644
--- a/t/t5515/fetch.br-branches-one-merge_branches-one
+++ b/t/t5515/fetch.br-branches-one-merge_branches-one
@@ -1,6 +1,6 @@
# br-branches-one-merge branches-one
-8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
+8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-config-explicit-merge b/t/t5515/fetch.br-config-explicit-merge
index f6475b717a..5ce764a06e 100644
--- a/t/t5515/fetch.br-config-explicit-merge
+++ b/t/t5515/fetch.br-config-explicit-merge
@@ -1,8 +1,8 @@
# br-config-explicit-merge
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-config-explicit-merge_config-explicit b/t/t5515/fetch.br-config-explicit-merge_config-explicit
index 018bdd752a..b1152b76dc 100644
--- a/t/t5515/fetch.br-config-explicit-merge_config-explicit
+++ b/t/t5515/fetch.br-config-explicit-merge_config-explicit
@@ -1,8 +1,8 @@
# br-config-explicit-merge config-explicit
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-config-explicit-octopus b/t/t5515/fetch.br-config-explicit-octopus
index 36d0270502..110577bb67 100644
--- a/t/t5515/fetch.br-config-explicit-octopus
+++ b/t/t5515/fetch.br-config-explicit-octopus
@@ -1,7 +1,7 @@
# br-config-explicit-octopus
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
diff --git a/t/t5515/fetch.br-config-explicit-octopus_config-explicit b/t/t5515/fetch.br-config-explicit-octopus_config-explicit
index 6654ad0898..a29dd8baba 100644
--- a/t/t5515/fetch.br-config-explicit-octopus_config-explicit
+++ b/t/t5515/fetch.br-config-explicit-octopus_config-explicit
@@ -1,7 +1,7 @@
# br-config-explicit-octopus config-explicit
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
diff --git a/t/t5515/fetch.br-config-glob-merge b/t/t5515/fetch.br-config-glob-merge
index 8bb5e8bc4e..89f2596cb9 100644
--- a/t/t5515/fetch.br-config-glob-merge
+++ b/t/t5515/fetch.br-config-glob-merge
@@ -1,7 +1,7 @@
# br-config-glob-merge
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
diff --git a/t/t5515/fetch.br-config-glob-merge_config-glob b/t/t5515/fetch.br-config-glob-merge_config-glob
index 113c08dabe..2ba4832160 100644
--- a/t/t5515/fetch.br-config-glob-merge_config-glob
+++ b/t/t5515/fetch.br-config-glob-merge_config-glob
@@ -1,7 +1,7 @@
# br-config-glob-merge config-glob
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
diff --git a/t/t5515/fetch.br-config-glob-octopus b/t/t5515/fetch.br-config-glob-octopus
index 9bbd537579..64994df7e2 100644
--- a/t/t5515/fetch.br-config-glob-octopus
+++ b/t/t5515/fetch.br-config-glob-octopus
@@ -1,8 +1,8 @@
# br-config-glob-octopus
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-config-glob-octopus_config-glob b/t/t5515/fetch.br-config-glob-octopus_config-glob
index 4e510437d9..681a725adc 100644
--- a/t/t5515/fetch.br-config-glob-octopus_config-glob
+++ b/t/t5515/fetch.br-config-glob-octopus_config-glob
@@ -1,8 +1,8 @@
# br-config-glob-octopus config-glob
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-remote-explicit-merge b/t/t5515/fetch.br-remote-explicit-merge
index 7421b2cb86..d018b3515f 100644
--- a/t/t5515/fetch.br-remote-explicit-merge
+++ b/t/t5515/fetch.br-remote-explicit-merge
@@ -1,8 +1,8 @@
# br-remote-explicit-merge
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-remote-explicit-merge_remote-explicit b/t/t5515/fetch.br-remote-explicit-merge_remote-explicit
index b6975d3890..0d3d780dd0 100644
--- a/t/t5515/fetch.br-remote-explicit-merge_remote-explicit
+++ b/t/t5515/fetch.br-remote-explicit-merge_remote-explicit
@@ -1,8 +1,8 @@
# br-remote-explicit-merge remote-explicit
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-remote-explicit-octopus b/t/t5515/fetch.br-remote-explicit-octopus
index 76812812ee..6f843044ed 100644
--- a/t/t5515/fetch.br-remote-explicit-octopus
+++ b/t/t5515/fetch.br-remote-explicit-octopus
@@ -1,7 +1,7 @@
# br-remote-explicit-octopus
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
diff --git a/t/t5515/fetch.br-remote-explicit-octopus_remote-explicit b/t/t5515/fetch.br-remote-explicit-octopus_remote-explicit
index 4c896cfc1a..3546a83713 100644
--- a/t/t5515/fetch.br-remote-explicit-octopus_remote-explicit
+++ b/t/t5515/fetch.br-remote-explicit-octopus_remote-explicit
@@ -1,7 +1,7 @@
# br-remote-explicit-octopus remote-explicit
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
diff --git a/t/t5515/fetch.br-remote-glob-merge b/t/t5515/fetch.br-remote-glob-merge
index 4b62b01de4..7e1a433a64 100644
--- a/t/t5515/fetch.br-remote-glob-merge
+++ b/t/t5515/fetch.br-remote-glob-merge
@@ -1,7 +1,7 @@
# br-remote-glob-merge
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
diff --git a/t/t5515/fetch.br-remote-glob-merge_remote-glob b/t/t5515/fetch.br-remote-glob-merge_remote-glob
index 7478f1f158..53571bb4ec 100644
--- a/t/t5515/fetch.br-remote-glob-merge_remote-glob
+++ b/t/t5515/fetch.br-remote-glob-merge_remote-glob
@@ -1,7 +1,7 @@
# br-remote-glob-merge remote-glob
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge branch 'one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b branch 'three' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 not-for-merge branch 'two' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
diff --git a/t/t5515/fetch.br-remote-glob-octopus b/t/t5515/fetch.br-remote-glob-octopus
index 2543420581..c7c8b6d7f4 100644
--- a/t/t5515/fetch.br-remote-glob-octopus
+++ b/t/t5515/fetch.br-remote-glob-octopus
@@ -1,8 +1,8 @@
# br-remote-glob-octopus
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5515/fetch.br-remote-glob-octopus_remote-glob b/t/t5515/fetch.br-remote-glob-octopus_remote-glob
index 5ffde9c03c..36076fba0c 100644
--- a/t/t5515/fetch.br-remote-glob-octopus_remote-glob
+++ b/t/t5515/fetch.br-remote-glob-octopus_remote-glob
@@ -1,8 +1,8 @@
# br-remote-glob-octopus remote-glob
-754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 branch 'one' of ../
-0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 branch 'two' of ../
+754b754407bf032e9a2f9d5a9ad05ca79a6b228f not-for-merge branch 'master' of ../
+0567da4d5edd2ff4bb292a465ba9e64dcad9536b not-for-merge branch 'three' of ../
6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 not-for-merge tag 'tag-master' of ../
8e32a6d901327a23ef831511badce7bf3bf46689 not-for-merge tag 'tag-one' of ../
22feea448b023a2d864ef94b013735af34d238ba not-for-merge tag 'tag-one-tree' of ../
diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh
index c229fe68f1..9ee52cfc45 100755
--- a/t/t5523-push-upstream.sh
+++ b/t/t5523-push-upstream.sh
@@ -108,4 +108,11 @@ test_expect_failure TTY 'push --no-progress suppresses progress' '
! grep "Writing objects" err
'
+test_expect_success TTY 'quiet push' '
+ ensure_fresh_upstream &&
+
+ test_terminal git push --quiet --no-progress upstream master 2>&1 | tee output &&
+ test_cmp /dev/null output
+'
+
test_done
diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh
index a73c82635f..d66ed24508 100755
--- a/t/t5541-http-push.sh
+++ b/t/t5541-http-push.sh
@@ -14,6 +14,7 @@ fi
ROOT_PATH="$PWD"
LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5541'}
. "$TEST_DIRECTORY"/lib-httpd.sh
+. "$TEST_DIRECTORY"/lib-terminal.sh
start_httpd
test_expect_success 'setup remote repository' '
@@ -95,6 +96,32 @@ test_expect_success 'create and delete remote branch' '
test_must_fail git show-ref --verify refs/remotes/origin/dev
'
+cat >"$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update" <<EOF
+#!/bin/sh
+exit 1
+EOF
+chmod a+x "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"
+
+cat >exp <<EOF
+remote: error: hook declined to update refs/heads/dev2
+To http://127.0.0.1:$LIB_HTTPD_PORT/smart/test_repo.git
+ ! [remote rejected] dev2 -> dev2 (hook declined)
+error: failed to push some refs to 'http://127.0.0.1:5541/smart/test_repo.git'
+EOF
+
+test_expect_success 'rejected update prints status' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ git checkout -b dev2 &&
+ : >path4 &&
+ git add path4 &&
+ test_tick &&
+ git commit -m dev2 &&
+ test_must_fail git push origin dev2 2>act &&
+ sed -e "/^remote: /s/ *$//" <act >cmp &&
+ test_cmp exp cmp
+'
+rm -f "$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git/hooks/update"
+
cat >exp <<EOF
GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200
@@ -106,6 +133,8 @@ GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
+GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200
+POST /smart/test_repo.git/git-receive-pack HTTP/1.1 200
EOF
test_expect_success 'used receive-pack service' '
sed -e "
@@ -154,5 +183,44 @@ test_expect_success 'push (chunked)' '
test $HEAD = $(git rev-parse --verify HEAD))
'
+test_expect_success 'push --all can push to empty repo' '
+ d=$HTTPD_DOCUMENT_ROOT_PATH/empty-all.git &&
+ git init --bare "$d" &&
+ git --git-dir="$d" config http.receivepack true &&
+ git push --all "$HTTPD_URL"/smart/empty-all.git
+'
+
+test_expect_success 'push --mirror can push to empty repo' '
+ d=$HTTPD_DOCUMENT_ROOT_PATH/empty-mirror.git &&
+ git init --bare "$d" &&
+ git --git-dir="$d" config http.receivepack true &&
+ git push --mirror "$HTTPD_URL"/smart/empty-mirror.git
+'
+
+test_expect_success 'push --all to repo with alternates' '
+ s=$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git &&
+ d=$HTTPD_DOCUMENT_ROOT_PATH/alternates-all.git &&
+ git clone --bare --shared "$s" "$d" &&
+ git --git-dir="$d" config http.receivepack true &&
+ git --git-dir="$d" repack -adl &&
+ git push --all "$HTTPD_URL"/smart/alternates-all.git
+'
+
+test_expect_success 'push --mirror to repo with alternates' '
+ s=$HTTPD_DOCUMENT_ROOT_PATH/test_repo.git &&
+ d=$HTTPD_DOCUMENT_ROOT_PATH/alternates-mirror.git &&
+ git clone --bare --shared "$s" "$d" &&
+ git --git-dir="$d" config http.receivepack true &&
+ git --git-dir="$d" repack -adl &&
+ git push --mirror "$HTTPD_URL"/smart/alternates-mirror.git
+'
+
+test_expect_success TTY 'quiet push' '
+ cd "$ROOT_PATH"/test_repo_clone &&
+ test_commit quiet &&
+ test_terminal git push --quiet --no-progress 2>&1 | tee output &&
+ test_cmp /dev/null output
+'
+
stop_httpd
test_done
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh
index 95a133d697..e5e6b8f643 100755
--- a/t/t5550-http-fetch.sh
+++ b/t/t5550-http-fetch.sh
@@ -162,8 +162,7 @@ test_expect_success 'http remote detects correct HEAD' '
test_expect_success 'fetch packed objects' '
cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/repo.git "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git &&
(cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git &&
- git --bare repack &&
- git --bare prune-packed
+ git --bare repack -a -d
) &&
git clone $HTTPD_URL/dumb/repo_pack.git
'
diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh
new file mode 100755
index 0000000000..7cbc9994a3
--- /dev/null
+++ b/t/t5570-git-daemon.sh
@@ -0,0 +1,148 @@
+#!/bin/sh
+
+test_description='test fetching over git protocol'
+. ./test-lib.sh
+
+LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-5570}
+. "$TEST_DIRECTORY"/lib-git-daemon.sh
+start_git_daemon
+
+test_expect_success 'setup repository' '
+ echo content >file &&
+ git add file &&
+ git commit -m one
+'
+
+test_expect_success 'create git-accessible bare repository' '
+ mkdir "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
+ (cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
+ git --bare init &&
+ : >git-daemon-export-ok
+ ) &&
+ git remote add public "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git" &&
+ git push public master:master
+'
+
+test_expect_success 'clone git repository' '
+ git clone "$GIT_DAEMON_URL/repo.git" clone &&
+ test_cmp file clone/file
+'
+
+test_expect_success 'fetch changes via git protocol' '
+ echo content >>file &&
+ git commit -a -m two &&
+ git push public &&
+ (cd clone && git pull) &&
+ test_cmp file clone/file
+'
+
+test_expect_failure 'remote detects correct HEAD' '
+ git push public master:other &&
+ (cd clone &&
+ git remote set-head -d origin &&
+ git remote set-head -a origin &&
+ git symbolic-ref refs/remotes/origin/HEAD > output &&
+ echo refs/remotes/origin/master > expect &&
+ test_cmp expect output
+ )
+'
+
+test_expect_success 'prepare pack objects' '
+ cp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git &&
+ (cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git &&
+ git --bare repack -a -d
+ )
+'
+
+test_expect_success 'fetch notices corrupt pack' '
+ cp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad1.git &&
+ (cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad1.git &&
+ p=`ls objects/pack/pack-*.pack` &&
+ chmod u+w $p &&
+ printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc
+ ) &&
+ mkdir repo_bad1.git &&
+ (cd repo_bad1.git &&
+ git --bare init &&
+ test_must_fail git --bare fetch "$GIT_DAEMON_URL/repo_bad1.git" &&
+ test 0 = `ls objects/pack/pack-*.pack | wc -l`
+ )
+'
+
+test_expect_success 'fetch notices corrupt idx' '
+ cp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
+ (cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
+ p=`ls objects/pack/pack-*.idx` &&
+ chmod u+w $p &&
+ printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc
+ ) &&
+ mkdir repo_bad2.git &&
+ (cd repo_bad2.git &&
+ git --bare init &&
+ test_must_fail git --bare fetch "$GIT_DAEMON_URL/repo_bad2.git" &&
+ test 0 = `ls objects/pack | wc -l`
+ )
+'
+
+test_remote_error()
+{
+ do_export=YesPlease
+ while test $# -gt 0
+ do
+ case $1 in
+ -x)
+ shift
+ chmod -x "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git"
+ ;;
+ -n)
+ shift
+ do_export=
+ ;;
+ *)
+ break
+ esac
+ done
+
+ if test $# -ne 3
+ then
+ error "invalid number of arguments"
+ fi
+
+ cmd=$1
+ repo=$2
+ msg=$3
+
+ if test -x "$GIT_DAEMON_DOCUMENT_ROOT_PATH/$repo"
+ then
+ if test -n "$do_export"
+ then
+ : >"$GIT_DAEMON_DOCUMENT_ROOT_PATH/$repo/git-daemon-export-ok"
+ else
+ rm -f "$GIT_DAEMON_DOCUMENT_ROOT_PATH/$repo/git-daemon-export-ok"
+ fi
+ fi
+
+ test_must_fail git "$cmd" "$GIT_DAEMON_URL/$repo" 2>output &&
+ echo "fatal: remote error: $msg: /$repo" >expect &&
+ test_cmp expect output
+ ret=$?
+ chmod +x "$GIT_DAEMON_DOCUMENT_ROOT_PATH/repo.git"
+ (exit $ret)
+}
+
+msg="access denied or repository not exported"
+test_expect_success 'clone non-existent' "test_remote_error clone nowhere.git '$msg'"
+test_expect_success 'push disabled' "test_remote_error push repo.git '$msg'"
+test_expect_success 'read access denied' "test_remote_error -x fetch repo.git '$msg'"
+test_expect_success 'not exported' "test_remote_error -n fetch repo.git '$msg'"
+
+stop_git_daemon
+start_git_daemon --informative-errors
+
+test_expect_success 'clone non-existent' "test_remote_error clone nowhere.git 'no such repository'"
+test_expect_success 'push disabled' "test_remote_error push repo.git 'service not enabled'"
+test_expect_success 'read access denied' "test_remote_error -x fetch repo.git 'no such repository'"
+test_expect_success 'not exported' "test_remote_error -n fetch repo.git 'repository not exported'"
+
+stop_git_daemon
+test_done
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 87ee01662c..67869b4813 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -9,10 +9,13 @@ test_expect_success setup '
rm -fr .git &&
test_create_repo src &&
(
- cd src
- >file
- git add file
- git commit -m initial
+ cd src &&
+ >file &&
+ git add file &&
+ git commit -m initial &&
+ echo 1 >file &&
+ git add file &&
+ git commit -m updated
)
'
@@ -88,6 +91,26 @@ test_expect_success 'clone --mirror' '
'
+test_expect_success 'clone --mirror with detached HEAD' '
+
+ ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) &&
+ git clone --mirror src mirror.detached &&
+ ( cd src && git checkout - ) &&
+ GIT_DIR=mirror.detached git rev-parse HEAD >actual &&
+ test_cmp expected actual
+
+'
+
+test_expect_success 'clone --bare with detached HEAD' '
+
+ ( cd src && git checkout HEAD^ && git rev-parse HEAD >../expected ) &&
+ git clone --bare src bare.detached &&
+ ( cd src && git checkout - ) &&
+ GIT_DIR=bare.detached git rev-parse HEAD >actual &&
+ test_cmp expected actual
+
+'
+
test_expect_success 'clone --bare names the local repository <name>.git' '
git clone --bare src &&
@@ -248,4 +271,13 @@ test_expect_success 'clone from original with relative alternate' '
grep /src/\\.git/objects target-10/objects/info/alternates
'
+test_expect_success 'clone checking out a tag' '
+ git clone --branch=some-tag src dst.tag &&
+ GIT_DIR=src/.git git rev-parse some-tag >expected &&
+ test_cmp expected dst.tag/.git/HEAD &&
+ GIT_DIR=dst.tag/.git git config remote.origin.fetch >fetch.actual &&
+ echo "+refs/heads/*:refs/remotes/origin/*" >fetch.expected &&
+ test_cmp fetch.expected fetch.actual
+'
+
test_done
diff --git a/t/t5704-bundle.sh b/t/t5704-bundle.sh
index 728ccd88c3..4ae127d106 100755
--- a/t/t5704-bundle.sh
+++ b/t/t5704-bundle.sh
@@ -53,4 +53,10 @@ test_expect_failure 'bundle --stdin <rev-list options>' '
'
+test_expect_success 'empty bundle file is rejected' '
+
+ >empty-bundle && test_must_fail git fetch empty-bundle
+
+'
+
test_done
diff --git a/t/t5706-clone-branch.sh b/t/t5706-clone-branch.sh
index f3f9a76056..56be67e07e 100755
--- a/t/t5706-clone-branch.sh
+++ b/t/t5706-clone-branch.sh
@@ -57,12 +57,8 @@ test_expect_success 'clone -b does not munge remotes/origin/HEAD' '
)
'
-test_expect_success 'clone -b with bogus branch chooses HEAD' '
- git clone -b bogus parent clone-bogus &&
- (cd clone-bogus &&
- check_HEAD master &&
- check_file one
- )
+test_expect_success 'clone -b with bogus branch' '
+ test_must_fail git clone -b bogus parent clone-bogus
'
test_done
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index d918cc02d0..444279077e 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -267,6 +267,12 @@ test_expect_success '%gd shortens ref name' '
test_cmp expect.gd-short actual.gd-short
'
+test_expect_success 'reflog identity' '
+ echo "C O Mitter:committer@example.com" >expect &&
+ git log -g -1 --format="%gn:%ge" >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'oneline with empty message' '
git commit -m "dummy" --allow-empty &&
git commit -m "dummy" --allow-empty &&
diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh
index af34a1e817..839ad97b79 100755
--- a/t/t6012-rev-list-simplify.sh
+++ b/t/t6012-rev-list-simplify.sh
@@ -86,5 +86,6 @@ check_result 'I H E C B A' --full-history --date-order -- file
check_result 'I E C B A' --simplify-merges -- file
check_result 'I B A' -- file
check_result 'I B A' --topo-order -- file
+check_result 'H' --first-parent -- another-file
test_done
diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh
index 320e1d1dbe..ff2590849d 100755
--- a/t/t7006-pager.sh
+++ b/t/t7006-pager.sh
@@ -6,11 +6,6 @@ test_description='Test automatic use of a pager.'
. "$TEST_DIRECTORY"/lib-pager.sh
. "$TEST_DIRECTORY"/lib-terminal.sh
-cleanup_fail() {
- echo >&2 cleanup failed
- (exit 1)
-}
-
test_expect_success 'setup' '
sane_unset GIT_PAGER GIT_PAGER_IN_USE &&
test_unconfig core.pager &&
@@ -22,9 +17,7 @@ test_expect_success 'setup' '
'
test_expect_success TTY 'some commands use a pager' '
- rm -f paginated.out ||
- cleanup_fail &&
-
+ rm -f paginated.out &&
test_terminal git log &&
test -e paginated.out
'
@@ -45,49 +38,37 @@ test_expect_failure TTY 'pager runs from subdir' '
'
test_expect_success TTY 'some commands do not use a pager' '
- rm -f paginated.out ||
- cleanup_fail &&
-
+ rm -f paginated.out &&
test_terminal git rev-list HEAD &&
! test -e paginated.out
'
test_expect_success 'no pager when stdout is a pipe' '
- rm -f paginated.out ||
- cleanup_fail &&
-
+ rm -f paginated.out &&
git log | cat &&
! test -e paginated.out
'
test_expect_success 'no pager when stdout is a regular file' '
- rm -f paginated.out ||
- cleanup_fail &&
-
+ rm -f paginated.out &&
git log >file &&
! test -e paginated.out
'
test_expect_success TTY 'git --paginate rev-list uses a pager' '
- rm -f paginated.out ||
- cleanup_fail &&
-
+ rm -f paginated.out &&
test_terminal git --paginate rev-list HEAD &&
test -e paginated.out
'
test_expect_success 'no pager even with --paginate when stdout is a pipe' '
- rm -f file paginated.out ||
- cleanup_fail &&
-
+ rm -f file paginated.out &&
git --paginate log | cat &&
! test -e paginated.out
'
test_expect_success TTY 'no pager with --no-pager' '
- rm -f paginated.out ||
- cleanup_fail &&
-
+ rm -f paginated.out &&
test_terminal git --no-pager log &&
! test -e paginated.out
'
@@ -136,9 +117,7 @@ colorful() {
}
test_expect_success 'tests can detect color' '
- rm -f colorful.log colorless.log ||
- cleanup_fail &&
-
+ rm -f colorful.log colorless.log &&
git log --no-color >colorless.log &&
git log --color >colorful.log &&
! colorful colorless.log &&
@@ -147,18 +126,14 @@ test_expect_success 'tests can detect color' '
test_expect_success 'no color when stdout is a regular file' '
rm -f colorless.log &&
- test_config color.ui auto ||
- cleanup_fail &&
-
+ test_config color.ui auto &&
git log >colorless.log &&
! colorful colorless.log
'
test_expect_success TTY 'color when writing to a pager' '
rm -f paginated.out &&
- test_config color.ui auto ||
- cleanup_fail &&
-
+ test_config color.ui auto &&
(
TERM=vt100 &&
export TERM &&
@@ -181,9 +156,7 @@ test_expect_success TTY 'colors are suppressed by color.pager' '
test_expect_success 'color when writing to a file intended for a pager' '
rm -f colorful.log &&
- test_config color.ui auto ||
- cleanup_fail &&
-
+ test_config color.ui auto &&
(
TERM=vt100 &&
GIT_PAGER_IN_USE=true &&
@@ -242,9 +215,7 @@ test_default_pager() {
$test_expectation SIMPLEPAGER,TTY "$cmd - default pager is used by default" "
sane_unset PAGER GIT_PAGER &&
test_unconfig core.pager &&
- rm -f default_pager_used ||
- cleanup_fail &&
-
+ rm -f default_pager_used &&
cat >\$less <<-\EOF &&
#!/bin/sh
wc >default_pager_used
@@ -265,9 +236,7 @@ test_PAGER_overrides() {
$test_expectation TTY "$cmd - PAGER overrides default pager" "
sane_unset GIT_PAGER &&
test_unconfig core.pager &&
- rm -f PAGER_used ||
- cleanup_fail &&
-
+ rm -f PAGER_used &&
PAGER='wc >PAGER_used' &&
export PAGER &&
$full_command &&
@@ -292,9 +261,7 @@ test_core_pager() {
$test_expectation TTY "$cmd - repository-local core.pager setting $used_if_wanted" "
sane_unset GIT_PAGER &&
- rm -f core.pager_used ||
- cleanup_fail &&
-
+ rm -f core.pager_used &&
PAGER=wc &&
export PAGER &&
test_config core.pager 'wc >core.pager_used' &&
@@ -321,9 +288,7 @@ test_pager_subdir_helper() {
$test_expectation TTY "$cmd - core.pager $used_if_wanted from subdirectory" "
sane_unset GIT_PAGER &&
rm -f core.pager_used &&
- rm -fr sub ||
- cleanup_fail &&
-
+ rm -fr sub &&
PAGER=wc &&
stampname=\$(pwd)/core.pager_used &&
export PAGER stampname &&
@@ -341,9 +306,7 @@ test_GIT_PAGER_overrides() {
parse_args "$@"
$test_expectation TTY "$cmd - GIT_PAGER overrides core.pager" "
- rm -f GIT_PAGER_used ||
- cleanup_fail &&
-
+ rm -f GIT_PAGER_used &&
test_config core.pager wc &&
GIT_PAGER='wc >GIT_PAGER_used' &&
export GIT_PAGER &&
@@ -356,9 +319,7 @@ test_doesnt_paginate() {
parse_args "$@"
$test_expectation TTY "no pager for '$cmd'" "
- rm -f GIT_PAGER_used ||
- cleanup_fail &&
-
+ rm -f GIT_PAGER_used &&
GIT_PAGER='wc >GIT_PAGER_used' &&
export GIT_PAGER &&
$full_command &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 33b292b8a8..5b97222c48 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -611,4 +611,12 @@ test_expect_success 'submodule update places git-dir in superprojects git-dir re
)
'
+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
+ )
+'
+
test_done
diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh
new file mode 100755
index 0000000000..1d3c56fe61
--- /dev/null
+++ b/t/t7510-signed-commit.sh
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+test_description='signed commit tests'
+. ./test-lib.sh
+. "$TEST_DIRECTORY/lib-gpg.sh"
+
+test_expect_success GPG 'create signed commits' '
+ echo 1 >file && git add file &&
+ test_tick && git commit -S -m initial &&
+ git tag initial &&
+ git branch side &&
+
+ echo 2 >file && test_tick && git commit -a -S -m second &&
+ git tag second &&
+
+ git checkout side &&
+ echo 3 >elif && git add elif &&
+ test_tick && git commit -m "third on side" &&
+
+ git checkout master &&
+ test_tick && git merge -S side &&
+ git tag merge &&
+
+ echo 4 >file && test_tick && git commit -a -m "fourth unsigned" &&
+ git tag fourth-unsigned &&
+
+ test_tick && git commit --amend -S -m "fourth signed" &&
+ git tag fourth-signed
+'
+
+test_expect_success GPG 'show signatures' '
+ (
+ for commit in initial second merge master
+ do
+ git show --pretty=short --show-signature $commit >actual &&
+ grep "Good signature from" actual || exit 1
+ ! grep "BAD signature from" actual || exit 1
+ echo $commit OK
+ done
+ ) &&
+ (
+ for commit in merge^2 fourth-unsigned
+ do
+ git show --pretty=short --show-signature $commit >actual &&
+ grep "Good signature from" actual && exit 1
+ ! grep "BAD signature from" actual || exit 1
+ echo $commit OK
+ done
+ )
+'
+
+test_expect_success GPG 'detect fudged signature' '
+ git cat-file commit master >raw &&
+
+ sed -e "s/fourth signed/4th forged/" raw >forged1 &&
+ git hash-object -w -t commit forged1 >forged1.commit &&
+ git show --pretty=short --show-signature $(cat forged1.commit) >actual1 &&
+ grep "BAD signature from" actual1 &&
+ ! grep "Good signature from" actual1
+'
+
+test_expect_success GPG 'detect fudged signature with NUL' '
+ git cat-file commit master >raw &&
+ cat raw >forged2 &&
+ echo Qwik | tr "Q" "\000" >>forged2 &&
+ git hash-object -w -t commit forged2 >forged2.commit &&
+ git show --pretty=short --show-signature $(cat forged2.commit) >actual2 &&
+ grep "BAD signature from" actual2 &&
+ ! grep "Good signature from" actual2
+'
+
+test_expect_success GPG 'amending already signed commit' '
+ git checkout fourth-signed^0 &&
+ git commit --amend -S --no-edit &&
+ git show -s --show-signature HEAD >actual &&
+ grep "Good signature from" actual &&
+ ! grep "BAD signature from" actual
+'
+
+test_done
diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh
index 4aab2a75b8..f5e16fc7db 100755
--- a/t/t7610-mergetool.sh
+++ b/t/t7610-mergetool.sh
@@ -39,6 +39,7 @@ test_expect_success 'setup' '
echo branch1 change >file1 &&
echo branch1 newfile >file2 &&
echo branch1 spaced >"spaced name" &&
+ echo branch1 both added >both &&
echo branch1 change file11 >file11 &&
echo branch1 change file13 >file13 &&
echo branch1 sub >subdir/file3 &&
@@ -50,6 +51,7 @@ test_expect_success 'setup' '
git checkout -b submod-branch1
) &&
git add file1 "spaced name" file11 file13 file2 subdir/file3 submod &&
+ git add both &&
git rm file12 &&
git commit -m "branch1 changes" &&
@@ -58,6 +60,7 @@ test_expect_success 'setup' '
echo master updated >file1 &&
echo master new >file2 &&
echo master updated spaced >"spaced name" &&
+ echo master both added >both &&
echo master updated file12 >file12 &&
echo master updated file14 >file14 &&
echo master new sub >subdir/file3 &&
@@ -69,18 +72,22 @@ test_expect_success 'setup' '
git checkout -b submod-master
) &&
git add file1 "spaced name" file12 file14 file2 subdir/file3 submod &&
+ git add both &&
git rm file11 &&
git commit -m "master updates" &&
git config merge.tool mytool &&
git config mergetool.mytool.cmd "cat \"\$REMOTE\" >\"\$MERGED\"" &&
- git config mergetool.mytool.trustExitCode true
+ git config mergetool.mytool.trustExitCode true &&
+ git config mergetool.mybase.cmd "cat \"\$BASE\" >\"\$MERGED\"" &&
+ git config mergetool.mybase.trustExitCode true
'
test_expect_success 'custom mergetool' '
git checkout -b test1 branch1 &&
git submodule update -N &&
test_must_fail git merge master >/dev/null 2>&1 &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "" | git mergetool file1 file1 ) &&
( yes "" | git mergetool file2 "spaced name" >/dev/null 2>&1 ) &&
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
@@ -101,6 +108,7 @@ test_expect_success 'mergetool crlf' '
( yes "" | git mergetool file1 >/dev/null 2>&1 ) &&
( yes "" | git mergetool file2 >/dev/null 2>&1 ) &&
( yes "" | git mergetool "spaced name" >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "" | git mergetool subdir/file3 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file12 >/dev/null 2>&1 ) &&
@@ -131,6 +139,7 @@ test_expect_success 'mergetool on file in parent dir' '
cd subdir &&
( yes "" | git mergetool ../file1 >/dev/null 2>&1 ) &&
( yes "" | git mergetool ../file2 ../spaced\ name >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool ../both >/dev/null 2>&1 ) &&
( 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 ) &&
@@ -212,6 +221,7 @@ test_expect_success 'deleted vs modified submodule' '
test_must_fail git merge master &&
test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "r" | git mergetool submod ) &&
rmdir submod && mv submod-movedaside submod &&
@@ -228,6 +238,7 @@ test_expect_success 'deleted vs modified submodule' '
test_must_fail git merge master &&
test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool submod ) &&
test ! -e submod &&
@@ -241,6 +252,7 @@ test_expect_success 'deleted vs modified submodule' '
test_must_fail git merge test6 &&
test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "r" | git mergetool submod ) &&
test ! -e submod &&
@@ -256,6 +268,7 @@ test_expect_success 'deleted vs modified submodule' '
test_must_fail git merge test6 &&
test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool submod ) &&
test "$(cat submod/bar)" = "master submodule" &&
@@ -279,6 +292,7 @@ test_expect_success 'file vs modified submodule' '
test_must_fail git merge master &&
test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "r" | git mergetool submod ) &&
rmdir submod && mv submod-movedaside submod &&
@@ -294,6 +308,7 @@ test_expect_success 'file vs modified submodule' '
test_must_fail git merge master &&
test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool submod ) &&
git submodule update -N &&
@@ -309,6 +324,7 @@ test_expect_success 'file vs modified submodule' '
test_must_fail git merge test7 &&
test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both >/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "r" | git mergetool submod ) &&
test -d submod.orig &&
@@ -324,6 +340,7 @@ test_expect_success 'file vs modified submodule' '
test_must_fail git merge test7 &&
test -n "$(git ls-files -u)" &&
( yes "" | git mergetool file1 file2 spaced\ name subdir/file3 >/dev/null 2>&1 ) &&
+ ( yes "" | git mergetool both>/dev/null 2>&1 ) &&
( yes "d" | git mergetool file11 file12 >/dev/null 2>&1 ) &&
( yes "l" | git mergetool submod ) &&
test "$(cat submod/bar)" = "master submodule" &&
@@ -445,4 +462,13 @@ test_expect_success 'directory vs modified submodule' '
git submodule update -N
'
+test_expect_success 'file with no base' '
+ git checkout -b test13 branch1 &&
+ test_must_fail git merge master &&
+ git mergetool --no-prompt --tool mybase -- both &&
+ >expected &&
+ test_cmp both expected &&
+ git reset --hard master >/dev/null 2>&1
+'
+
test_done
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 81263b7851..75f4716d8c 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -246,6 +246,28 @@ do
done
cat >expected <<EOF
+file
+EOF
+test_expect_success 'grep -l -C' '
+ git grep -l -C1 foo >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
+file:5
+EOF
+test_expect_success 'grep -l -C' '
+ git grep -c -C1 foo >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'grep -L -C' '
+ git ls-files >expected &&
+ git grep -L -C1 nonexistent_string >actual &&
+ test_cmp expected actual
+'
+
+cat >expected <<EOF
file:foo mmap bar_mmap
EOF
@@ -523,6 +545,20 @@ test_expect_success 'grep -W' '
test_cmp expected actual
'
+cat >expected <<EOF
+hello.c= printf("Hello world.\n");
+hello.c: return 0;
+hello.c- /* char ?? */
+EOF
+
+test_expect_success 'grep -W with userdiff' '
+ test_when_finished "rm -f .gitattributes" &&
+ git config diff.custom.xfuncname "(printf.*|})$" &&
+ echo "hello.c diff=custom" >.gitattributes &&
+ git grep -W return >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'grep from a subdirectory to search wider area (1)' '
mkdir -p s &&
(
diff --git a/t/t8006-blame-textconv.sh b/t/t8006-blame-textconv.sh
index 4ee42f12f0..c3c22f7764 100755
--- a/t/t8006-blame-textconv.sh
+++ b/t/t8006-blame-textconv.sh
@@ -10,7 +10,7 @@ find_blame() {
cat >helper <<'EOF'
#!/bin/sh
grep -q '^bin: ' "$1" || { echo "E: $1 is not \"binary\" file" 1>&2; exit 1; }
-sed 's/^bin: /converted: /' "$1"
+perl -p -e 's/^bin: /converted: /' "$1"
EOF
chmod +x helper
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index 41db05cb4a..518358aa64 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -19,9 +19,9 @@ then
test_done
fi
-CVSROOT=$(pwd)/cvsroot
-CVSWORK=$(pwd)/cvswork
-GIT_DIR=$(pwd)/.git
+CVSROOT=$PWD/cvsroot
+CVSWORK=$PWD/cvswork
+GIT_DIR=$PWD/.git
export CVSROOT CVSWORK GIT_DIR
rm -rf "$CVSROOT" "$CVSWORK"
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index ab24917812..0f771c673d 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -475,6 +475,14 @@ test_expect_success \
'gitweb_run "" "/.git/master:foo/"'
test_expect_success \
+ 'path_info: project/branch (non-existent)' \
+ 'gitweb_run "" "/.git/non-existent"'
+
+test_expect_success \
+ 'path_info: project/branch:filename (non-existent branch)' \
+ 'gitweb_run "" "/.git/non-existent:non-existent"'
+
+test_expect_success \
'path_info: project/branch:file (non-existent)' \
'gitweb_run "" "/.git/master:non-existent"'
diff --git a/t/t9800-git-p4.sh b/t/t9800-git-p4-basic.sh
index 272de3fea3..04ee20e642 100755
--- a/t/t9800-git-p4.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -65,6 +65,66 @@ test_expect_success 'git-p4 sync new branch' '
)
'
+test_expect_success 'clone two dirs' '
+ (
+ cd "$cli" &&
+ mkdir sub1 sub2 &&
+ echo sub1/f1 >sub1/f1 &&
+ echo sub2/f2 >sub2/f2 &&
+ p4 add sub1/f1 &&
+ p4 submit -d "sub1/f1" &&
+ p4 add sub2/f2 &&
+ p4 submit -d "sub2/f2"
+ ) &&
+ "$GITP4" clone --dest="$git" //depot/sub1 //depot/sub2 &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git ls-files >lines &&
+ test_line_count = 2 lines &&
+ git log --oneline p4/master >lines &&
+ test_line_count = 1 lines
+ )
+'
+
+test_expect_success 'clone two dirs, @all' '
+ (
+ cd "$cli" &&
+ echo sub1/f3 >sub1/f3 &&
+ p4 add sub1/f3 &&
+ p4 submit -d "sub1/f3"
+ ) &&
+ "$GITP4" clone --dest="$git" //depot/sub1@all //depot/sub2@all &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git ls-files >lines &&
+ test_line_count = 3 lines &&
+ git log --oneline p4/master >lines &&
+ test_line_count = 3 lines
+ )
+'
+
+test_expect_success 'clone two dirs, @all, conflicting files' '
+ (
+ cd "$cli" &&
+ echo sub2/f3 >sub2/f3 &&
+ p4 add sub2/f3 &&
+ p4 submit -d "sub2/f3"
+ ) &&
+ "$GITP4" clone --dest="$git" //depot/sub1@all //depot/sub2@all &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git ls-files >lines &&
+ test_line_count = 3 lines &&
+ git log --oneline p4/master >lines &&
+ test_line_count = 4 lines &&
+ echo sub2/f3 >expected &&
+ test_cmp expected f3
+ )
+'
+
test_expect_success 'exit when p4 fails to produce marshaled output' '
badp4dir="$TRASH_DIRECTORY/badp4dir" &&
mkdir "$badp4dir" &&
diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh
index a25f18d36a..d414705416 100755
--- a/t/t9801-git-p4-branch.sh
+++ b/t/t9801-git-p4-branch.sh
@@ -172,9 +172,9 @@ test_expect_success 'add simple p4 branches' '
echo file1 >file1 &&
echo file2 >file2 &&
p4 add file1 file2 &&
- p4 submit -d "branch1" &&
+ p4 submit -d "Create branch1" &&
p4 integrate //depot/branch1/... //depot/branch2/... &&
- p4 submit -d "branch2" &&
+ p4 submit -d "Integrate branch2 from branch1" &&
echo file3 >file3 &&
p4 add file3 &&
p4 submit -d "add file3 in branch1" &&
@@ -182,7 +182,7 @@ test_expect_success 'add simple p4 branches' '
echo update >>file2 &&
p4 submit -d "update file2 in branch1" &&
p4 integrate //depot/branch1/... //depot/branch3/... &&
- p4 submit -d "branch3"
+ p4 submit -d "Integrate branch3 from branch1"
)
'
@@ -203,17 +203,17 @@ test_expect_success 'git-p4 clone simple branches' '
test -f file1 &&
test -f file2 &&
test -f file3 &&
- grep -q update file2 &&
+ grep update file2 &&
git reset --hard p4/depot/branch2 &&
test -f file1 &&
test -f file2 &&
test ! -f file3 &&
- test_must_fail grep -q update file2 &&
+ ! grep update file2 &&
git reset --hard p4/depot/branch3 &&
test -f file1 &&
test -f file2 &&
test -f file3 &&
- grep -q update file2 &&
+ grep update file2 &&
cd "$cli" &&
cd branch1 &&
p4 edit file2 &&
@@ -222,7 +222,87 @@ test_expect_success 'git-p4 clone simple branches' '
cd "$git" &&
git reset --hard p4/depot/branch1 &&
"$GITP4" rebase &&
- grep -q file2_ file2
+ grep file2_ file2
+ )
+'
+
+# Create a complex branch structure in P4 depot to check if they are correctly
+# cloned. The branches are created from older changelists to check if git-p4 is
+# able to correctly detect them.
+# The final expected structure is:
+# `branch1
+# | `- file1
+# | `- file2 (updated)
+# | `- file3
+# `branch2
+# | `- file1
+# | `- file2
+# `branch3
+# | `- file1
+# | `- file2 (updated)
+# | `- file3
+# `branch4
+# | `- file1
+# | `- file2
+# `branch5
+# `- file1
+# `- file2
+# `- file3
+test_expect_success 'git-p4 add complex branches' '
+ test_when_finished cleanup_git &&
+ test_create_repo "$git" &&
+ (
+ cd "$cli" &&
+ changelist=$(p4 changes -m1 //depot/... | cut -d" " -f2) &&
+ changelist=$(($changelist - 5)) &&
+ p4 integrate //depot/branch1/...@$changelist //depot/branch4/... &&
+ p4 submit -d "Integrate branch4 from branch1@${changelist}" &&
+ changelist=$(($changelist + 2)) &&
+ p4 integrate //depot/branch1/...@$changelist //depot/branch5/... &&
+ p4 submit -d "Integrate branch5 from branch1@${changelist}"
+ )
+'
+
+# Configure branches through git-config and clone them. git-p4 will only be able
+# to clone the original structure if it is able to detect the origin changelist
+# of each branch.
+test_expect_success 'git-p4 clone complex branches' '
+ test_when_finished cleanup_git &&
+ test_create_repo "$git" &&
+ (
+ cd "$git" &&
+ git config git-p4.branchList branch1:branch2 &&
+ git config --add git-p4.branchList branch1:branch3 &&
+ git config --add git-p4.branchList branch1:branch4 &&
+ git config --add git-p4.branchList branch1:branch5 &&
+ "$GITP4" clone --dest=. --detect-branches //depot@all &&
+ git log --all --graph --decorate --stat &&
+ git reset --hard p4/depot/branch1 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ grep update file2 &&
+ git reset --hard p4/depot/branch2 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_missing file3 &&
+ ! grep update file2 &&
+ git reset --hard p4/depot/branch3 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ grep update file2 &&
+ git reset --hard p4/depot/branch4 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_missing file3 &&
+ ! grep update file2 &&
+ git reset --hard p4/depot/branch5 &&
+ test_path_is_file file1 &&
+ test_path_is_file file2 &&
+ test_path_is_file file3 &&
+ ! grep update file2 &&
+ test_path_is_missing .git/git-p4-tmp
)
'
diff --git a/t/t9803-git-shell-metachars.sh b/t/t9803-git-p4-shell-metachars.sh
index db04375a13..db670207bd 100755
--- a/t/t9803-git-shell-metachars.sh
+++ b/t/t9803-git-p4-shell-metachars.sh
@@ -57,6 +57,54 @@ test_expect_success 'deleting with shell metachars' '
)
'
+# Create a branch with a shell metachar in its name
+#
+# 1. //depot/main
+# 2. //depot/branch$3
+
+test_expect_success 'branch with shell char' '
+ test_when_finished cleanup_git &&
+ test_create_repo "$git" &&
+ (
+ cd "$cli" &&
+
+ mkdir -p main &&
+
+ echo f1 >main/f1 &&
+ p4 add main/f1 &&
+ p4 submit -d "main/f1" &&
+
+ p4 integrate //depot/main/... //depot/branch\$3/... &&
+ p4 submit -d "integrate main to branch\$3" &&
+
+ echo f1 >branch\$3/shell_char_branch_file &&
+ p4 add branch\$3/shell_char_branch_file &&
+ p4 submit -d "branch\$3/shell_char_branch_file" &&
+
+ p4 branch -i <<-EOF &&
+ Branch: branch\$3
+ View: //depot/main/... //depot/branch\$3/...
+ EOF
+
+ p4 edit main/f1 &&
+ echo "a change" >> main/f1 &&
+ p4 submit -d "a change" main/f1 &&
+
+ p4 integrate -b branch\$3 &&
+ p4 resolve -am branch\$3/... &&
+ p4 submit -d "integrate main to branch\$3" &&
+
+ cd "$git" &&
+
+ git config git-p4.branchList main:branch\$3 &&
+ "$GITP4" clone --dest=. --detect-branches //depot@all &&
+ git log --all --graph --decorate --stat &&
+ git reset --hard p4/depot/branch\$3 &&
+ test -f shell_char_branch_file &&
+ test -f f1
+ )
+'
+
test_expect_success 'kill p4d' '
kill_p4d
'
diff --git a/t/t9804-git-p4-label.sh b/t/t9804-git-p4-label.sh
new file mode 100755
index 0000000000..80d01ea438
--- /dev/null
+++ b/t/t9804-git-p4-label.sh
@@ -0,0 +1,113 @@
+test_description='git-p4 p4 label tests'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+# Basic p4 label tests.
+#
+# Note: can't have more than one label per commit - others
+# are silently discarded.
+#
+test_expect_success 'basic p4 labels' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$cli" &&
+ mkdir -p main &&
+
+ echo f1 >main/f1 &&
+ p4 add main/f1 &&
+ p4 submit -d "main/f1" &&
+
+ echo f2 >main/f2 &&
+ p4 add main/f2 &&
+ p4 submit -d "main/f2" &&
+
+ echo f3 >main/file_with_\$metachar &&
+ p4 add main/file_with_\$metachar &&
+ p4 submit -d "file with metachar" &&
+
+ p4 tag -l tag_f1_only main/f1 &&
+ p4 tag -l tag_with\$_shell_char main/... &&
+
+ echo f4 >main/f4 &&
+ p4 add main/f4 &&
+ p4 submit -d "main/f4" &&
+
+ p4 label -i <<-EOF &&
+ Label: long_label
+ Description:
+ A Label first line
+ A Label second line
+ View: //depot/...
+ EOF
+
+ p4 tag -l long_label ... &&
+
+ p4 labels ... &&
+
+ "$GITP4" clone --dest="$git" --detect-labels //depot@all &&
+ cd "$git" &&
+
+ git tag &&
+ git tag >taglist &&
+ test_line_count = 3 taglist &&
+
+ cd main &&
+ git checkout tag_tag_f1_only &&
+ ! test -f f2 &&
+ git checkout tag_tag_with\$_shell_char &&
+ test -f f1 && test -f f2 && test -f file_with_\$metachar &&
+
+ git show tag_long_label | grep -q "A Label second line"
+ )
+'
+
+# Test some label corner cases:
+#
+# - two tags on the same file; both should be available
+# - a tag that is only on one file; this kind of tag
+# cannot be imported (at least not easily).
+
+test_expect_failure 'two labels on the same changelist' '
+ test_when_finished cleanup_git &&
+ (
+ cd "$cli" &&
+ mkdir -p main &&
+
+ p4 edit main/f1 main/f2 &&
+ echo "hello world" >main/f1 &&
+ echo "not in the tag" >main/f2 &&
+ p4 submit -d "main/f[12]: testing two labels" &&
+
+ p4 tag -l tag_f1_1 main/... &&
+ p4 tag -l tag_f1_2 main/... &&
+
+ p4 labels ... &&
+
+ "$GITP4" clone --dest="$git" --detect-labels //depot@all &&
+ cd "$git" &&
+
+ git tag | grep tag_f1 &&
+ git tag | grep -q tag_f1_1 &&
+ git tag | grep -q tag_f1_2 &&
+
+ cd main &&
+
+ git checkout tag_tag_f1_1 &&
+ ls &&
+ test -f f1 &&
+
+ git checkout tag_tag_f1_2 &&
+ ls &&
+ test -f f1
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/t9805-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh
index df929e0555..df929e0555 100755
--- a/t/t9805-skip-submit-edit.sh
+++ b/t/t9805-git-p4-skip-submit-edit.sh
diff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh
new file mode 100755
index 0000000000..0571602129
--- /dev/null
+++ b/t/t9806-git-p4-options.sh
@@ -0,0 +1,170 @@
+#!/bin/sh
+
+test_description='git-p4 options'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'init depot' '
+ (
+ cd "$cli" &&
+ echo file1 >file1 &&
+ p4 add file1 &&
+ p4 submit -d "change 1" &&
+ echo file2 >file2 &&
+ p4 add file2 &&
+ p4 submit -d "change 2" &&
+ echo file3 >file3 &&
+ p4 add file3 &&
+ p4 submit -d "change 3"
+ )
+'
+
+test_expect_success 'clone no --git-dir' '
+ test_must_fail "$GITP4" clone --git-dir=xx //depot
+'
+
+test_expect_success 'clone --branch' '
+ "$GITP4" 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
+ )
+'
+
+test_expect_success 'clone --changesfile' '
+ cf="$TRASH_DIRECTORY/cf" &&
+ test_when_finished "rm \"$cf\"" &&
+ printf "1\n3\n" >"$cf" &&
+ "$GITP4" clone --changesfile="$cf" --dest="$git" //depot &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git log --oneline p4/master >lines &&
+ test_line_count = 2 lines
+ test_path_is_file file1 &&
+ test_path_is_missing file2 &&
+ test_path_is_file file3
+ )
+'
+
+test_expect_success 'clone --changesfile, @all' '
+ cf="$TRASH_DIRECTORY/cf" &&
+ test_when_finished "rm \"$cf\"" &&
+ printf "1\n3\n" >"$cf" &&
+ test_must_fail "$GITP4" clone --changesfile="$cf" --dest="$git" //depot@all
+'
+
+# imports both master and p4/master in refs/heads
+# requires --import-local on sync to find p4 refs/heads
+# does not update master on sync, just p4/master
+test_expect_success 'clone/sync --import-local' '
+ "$GITP4" clone --import-local --dest="$git" //depot@1,2 &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git log --oneline refs/heads/master >lines &&
+ test_line_count = 2 lines &&
+ git log --oneline refs/heads/p4/master >lines &&
+ test_line_count = 2 lines &&
+ test_must_fail "$GITP4" sync &&
+
+ "$GITP4" sync --import-local &&
+ git log --oneline refs/heads/master >lines &&
+ test_line_count = 2 lines &&
+ git log --oneline refs/heads/p4/master >lines &&
+ test_line_count = 3 lines
+ )
+'
+
+test_expect_success 'clone --max-changes' '
+ "$GITP4" clone --dest="$git" --max-changes 2 //depot@all &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ git log --oneline refs/heads/master >lines &&
+ test_line_count = 2 lines
+ )
+'
+
+test_expect_success 'clone --keep-path' '
+ (
+ cd "$cli" &&
+ mkdir -p sub/dir &&
+ echo f4 >sub/dir/f4 &&
+ p4 add sub/dir/f4 &&
+ p4 submit -d "change 4"
+ ) &&
+ "$GITP4" clone --dest="$git" --keep-path //depot/sub/dir@all &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test_path_is_missing f4 &&
+ test_path_is_file sub/dir/f4
+ ) &&
+ cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot/sub/dir@all &&
+ (
+ cd "$git" &&
+ test_path_is_file f4 &&
+ test_path_is_missing sub/dir/f4
+ )
+'
+
+# clone --use-client-spec must still specify a depot path
+# if given, it should rearrange files according to client spec
+# when it has view lines that match the depot path
+# XXX: should clone/sync just use the client spec exactly, rather
+# than needing depot paths?
+test_expect_success 'clone --use-client-spec' '
+ (
+ # big usage message
+ exec >/dev/null &&
+ test_must_fail "$GITP4" clone --dest="$git" --use-client-spec
+ ) &&
+ cli2="$TRASH_DIRECTORY/cli2" &&
+ mkdir -p "$cli2" &&
+ test_when_finished "rmdir \"$cli2\"" &&
+ (
+ cd "$cli2" &&
+ p4 client -i <<-EOF
+ Client: client2
+ Description: client2
+ Root: $cli2
+ View: //depot/sub/... //client2/bus/...
+ EOF
+ ) &&
+ P4CLIENT=client2 &&
+ test_when_finished cleanup_git &&
+ "$GITP4" 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
+ mkdir "$git" &&
+ (
+ cd "$git" &&
+ git init &&
+ git config git-p4.useClientSpec true &&
+ "$GITP4" sync //depot/... &&
+ git checkout -b master p4/master &&
+ test_path_is_file bus/dir/f4 &&
+ test_path_is_missing file1
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh
new file mode 100755
index 0000000000..b1f61e3db5
--- /dev/null
+++ b/t/t9807-git-p4-submit.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+test_description='git-p4 submit'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'init depot' '
+ (
+ cd "$cli" &&
+ echo file1 >file1 &&
+ p4 add file1 &&
+ p4 submit -d "change 1"
+ )
+'
+
+test_expect_success 'submit with no client dir' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ echo file2 >file2 &&
+ git add file2 &&
+ git commit -m "git commit 2" &&
+ rm -rf "$cli" &&
+ git config git-p4.skipSubmitEdit true &&
+ "$GITP4" submit
+ )
+'
+
+# make two commits, but tell it to apply only from HEAD^
+test_expect_success 'submit --origin' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ test_commit "file3" &&
+ test_commit "file4" &&
+ git config git-p4.skipSubmitEdit true &&
+ "$GITP4" submit --origin=HEAD^
+ ) &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ test_path_is_missing "file3.t" &&
+ test_path_is_file "file4.t"
+ )
+'
+
+test_expect_success 'submit with allowSubmit' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ test_commit "file5" &&
+ git config git-p4.skipSubmitEdit true &&
+ git config git-p4.allowSubmit "nobranch" &&
+ test_must_fail "$GITP4" submit &&
+ git config git-p4.allowSubmit "nobranch,master" &&
+ "$GITP4" submit
+ )
+'
+
+test_expect_success 'submit with master branch name from argv' '
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --dest="$git" //depot &&
+ (
+ cd "$git" &&
+ test_commit "file6" &&
+ git config git-p4.skipSubmitEdit true &&
+ test_must_fail "$GITP4" submit nobranch &&
+ git branch otherbranch &&
+ git reset --hard HEAD^ &&
+ test_commit "file7" &&
+ "$GITP4" submit otherbranch
+ ) &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ test_path_is_file "file6.t" &&
+ test_path_is_missing "file7.t"
+ )
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/t9807-submit.sh b/t/t9807-submit.sh
deleted file mode 100755
index 2cb724e14c..0000000000
--- a/t/t9807-submit.sh
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/bin/sh
-
-test_description='git-p4 submit'
-
-. ./lib-git-p4.sh
-
-test_expect_success 'start p4d' '
- start_p4d
-'
-
-test_expect_success 'init depot' '
- (
- cd "$cli" &&
- echo file1 >file1 &&
- p4 add file1 &&
- p4 submit -d "change 1"
- )
-'
-
-test_expect_success 'submit with no client dir' '
- test_when_finished cleanup_git &&
- "$GITP4" clone --dest="$git" //depot &&
- (
- cd "$git" &&
- echo file2 >file2 &&
- git add file2 &&
- git commit -m "git commit 2" &&
- rm -rf "$cli" &&
- git config git-p4.skipSubmitEdit true &&
- "$GITP4" submit
- )
-'
-
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
-test_done
diff --git a/t/t9808-chdir.sh b/t/t9808-git-p4-chdir.sh
index eb8cc9523e..eb8cc9523e 100755
--- a/t/t9808-chdir.sh
+++ b/t/t9808-git-p4-chdir.sh
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
new file mode 100755
index 0000000000..ae9145e307
--- /dev/null
+++ b/t/t9809-git-p4-client-view.sh
@@ -0,0 +1,683 @@
+#!/bin/sh
+
+test_description='git-p4 client view'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+#
+# Construct a client with this list of View lines
+#
+client_view() {
+ (
+ cat <<-EOF &&
+ Client: client
+ Description: client
+ Root: $cli
+ View:
+ EOF
+ for arg ; do
+ printf "\t$arg\n"
+ done
+ ) | p4 client -i
+}
+
+#
+# Verify these files exist, exactly. Caller creates
+# a list of files in file "files".
+#
+check_files_exist() {
+ ok=0 &&
+ num=${#@} &&
+ for arg ; do
+ test_path_is_file "$arg" &&
+ ok=$(($ok + 1))
+ done &&
+ test $ok -eq $num &&
+ test_line_count = $num files
+}
+
+#
+# Sync up the p4 client, make sure the given files (and only
+# those) exist.
+#
+client_verify() {
+ (
+ cd "$cli" &&
+ p4 sync &&
+ find . -type f ! -name files >files &&
+ check_files_exist "$@"
+ )
+}
+
+#
+# Make sure the named files, exactly, exist.
+#
+git_verify() {
+ (
+ cd "$git" &&
+ git ls-files >files &&
+ check_files_exist "$@"
+ )
+}
+
+# //depot
+# - dir1
+# - file11
+# - file12
+# - dir2
+# - file21
+# - file22
+test_expect_success 'init depot' '
+ (
+ cd "$cli" &&
+ for d in 1 2 ; do
+ mkdir -p dir$d &&
+ for f in 1 2 ; do
+ echo dir$d/file$d$f >dir$d/file$d$f &&
+ p4 add dir$d/file$d$f &&
+ p4 submit -d "dir$d/file$d$f"
+ done
+ done &&
+ find . -type f ! -name files >files &&
+ check_files_exist dir1/file11 dir1/file12 \
+ dir2/file21 dir2/file22
+ )
+'
+
+# double % for printf
+test_expect_success 'unsupported view wildcard %%n' '
+ client_view "//depot/%%%%1/sub/... //client/sub/%%%%1/..." &&
+ test_when_finished cleanup_git &&
+ test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
+'
+
+test_expect_success 'unsupported view wildcard *' '
+ client_view "//depot/*/bar/... //client/*/bar/..." &&
+ test_when_finished cleanup_git &&
+ test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
+'
+
+test_expect_success 'wildcard ... only supported at end of spec 1' '
+ client_view "//depot/.../file11 //client/.../file11" &&
+ test_when_finished cleanup_git &&
+ test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
+'
+
+test_expect_success 'wildcard ... only supported at end of spec 2' '
+ client_view "//depot/.../a/... //client/.../a/..." &&
+ test_when_finished cleanup_git &&
+ test_must_fail "$GITP4" clone --use-client-spec --dest="$git" //depot
+'
+
+test_expect_success 'basic map' '
+ client_view "//depot/dir1/... //client/cli1/..." &&
+ files="cli1/file11 cli1/file12" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'client view with no mappings' '
+ client_view &&
+ client_verify &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify
+'
+
+test_expect_success 'single file map' '
+ client_view "//depot/dir1/file11 //client/file11" &&
+ files="file11" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'later mapping takes precedence (entire repo)' '
+ client_view "//depot/dir1/... //client/cli1/..." \
+ "//depot/... //client/cli2/..." &&
+ files="cli2/dir1/file11 cli2/dir1/file12
+ cli2/dir2/file21 cli2/dir2/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'later mapping takes precedence (partial repo)' '
+ client_view "//depot/dir1/... //client/..." \
+ "//depot/dir2/... //client/..." &&
+ files="file21 file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+# Reading the view backwards,
+# dir2 goes to cli12
+# dir1 cannot go to cli12 since it was filled by dir2
+# dir1 also does not go to cli3, since the second rule
+# noticed that it matched, but was already filled
+test_expect_success 'depot path matching rejected client path' '
+ client_view "//depot/dir1/... //client/cli3/..." \
+ "//depot/dir1/... //client/cli12/..." \
+ "//depot/dir2/... //client/cli12/..." &&
+ files="cli12/file21 cli12/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+# since both have the same //client/..., the exclusion
+# rule keeps everything out
+test_expect_success 'exclusion wildcard, client rhs same (odd)' '
+ client_view "//depot/... //client/..." \
+ "-//depot/dir2/... //client/..." &&
+ client_verify &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify
+'
+
+test_expect_success 'exclusion wildcard, client rhs different (normal)' '
+ client_view "//depot/... //client/..." \
+ "-//depot/dir2/... //client/dir2/..." &&
+ files="dir1/file11 dir1/file12" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'exclusion single file' '
+ client_view "//depot/... //client/..." \
+ "-//depot/dir2/file22 //client/file22" &&
+ files="dir1/file11 dir1/file12 dir2/file21" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'overlay wildcard' '
+ client_view "//depot/dir1/... //client/cli/..." \
+ "+//depot/dir2/... //client/cli/...\n" &&
+ files="cli/file11 cli/file12 cli/file21 cli/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'overlay single file' '
+ client_view "//depot/dir1/... //client/cli/..." \
+ "+//depot/dir2/file21 //client/cli/file21" &&
+ files="cli/file11 cli/file12 cli/file21" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'exclusion with later inclusion' '
+ client_view "//depot/... //client/..." \
+ "-//depot/dir2/... //client/dir2/..." \
+ "//depot/dir2/... //client/dir2incl/..." &&
+ files="dir1/file11 dir1/file12 dir2incl/file21 dir2incl/file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'quotes on rhs only' '
+ client_view "//depot/dir1/... \"//client/cdir 1/...\"" &&
+ client_verify "cdir 1/file11" "cdir 1/file12" &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify "cdir 1/file11" "cdir 1/file12"
+'
+
+#
+# What happens when two files of the same name are overlayed together?
+# The last-listed file should take preference.
+#
+# //depot
+# - dir1
+# - file11
+# - file12
+# - filecollide
+# - dir2
+# - file21
+# - file22
+# - filecollide
+#
+test_expect_success 'overlay collision setup' '
+ client_view "//depot/... //client/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir1/filecollide >dir1/filecollide &&
+ p4 add dir1/filecollide &&
+ p4 submit -d dir1/filecollide &&
+ echo dir2/filecollide >dir2/filecollide &&
+ p4 add dir2/filecollide &&
+ p4 submit -d dir2/filecollide
+ )
+'
+
+test_expect_success 'overlay collision 1 to 2' '
+ client_view "//depot/dir1/... //client/..." \
+ "+//depot/dir2/... //client/..." &&
+ files="file11 file12 file21 file22 filecollide" &&
+ echo dir2/filecollide >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/filecollide &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files &&
+ test_cmp actual "$git"/filecollide
+'
+
+test_expect_failure 'overlay collision 2 to 1' '
+ client_view "//depot/dir2/... //client/..." \
+ "+//depot/dir1/... //client/..." &&
+ files="file11 file12 file21 file22 filecollide" &&
+ echo dir1/filecollide >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/filecollide &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files &&
+ test_cmp actual "$git"/filecollide
+'
+
+test_expect_success 'overlay collision delete 2' '
+ client_view "//depot/... //client/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ p4 delete dir2/filecollide &&
+ p4 submit -d "remove dir2/filecollide"
+ )
+'
+
+# no filecollide, got deleted with dir2
+test_expect_failure 'overlay collision 1 to 2, but 2 deleted' '
+ client_view "//depot/dir1/... //client/..." \
+ "+//depot/dir2/... //client/..." &&
+ files="file11 file12 file21 file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'overlay collision update 1' '
+ client_view "//depot/dir1/... //client/dir1/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ p4 open dir1/filecollide &&
+ echo dir1/filecollide update >dir1/filecollide &&
+ p4 submit -d "update dir1/filecollide"
+ )
+'
+
+# still no filecollide, dir2 still wins with the deletion even though the
+# change to dir1 is more recent
+test_expect_failure 'overlay collision 1 to 2, but 2 deleted, then 1 updated' '
+ client_view "//depot/dir1/... //client/..." \
+ "+//depot/dir2/... //client/..." &&
+ files="file11 file12 file21 file22" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files
+'
+
+test_expect_success 'overlay collision delete filecollides' '
+ client_view "//depot/... //client/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ p4 delete dir1/filecollide dir2/filecollide &&
+ p4 submit -d "remove filecollides"
+ )
+'
+
+#
+# Overlays as part of sync, rather than initial checkout:
+# 1. add a file in dir1
+# 2. sync to include it
+# 3. add same file in dir2
+# 4. sync, make sure content switches as dir2 has priority
+# 5. add another file in dir1
+# 6. sync
+# 7. add/delete same file in dir2
+# 8. sync, make sure it disappears, again dir2 wins
+# 9. cleanup
+#
+# //depot
+# - dir1
+# - file11
+# - file12
+# - colA
+# - colB
+# - dir2
+# - file21
+# - file22
+# - colA
+# - colB
+#
+test_expect_success 'overlay sync: add colA in dir1' '
+ client_view "//depot/dir1/... //client/dir1/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir1/colA >dir1/colA &&
+ p4 add dir1/colA &&
+ p4 submit -d dir1/colA
+ )
+'
+
+test_expect_success 'overlay sync: initial git checkout' '
+ client_view "//depot/dir1/... //client/..." \
+ "+//depot/dir2/... //client/..." &&
+ files="file11 file12 file21 file22 colA" &&
+ echo dir1/colA >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/colA &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files &&
+ test_cmp actual "$git"/colA
+'
+
+test_expect_success 'overlay sync: add colA in dir2' '
+ client_view "//depot/dir2/... //client/dir2/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir2/colA >dir2/colA &&
+ p4 add dir2/colA &&
+ p4 submit -d dir2/colA
+ )
+'
+
+test_expect_success 'overlay sync: colA content switch' '
+ client_view "//depot/dir1/... //client/..." \
+ "+//depot/dir2/... //client/..." &&
+ files="file11 file12 file21 file22 colA" &&
+ echo dir2/colA >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/colA &&
+ (
+ cd "$git" &&
+ "$GITP4" sync --use-client-spec &&
+ git merge --ff-only p4/master
+ ) &&
+ git_verify $files &&
+ test_cmp actual "$git"/colA
+'
+
+test_expect_success 'overlay sync: add colB in dir1' '
+ client_view "//depot/dir1/... //client/dir1/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir1/colB >dir1/colB &&
+ p4 add dir1/colB &&
+ p4 submit -d dir1/colB
+ )
+'
+
+test_expect_success 'overlay sync: colB appears' '
+ client_view "//depot/dir1/... //client/..." \
+ "+//depot/dir2/... //client/..." &&
+ files="file11 file12 file21 file22 colA colB" &&
+ echo dir1/colB >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/colB &&
+ (
+ cd "$git" &&
+ "$GITP4" sync --use-client-spec &&
+ git merge --ff-only p4/master
+ ) &&
+ git_verify $files &&
+ test_cmp actual "$git"/colB
+'
+
+test_expect_success 'overlay sync: add/delete colB in dir2' '
+ client_view "//depot/dir2/... //client/dir2/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir2/colB >dir2/colB &&
+ p4 add dir2/colB &&
+ p4 submit -d dir2/colB &&
+ p4 delete dir2/colB &&
+ p4 submit -d "delete dir2/colB"
+ )
+'
+
+test_expect_success 'overlay sync: colB disappears' '
+ client_view "//depot/dir1/... //client/..." \
+ "+//depot/dir2/... //client/..." &&
+ files="file11 file12 file21 file22 colA" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ "$GITP4" sync --use-client-spec &&
+ git merge --ff-only p4/master
+ ) &&
+ git_verify $files
+'
+
+test_expect_success 'overlay sync: cleanup' '
+ client_view "//depot/... //client/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ p4 delete dir1/colA dir2/colA dir1/colB &&
+ p4 submit -d "remove overlay sync files"
+ )
+'
+
+#
+# Overlay tests again, but swapped so dir1 has priority.
+# 1. add a file in dir1
+# 2. sync to include it
+# 3. add same file in dir2
+# 4. sync, make sure content does not switch
+# 5. add another file in dir1
+# 6. sync
+# 7. add/delete same file in dir2
+# 8. sync, make sure it is still there
+# 9. cleanup
+#
+# //depot
+# - dir1
+# - file11
+# - file12
+# - colA
+# - colB
+# - dir2
+# - file21
+# - file22
+# - colA
+# - colB
+#
+test_expect_success 'overlay sync swap: add colA in dir1' '
+ client_view "//depot/dir1/... //client/dir1/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir1/colA >dir1/colA &&
+ p4 add dir1/colA &&
+ p4 submit -d dir1/colA
+ )
+'
+
+test_expect_success 'overlay sync swap: initial git checkout' '
+ client_view "//depot/dir2/... //client/..." \
+ "+//depot/dir1/... //client/..." &&
+ files="file11 file12 file21 file22 colA" &&
+ echo dir1/colA >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/colA &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify $files &&
+ test_cmp actual "$git"/colA
+'
+
+test_expect_success 'overlay sync swap: add colA in dir2' '
+ client_view "//depot/dir2/... //client/dir2/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir2/colA >dir2/colA &&
+ p4 add dir2/colA &&
+ p4 submit -d dir2/colA
+ )
+'
+
+test_expect_failure 'overlay sync swap: colA no content switch' '
+ client_view "//depot/dir2/... //client/..." \
+ "+//depot/dir1/... //client/..." &&
+ files="file11 file12 file21 file22 colA" &&
+ echo dir1/colA >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/colA &&
+ (
+ cd "$git" &&
+ "$GITP4" sync --use-client-spec &&
+ git merge --ff-only p4/master
+ ) &&
+ git_verify $files &&
+ test_cmp actual "$git"/colA
+'
+
+test_expect_success 'overlay sync swap: add colB in dir1' '
+ client_view "//depot/dir1/... //client/dir1/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir1/colB >dir1/colB &&
+ p4 add dir1/colB &&
+ p4 submit -d dir1/colB
+ )
+'
+
+test_expect_success 'overlay sync swap: colB appears' '
+ client_view "//depot/dir2/... //client/..." \
+ "+//depot/dir1/... //client/..." &&
+ files="file11 file12 file21 file22 colA colB" &&
+ echo dir1/colB >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/colB &&
+ (
+ cd "$git" &&
+ "$GITP4" sync --use-client-spec &&
+ git merge --ff-only p4/master
+ ) &&
+ git_verify $files &&
+ test_cmp actual "$git"/colB
+'
+
+test_expect_success 'overlay sync swap: add/delete colB in dir2' '
+ client_view "//depot/dir2/... //client/dir2/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ echo dir2/colB >dir2/colB &&
+ p4 add dir2/colB &&
+ p4 submit -d dir2/colB &&
+ p4 delete dir2/colB &&
+ p4 submit -d "delete dir2/colB"
+ )
+'
+
+test_expect_failure 'overlay sync swap: colB no change' '
+ client_view "//depot/dir2/... //client/..." \
+ "+//depot/dir1/... //client/..." &&
+ files="file11 file12 file21 file22 colA colB" &&
+ echo dir1/colB >actual &&
+ client_verify $files &&
+ test_cmp actual "$cli"/colB &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ "$GITP4" sync --use-client-spec &&
+ git merge --ff-only p4/master
+ ) &&
+ git_verify $files &&
+ test_cmp actual "$cli"/colB
+'
+
+test_expect_success 'overlay sync swap: cleanup' '
+ client_view "//depot/... //client/..." &&
+ (
+ cd "$cli" &&
+ p4 sync &&
+ p4 delete dir1/colA dir2/colA dir1/colB &&
+ p4 submit -d "remove overlay sync files"
+ )
+'
+
+#
+# Rename directories to test quoting in depot-side mappings
+# //depot
+# - "dir 1"
+# - file11
+# - file12
+# - "dir 2"
+# - file21
+# - file22
+#
+test_expect_success 'rename files to introduce spaces' '
+ client_view "//depot/... //client/..." &&
+ client_verify dir1/file11 dir1/file12 \
+ dir2/file21 dir2/file22 &&
+ (
+ cd "$cli" &&
+ p4 open dir1/... &&
+ p4 move dir1/... "dir 1"/... &&
+ p4 open dir2/... &&
+ p4 move dir2/... "dir 2"/... &&
+ p4 submit -d "rename with spaces"
+ ) &&
+ client_verify "dir 1/file11" "dir 1/file12" \
+ "dir 2/file21" "dir 2/file22"
+'
+
+test_expect_success 'quotes on lhs only' '
+ client_view "\"//depot/dir 1/...\" //client/cdir1/..." &&
+ files="cdir1/file11 cdir1/file12" &&
+ client_verify $files &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ client_verify $files
+'
+
+test_expect_success 'quotes on both sides' '
+ client_view "\"//depot/dir 1/...\" \"//client/cdir 1/...\"" &&
+ client_verify "cdir 1/file11" "cdir 1/file12" &&
+ test_when_finished cleanup_git &&
+ "$GITP4" clone --use-client-spec --dest="$git" //depot &&
+ git_verify "cdir 1/file11" "cdir 1/file12"
+'
+
+test_expect_success 'kill p4d' '
+ kill_p4d
+'
+
+test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 0e932dd975..709a30067e 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -192,6 +192,7 @@ then
fi
exec 5>&1
+exec 6<&0
if test "$verbose" = "t"
then
exec 4>&2 3>&1
@@ -328,6 +329,19 @@ test_tick () {
export GIT_COMMITTER_DATE GIT_AUTHOR_DATE
}
+# Stop execution and start a shell. This is useful for debugging tests and
+# only makes sense together with "-v".
+#
+# Be sure to remove all invocations of this command before submitting.
+
+test_pause () {
+ if test "$verbose" = t; then
+ "$SHELL_PATH" <&6 >&3 2>&4
+ else
+ error >&5 "test_pause requires --verbose"
+ fi
+}
+
# Call test_commit with the arguments "<message> [<file> [<contents>]]"
#
# This will commit a file with the given contents and the given commit
@@ -475,7 +489,7 @@ test_debug () {
test_eval_ () {
# This is a separate function because some tests use
# "return" to end a test_expect_success block early.
- eval >&3 2>&4 "$*"
+ eval </dev/null >&3 2>&4 "$*"
}
test_run_ () {
diff --git a/t/test-terminal.perl b/t/test-terminal.perl
index ee01eb957e..10172aee18 100755
--- a/t/test-terminal.perl
+++ b/t/test-terminal.perl
@@ -69,6 +69,10 @@ if ($#ARGV < 1) {
}
my $master_out = new IO::Pty;
my $master_err = new IO::Pty;
+$master_out->set_raw();
+$master_err->set_raw();
+$master_out->slave->set_raw();
+$master_err->slave->set_raw();
my $pid = start_child(\@ARGV, $master_out->slave, $master_err->slave);
close $master_out->slave;
close $master_err->slave;