summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/annotate-tests.sh40
-rw-r--r--t/lib-git-p4.sh3
-rwxr-xr-xt/perf/p2000-sparse-operations.sh2
-rwxr-xr-xt/t0012-help.sh2
-rwxr-xr-xt/t0027-auto-crlf.sh8
-rwxr-xr-xt/t0033-safe-directory.sh30
-rwxr-xr-xt/t0060-path-utils.sh4
-rwxr-xr-xt/t1006-cat-file.sh10
-rwxr-xr-xt/t1011-read-tree-sparse-checkout.sh46
-rwxr-xr-xt/t1092-sparse-checkout-compatibility.sh114
-rwxr-xr-xt/t1450-fsck.sh13
-rwxr-xr-xt/t2203-add-intent.sh1
-rwxr-xr-xt/t3202-show-branch.sh14
-rwxr-xr-xt/t3416-rebase-onto-threedots.sh29
-rwxr-xr-xt/t3501-revert-cherry-pick.sh9
-rwxr-xr-xt/t4013-diff-various.sh33
-rwxr-xr-xt/t4014-format-patch.sh33
-rwxr-xr-xt/t4020-diff-external.sh8
-rwxr-xr-xt/t4202-log.sh11
-rwxr-xr-xt/t4217-log-limit.sh41
-rwxr-xr-xt/t5572-pull-submodule.sh26
-rwxr-xr-xt/t5605-clone-local.sh9
-rwxr-xr-xt/t6030-bisect-porcelain.sh28
-rwxr-xr-xt/t7011-skip-worktree-reading.sh1
-rwxr-xr-xt/t7063-status-untracked-cache.sh113
-rwxr-xr-xt/t7406-submodule-update.sh33
-rwxr-xr-xt/t7524-commit-summary.sh31
-rwxr-xr-xt/t7609-mergetool--lib.sh14
-rwxr-xr-xt/t7812-grep-icase-non-ascii.sh10
-rwxr-xr-xt/t9350-fast-export.sh7
-rwxr-xr-xt/t9800-git-p4-basic.sh85
-rwxr-xr-xt/t9801-git-p4-branch.sh10
-rwxr-xr-xt/t9802-git-p4-filetype.sh34
-rwxr-xr-xt/t9835-git-p4-metadata-encoding-python2.sh213
-rwxr-xr-xt/t9836-git-p4-metadata-encoding-python3.sh214
-rw-r--r--t/test-lib.sh6
36 files changed, 1231 insertions, 54 deletions
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh
index 09e86f9..cc01d89 100644
--- a/t/annotate-tests.sh
+++ b/t/annotate-tests.sh
@@ -56,6 +56,10 @@ check_count () {
' "$@" <actual
}
+get_progress_result () {
+ tr '\015' '\012' | tail -n 1
+}
+
test_expect_success 'setup A lines' '
echo "1A quick brown fox jumps over the" >file &&
echo "lazy dog" >>file &&
@@ -604,3 +608,39 @@ test_expect_success 'blame -L X,-N (non-numeric N)' '
test_expect_success 'blame -L ,^/RE/' '
test_must_fail $PROG -L1,^/99/ file
'
+
+test_expect_success 'blame progress on a full file' '
+ cat >expect <<-\EOF &&
+ Blaming lines: 100% (10/10), done.
+ EOF
+
+ GIT_PROGRESS_DELAY=0 \
+ git blame --progress hello.c 2>stderr &&
+
+ get_progress_result <stderr >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'blame progress on a single range' '
+ cat >expect <<-\EOF &&
+ Blaming lines: 100% (4/4), done.
+ EOF
+
+ GIT_PROGRESS_DELAY=0 \
+ git blame --progress -L 3,6 hello.c 2>stderr &&
+
+ get_progress_result <stderr >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'blame progress on multiple ranges' '
+ cat >expect <<-\EOF &&
+ Blaming lines: 100% (7/7), done.
+ EOF
+
+ GIT_PROGRESS_DELAY=0 \
+ git blame --progress -L 3,6 -L 8,10 hello.c 2>stderr &&
+
+ get_progress_result <stderr >actual &&
+ test_cmp expect actual
+'
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index 5aff2ab..2a5b873 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -142,10 +142,11 @@ start_p4d () {
p4_add_user () {
name=$1 &&
+ fullname="${2:-Dr. $1}"
p4 user -f -i <<-EOF
User: $name
Email: $name@example.com
- FullName: Dr. $name
+ FullName: $fullname
EOF
}
diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh
index 382716c..76710cb 100755
--- a/t/perf/p2000-sparse-operations.sh
+++ b/t/perf/p2000-sparse-operations.sh
@@ -106,6 +106,8 @@ test_perf_on_all () {
}
test_perf_on_all git status
+test_perf_on_all 'git stash && git stash pop'
+test_perf_on_all 'echo >>new && git stash -u && git stash pop'
test_perf_on_all git add -A
test_perf_on_all git add .
test_perf_on_all git commit -a -m A
diff --git a/t/t0012-help.sh b/t/t0012-help.sh
index 6c3e1f7..6c33a43 100755
--- a/t/t0012-help.sh
+++ b/t/t0012-help.sh
@@ -181,7 +181,7 @@ for cmd in git "git help"
do
test_expect_success "'$cmd' section spacing" '
test_section_spacing_trailer git help <<-\EOF &&
- usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
+ usage: git [-v | --version] [-h | --help] [-C <path>] [-c <name>=<value>]
These are common Git commands used in various situations:
diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index 0feb41a..7f80f46 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -77,12 +77,12 @@ create_NNO_MIX_files () {
check_warning () {
case "$1" in
- LF_CRLF) echo "warning: LF will be replaced by CRLF" >"$2".expect ;;
- CRLF_LF) echo "warning: CRLF will be replaced by LF" >"$2".expect ;;
- '') >"$2".expect ;;
+ LF_CRLF) echo "LF will be replaced by CRLF" >"$2".expect ;;
+ CRLF_LF) echo "CRLF will be replaced by LF" >"$2".expect ;;
+ '') >"$2".expect ;;
*) echo >&2 "Illegal 1": "$1" ; return false ;;
esac
- grep "will be replaced by" "$2" | sed -e "s/\(.*\) in [^ ]*$/\1/" | uniq >"$2".actual
+ sed -e "s/^.* \([^ ]* will be replaced by [^ ]*\) .*$/\1/" "$2" | uniq >"$2".actual
test_cmp "$2".expect "$2".actual
}
diff --git a/t/t0033-safe-directory.sh b/t/t0033-safe-directory.sh
index 239d93f..238b25f 100755
--- a/t/t0033-safe-directory.sh
+++ b/t/t0033-safe-directory.sh
@@ -9,13 +9,41 @@ export GIT_TEST_ASSUME_DIFFERENT_OWNER
expect_rejected_dir () {
test_must_fail git status 2>err &&
- grep "safe.directory" err
+ grep "unsafe repository" err
}
test_expect_success 'safe.directory is not set' '
expect_rejected_dir
'
+test_expect_success 'ignoring safe.directory on the command line' '
+ test_must_fail git -c safe.directory="$(pwd)" status 2>err &&
+ grep "unsafe repository" err
+'
+
+test_expect_success 'ignoring safe.directory in the environment' '
+ test_must_fail env GIT_CONFIG_COUNT=1 \
+ GIT_CONFIG_KEY_0="safe.directory" \
+ GIT_CONFIG_VALUE_0="$(pwd)" \
+ git status 2>err &&
+ grep "unsafe repository" err
+'
+
+test_expect_success 'ignoring safe.directory in GIT_CONFIG_PARAMETERS' '
+ test_must_fail env \
+ GIT_CONFIG_PARAMETERS="${SQ}safe.directory${SQ}=${SQ}$(pwd)${SQ}" \
+ git status 2>err &&
+ grep "unsafe repository" err
+'
+
+test_expect_success 'ignoring safe.directory in repo config' '
+ (
+ unset GIT_TEST_ASSUME_DIFFERENT_OWNER &&
+ git config safe.directory "$(pwd)"
+ ) &&
+ expect_rejected_dir
+'
+
test_expect_success 'safe.directory does not match' '
git config --global safe.directory bogus &&
expect_rejected_dir
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 2fe6ae6..aa35350 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -542,7 +542,7 @@ test_lazy_prereq CAN_EXEC_IN_PWD '
./git rev-parse
'
-test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' '
+test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' '
mkdir -p pretend/bin pretend/libexec/git-core &&
echo "echo HERE" | write_script pretend/libexec/git-core/git-here &&
cp "$GIT_EXEC_PATH"/git$X pretend/bin/ &&
@@ -550,7 +550,7 @@ test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' '
echo HERE >expect &&
test_cmp expect actual'
-test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' '
+test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' '
mkdir -p pretend/bin &&
cp "$GIT_EXEC_PATH"/git$X pretend/bin/ &&
git config yes.path "%(prefix)/yes" &&
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 1b85207..dadf3b1 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -681,7 +681,7 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' '
# Setup and create the empty blob and its path
empty_path=$(git rev-parse --git-path objects/$(test_oid_to_path "$EMPTY_BLOB")) &&
- git hash-object -w --stdin </dev/null &&
+ empty_blob=$(git hash-object -w --stdin </dev/null) &&
# Create another blob and its path
echo other >other.blob &&
@@ -722,7 +722,13 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' '
# content out as-is. Try to make it zlib-invalid.
mv -f other.blob "$empty_path" &&
test_must_fail git fsck 2>err.fsck &&
- grep "^error: inflate: data stream error (" err.fsck
+ cat >expect <<-EOF &&
+ error: inflate: data stream error (incorrect header check)
+ error: unable to unpack header of ./$empty_path
+ error: $empty_blob: object corrupt or missing: ./$empty_path
+ EOF
+ grep "^error: " err.fsck >actual &&
+ test_cmp expect actual
)
'
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index dd957be..63a553d 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -57,8 +57,8 @@ test_expect_success 'read-tree with .git/info/sparse-checkout but disabled' '
read_tree_u_must_succeed -m -u HEAD &&
git ls-files -t >result &&
test_cmp expected.swt result &&
- test -f init.t &&
- test -f sub/added
+ test_path_is_file init.t &&
+ test_path_is_file sub/added
'
test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-checkout and enabled' '
@@ -67,8 +67,8 @@ test_expect_success 'read-tree --no-sparse-checkout with empty .git/info/sparse-
read_tree_u_must_succeed --no-sparse-checkout -m -u HEAD &&
git ls-files -t >result &&
test_cmp expected.swt result &&
- test -f init.t &&
- test -f sub/added
+ test_path_is_file init.t &&
+ test_path_is_file sub/added
'
test_expect_success 'read-tree with empty .git/info/sparse-checkout' '
@@ -85,8 +85,8 @@ test_expect_success 'read-tree with empty .git/info/sparse-checkout' '
S subsub/added
EOF
test_cmp expected.swt result &&
- ! test -f init.t &&
- ! test -f sub/added
+ test_path_is_missing init.t &&
+ test_path_is_missing sub/added
'
test_expect_success 'match directories with trailing slash' '
@@ -101,8 +101,8 @@ test_expect_success 'match directories with trailing slash' '
read_tree_u_must_succeed -m -u HEAD &&
git ls-files -t > result &&
test_cmp expected.swt-noinit result &&
- test ! -f init.t &&
- test -f sub/added
+ test_path_is_missing init.t &&
+ test_path_is_file sub/added
'
test_expect_success 'match directories without trailing slash' '
@@ -110,8 +110,8 @@ test_expect_success 'match directories without trailing slash' '
read_tree_u_must_succeed -m -u HEAD &&
git ls-files -t >result &&
test_cmp expected.swt-noinit result &&
- test ! -f init.t &&
- test -f sub/added
+ test_path_is_missing init.t &&
+ test_path_is_file sub/added
'
test_expect_success 'match directories with negated patterns' '
@@ -129,9 +129,9 @@ EOF
git read-tree -m -u HEAD &&
git ls-files -t >result &&
test_cmp expected.swt-negation result &&
- test ! -f init.t &&
- test ! -f sub/added &&
- test -f sub/addedtoo
+ test_path_is_missing init.t &&
+ test_path_is_missing sub/added &&
+ test_path_is_file sub/addedtoo
'
test_expect_success 'match directories with negated patterns (2)' '
@@ -150,9 +150,9 @@ EOF
git read-tree -m -u HEAD &&
git ls-files -t >result &&
test_cmp expected.swt-negation2 result &&
- test -f init.t &&
- test -f sub/added &&
- test ! -f sub/addedtoo
+ test_path_is_file init.t &&
+ test_path_is_file sub/added &&
+ test_path_is_missing sub/addedtoo
'
test_expect_success 'match directory pattern' '
@@ -160,8 +160,8 @@ test_expect_success 'match directory pattern' '
read_tree_u_must_succeed -m -u HEAD &&
git ls-files -t >result &&
test_cmp expected.swt-noinit result &&
- test ! -f init.t &&
- test -f sub/added
+ test_path_is_missing init.t &&
+ test_path_is_file sub/added
'
test_expect_success 'checkout area changes' '
@@ -176,15 +176,15 @@ test_expect_success 'checkout area changes' '
read_tree_u_must_succeed -m -u HEAD &&
git ls-files -t >result &&
test_cmp expected.swt-nosub result &&
- test -f init.t &&
- test ! -f sub/added
+ test_path_is_file init.t &&
+ test_path_is_missing sub/added
'
test_expect_success 'read-tree updates worktree, absent case' '
echo sub/added >.git/info/sparse-checkout &&
git checkout -f top &&
read_tree_u_must_succeed -m -u HEAD^ &&
- test ! -f init.t
+ test_path_is_missing init.t
'
test_expect_success 'read-tree will not throw away dirty changes, non-sparse' '
@@ -229,7 +229,7 @@ test_expect_success 'read-tree adds to worktree, absent case' '
echo init.t >.git/info/sparse-checkout &&
git checkout -f removed &&
read_tree_u_must_succeed -u -m HEAD^ &&
- test ! -f sub/added
+ test_path_is_missing sub/added
'
test_expect_success 'read-tree adds to worktree, dirty case' '
@@ -248,7 +248,7 @@ test_expect_success 'index removal and worktree narrowing at the same time' '
echo init.t >.git/info/sparse-checkout &&
git checkout removed &&
git ls-files sub/added >result &&
- test ! -f sub/added &&
+ test_path_is_missing sub/added &&
test_must_be_empty result
'
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index 236ab53..6f778cf 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -1034,6 +1034,55 @@ test_expect_success 'cherry-pick with conflicts' '
test_all_match test_must_fail git cherry-pick to-cherry-pick
'
+test_expect_success 'stash' '
+ init_repos &&
+
+ write_script edit-contents <<-\EOF &&
+ echo text >>$1
+ EOF
+
+ # Stash a sparse directory (folder1)
+ test_all_match git checkout -b test-branch rename-base &&
+ test_all_match git reset --soft rename-out-to-out &&
+ test_all_match git stash &&
+ test_all_match git status --porcelain=v2 &&
+
+ # Apply the sparse directory stash without reinstating the index
+ test_all_match git stash apply -q &&
+ test_all_match git status --porcelain=v2 &&
+
+ # Reset to state where stash can be applied
+ test_sparse_match git sparse-checkout reapply &&
+ test_all_match git reset --hard rename-out-to-out &&
+
+ # Apply the sparse directory stash *with* reinstating the index
+ test_all_match git stash apply --index -q &&
+ test_all_match git status --porcelain=v2 &&
+
+ # Reset to state where we will get a conflict applying the stash
+ test_sparse_match git sparse-checkout reapply &&
+ test_all_match git reset --hard update-folder1 &&
+
+ # Apply the sparse directory stash with conflicts
+ test_all_match test_must_fail git stash apply --index -q &&
+ test_all_match test_must_fail git stash apply -q &&
+ test_all_match git status --porcelain=v2 &&
+
+ # Reset to base branch
+ test_sparse_match git sparse-checkout reapply &&
+ test_all_match git reset --hard base &&
+
+ # Stash & unstash an untracked file outside of the sparse checkout
+ # definition.
+ run_on_sparse mkdir -p folder1 &&
+ run_on_all ../edit-contents folder1/new &&
+ test_all_match git stash -u &&
+ test_all_match git status --porcelain=v2 &&
+
+ test_all_match git stash pop -q &&
+ test_all_match git status --porcelain=v2
+'
+
test_expect_success 'checkout-index inside sparse definition' '
init_repos &&
@@ -1151,6 +1200,33 @@ test_expect_success 'clean' '
test_sparse_match test_path_is_dir folder1
'
+for builtin in show rev-parse
+do
+ test_expect_success "$builtin (cached blobs/trees)" "
+ init_repos &&
+
+ test_all_match git $builtin :a &&
+ test_all_match git $builtin :deep/a &&
+ test_sparse_match git $builtin :folder1/a &&
+
+ # The error message differs depending on whether
+ # the directory exists in the worktree.
+ test_all_match test_must_fail git $builtin :deep/ &&
+ test_must_fail git -C full-checkout $builtin :folder1/ &&
+ test_sparse_match test_must_fail git $builtin :folder1/ &&
+
+ # Change the sparse cone for an extra case:
+ run_on_sparse git sparse-checkout set deep/deeper1 &&
+
+ # deep/deeper2 is a sparse directory in the sparse index.
+ test_sparse_match test_must_fail git $builtin :deep/deeper2/ &&
+
+ # deep/deeper2/deepest is not in the sparse index, but
+ # will trigger an index expansion.
+ test_sparse_match test_must_fail git $builtin :deep/deeper2/deepest/
+ "
+done
+
test_expect_success 'submodule handling' '
init_repos &&
@@ -1222,7 +1298,10 @@ test_expect_success 'index.sparse disabled inline uses full index' '
ensure_not_expanded () {
rm -f trace2.txt &&
- echo >>sparse-index/untracked.txt &&
+ if test -z "$WITHOUT_UNTRACKED_TXT"
+ then
+ echo >>sparse-index/untracked.txt
+ fi &&
if test "$1" = "!"
then
@@ -1326,6 +1405,30 @@ test_expect_success 'sparse-index is not expanded: merge conflict in cone' '
)
'
+test_expect_success 'sparse-index is not expanded: stash' '
+ init_repos &&
+
+ echo >>sparse-index/a &&
+ ensure_not_expanded stash &&
+ ensure_not_expanded stash list &&
+ ensure_not_expanded stash show stash@{0} &&
+ ensure_not_expanded stash apply stash@{0} &&
+ ensure_not_expanded stash drop stash@{0} &&
+
+ echo >>sparse-index/deep/new &&
+ ensure_not_expanded stash -u &&
+ (
+ WITHOUT_UNTRACKED_TXT=1 &&
+ ensure_not_expanded stash pop
+ ) &&
+
+ ensure_not_expanded stash create &&
+ oid=$(git -C sparse-index stash create) &&
+ ensure_not_expanded stash store -m "test" $oid &&
+ ensure_not_expanded reset --hard &&
+ ensure_not_expanded stash pop
+'
+
test_expect_success 'sparse index is not expanded: diff' '
init_repos &&
@@ -1372,6 +1475,15 @@ test_expect_success 'sparse index is not expanded: diff' '
ensure_not_expanded diff --cached
'
+test_expect_success 'sparse index is not expanded: show and rev-parse' '
+ init_repos &&
+
+ ensure_not_expanded show :a &&
+ ensure_not_expanded show :deep/a &&
+ ensure_not_expanded rev-parse :a &&
+ ensure_not_expanded rev-parse :deep/a
+'
+
test_expect_success 'sparse index is not expanded: update-index' '
init_repos &&
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index de50c0e..ab7f31f 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -774,10 +774,19 @@ test_expect_success 'fsck finds problems in duplicate loose objects' '
# no "-d" here, so we end up with duplicates
git repack &&
# now corrupt the loose copy
- file=$(sha1_file "$(git rev-parse HEAD)") &&
+ oid="$(git rev-parse HEAD)" &&
+ file=$(sha1_file "$oid") &&
rm "$file" &&
echo broken >"$file" &&
- test_must_fail git fsck
+ test_must_fail git fsck 2>err &&
+
+ cat >expect <<-EOF &&
+ error: inflate: data stream error (incorrect header check)
+ error: unable to unpack header of $file
+ error: $oid: object corrupt or missing: $file
+ EOF
+ grep "^error: " err >actual &&
+ test_cmp expect actual
)
'
diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh
index db7ca55..ebf58db 100755
--- a/t/t2203-add-intent.sh
+++ b/t/t2203-add-intent.sh
@@ -2,6 +2,7 @@
test_description='Intent to add'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
test_expect_success 'intent to add' '
diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh
index 7a1be73..f2b9199 100755
--- a/t/t3202-show-branch.sh
+++ b/t/t3202-show-branch.sh
@@ -161,4 +161,18 @@ test_expect_success 'show branch --reflog=2' '
test_cmp actual expect
'
+# incompatible options
+while read combo
+do
+ test_expect_success "show-branch $combo (should fail)" '
+ test_must_fail git show-branch $combo 2>error &&
+ grep -e "cannot be used together" -e "usage:" error
+ '
+done <<\EOF
+--all --reflog
+--merge-base --reflog
+--list --merge-base
+--reflog --current
+EOF
+
test_done
diff --git a/t/t3416-rebase-onto-threedots.sh b/t/t3416-rebase-onto-threedots.sh
index 3716a42..3e04802 100755
--- a/t/t3416-rebase-onto-threedots.sh
+++ b/t/t3416-rebase-onto-threedots.sh
@@ -129,6 +129,20 @@ test_expect_success 'rebase --keep-base main from topic' '
test_cmp expect actual
'
+test_expect_success 'rebase --keep-base main topic from main' '
+ git checkout main &&
+ git branch -f topic G &&
+
+ git rebase --keep-base main topic &&
+ git rev-parse C >base.expect &&
+ git merge-base main HEAD >base.actual &&
+ test_cmp base.expect base.actual &&
+
+ git rev-parse HEAD~2 >actual &&
+ git rev-parse C^0 >expect &&
+ test_cmp expect actual
+'
+
test_expect_success 'rebase --keep-base main from side' '
git reset --hard &&
git checkout side &&
@@ -153,6 +167,21 @@ test_expect_success 'rebase -i --keep-base main from topic' '
test_cmp expect actual
'
+test_expect_success 'rebase -i --keep-base main topic from main' '
+ git checkout main &&
+ git branch -f topic G &&
+
+ set_fake_editor &&
+ EXPECT_COUNT=2 git rebase -i --keep-base main topic &&
+ git rev-parse C >base.expect &&
+ git merge-base main HEAD >base.actual &&
+ test_cmp base.expect base.actual &&
+
+ git rev-parse HEAD~2 >actual &&
+ git rev-parse C^0 >expect &&
+ test_cmp expect actual
+'
+
test_expect_success 'rebase -i --keep-base main from side' '
git reset --hard &&
git checkout side &&
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 8617efa..9eb1920 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -66,8 +66,7 @@ test_expect_success 'cherry-pick after renaming branch' '
git checkout rename2 &&
git cherry-pick added &&
- test $(git rev-parse HEAD^) = $(git rev-parse rename2) &&
- test -f opos &&
+ test_cmp_rev rename2 HEAD^ &&
grep "Add extra line at the end" opos &&
git reflog -1 | grep cherry-pick
@@ -77,9 +76,9 @@ test_expect_success 'revert after renaming branch' '
git checkout rename1 &&
git revert added &&
- test $(git rev-parse HEAD^) = $(git rev-parse rename1) &&
- test -f spoo &&
- ! grep "Add extra line at the end" spoo &&
+ test_cmp_rev rename1 HEAD^ &&
+ test_path_is_file spoo &&
+ test_cmp_rev initial:oops HEAD:spoo &&
git reflog -1 | grep revert
'
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 750aee1..056e922 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -542,6 +542,39 @@ test_expect_success 'diff-tree --stdin with log formatting' '
test_cmp expect actual
'
+test_expect_success 'diff-tree --stdin with pathspec' '
+ cat >expect <<-EOF &&
+ Third
+
+ dir/sub
+ Second
+
+ dir/sub
+ EOF
+ git rev-list master^ |
+ git diff-tree -r --stdin --name-only --format=%s dir >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'show A B ... -- <pathspec>' '
+ # side touches dir/sub, file0, and file3
+ # master^ touches dir/sub, and file1
+ # master^^ touches dir/sub, file0, and file2
+ git show --name-only --format="<%s>" side master^ master^^ -- dir >actual &&
+ cat >expect <<-\EOF &&
+ <Side>
+
+ dir/sub
+ <Third>
+
+ dir/sub
+ <Second>
+
+ dir/sub
+ EOF
+ test_cmp expect actual
+'
+
test_expect_success 'diff -I<regex>: setup' '
git checkout master &&
test_seq 50 >file0 &&
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index 7dc5a5c..fbec8ad 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -926,11 +926,40 @@ test_expect_success 'format-patch --numstat should produce a patch' '
'
test_expect_success 'format-patch -- <path>' '
- git format-patch main..side -- file 2>error &&
- ! grep "Use .--" error
+ rm -f *.patch &&
+ git checkout -b pathspec main &&
+
+ echo file_a 1 >file_a &&
+ echo file_b 1 >file_b &&
+ git add file_a file_b &&
+ git commit -m pathspec_initial &&
+
+ echo file_a 2 >>file_a &&
+ git add file_a &&
+ git commit -m pathspec_a &&
+
+ echo file_b 2 >>file_b &&
+ git add file_b &&
+ git commit -m pathspec_b &&
+
+ echo file_a 3 >>file_a &&
+ echo file_b 3 >>file_b &&
+ git add file_a file_b &&
+ git commit -m pathspec_ab &&
+
+ cat >expect <<-\EOF &&
+ 0001-pathspec_initial.patch
+ 0002-pathspec_a.patch
+ 0003-pathspec_ab.patch
+ EOF
+
+ git format-patch main..pathspec -- file_a >output &&
+ test_cmp expect output &&
+ ! grep file_b *.patch
'
test_expect_success 'format-patch --ignore-if-in-upstream HEAD' '
+ git checkout side &&
git format-patch --ignore-if-in-upstream HEAD
'
diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh
index 1219f8b..858a552 100755
--- a/t/t4020-diff-external.sh
+++ b/t/t4020-diff-external.sh
@@ -206,17 +206,17 @@ test_expect_success 'GIT_EXTERNAL_DIFF path counter/total' '
'
test_expect_success 'GIT_EXTERNAL_DIFF generates pretty paths' '
+ test_when_finished "git rm -f file.ext" &&
touch file.ext &&
git add file.ext &&
echo with extension > file.ext &&
cat >expect <<-EOF &&
- file.ext file $(git rev-parse --verify HEAD:file) 100644 file.ext $(test_oid zero) 100644
+ file.ext
EOF
GIT_EXTERNAL_DIFF=echo git diff file.ext >out &&
- cut -d" " -f1,3- <out >actual &&
- git update-index --force-remove file.ext &&
- rm file.ext
+ basename $(cut -d" " -f2 <out) >actual &&
+ test_cmp expect actual
'
echo "#!$SHELL_PATH" >fake-diff.sh
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index be07407..6e66352 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -1992,10 +1992,13 @@ test_expect_success GPG 'log --show-signature for merged tag with GPG failure' '
git tag -s -m signed_tag_msg signed_tag_fail &&
git checkout plain-fail &&
git merge --no-ff -m msg signed_tag_fail &&
- TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual &&
- grep "^merged tag" actual &&
- grep "^No signature" actual &&
- ! grep "^gpg: Signature made" actual
+ if ! test_have_prereq VALGRIND
+ then
+ TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual &&
+ grep "^merged tag" actual &&
+ grep "^No signature" actual &&
+ ! grep "^gpg: Signature made" actual
+ fi
'
test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' '
diff --git a/t/t4217-log-limit.sh b/t/t4217-log-limit.sh
new file mode 100755
index 0000000..6e01e26
--- /dev/null
+++ b/t/t4217-log-limit.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+test_description='git log with filter options limiting the output'
+
+. ./test-lib.sh
+
+test_expect_success 'setup test' '
+ git init &&
+ echo a >file &&
+ git add file &&
+ GIT_COMMITTER_DATE="2021-02-01 00:00" git commit -m init &&
+ echo a >>file &&
+ git add file &&
+ GIT_COMMITTER_DATE="2022-02-01 00:00" git commit -m first &&
+ echo a >>file &&
+ git add file &&
+ GIT_COMMITTER_DATE="2021-03-01 00:00" git commit -m second &&
+ echo a >>file &&
+ git add file &&
+ GIT_COMMITTER_DATE="2022-03-01 00:00" git commit -m third
+'
+
+test_expect_success 'git log --since-as-filter=...' '
+ git log --since-as-filter="2022-01-01" --format=%s >actual &&
+ cat >expect <<-\EOF &&
+ third
+ first
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'git log --children --since-as-filter=...' '
+ git log --children --since-as-filter="2022-01-01" --format=%s >actual &&
+ cat >expect <<-\EOF &&
+ third
+ first
+ EOF
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t5572-pull-submodule.sh b/t/t5572-pull-submodule.sh
index fa6b4cc..a35396f 100755
--- a/t/t5572-pull-submodule.sh
+++ b/t/t5572-pull-submodule.sh
@@ -107,6 +107,32 @@ test_expect_success " --[no-]recurse-submodule and submodule.recurse" '
test_path_is_file super/sub/merge_strategy_4.t
'
+test_expect_success "fetch.recurseSubmodules option triggers recursive fetch (but not recursive update)" '
+ test_commit -C child merge_strategy_5 &&
+ # Omit the parent commit, otherwise this passes with the
+ # default "pull" behavior.
+
+ git -C super -c fetch.recursesubmodules=true pull --no-rebase &&
+ # Check that the submodule commit was fetched
+ sub_oid=$(git -C child rev-parse HEAD) &&
+ git -C super/sub cat-file -e $sub_oid &&
+ # Check that the submodule worktree did not update
+ ! test_path_is_file super/sub/merge_strategy_5.t
+'
+
+test_expect_success "fetch.recurseSubmodules takes precedence over submodule.recurse" '
+ test_commit -C child merge_strategy_6 &&
+ # Omit the parent commit, otherwise this passes with the
+ # default "pull" behavior.
+
+ git -C super -c submodule.recurse=false -c fetch.recursesubmodules=true pull --no-rebase &&
+ # Check that the submodule commit was fetched
+ sub_oid=$(git -C child rev-parse HEAD) &&
+ git -C super/sub cat-file -e $sub_oid &&
+ # Check that the submodule worktree did not update
+ ! test_path_is_file super/sub/merge_strategy_6.t
+'
+
test_expect_success 'pull --rebase --recurse-submodules (remote superproject submodule changes, local submodule changes)' '
# This tests the following scenario :
# - local submodule has new commits
diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh
index 7d63365..21ab619 100755
--- a/t/t5605-clone-local.sh
+++ b/t/t5605-clone-local.sh
@@ -141,4 +141,13 @@ test_expect_success 'cloning locally respects "-u" for fetching refs' '
test_must_fail git clone --bare -u false a should_not_work.git
'
+test_expect_success 'local clone from repo with corrupt refs fails gracefully' '
+ git init corrupt &&
+ test_commit -C corrupt one &&
+ echo a >corrupt/.git/refs/heads/topic &&
+
+ test_must_fail git clone corrupt working 2>err &&
+ grep "has a null OID" err
+'
+
test_done
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 5382e5d..83931d4 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -1025,4 +1025,32 @@ test_expect_success 'bisect visualize with a filename with dash and space' '
git bisect visualize -p -- "-hello 2"
'
+test_expect_success 'bisect state output with multiple good commits' '
+ git bisect reset &&
+ git bisect start >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect log >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect good "$HASH1" >output &&
+ grep "waiting for bad commit, 1 good commit known" output &&
+ git bisect log >output &&
+ grep "waiting for bad commit, 1 good commit known" output &&
+ git bisect good "$HASH2" >output &&
+ grep "waiting for bad commit, 2 good commits known" output &&
+ git bisect log >output &&
+ grep "waiting for bad commit, 2 good commits known" output
+'
+
+test_expect_success 'bisect state output with bad commit' '
+ git bisect reset &&
+ git bisect start >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect log >output &&
+ grep "waiting for both good and bad commits" output &&
+ git bisect bad "$HASH4" >output &&
+ grep -F "waiting for good commit(s), bad commit known" output &&
+ git bisect log >output &&
+ grep -F "waiting for good commit(s), bad commit known" output
+'
+
test_done
diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh
index 1761a2b..4adac5a 100755
--- a/t/t7011-skip-worktree-reading.sh
+++ b/t/t7011-skip-worktree-reading.sh
@@ -5,6 +5,7 @@
test_description='skip-worktree bit test'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
cat >expect.full <<EOF
diff --git a/t/t7063-status-untracked-cache.sh b/t/t7063-status-untracked-cache.sh
index ca90ee8..9936cc3 100755
--- a/t/t7063-status-untracked-cache.sh
+++ b/t/t7063-status-untracked-cache.sh
@@ -190,6 +190,119 @@ test_expect_success 'untracked cache after second status' '
test_cmp ../dump.expect ../actual
'
+cat >../status_uall.expect <<EOF &&
+A done/one
+A one
+A two
+?? dthree/three
+?? dtwo/two
+?? three
+EOF
+
+# Bypassing the untracked cache here is not desirable from an
+# end-user perspective, but is expected in the current design.
+# The untracked cache data stored for a -unormal run cannot be
+# correctly used in a -uall run - it would yield incorrect output.
+test_expect_success 'untracked cache is bypassed with -uall' '
+ : >../trace.output &&
+ GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+ git status -uall --porcelain >../actual &&
+ iuc status -uall --porcelain >../status.iuc &&
+ test_cmp ../status_uall.expect ../status.iuc &&
+ test_cmp ../status_uall.expect ../actual &&
+ get_relevant_traces ../trace.output ../trace.relevant &&
+ cat >../trace.expect <<EOF &&
+ ....path:
+EOF
+ test_cmp ../trace.expect ../trace.relevant
+'
+
+test_expect_success 'untracked cache remains after bypass' '
+ test-tool dump-untracked-cache >../actual &&
+ test_cmp ../dump.expect ../actual
+'
+
+test_expect_success 'if -uall is configured, untracked cache gets populated by default' '
+ test_config status.showuntrackedfiles all &&
+ : >../trace.output &&
+ GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+ git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
+ test_cmp ../status_uall.expect ../status.iuc &&
+ test_cmp ../status_uall.expect ../actual &&
+ get_relevant_traces ../trace.output ../trace.relevant &&
+ cat >../trace.expect <<EOF &&
+ ....path:
+ ....node-creation:3
+ ....gitignore-invalidation:1
+ ....directory-invalidation:0
+ ....opendir:4
+EOF
+ test_cmp ../trace.expect ../trace.relevant
+'
+
+cat >../dump_uall.expect <<EOF &&
+info/exclude $EMPTY_BLOB
+core.excludesfile $ZERO_OID
+exclude_per_dir .gitignore
+flags 00000000
+/ $ZERO_OID recurse valid
+three
+/done/ $ZERO_OID recurse valid
+/dthree/ $ZERO_OID recurse valid
+three
+/dtwo/ $ZERO_OID recurse valid
+two
+EOF
+
+test_expect_success 'if -uall was configured, untracked cache is populated' '
+ test-tool dump-untracked-cache >../actual &&
+ test_cmp ../dump_uall.expect ../actual
+'
+
+test_expect_success 'if -uall is configured, untracked cache is used by default' '
+ test_config status.showuntrackedfiles all &&
+ : >../trace.output &&
+ GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+ git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
+ test_cmp ../status_uall.expect ../status.iuc &&
+ test_cmp ../status_uall.expect ../actual &&
+ get_relevant_traces ../trace.output ../trace.relevant &&
+ cat >../trace.expect <<EOF &&
+ ....path:
+ ....node-creation:0
+ ....gitignore-invalidation:0
+ ....directory-invalidation:0
+ ....opendir:0
+EOF
+ test_cmp ../trace.expect ../trace.relevant
+'
+
+# Bypassing the untracked cache here is not desirable from an
+# end-user perspective, but is expected in the current design.
+# The untracked cache data stored for a -all run cannot be
+# correctly used in a -unormal run - it would yield incorrect
+# output.
+test_expect_success 'if -uall is configured, untracked cache is bypassed with -unormal' '
+ test_config status.showuntrackedfiles all &&
+ : >../trace.output &&
+ GIT_TRACE2_PERF="$TRASH_DIRECTORY/trace.output" \
+ git status -unormal --porcelain >../actual &&
+ iuc status -unormal --porcelain >../status.iuc &&
+ test_cmp ../status.expect ../status.iuc &&
+ test_cmp ../status.expect ../actual &&
+ get_relevant_traces ../trace.output ../trace.relevant &&
+ cat >../trace.expect <<EOF &&
+ ....path:
+EOF
+ test_cmp ../trace.expect ../trace.relevant
+'
+
+test_expect_success 'repopulate untracked cache for -unormal' '
+ git status --porcelain
+'
+
test_expect_success 'modify in root directory, one dir invalidation' '
: >four &&
test-tool chmtime =-240 four &&
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 000e055..43f779d 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -670,6 +670,39 @@ test_expect_success 'submodule update --init skips submodule with update=none' '
)
'
+test_expect_success 'submodule update with pathspec warns against uninitialized ones' '
+ test_when_finished "rm -fr selective" &&
+ git clone super selective &&
+ (
+ cd selective &&
+ git submodule init submodule &&
+
+ git submodule update submodule 2>err &&
+ ! grep "Submodule path .* not initialized" err &&
+
+ git submodule update rebasing 2>err &&
+ grep "Submodule path .rebasing. not initialized" err &&
+
+ test_path_exists submodule/.git &&
+ test_path_is_missing rebasing/.git
+ )
+
+'
+
+test_expect_success 'submodule update without pathspec updates only initialized ones' '
+ test_when_finished "rm -fr selective" &&
+ git clone super selective &&
+ (
+ cd selective &&
+ git submodule init submodule &&
+ git submodule update 2>err &&
+ test_path_exists submodule/.git &&
+ test_path_is_missing rebasing/.git &&
+ ! grep "Submodule path .* not initialized" err
+ )
+
+'
+
test_expect_success 'submodule update continues after checkout error' '
(cd super &&
git reset --hard HEAD &&
diff --git a/t/t7524-commit-summary.sh b/t/t7524-commit-summary.sh
new file mode 100755
index 0000000..47b2f1d
--- /dev/null
+++ b/t/t7524-commit-summary.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='git commit summary'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_seq 101 200 >file &&
+ git add file &&
+ git commit -m initial &&
+ git tag initial
+'
+
+test_expect_success 'commit summary ignores rewrites' '
+ git reset --hard initial &&
+ test_seq 200 300 >file &&
+
+ git diff --stat >diffstat &&
+ git diff --stat --break-rewrites >diffstatrewrite &&
+
+ # make sure this scenario is a detectable rewrite
+ ! test_cmp_bin diffstat diffstatrewrite &&
+
+ git add file &&
+ git commit -m second >actual &&
+
+ grep "1 file" <actual >actual.total &&
+ grep "1 file" <diffstat >diffstat.total &&
+ test_cmp diffstat.total actual.total
+'
+
+test_done
diff --git a/t/t7609-mergetool--lib.sh b/t/t7609-mergetool--lib.sh
new file mode 100755
index 0000000..d848fe6
--- /dev/null
+++ b/t/t7609-mergetool--lib.sh
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+test_description='git mergetool
+
+Testing basic merge tools options'
+
+. ./test-lib.sh
+
+test_expect_success 'mergetool --tool=vimdiff creates the expected layout' '
+ . $GIT_BUILD_DIR/mergetools/vimdiff &&
+ run_unit_tests
+'
+
+test_done
diff --git a/t/t7812-grep-icase-non-ascii.sh b/t/t7812-grep-icase-non-ascii.sh
index 9047d66..ac7be54 100755
--- a/t/t7812-grep-icase-non-ascii.sh
+++ b/t/t7812-grep-icase-non-ascii.sh
@@ -4,6 +4,10 @@ test_description='grep icase on non-English locales'
. ./lib-gettext.sh
+doalarm () {
+ perl -e 'alarm shift; exec @ARGV' -- "$@"
+}
+
test_expect_success GETTEXT_LOCALE 'setup' '
test_write_lines "TILRAUN: Halló Heimur!" >file &&
git add file &&
@@ -139,4 +143,10 @@ test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-literal ASCII fro
test_cmp expected actual
'
+test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep avoid endless loop bug' '
+ echo " Halló" >leading-whitespace &&
+ git add leading-whitespace &&
+ doalarm 1 git grep --perl-regexp "^\s" leading-whitespace
+'
+
test_done
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 7b7a18d..fc99703 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -500,6 +500,13 @@ test_expect_success 'path limiting with import-marks does not lose unmodified fi
grep file0 actual
'
+test_expect_success 'path limiting works' '
+ git fast-export simple -- file >actual &&
+ sed -ne "s/^M .* //p" <actual | sort -u >actual.files &&
+ echo file >expect &&
+ test_cmp expect actual.files
+'
+
test_expect_success 'avoid corrupt stream with non-existent mark' '
test_create_repo avoid_non_existent_mark &&
(
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 8b30062..dc88d0e 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -74,6 +74,91 @@ test_expect_success 'git p4 sync new branch' '
)
'
+#
+# Setup as before, and then explicitly sync imported branch, using a
+# different ref format.
+#
+test_expect_success 'git p4 sync existing branch without changes' '
+ test_create_repo "$git" &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test_commit head &&
+ git p4 sync --branch=depot //depot@all &&
+ git p4 sync --branch=refs/remotes/p4/depot >out &&
+ test_i18ngrep "No changes to import!" out
+ )
+'
+
+#
+# Same as before, relative branch name.
+#
+test_expect_success 'git p4 sync existing branch with relative name' '
+ test_create_repo "$git" &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test_commit head &&
+ git p4 sync --branch=branch1 //depot@all &&
+ git p4 sync --branch=p4/branch1 >out &&
+ test_i18ngrep "No changes to import!" out
+ )
+'
+
+#
+# Same as before, with a nested branch path, referenced different ways.
+#
+test_expect_success 'git p4 sync existing branch with nested path' '
+ test_create_repo "$git" &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test_commit head &&
+ git p4 sync --branch=p4/some/path //depot@all &&
+ git p4 sync --branch=some/path >out &&
+ test_i18ngrep "No changes to import!" out
+ )
+'
+
+#
+# Same as before, with a full ref path outside the p4/* namespace.
+#
+test_expect_success 'git p4 sync branch explicit ref without p4 in path' '
+ test_create_repo "$git" &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test_commit head &&
+ git p4 sync --branch=refs/remotes/someremote/depot //depot@all &&
+ git p4 sync --branch=refs/remotes/someremote/depot >out &&
+ test_i18ngrep "No changes to import!" out
+ )
+'
+
+test_expect_success 'git p4 sync nonexistent ref' '
+ test_create_repo "$git" &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test_commit head &&
+ git p4 sync --branch=depot //depot@all &&
+ test_must_fail git p4 sync --branch=depot2 2>errs &&
+ test_i18ngrep "Perhaps you never did" errs
+ )
+'
+
+test_expect_success 'git p4 sync existing non-p4-imported ref' '
+ test_create_repo "$git" &&
+ test_when_finished cleanup_git &&
+ (
+ cd "$git" &&
+ test_commit head &&
+ git p4 sync --branch=depot //depot@all &&
+ test_must_fail git p4 sync --branch=refs/heads/master 2>errs &&
+ test_i18ngrep "Perhaps you never did" errs
+ )
+'
+
test_expect_success 'clone two dirs' '
(
cd "$cli" &&
diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh
index 50a6f8b..759a14f 100755
--- a/t/t9801-git-p4-branch.sh
+++ b/t/t9801-git-p4-branch.sh
@@ -129,6 +129,16 @@ test_expect_success 'import depot, branch detection' '
)
'
+test_expect_success 'sync specific detected branch' '
+ test_when_finished cleanup_git &&
+ git p4 clone --dest="$git" --detect-branches //depot@all &&
+ (
+ cd "$git" &&
+ git p4 sync --branch=depot/branch2 >out &&
+ test_i18ngrep "No changes to import!" out
+ )
+'
+
test_expect_success 'import depot, branch detection, branchList branch definition' '
test_when_finished cleanup_git &&
test_create_repo "$git" &&
diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh
index 19073c6..2a6ee2a 100755
--- a/t/t9802-git-p4-filetype.sh
+++ b/t/t9802-git-p4-filetype.sh
@@ -333,4 +333,38 @@ test_expect_success SYMLINKS 'empty symlink target' '
)
'
+test_expect_success SYMLINKS 'utf-8 with and without BOM in text file' '
+ (
+ cd "$cli" &&
+
+ # some utf8 content
+ echo some tǣxt >utf8-nobom-test &&
+
+ # same utf8 content as before but with bom
+ echo some tǣxt | sed '\''s/^/\xef\xbb\xbf/'\'' >utf8-bom-test &&
+
+ # bom only
+ dd bs=1 count=3 if=utf8-bom-test of=utf8-bom-empty-test &&
+
+ p4 add utf8-nobom-test utf8-bom-test utf8-bom-empty-test &&
+ p4 submit -d "add utf8 test files"
+ ) &&
+ test_when_finished cleanup_git &&
+
+ git p4 clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git checkout refs/remotes/p4/master &&
+
+ echo some tǣxt >utf8-nobom-check &&
+ test_cmp utf8-nobom-check utf8-nobom-test &&
+
+ echo some tǣxt | sed '\''s/^/\xef\xbb\xbf/'\'' >utf8-bom-check &&
+ test_cmp utf8-bom-check utf8-bom-test &&
+
+ dd bs=1 count=3 if=utf8-bom-check of=utf8-bom-empty-check &&
+ test_cmp utf8-bom-empty-check utf8-bom-empty-test
+ )
+'
+
test_done
diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh
new file mode 100755
index 0000000..036bf79
--- /dev/null
+++ b/t/t9835-git-p4-metadata-encoding-python2.sh
@@ -0,0 +1,213 @@
+#!/bin/sh
+
+test_description='git p4 metadata encoding
+
+This test checks that the import process handles inconsistent text
+encoding in p4 metadata (author names, commit messages, etc) without
+failing, and produces maximally sane output in git.'
+
+. ./lib-git-p4.sh
+
+python_target_version='2'
+
+###############################
+## SECTION REPEATED IN t9836 ##
+###############################
+
+# Please note: this test calls "git-p4.py" rather than "git-p4", because the
+# latter references a specific path so we can't easily force it to run under
+# the python version we need to.
+
+python_major_version=$(python -V 2>&1 | cut -c 8)
+python_target_binary=$(which python$python_target_version)
+if ! test "$python_major_version" = "$python_target_version" && test "$python_target_binary"
+then
+ mkdir temp_python
+ PATH="$(pwd)/temp_python:$PATH" && export PATH
+ ln -s $python_target_binary temp_python/python
+fi
+
+python_major_version=$(python -V 2>&1 | cut -c 8)
+if ! test "$python_major_version" = "$python_target_version"
+then
+ skip_all="skipping python$python_target_version-specific git p4 tests; python$python_target_version not available"
+ test_done
+fi
+
+remove_user_cache () {
+ rm "$HOME/.gitp4-usercache.txt" || true
+}
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'init depot' '
+ (
+ cd "$cli" &&
+
+ p4_add_user "utf8_author" "ǣuthor" &&
+ P4USER=utf8_author &&
+ touch file1 &&
+ p4 add file1 &&
+ p4 submit -d "first CL has some utf-8 tǣxt" &&
+
+ p4_add_user "latin1_author" "$(echo æuthor |
+ iconv -f utf8 -t latin1)" &&
+ P4USER=latin1_author &&
+ touch file2 &&
+ p4 add file2 &&
+ p4 submit -d "$(echo second CL has some latin-1 tæxt |
+ iconv -f utf8 -t latin1)" &&
+
+ p4_add_user "cp1252_author" "$(echo æuthœr |
+ iconv -f utf8 -t cp1252)" &&
+ P4USER=cp1252_author &&
+ touch file3 &&
+ p4 add file3 &&
+ p4 submit -d "$(echo third CL has sœme cp-1252 tæxt |
+ iconv -f utf8 -t cp1252)" &&
+
+ p4_add_user "cp850_author" "$(echo Åuthor |
+ iconv -f utf8 -t cp850)" &&
+ P4USER=cp850_author &&
+ touch file4 &&
+ p4 add file4 &&
+ p4 submit -d "$(echo fourth CL hÅs some cp850 text |
+ iconv -f utf8 -t cp850)"
+ )
+'
+
+test_expect_success 'clone non-utf8 repo with strict encoding' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest="$git" //depot@all 2>err &&
+ grep "Decoding perforce metadata failed!" err
+'
+
+test_expect_success 'check utf-8 contents with passthrough strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "some utf-8 tǣxt" actual &&
+ grep "ǣuthor" actual
+ )
+'
+
+test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ badly_encoded_in_git=$(echo "some latin-1 tæxt" | iconv -f utf8 -t latin1) &&
+ grep "$badly_encoded_in_git" actual &&
+ bad_author_in_git="$(echo æuthor | iconv -f utf8 -t latin1)" &&
+ grep "$bad_author_in_git" actual
+ )
+'
+
+test_expect_success 'check utf-8 contents with fallback strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "some utf-8 tǣxt" actual &&
+ grep "ǣuthor" actual
+ )
+'
+
+test_expect_success 'check latin-1 contents with fallback strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "some latin-1 tæxt" actual &&
+ grep "æuthor" actual
+ )
+'
+
+test_expect_success 'check cp-1252 contents with fallback strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "sœme cp-1252 tæxt" actual &&
+ grep "æuthœr" actual
+ )
+'
+
+test_expect_success 'check cp850 contents parsed with correct fallback' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "hÅs some cp850 text" actual &&
+ grep "Åuthor" actual
+ )
+'
+
+test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "h%8Fs some cp850 text" actual &&
+ grep "%8Futhor" actual
+ )
+'
+
+test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$cli" &&
+ P4USER=cp1252_author &&
+ touch file10 &&
+ p4 add file10 &&
+ p4 submit -d "$(echo later CL has sœme more cp-1252 tæxt |
+ iconv -f utf8 -t cp1252)"
+ ) &&
+ (
+ cd "$git" &&
+
+ git p4.py sync --branch=master &&
+
+ git log p4/master >actual &&
+ grep "sœme more cp-1252 tæxt" actual &&
+ grep "æuthœr" actual
+ )
+'
+
+############################
+## / END REPEATED SECTION ##
+############################
+
+test_expect_success 'passthrough (latin-1 contents corrupted in git) is the default with python2' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ badly_encoded_in_git=$(echo "some latin-1 tæxt" | iconv -f utf8 -t latin1) &&
+ grep "$badly_encoded_in_git" actual
+ )
+'
+
+test_done
diff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh
new file mode 100755
index 0000000..63350dc
--- /dev/null
+++ b/t/t9836-git-p4-metadata-encoding-python3.sh
@@ -0,0 +1,214 @@
+#!/bin/sh
+
+test_description='git p4 metadata encoding
+
+This test checks that the import process handles inconsistent text
+encoding in p4 metadata (author names, commit messages, etc) without
+failing, and produces maximally sane output in git.'
+
+. ./lib-git-p4.sh
+
+python_target_version='3'
+
+###############################
+## SECTION REPEATED IN t9835 ##
+###############################
+
+# Please note: this test calls "git-p4.py" rather than "git-p4", because the
+# latter references a specific path so we can't easily force it to run under
+# the python version we need to.
+
+python_major_version=$(python -V 2>&1 | cut -c 8)
+python_target_binary=$(which python$python_target_version)
+if ! test "$python_major_version" = "$python_target_version" && test "$python_target_binary"
+then
+ mkdir temp_python
+ PATH="$(pwd)/temp_python:$PATH" && export PATH
+ ln -s $python_target_binary temp_python/python
+fi
+
+python_major_version=$(python -V 2>&1 | cut -c 8)
+if ! test "$python_major_version" = "$python_target_version"
+then
+ skip_all="skipping python$python_target_version-specific git p4 tests; python$python_target_version not available"
+ test_done
+fi
+
+remove_user_cache () {
+ rm "$HOME/.gitp4-usercache.txt" || true
+}
+
+test_expect_success 'start p4d' '
+ start_p4d
+'
+
+test_expect_success 'init depot' '
+ (
+ cd "$cli" &&
+
+ p4_add_user "utf8_author" "ǣuthor" &&
+ P4USER=utf8_author &&
+ touch file1 &&
+ p4 add file1 &&
+ p4 submit -d "first CL has some utf-8 tǣxt" &&
+
+ p4_add_user "latin1_author" "$(echo æuthor |
+ iconv -f utf8 -t latin1)" &&
+ P4USER=latin1_author &&
+ touch file2 &&
+ p4 add file2 &&
+ p4 submit -d "$(echo second CL has some latin-1 tæxt |
+ iconv -f utf8 -t latin1)" &&
+
+ p4_add_user "cp1252_author" "$(echo æuthœr |
+ iconv -f utf8 -t cp1252)" &&
+ P4USER=cp1252_author &&
+ touch file3 &&
+ p4 add file3 &&
+ p4 submit -d "$(echo third CL has sœme cp-1252 tæxt |
+ iconv -f utf8 -t cp1252)" &&
+
+ p4_add_user "cp850_author" "$(echo Åuthor |
+ iconv -f utf8 -t cp850)" &&
+ P4USER=cp850_author &&
+ touch file4 &&
+ p4 add file4 &&
+ p4 submit -d "$(echo fourth CL hÅs some cp850 text |
+ iconv -f utf8 -t cp850)"
+ )
+'
+
+test_expect_success 'clone non-utf8 repo with strict encoding' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest="$git" //depot@all 2>err &&
+ grep "Decoding perforce metadata failed!" err
+'
+
+test_expect_success 'check utf-8 contents with passthrough strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "some utf-8 tǣxt" actual &&
+ grep "ǣuthor" actual
+ )
+'
+
+test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ badly_encoded_in_git=$(echo "some latin-1 tæxt" | iconv -f utf8 -t latin1) &&
+ grep "$badly_encoded_in_git" actual &&
+ bad_author_in_git="$(echo æuthor | iconv -f utf8 -t latin1)" &&
+ grep "$bad_author_in_git" actual
+ )
+'
+
+test_expect_success 'check utf-8 contents with fallback strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "some utf-8 tǣxt" actual &&
+ grep "ǣuthor" actual
+ )
+'
+
+test_expect_success 'check latin-1 contents with fallback strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "some latin-1 tæxt" actual &&
+ grep "æuthor" actual
+ )
+'
+
+test_expect_success 'check cp-1252 contents with fallback strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "sœme cp-1252 tæxt" actual &&
+ grep "æuthœr" actual
+ )
+'
+
+test_expect_success 'check cp850 contents parsed with correct fallback' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "hÅs some cp850 text" actual &&
+ grep "Åuthor" actual
+ )
+'
+
+test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "h%8Fs some cp850 text" actual &&
+ grep "%8Futhor" actual
+ )
+'
+
+test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$cli" &&
+ P4USER=cp1252_author &&
+ touch file10 &&
+ p4 add file10 &&
+ p4 submit -d "$(echo later CL has sœme more cp-1252 tæxt |
+ iconv -f utf8 -t cp1252)"
+ ) &&
+ (
+ cd "$git" &&
+
+ git p4.py sync --branch=master &&
+
+ git log p4/master >actual &&
+ grep "sœme more cp-1252 tæxt" actual &&
+ grep "æuthœr" actual
+ )
+'
+
+############################
+## / END REPEATED SECTION ##
+############################
+
+
+test_expect_success 'fallback (both utf-8 and cp-1252 contents handled) is the default with python3' '
+ test_when_finished cleanup_git &&
+ test_when_finished remove_user_cache &&
+ git p4.py clone --dest="$git" //depot@all &&
+ (
+ cd "$git" &&
+ git log >actual &&
+ grep "sœme cp-1252 tæxt" actual &&
+ grep "æuthœr" actual
+ )
+'
+
+test_done
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 531cef0..8ba5ca1 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -535,9 +535,10 @@ case $GIT_TEST_FSYNC in
;;
esac
-# Add libc MALLOC and MALLOC_PERTURB test
-# only if we are not executing the test with valgrind
+# Add libc MALLOC and MALLOC_PERTURB test only if we are not executing
+# the test with valgrind and have not compiled with SANITIZE=address.
if test -n "$valgrind" ||
+ test -n "$SANITIZE_ADDRESS" ||
test -n "$TEST_NO_MALLOC_CHECK"
then
setup_malloc_check () {
@@ -1666,6 +1667,7 @@ test -n "$USE_LIBPCRE2" && test_set_prereq PCRE
test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
test -n "$SANITIZE_LEAK" && test_set_prereq SANITIZE_LEAK
+test -n "$GIT_VALGRIND_ENABLED" && test_set_prereq VALGRIND
if test -z "$GIT_TEST_CHECK_CACHE_TREE"
then