summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/lib-httpd/apache.conf3
-rwxr-xr-xt/t0001-init.sh20
-rwxr-xr-xt/t0027-auto-crlf.sh314
-rwxr-xr-xt/t1300-repo-config.sh166
-rwxr-xr-xt/t1308-config-set.sh15
-rwxr-xr-xt/t1501-work-tree.sh (renamed from t/t1501-worktree.sh)0
-rwxr-xr-xt/t1509-root-work-tree.sh (renamed from t/t1509-root-worktree.sh)0
-rwxr-xr-xt/t2019-checkout-ambiguous-ref.sh26
-rwxr-xr-xt/t2025-worktree-add.sh15
-rwxr-xr-xt/t2027-worktree-list.sh10
-rwxr-xr-xt/t3032-merge-recursive-space-options.sh (renamed from t/t3032-merge-recursive-options.sh)2
-rwxr-xr-xt/t3034-merge-recursive-rename-options.sh312
-rwxr-xr-xt/t3200-branch.sh16
-rwxr-xr-xt/t5313-pack-bounds-checks.sh179
-rwxr-xr-xt/t5504-fetch-receive-strict.sh5
-rwxr-xr-xt/t5505-remote.sh42
-rwxr-xr-xt/t5510-fetch.sh10
-rwxr-xr-xt/t6133-pathspec-rev-dwim.sh48
-rwxr-xr-xt/t6302-for-each-ref-filter.sh42
-rwxr-xr-xt/t7008-grep-binary.sh3
-rwxr-xr-xt/t7400-submodule-basic.sh38
-rwxr-xr-xt/t7409-submodule-detached-work-tree.sh (renamed from t/t7409-submodule-detached-worktree.sh)0
-rwxr-xr-xt/t8005-blame-i18n.sh28
-rwxr-xr-xt/t9108-git-svn-glob.sh9
-rwxr-xr-xt/t9109-git-svn-multi-glob.sh9
-rwxr-xr-xt/t9115-git-svn-dcommit-funky-renames.sh4
-rwxr-xr-xt/t9117-git-svn-init-clone.sh6
-rwxr-xr-xt/t9168-git-svn-partially-globbed-names.sh223
-rwxr-xr-xt/t9200-git-cvsexportcommit.sh2
-rwxr-xr-xt/t9700/test.pl8
-rw-r--r--t/test-lib-functions.sh2
31 files changed, 1339 insertions, 218 deletions
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index 7d15e6d44c..f667e7ce2f 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -64,6 +64,9 @@ LockFile accept.lock
<IfModule !mod_mpm_prefork.c>
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
</IfModule>
+<IfModule !mod_unixd.c>
+ LoadModule unixd_module modules/mod_unixd.so
+</IfModule>
</IfVersion>
PassEnv GIT_VALGRIND
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 295aa5949a..a5b9e7a4c7 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -88,19 +88,17 @@ test_expect_success 'plain nested in bare through aliased command' '
'
test_expect_success 'No extra GIT_* on alias scripts' '
- (
- env | sed -ne "/^GIT_/s/=.*//p" &&
- echo GIT_PREFIX && # setup.c
- echo GIT_TEXTDOMAINDIR # wrapper-for-bin.sh
- ) | sort | uniq >expected &&
- cat <<-\EOF >script &&
- #!/bin/sh
- env | sed -ne "/^GIT_/s/=.*//p" | sort >actual
- exit 0
+ write_script script <<-\EOF &&
+ env |
+ sed -n \
+ -e "/^GIT_PREFIX=/d" \
+ -e "/^GIT_TEXTDOMAINDIR=/d" \
+ -e "/^GIT_/s/=.*//p" |
+ sort
EOF
- chmod 755 script &&
+ ./script >expected &&
git config alias.script \!./script &&
- ( mkdir sub && cd sub && git script ) &&
+ ( mkdir sub && cd sub && git script >../actual ) &&
test_cmp expected actual
'
diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index 504e5a02a1..f33962b178 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -21,38 +21,32 @@ compare_ws_file () {
pfx=$1
exp=$2.expect
act=$pfx.actual.$3
- tr '\015\000' QN <"$2" >"$exp" &&
- tr '\015\000' QN <"$3" >"$act" &&
- test_cmp $exp $act &&
- rm $exp $act
+ tr '\015\000abcdef0123456789' QN00000000000000000 <"$2" >"$exp" &&
+ tr '\015\000abcdef0123456789' QN00000000000000000 <"$3" >"$act" &&
+ test_cmp "$exp" "$act" &&
+ rm "$exp" "$act"
}
create_gitattributes () {
- attr=$1
- case "$attr" in
- auto)
- echo "*.txt text=auto" >.gitattributes
- ;;
- text)
- echo "*.txt text" >.gitattributes
- ;;
- -text)
- echo "*.txt -text" >.gitattributes
- ;;
- crlf)
- echo "*.txt eol=crlf" >.gitattributes
- ;;
- lf)
- echo "*.txt eol=lf" >.gitattributes
- ;;
- "")
- echo >.gitattributes
- ;;
- *)
- echo >&2 invalid attribute: $attr
- exit 1
- ;;
- esac
+ {
+ while test "$#" != 0
+ do
+ case "$1" in
+ auto) echo '*.txt text=auto' ;;
+ ident) echo '*.txt ident' ;;
+ text) echo '*.txt text' ;;
+ -text) echo '*.txt -text' ;;
+ crlf) echo '*.txt eol=crlf' ;;
+ lf) echo '*.txt eol=lf' ;;
+ "") ;;
+ *)
+ echo >&2 invalid attribute: "$1"
+ exit 1
+ ;;
+ esac &&
+ shift
+ done
+ } >.gitattributes
}
create_NNO_files () {
@@ -165,6 +159,25 @@ stats_ascii () {
}
+
+# contruct the attr/ returned by git ls-files --eol
+# Take none (=empty), one or two args
+attr_ascii () {
+ case $1,$2 in
+ -text,*) echo "-text" ;;
+ text,) echo "text" ;;
+ text,lf) echo "text eol=lf" ;;
+ text,crlf) echo "text eol=crlf" ;;
+ auto,) echo "text=auto" ;;
+ auto,lf) echo "text=auto eol=lf" ;;
+ auto,crlf) echo "text=auto eol=crlf" ;;
+ lf,) echo "text eol=lf" ;;
+ crlf,) echo "text eol=crlf" ;;
+ ,) echo "" ;;
+ *) echo invalid_attr "$1,$2" ;;
+ esac
+}
+
check_files_in_repo () {
crlf=$1
attr=$2
@@ -208,55 +221,57 @@ check_in_repo_NNO () {
}
checkout_files () {
- eol=$1
- crlf=$2
- attr=$3
- lfname=$4
- crlfname=$5
- lfmixcrlf=$6
- lfmixcr=$7
- crlfnul=$8
- create_gitattributes $attr &&
+ attr=$1 ; shift
+ ident=$1; shift
+ aeol=$1 ; shift
+ crlf=$1 ; shift
+ ceol=$1 ; shift
+ lfname=$1 ; shift
+ crlfname=$1 ; shift
+ lfmixcrlf=$1 ; shift
+ lfmixcr=$1 ; shift
+ crlfnul=$1 ; shift
+ create_gitattributes "$attr" "$ident" &&
git config core.autocrlf $crlf &&
- pfx=eol_${eol}_crlf_${crlf}_attr_${attr}_ &&
+ pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ &&
for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul
do
rm crlf_false_attr__$f.txt &&
- if test -z "$eol"; then
+ if test -z "$ceol"; then
git checkout crlf_false_attr__$f.txt
else
- git -c core.eol=$eol checkout crlf_false_attr__$f.txt
+ git -c core.eol=$ceol checkout crlf_false_attr__$f.txt
fi
done
- test_expect_success "ls-files --eol $lfname ${pfx}LF.txt" '
+ test_expect_success "ls-files --eol attr=$attr $ident $aeol core.autocrlf=$crlf core.eol=$ceol" '
test_when_finished "rm expect actual" &&
sort <<-EOF >expect &&
- i/crlf w/$(stats_ascii $crlfname) crlf_false_attr__CRLF.txt
- i/mixed w/$(stats_ascii $lfmixcrlf) crlf_false_attr__CRLF_mix_LF.txt
- i/lf w/$(stats_ascii $lfname) crlf_false_attr__LF.txt
- i/-text w/$(stats_ascii $lfmixcr) crlf_false_attr__LF_mix_CR.txt
- i/-text w/$(stats_ascii $crlfnul) crlf_false_attr__CRLF_nul.txt
- i/-text w/$(stats_ascii $crlfnul) crlf_false_attr__LF_nul.txt
+ i/crlf w/$(stats_ascii $crlfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF.txt
+ i/mixed w/$(stats_ascii $lfmixcrlf) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF_mix_LF.txt
+ i/lf w/$(stats_ascii $lfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF.txt
+ i/-text w/$(stats_ascii $lfmixcr) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF_mix_CR.txt
+ i/-text w/$(stats_ascii $crlfnul) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF_nul.txt
+ i/-text w/$(stats_ascii $crlfnul) attr/$(attr_ascii $attr $aeol) crlf_false_attr__LF_nul.txt
EOF
git ls-files --eol crlf_false_attr__* |
- sed -e "s!attr/[^ ]*!!g" -e "s/ / /g" -e "s/ */ /g" |
+ sed -e "s/ / /g" -e "s/ */ /g" |
sort >actual &&
test_cmp expect actual
'
- test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF" "
+ test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF" "
compare_ws_file $pfx $lfname crlf_false_attr__LF.txt
"
- test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=CRLF" "
+ test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" "
compare_ws_file $pfx $crlfname crlf_false_attr__CRLF.txt
"
- test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=CRLF_mix_LF" "
+ test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" "
compare_ws_file $pfx $lfmixcrlf crlf_false_attr__CRLF_mix_LF.txt
"
- test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF_mix_CR" "
+ test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" "
compare_ws_file $pfx $lfmixcr crlf_false_attr__LF_mix_CR.txt
"
- test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF_nul" "
+ test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" "
compare_ws_file $pfx $crlfnul crlf_false_attr__LF_nul.txt
"
}
@@ -301,14 +316,13 @@ test_expect_success 'setup master' '
git checkout -b master &&
git add .gitattributes &&
git commit -m "add .gitattributes" "" &&
- printf "line1\nline2\nline3" >LF &&
- printf "line1\r\nline2\r\nline3" >CRLF &&
- printf "line1\r\nline2\nline3" >repoMIX &&
- printf "line1\r\nline2\nline3" >CRLF_mix_LF &&
- printf "line1\nline2\rline3" >LF_mix_CR &&
- printf "line1\r\nline2\rline3" >CRLF_mix_CR &&
- printf "line1Q\r\nline2\r\nline3" | q_to_nul >CRLF_nul &&
- printf "line1Q\nline2\nline3" | q_to_nul >LF_nul &&
+ printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\nLINETWO\nLINETHREE" >LF &&
+ printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONE\r\nLINETWO\r\nLINETHREE" >CRLF &&
+ printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\r\nLINETWO\nLINETHREE" >CRLF_mix_LF &&
+ printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONE\nLINETWO\rLINETHREE" >LF_mix_CR &&
+ printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONE\r\nLINETWO\rLINETHREE" >CRLF_mix_CR &&
+ printf "\$Id: 0000000000000000000000000000000000000000 \$\r\nLINEONEQ\r\nLINETWO\r\nLINETHREE" | q_to_nul >CRLF_nul &&
+ printf "\$Id: 0000000000000000000000000000000000000000 \$\nLINEONEQ\nLINETWO\nLINETHREE" | q_to_nul >LF_nul &&
create_NNO_files CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF &&
git -c core.autocrlf=false add NNO_*.txt &&
git commit -m "mixed line endings" &&
@@ -449,23 +463,18 @@ check_in_repo_NNO input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF
# How to read the table below:
# - checkout_files will check multiple files with a combination of settings
# and attributes (core.autocrlf=input is forbidden with core.eol=crlf)
-# - parameter $1 : core.eol lf | crlf
-# - parameter $2 : core.autocrlf false | true | input
-# - parameter $3 : text in .gitattributs "" (empty) | auto | text | -text
-# - parameter $4 : reference for a file with only LF in the repo
-# - parameter $5 : reference for a file with only CRLF in the repo
-# - parameter $6 : reference for a file with mixed LF and CRLF in the repo
-# - parameter $7 : reference for a file with LF and CR in the repo (does somebody uses this ?)
-# - parameter $8 : reference for a file with CRLF and a NUL (should be handled as binary when auto)
-
-# What we have in the repo:
-# ----------------- EOL in repo ----------------
-# LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul
-# settings with checkout:
-# core. core. .gitattr
-# eol acrlf
-# ----------------------------------------------
-# What we want to have in the working tree:
+#
+# - parameter $1 : text in .gitattributs "" (empty) | auto | text | -text
+# - parameter $2 : ident "" | i (i == ident)
+# - parameter $3 : eol in .gitattributs "" (empty) | lf | crlf
+# - parameter $4 : core.autocrlf false | true | input
+# - parameter $5 : core.eol "" | lf | crlf | "native"
+# - parameter $6 : reference for a file with only LF in the repo
+# - parameter $7 : reference for a file with only CRLF in the repo
+# - parameter $8 : reference for a file with mixed LF and CRLF in the repo
+# - parameter $9 : reference for a file with LF and CR in the repo
+# - parameter $10 : reference for a file with CRLF and a NUL (should be handled as binary when auto)
+
if test_have_prereq NATIVE_CRLF
then
MIX_CRLF_LF=CRLF
@@ -480,69 +489,90 @@ LFNUL=LF_nul
fi
export CRLF_MIX_LF_CR MIX NL
-checkout_files lf false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf false "auto" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf true "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
-checkout_files lf input "auto" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf false "text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files lf input "text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf false "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf true "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf input "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf false "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf true "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf input "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files lf false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files lf true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files lf input "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-
-checkout_files crlf false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files crlf true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files crlf false "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
-checkout_files crlf true "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
-checkout_files crlf false "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files crlf true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files crlf false "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files crlf true "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files crlf false "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files crlf true "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files crlf false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files crlf true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-
-checkout_files "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" false "auto" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul
-checkout_files "" true "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
-checkout_files "" input "auto" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" false "text" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL
-checkout_files "" true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files "" input "text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" false "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" true "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" input "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" false "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" true "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" input "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files "" false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files "" true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files "" input "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-
-checkout_files native false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files native true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files native false "auto" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul
-checkout_files native true "auto" CRLF CRLF CRLF LF_mix_CR LF_nul
-checkout_files native false "text" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL
-checkout_files native true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files native false "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files native true "-text" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files native false "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files native true "lf" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
-checkout_files native false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
-checkout_files native true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+checkout_files "" "" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" true crlf CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" true lf CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" "" "" true native CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "" ident "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" "" "" false "" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul
+checkout_files "auto" "" "" false crlf CRLF CRLF CRLF LF_mix_CR LF_nul
+checkout_files "auto" "" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" "" "" false native $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul
+checkout_files "auto" "" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" "" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" "" "" true "" CRLF CRLF CRLF LF_mix_CR LF_nul
+checkout_files "auto" "" "" true crlf CRLF CRLF CRLF LF_mix_CR LF_nul
+checkout_files "auto" "" "" true lf CRLF CRLF CRLF LF_mix_CR LF_nul
+checkout_files "auto" "" "" true native CRLF CRLF CRLF LF_mix_CR LF_nul
+checkout_files "auto" ident "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+checkout_files "auto" ident "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+
+for id in "" ident;
+do
+ checkout_files "crlf" "$id" "" false "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" false crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" false lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" false native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" input "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" input lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" true "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" true crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" true lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "crlf" "$id" "" true native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "lf" "$id" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "lf" "$id" "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "text" "$id" "" false "" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL
+ checkout_files "text" "$id" "" false crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "text" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "text" "$id" "" false native $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL
+ checkout_files "text" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "text" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "text" "$id" "" true "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "text" "$id" "" true crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "text" "$id" "" true lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "text" "$id" "" true native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul
+ checkout_files "-text" "$id" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+ checkout_files "-text" "$id" "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul
+done
# Should be the last test case: remove some files from the worktree
test_expect_success 'ls-files --eol -d -z' '
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 52678e7d0a..6767da87cb 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -699,11 +699,13 @@ test_expect_success 'invalid unit' '
echo 1auto >expect &&
git config aninvalid.unit >actual &&
test_cmp expect actual &&
- cat >expect <<-\EOF &&
- fatal: bad numeric config value '\''1auto'\'' for '\''aninvalid.unit'\'' in .git/config: invalid unit
- EOF
test_must_fail git config --int --get aninvalid.unit 2>actual &&
- test_i18ncmp expect actual
+ test_i18ngrep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
+'
+
+test_expect_success 'invalid stdin config' '
+ echo "[broken" | test_must_fail git config --list --file - >output 2>&1 &&
+ test_i18ngrep "bad config line 1 in standard input" output
'
cat > expect << EOF
@@ -957,13 +959,15 @@ Qsection.sub=section.val4
Qsection.sub=section.val5Q
EOF
test_expect_success '--null --list' '
- git config --null --list | nul_to_q >result &&
+ git config --null --list >result.raw &&
+ nul_to_q <result.raw >result &&
echo >>result &&
test_cmp expect result
'
test_expect_success '--null --get-regexp' '
- git config --null --get-regexp "val[0-9]" | nul_to_q >result &&
+ git config --null --get-regexp "val[0-9]" >result.raw &&
+ nul_to_q <result.raw >result &&
echo >>result &&
test_cmp expect result
'
@@ -1201,4 +1205,154 @@ test_expect_success POSIXPERM,PERL 'preserves existing permissions' '
"die q(badrename) if ((stat(q(.git/config)))[2] & 07777) != 0600"
'
+! test_have_prereq MINGW ||
+HOME="$(pwd)" # convert to Windows path
+
+test_expect_success 'set up --show-origin tests' '
+ INCLUDE_DIR="$HOME/include" &&
+ mkdir -p "$INCLUDE_DIR" &&
+ cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
+ [user]
+ absolute = include
+ EOF
+ cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
+ [user]
+ relative = include
+ EOF
+ cat >"$HOME"/.gitconfig <<-EOF &&
+ [user]
+ global = true
+ override = global
+ [include]
+ path = "$INCLUDE_DIR/absolute.include"
+ EOF
+ cat >.git/config <<-\EOF
+ [user]
+ local = true
+ override = local
+ [include]
+ path = ../include/relative.include
+ EOF
+'
+
+test_expect_success '--show-origin with --list' '
+ cat >expect <<-EOF &&
+ file:$HOME/.gitconfig user.global=true
+ file:$HOME/.gitconfig user.override=global
+ file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
+ file:$INCLUDE_DIR/absolute.include user.absolute=include
+ file:.git/config user.local=true
+ file:.git/config user.override=local
+ file:.git/config include.path=../include/relative.include
+ file:.git/../include/relative.include user.relative=include
+ command line: user.cmdline=true
+ EOF
+ git -c user.cmdline=true config --list --show-origin >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin with --list --null' '
+ cat >expect <<-EOF &&
+ file:$HOME/.gitconfigQuser.global
+ trueQfile:$HOME/.gitconfigQuser.override
+ globalQfile:$HOME/.gitconfigQinclude.path
+ $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
+ includeQfile:.git/configQuser.local
+ trueQfile:.git/configQuser.override
+ localQfile:.git/configQinclude.path
+ ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
+ includeQcommand line:Quser.cmdline
+ trueQ
+ EOF
+ git -c user.cmdline=true config --null --list --show-origin >output.raw &&
+ nul_to_q <output.raw >output &&
+ # The here-doc above adds a newline that the --null output would not
+ # include. Add it here to make the two comparable.
+ echo >>output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin with single file' '
+ cat >expect <<-\EOF &&
+ file:.git/config user.local=true
+ file:.git/config user.override=local
+ file:.git/config include.path=../include/relative.include
+ EOF
+ git config --local --list --show-origin >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin with --get-regexp' '
+ cat >expect <<-EOF &&
+ file:$HOME/.gitconfig user.global true
+ file:.git/config user.local true
+ EOF
+ git config --show-origin --get-regexp "user\.[g|l].*" >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin getting a single key' '
+ cat >expect <<-\EOF &&
+ file:.git/config local
+ EOF
+ git config --show-origin user.override >output &&
+ test_cmp expect output
+'
+
+test_expect_success 'set up custom config file' '
+ CUSTOM_CONFIG_FILE="file\" (dq) and spaces.conf" &&
+ cat >"$CUSTOM_CONFIG_FILE" <<-\EOF
+ [user]
+ custom = true
+ EOF
+'
+
+test_expect_success !MINGW '--show-origin escape special file name characters' '
+ cat >expect <<-\EOF &&
+ file:"file\" (dq) and spaces.conf" user.custom=true
+ EOF
+ git config --file "$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin stdin' '
+ cat >expect <<-\EOF &&
+ standard input: user.custom=true
+ EOF
+ git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
+ test_cmp expect output
+'
+
+test_expect_success '--show-origin stdin with file include' '
+ cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
+ [user]
+ stdin = include
+ EOF
+ cat >expect <<-EOF &&
+ file:$INCLUDE_DIR/stdin.include include
+ EOF
+ echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" \
+ | git config --show-origin --includes --file - user.stdin >output &&
+ test_cmp expect output
+'
+
+test_expect_success !MINGW '--show-origin blob' '
+ cat >expect <<-\EOF &&
+ blob:a9d9f9e555b5c6f07cbe09d3f06fe3df11e09c08 user.custom=true
+ EOF
+ blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
+ git config --blob=$blob --show-origin --list >output &&
+ test_cmp expect output
+'
+
+test_expect_success !MINGW '--show-origin blob ref' '
+ cat >expect <<-\EOF &&
+ blob:"master:file\" (dq) and spaces.conf" user.custom=true
+ EOF
+ git add "$CUSTOM_CONFIG_FILE" &&
+ git commit -m "new config file" &&
+ git config --blob=master:"$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
+ test_cmp expect output
+'
+
test_done
diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh
index 91235b76ba..005d66dbef 100755
--- a/t/t1308-config-set.sh
+++ b/t/t1308-config-set.sh
@@ -195,14 +195,14 @@ test_expect_success 'proper error on error in default config files' '
cp .git/config .git/config.old &&
test_when_finished "mv .git/config.old .git/config" &&
echo "[" >>.git/config &&
- echo "fatal: bad config file line 34 in .git/config" >expect &&
+ echo "fatal: bad config line 34 in file .git/config" >expect &&
test_expect_code 128 test-config get_value foo.bar 2>actual &&
test_cmp expect actual
'
test_expect_success 'proper error on error in custom config files' '
echo "[" >>syntax-error &&
- echo "fatal: bad config file line 1 in syntax-error" >expect &&
+ echo "fatal: bad config line 1 in file syntax-error" >expect &&
test_expect_code 128 test-config configset_get_value foo.bar syntax-error 2>actual &&
test_cmp expect actual
'
@@ -218,4 +218,15 @@ test_expect_success 'check line errors for malformed values' '
test_i18ngrep "fatal: .*alias\.br.*\.git/config.*line 2" result
'
+test_expect_success 'error on modifying repo config without repo' '
+ mkdir no-repo &&
+ (
+ GIT_CEILING_DIRECTORIES=$(pwd) &&
+ export GIT_CEILING_DIRECTORIES &&
+ cd no-repo &&
+ test_must_fail git config a.b c 2>err &&
+ grep "not in a git directory" err
+ )
+'
+
test_done
diff --git a/t/t1501-worktree.sh b/t/t1501-work-tree.sh
index cc5b870e58..cc5b870e58 100755
--- a/t/t1501-worktree.sh
+++ b/t/t1501-work-tree.sh
diff --git a/t/t1509-root-worktree.sh b/t/t1509-root-work-tree.sh
index 553a3f601b..553a3f601b 100755
--- a/t/t1509-root-worktree.sh
+++ b/t/t1509-root-work-tree.sh
diff --git a/t/t2019-checkout-ambiguous-ref.sh b/t/t2019-checkout-ambiguous-ref.sh
index 199b22d85e..b99d5192a9 100755
--- a/t/t2019-checkout-ambiguous-ref.sh
+++ b/t/t2019-checkout-ambiguous-ref.sh
@@ -56,30 +56,4 @@ test_expect_success VAGUENESS_SUCCESS 'checkout reports switch to branch' '
test_i18ngrep ! "^HEAD is now at" stderr
'
-test_expect_success 'wildcard ambiguation, paths win' '
- git init ambi &&
- (
- cd ambi &&
- echo a >a.c &&
- git add a.c &&
- echo b >a.c &&
- git checkout "*.c" &&
- echo a >expect &&
- test_cmp expect a.c
- )
-'
-
-test_expect_success !MINGW 'wildcard ambiguation, refs lose' '
- git init ambi2 &&
- (
- cd ambi2 &&
- echo a >"*.c" &&
- git add . &&
- test_must_fail git show :"*.c" &&
- git show :"*.c" -- >actual &&
- echo a >expect &&
- test_cmp expect actual
- )
-'
-
test_done
diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh
index 0a804dab63..cbfa41ec61 100755
--- a/t/t2025-worktree-add.sh
+++ b/t/t2025-worktree-add.sh
@@ -193,6 +193,21 @@ test_expect_success '"add" -B/--detach mutually exclusive' '
test_must_fail git worktree add -B poodle --detach bamboo master
'
+test_expect_success '"add -B" fails if the branch is checked out' '
+ git rev-parse newmaster >before &&
+ test_must_fail git worktree add -B newmaster bamboo master &&
+ git rev-parse newmaster >after &&
+ test_cmp before after
+'
+
+test_expect_success 'add -B' '
+ git worktree add -B poodle bamboo2 master^ &&
+ git -C bamboo2 symbolic-ref HEAD >actual &&
+ echo refs/heads/poodle >expected &&
+ test_cmp expected actual &&
+ test_cmp_rev master^ poodle
+'
+
test_expect_success 'local clone from linked checkout' '
git clone --local here here-clone &&
( cd here-clone && git fsck )
diff --git a/t/t2027-worktree-list.sh b/t/t2027-worktree-list.sh
index 75ebb1b4a0..1b1b65a6b0 100755
--- a/t/t2027-worktree-list.sh
+++ b/t/t2027-worktree-list.sh
@@ -8,6 +8,16 @@ test_expect_success 'setup' '
test_commit init
'
+test_expect_success 'rev-parse --git-common-dir on main worktree' '
+ git rev-parse --git-common-dir >actual &&
+ echo .git >expected &&
+ test_cmp expected actual &&
+ mkdir sub &&
+ git -C sub rev-parse --git-common-dir >actual2 &&
+ echo sub/.git >expected2 &&
+ test_cmp expected2 actual2
+'
+
test_expect_success '"list" all worktrees from main' '
echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect &&
test_when_finished "rm -rf here && git worktree prune" &&
diff --git a/t/t3032-merge-recursive-options.sh b/t/t3032-merge-recursive-space-options.sh
index 4029c9c8c0..b56180ee4a 100755
--- a/t/t3032-merge-recursive-options.sh
+++ b/t/t3032-merge-recursive-space-options.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='merge-recursive options
+test_description='merge-recursive space options
* [master] Clarify
! [remote] Remove cruft
diff --git a/t/t3034-merge-recursive-rename-options.sh b/t/t3034-merge-recursive-rename-options.sh
new file mode 100755
index 0000000000..b9c4028496
--- /dev/null
+++ b/t/t3034-merge-recursive-rename-options.sh
@@ -0,0 +1,312 @@
+#!/bin/sh
+
+test_description='merge-recursive rename options
+
+Test rename detection by examining rename/delete conflicts.
+
+* (HEAD -> rename) rename
+| * (master) delete
+|/
+* base
+
+git diff --name-status base master
+D 0-old
+D 1-old
+D 2-old
+D 3-old
+
+git diff --name-status -M01 base rename
+R025 0-old 0-new
+R050 1-old 1-new
+R075 2-old 2-new
+R100 3-old 3-new
+
+Actual similarity indices are parsed from diff output. We rely on the fact that
+they are rounded down (see, e.g., Documentation/diff-generate-patch.txt, which
+mentions this in a different context).
+'
+
+. ./test-lib.sh
+
+get_expected_stages () {
+ git checkout rename -- $1-new &&
+ git ls-files --stage $1-new >expected-stages-undetected-$1 &&
+ sed "s/ 0 / 2 /" <expected-stages-undetected-$1 \
+ >expected-stages-detected-$1 &&
+ git read-tree -u --reset HEAD
+}
+
+rename_detected () {
+ git ls-files --stage $1-old $1-new >stages-actual-$1 &&
+ test_cmp expected-stages-detected-$1 stages-actual-$1
+}
+
+rename_undetected () {
+ git ls-files --stage $1-old $1-new >stages-actual-$1 &&
+ test_cmp expected-stages-undetected-$1 stages-actual-$1
+}
+
+check_common () {
+ git ls-files --stage >stages-actual &&
+ test_line_count = 4 stages-actual
+}
+
+check_threshold_0 () {
+ check_common &&
+ rename_detected 0 &&
+ rename_detected 1 &&
+ rename_detected 2 &&
+ rename_detected 3
+}
+
+check_threshold_1 () {
+ check_common &&
+ rename_undetected 0 &&
+ rename_detected 1 &&
+ rename_detected 2 &&
+ rename_detected 3
+}
+
+check_threshold_2 () {
+ check_common &&
+ rename_undetected 0 &&
+ rename_undetected 1 &&
+ rename_detected 2 &&
+ rename_detected 3
+}
+
+check_exact_renames () {
+ check_common &&
+ rename_undetected 0 &&
+ rename_undetected 1 &&
+ rename_undetected 2 &&
+ rename_detected 3
+}
+
+check_no_renames () {
+ check_common &&
+ rename_undetected 0 &&
+ rename_undetected 1 &&
+ rename_undetected 2 &&
+ rename_undetected 3
+}
+
+test_expect_success 'setup repo' '
+ cat <<-\EOF >3-old &&
+ 33a
+ 33b
+ 33c
+ 33d
+ EOF
+ sed s/33/22/ <3-old >2-old &&
+ sed s/33/11/ <3-old >1-old &&
+ sed s/33/00/ <3-old >0-old &&
+ git add [0-3]-old &&
+ git commit -m base &&
+ git rm [0-3]-old &&
+ git commit -m delete &&
+ git checkout -b rename HEAD^ &&
+ cp 3-old 3-new &&
+ sed 1,1s/./x/ <2-old >2-new &&
+ sed 1,2s/./x/ <1-old >1-new &&
+ sed 1,3s/./x/ <0-old >0-new &&
+ git add [0-3]-new &&
+ git rm [0-3]-old &&
+ git commit -m rename &&
+ get_expected_stages 0 &&
+ get_expected_stages 1 &&
+ get_expected_stages 2 &&
+ get_expected_stages 3 &&
+ check_50="false" &&
+ tail="HEAD^ -- HEAD master"
+'
+
+test_expect_success 'setup thresholds' '
+ git diff --name-status -M01 HEAD^ HEAD >diff-output &&
+ test_debug "cat diff-output" &&
+ test_line_count = 4 diff-output &&
+ grep "R[0-9][0-9][0-9] \([0-3]\)-old \1-new" diff-output \
+ >grep-output &&
+ test_cmp diff-output grep-output &&
+ th0=$(sed -n "s/R\(...\) 0-old 0-new/\1/p" <diff-output) &&
+ th1=$(sed -n "s/R\(...\) 1-old 1-new/\1/p" <diff-output) &&
+ th2=$(sed -n "s/R\(...\) 2-old 2-new/\1/p" <diff-output) &&
+ th3=$(sed -n "s/R\(...\) 3-old 3-new/\1/p" <diff-output) &&
+ test "$th0" -lt "$th1" &&
+ test "$th1" -lt "$th2" &&
+ test "$th2" -lt "$th3" &&
+ test "$th3" = 100 &&
+ if test 50 -le "$th0"
+ then
+ check_50=check_threshold_0
+ elif test 50 -le "$th1"
+ then
+ check_50=check_threshold_1
+ elif test 50 -le "$th2"
+ then
+ check_50=check_threshold_2
+ fi &&
+ th0="$th0%" &&
+ th1="$th1%" &&
+ th2="$th2%" &&
+ th3="$th3%"
+'
+
+test_expect_success 'assumption for tests: rename detection with diff' '
+ git diff --name-status -M$th0 --diff-filter=R HEAD^ HEAD \
+ >diff-output-0 &&
+ git diff --name-status -M$th1 --diff-filter=R HEAD^ HEAD \
+ >diff-output-1 &&
+ git diff --name-status -M$th2 --diff-filter=R HEAD^ HEAD \
+ >diff-output-2 &&
+ git diff --name-status -M100% --diff-filter=R HEAD^ HEAD \
+ >diff-output-3 &&
+ test_line_count = 4 diff-output-0 &&
+ test_line_count = 3 diff-output-1 &&
+ test_line_count = 2 diff-output-2 &&
+ test_line_count = 1 diff-output-3
+'
+
+test_expect_success 'default similarity threshold is 50%' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive $tail &&
+ $check_50
+'
+
+test_expect_success 'low rename threshold' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --find-renames=$th0 $tail &&
+ check_threshold_0
+'
+
+test_expect_success 'medium rename threshold' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --find-renames=$th1 $tail &&
+ check_threshold_1
+'
+
+test_expect_success 'high rename threshold' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --find-renames=$th2 $tail &&
+ check_threshold_2
+'
+
+test_expect_success 'exact renames only' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --find-renames=100% $tail &&
+ check_exact_renames
+'
+
+test_expect_success 'rename threshold is truncated' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --find-renames=200% $tail &&
+ check_exact_renames
+'
+
+test_expect_success 'disabled rename detection' '
+ git read-tree --reset -u HEAD &&
+ git merge-recursive --no-renames $tail &&
+ check_no_renames
+'
+
+test_expect_success 'last wins in --find-renames=<m> --find-renames=<n>' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive \
+ --find-renames=$th0 --find-renames=$th2 $tail &&
+ check_threshold_2
+'
+
+test_expect_success '--find-renames resets threshold' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive \
+ --find-renames=$th0 --find-renames $tail &&
+ $check_50
+'
+
+test_expect_success 'last wins in --no-renames --find-renames' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --no-renames --find-renames $tail &&
+ $check_50
+'
+
+test_expect_success 'last wins in --find-renames --no-renames' '
+ git read-tree --reset -u HEAD &&
+ git merge-recursive --find-renames --no-renames $tail &&
+ check_no_renames
+'
+
+test_expect_success 'assumption for further tests: trivial merge succeeds' '
+ git read-tree --reset -u HEAD &&
+ git merge-recursive HEAD -- HEAD HEAD &&
+ git diff --quiet --cached &&
+ git merge-recursive --find-renames=$th0 HEAD -- HEAD HEAD &&
+ git diff --quiet --cached &&
+ git merge-recursive --find-renames=$th2 HEAD -- HEAD HEAD &&
+ git diff --quiet --cached &&
+ git merge-recursive --find-renames=100% HEAD -- HEAD HEAD &&
+ git diff --quiet --cached &&
+ git merge-recursive --no-renames HEAD -- HEAD HEAD &&
+ git diff --quiet --cached
+'
+
+test_expect_success '--find-renames rejects negative argument' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --find-renames=-25 \
+ HEAD -- HEAD HEAD &&
+ git diff --quiet --cached
+'
+
+test_expect_success '--find-renames rejects non-numbers' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --find-renames=0xf \
+ HEAD -- HEAD HEAD &&
+ git diff --quiet --cached
+'
+
+test_expect_success 'rename-threshold=<n> is a synonym for find-renames=<n>' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --rename-threshold=$th0 $tail &&
+ check_threshold_0
+'
+
+test_expect_success 'last wins in --no-renames --rename-threshold=<n>' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --no-renames --rename-threshold=$th0 $tail &&
+ check_threshold_0
+'
+
+test_expect_success 'last wins in --rename-threshold=<n> --no-renames' '
+ git read-tree --reset -u HEAD &&
+ git merge-recursive --rename-threshold=$th0 --no-renames $tail &&
+ check_no_renames
+'
+
+test_expect_success '--rename-threshold=<n> rejects negative argument' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --rename-threshold=-25 \
+ HEAD -- HEAD HEAD &&
+ git diff --quiet --cached
+'
+
+test_expect_success '--rename-threshold=<n> rejects non-numbers' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive --rename-threshold=0xf \
+ HEAD -- HEAD HEAD &&
+ git diff --quiet --cached
+'
+
+test_expect_success 'last wins in --rename-threshold=<m> --find-renames=<n>' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive \
+ --rename-threshold=$th0 --find-renames=$th2 $tail &&
+ check_threshold_2
+'
+
+test_expect_success 'last wins in --find-renames=<m> --rename-threshold=<n>' '
+ git read-tree --reset -u HEAD &&
+ test_must_fail git merge-recursive \
+ --find-renames=$th2 --rename-threshold=$th0 $tail &&
+ check_threshold_0
+'
+
+test_done
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index cdaf6f64ec..a897248490 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -446,6 +446,13 @@ test_expect_success '--set-upstream-to fails on a non-ref' '
test_must_fail git branch --set-upstream-to HEAD^{}
'
+test_expect_success '--set-upstream-to fails on locked config' '
+ test_when_finished "rm -f .git/config.lock" &&
+ >.git/config.lock &&
+ git branch locked &&
+ test_must_fail git branch --set-upstream-to locked
+'
+
test_expect_success 'use --set-upstream-to modify HEAD' '
test_config branch.master.remote foo &&
test_config branch.master.merge foo &&
@@ -466,6 +473,13 @@ test_expect_success '--unset-upstream should fail if given a non-existent branch
test_must_fail git branch --unset-upstream i-dont-exist
'
+test_expect_success '--unset-upstream should fail if config is locked' '
+ test_when_finished "rm -f .git/config.lock" &&
+ git branch --set-upstream-to locked &&
+ >.git/config.lock &&
+ test_must_fail git branch --unset-upstream
+'
+
test_expect_success 'test --unset-upstream on HEAD' '
git branch my14 &&
test_config branch.master.remote foo &&
@@ -579,7 +593,7 @@ test_expect_success 'avoid ambiguous track' '
git config remote.ambi1.fetch refs/heads/lalala:refs/heads/master &&
git config remote.ambi2.url lilili &&
git config remote.ambi2.fetch refs/heads/lilili:refs/heads/master &&
- git branch all1 master &&
+ test_must_fail git branch all1 master &&
test -z "$(git config branch.all1.merge)"
'
diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh
new file mode 100755
index 0000000000..a8a587abc3
--- /dev/null
+++ b/t/t5313-pack-bounds-checks.sh
@@ -0,0 +1,179 @@
+#!/bin/sh
+
+test_description='bounds-checking of access to mmapped on-disk file formats'
+. ./test-lib.sh
+
+clear_base () {
+ test_when_finished 'restore_base' &&
+ rm -f $base
+}
+
+restore_base () {
+ cp base-backup/* .git/objects/pack/
+}
+
+do_pack () {
+ pack_objects=$1; shift
+ sha1=$(
+ for i in $pack_objects
+ do
+ echo $i
+ done | git pack-objects "$@" .git/objects/pack/pack
+ ) &&
+ pack=.git/objects/pack/pack-$sha1.pack &&
+ idx=.git/objects/pack/pack-$sha1.idx &&
+ chmod +w $pack $idx &&
+ test_when_finished 'rm -f "$pack" "$idx"'
+}
+
+munge () {
+ printf "$3" | dd of="$1" bs=1 conv=notrunc seek=$2
+}
+
+# Offset in a v2 .idx to its initial and extended offset tables. For an index
+# with "nr" objects, this is:
+#
+# magic(4) + version(4) + fan-out(4*256) + sha1s(20*nr) + crc(4*nr),
+#
+# for the initial, and another ofs(4*nr) past that for the extended.
+#
+ofs_table () {
+ echo $((4 + 4 + 4*256 + 20*$1 + 4*$1))
+}
+extended_table () {
+ echo $(($(ofs_table "$1") + 4*$1))
+}
+
+test_expect_success 'set up base packfile and variables' '
+ # the hash of this content starts with ff, which
+ # makes some later computations much simpler
+ echo 74 >file &&
+ git add file &&
+ git commit -m base &&
+ git repack -ad &&
+ base=$(echo .git/objects/pack/*) &&
+ chmod +w $base &&
+ mkdir base-backup &&
+ cp $base base-backup/ &&
+ object=$(git rev-parse HEAD:file)
+'
+
+test_expect_success 'pack/index object count mismatch' '
+ do_pack $object &&
+ munge $pack 8 "\377\0\0\0" &&
+ clear_base &&
+
+ # We enumerate the objects from the completely-fine
+ # .idx, but notice later that the .pack is bogus
+ # and fail to show any data.
+ echo "$object missing" >expect &&
+ git cat-file --batch-all-objects --batch-check >actual &&
+ test_cmp expect actual &&
+
+ # ...and here fail to load the object (without segfaulting),
+ # but fallback to a good copy if available.
+ test_must_fail git cat-file blob $object &&
+ restore_base &&
+ git cat-file blob $object >actual &&
+ test_cmp file actual &&
+
+ # ...and make sure that index-pack --verify, which has its
+ # own reading routines, does not segfault.
+ test_must_fail git index-pack --verify $pack
+'
+
+test_expect_success 'matched bogus object count' '
+ do_pack $object &&
+ munge $pack 8 "\377\0\0\0" &&
+ munge $idx $((255 * 4)) "\377\0\0\0" &&
+ clear_base &&
+
+ # Unlike above, we should notice early that the .idx is totally
+ # bogus, and not even enumerate its contents.
+ >expect &&
+ git cat-file --batch-all-objects --batch-check >actual &&
+ test_cmp expect actual &&
+
+ # But as before, we can do the same object-access checks.
+ test_must_fail git cat-file blob $object &&
+ restore_base &&
+ git cat-file blob $object >actual &&
+ test_cmp file actual &&
+
+ test_must_fail git index-pack --verify $pack
+'
+
+# Note that we cannot check the fallback case for these
+# further .idx tests, as we notice the problem in functions
+# whose interface doesn't allow an error return (like use_pack()),
+# and thus we just die().
+#
+# There's also no point in doing enumeration tests, as
+# we are munging offsets here, which are about looking up
+# specific objects.
+
+test_expect_success 'bogus object offset (v1)' '
+ do_pack $object --index-version=1 &&
+ munge $idx $((4 * 256)) "\377\0\0\0" &&
+ clear_base &&
+ test_must_fail git cat-file blob $object &&
+ test_must_fail git index-pack --verify $pack
+'
+
+test_expect_success 'bogus object offset (v2, no msb)' '
+ do_pack $object --index-version=2 &&
+ munge $idx $(ofs_table 1) "\0\377\0\0" &&
+ clear_base &&
+ test_must_fail git cat-file blob $object &&
+ test_must_fail git index-pack --verify $pack
+'
+
+test_expect_success 'bogus offset into v2 extended table' '
+ do_pack $object --index-version=2 &&
+ munge $idx $(ofs_table 1) "\377\0\0\0" &&
+ clear_base &&
+ test_must_fail git cat-file blob $object &&
+ test_must_fail git index-pack --verify $pack
+'
+
+test_expect_success 'bogus offset inside v2 extended table' '
+ # We need two objects here, so we can plausibly require
+ # an extended table (if the first object were larger than 2^31).
+ do_pack "$object $(git rev-parse HEAD)" --index-version=2 &&
+
+ # We have to make extra room for the table, so we cannot
+ # just munge in place as usual.
+ {
+ dd if=$idx bs=1 count=$(($(ofs_table 2) + 4)) &&
+ printf "\200\0\0\0" &&
+ printf "\377\0\0\0\0\0\0\0" &&
+ dd if=$idx bs=1 skip=$(extended_table 2)
+ } >tmp &&
+ mv tmp "$idx" &&
+ clear_base &&
+ test_must_fail git cat-file blob $object &&
+ test_must_fail git index-pack --verify $pack
+'
+
+test_expect_success 'bogus OFS_DELTA in packfile' '
+ # Generate a pack with a delta in it.
+ base=$(test-genrandom foo 3000 | git hash-object --stdin -w) &&
+ delta=$(test-genrandom foo 2000 | git hash-object --stdin -w) &&
+ do_pack "$base $delta" --delta-base-offset &&
+ rm -f .git/objects/??/* &&
+
+ # Double check that we have the delta we expect.
+ echo $base >expect &&
+ echo $delta | git cat-file --batch-check="%(deltabase)" >actual &&
+ test_cmp expect actual &&
+
+ # Now corrupt it. We assume the varint size for the delta is small
+ # enough to fit in the first byte (which it should be, since it
+ # is a pure deletion from the base), and that original ofs_delta
+ # takes 2 bytes (which it should, as it should be ~3000).
+ ofs=$(git show-index <$idx | grep $delta | cut -d" " -f1) &&
+ munge $pack $(($ofs + 1)) "\177\377" &&
+ test_must_fail git cat-file blob $delta >/dev/null
+'
+
+test_done
diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh
index 89224edcc5..a3e12d295a 100755
--- a/t/t5504-fetch-receive-strict.sh
+++ b/t/t5504-fetch-receive-strict.sh
@@ -101,7 +101,10 @@ test_expect_success 'push with receive.fsckobjects' '
git config transfer.fsckobjects false
) &&
test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act &&
- test_cmp exp act
+ {
+ test_cmp exp act ||
+ ! test -s act
+ }
'
test_expect_success 'push with transfer.fsckobjects' '
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 0dcc752076..dd2e6ce34e 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -144,6 +144,39 @@ test_expect_success 'remove remote protects local branches' '
)
'
+test_expect_success 'remove errors out early when deleting non-existent branch' '
+ (
+ cd test &&
+ echo "fatal: No such remote: foo" >expect &&
+ test_must_fail git remote rm foo 2>actual &&
+ test_i18ncmp expect actual
+ )
+'
+
+test_expect_success 'rename errors out early when deleting non-existent branch' '
+ (
+ cd test &&
+ echo "fatal: No such remote: foo" >expect &&
+ test_must_fail git remote rename foo bar 2>actual &&
+ test_i18ncmp expect actual
+ )
+'
+
+test_expect_success 'add existing foreign_vcs remote' '
+ test_config remote.foo.vcs bar &&
+ echo "fatal: remote foo already exists." >expect &&
+ test_must_fail git remote add foo bar 2>actual &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'add existing foreign_vcs remote' '
+ test_config remote.foo.vcs bar &&
+ test_config remote.bar.vcs bar &&
+ echo "fatal: remote bar already exists." >expect &&
+ test_must_fail git remote rename foo bar 2>actual &&
+ test_i18ncmp expect actual
+'
+
cat >test/expect <<EOF
* remote origin
Fetch URL: $(pwd)/one
@@ -937,6 +970,15 @@ test_expect_success 'get-url on new remote' '
echo foo | get_url_test --push --all someremote
'
+test_expect_success 'remote set-url with locked config' '
+ test_when_finished "rm -f .git/config.lock" &&
+ git config --get-all remote.someremote.url >expect &&
+ >.git/config.lock &&
+ test_must_fail git remote set-url someremote baz &&
+ git config --get-all remote.someremote.url >actual &&
+ cmp expect actual
+'
+
test_expect_success 'remote set-url bar' '
git remote set-url someremote bar &&
echo bar >expect &&
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 0c10c856a9..38321d19ef 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -679,10 +679,12 @@ test_expect_success 'fetching with auto-gc does not lock up' '
EOF
git clone "file://$D" auto-gc &&
test_commit test2 &&
- cd auto-gc &&
- git config gc.autoPackLimit 1 &&
- GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 &&
- ! grep "Should I try again" fetch.out
+ (
+ cd auto-gc &&
+ git config gc.autoPackLimit 1 &&
+ GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 &&
+ ! grep "Should I try again" fetch.out
+ )
'
test_done
diff --git a/t/t6133-pathspec-rev-dwim.sh b/t/t6133-pathspec-rev-dwim.sh
new file mode 100755
index 0000000000..a290ffca0d
--- /dev/null
+++ b/t/t6133-pathspec-rev-dwim.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+test_description='test dwim of revs versus pathspecs in revision parser'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit base &&
+ echo content >"br[ack]ets" &&
+ git add . &&
+ test_tick &&
+ git commit -m brackets
+'
+
+test_expect_success 'non-rev wildcard dwims to pathspec' '
+ git log -- "*.t" >expect &&
+ git log "*.t" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'tree:path with metacharacters dwims to rev' '
+ git show "HEAD:br[ack]ets" -- >expect &&
+ git show "HEAD:br[ack]ets" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '^{foo} with metacharacters dwims to rev' '
+ git log "HEAD^{/b.*}" -- >expect &&
+ git log "HEAD^{/b.*}" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '@{foo} with metacharacters dwims to rev' '
+ git log "HEAD@{now [or thereabouts]}" -- >expect &&
+ git log "HEAD@{now [or thereabouts]}" >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success ':/*.t from a subdir dwims to a pathspec' '
+ mkdir subdir &&
+ (
+ cd subdir &&
+ git log -- ":/*.t" >expect &&
+ git log ":/*.t" >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_done
diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh
index fe4796cc9c..bcf472bf51 100755
--- a/t/t6302-for-each-ref-filter.sh
+++ b/t/t6302-for-each-ref-filter.sh
@@ -133,6 +133,48 @@ test_expect_success 'right alignment' '
test_cmp expect actual
'
+cat >expect <<-\EOF
+| refname is refs/heads/master |refs/heads/master
+| refname is refs/heads/side |refs/heads/side
+| refname is refs/odd/spot |refs/odd/spot
+| refname is refs/tags/double-tag |refs/tags/double-tag
+| refname is refs/tags/four |refs/tags/four
+| refname is refs/tags/one |refs/tags/one
+| refname is refs/tags/signed-tag |refs/tags/signed-tag
+| refname is refs/tags/three |refs/tags/three
+| refname is refs/tags/two |refs/tags/two
+EOF
+
+test_align_permutations() {
+ while read -r option
+ do
+ test_expect_success "align:$option" '
+ git for-each-ref --format="|%(align:$option)refname is %(refname)%(end)|%(refname)" >actual &&
+ test_cmp expect actual
+ '
+ done
+}
+
+test_align_permutations <<-\EOF
+ middle,42
+ 42,middle
+ position=middle,42
+ 42,position=middle
+ middle,width=42
+ width=42,middle
+ position=middle,width=42
+ width=42,position=middle
+EOF
+
+# Last one wins (silently) when multiple arguments of the same type are given
+
+test_align_permutations <<-\EOF
+ 32,width=42,middle
+ width=30,42,middle
+ width=42,position=right,middle
+ 42,right,position=middle
+EOF
+
# Individual atoms inside %(align:...) and %(end) must not be quoted.
test_expect_success 'alignment with format quote' "
diff --git a/t/t7008-grep-binary.sh b/t/t7008-grep-binary.sh
index b146406e9c..9c9c378119 100755
--- a/t/t7008-grep-binary.sh
+++ b/t/t7008-grep-binary.sh
@@ -141,7 +141,8 @@ test_expect_success 'grep respects not-binary diff attribute' '
test_cmp expect actual &&
echo "b diff" >.gitattributes &&
echo "b:binQary" >expect &&
- git grep bin b | nul_to_q >actual &&
+ git grep bin b >actual.raw &&
+ nul_to_q <actual.raw >actual &&
test_cmp expect actual
'
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 540771ca41..e1abd19230 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -849,6 +849,19 @@ test_expect_success 'set up a second submodule' '
git commit -m "submodule example2 added"
'
+test_expect_success 'submodule deinit works on repository without submodules' '
+ test_when_finished "rm -rf newdirectory" &&
+ mkdir newdirectory &&
+ (
+ cd newdirectory &&
+ git init &&
+ >file &&
+ git add file &&
+ git commit -m "repo should not be empty"
+ git submodule deinit .
+ )
+'
+
test_expect_success 'submodule deinit should remove the whole submodule section from .git/config' '
git config submodule.example.foo bar &&
git config submodule.example2.frotz nitfol &&
@@ -999,5 +1012,30 @@ test_expect_success 'submodule add clone shallow submodule' '
)
'
+test_expect_success 'submodule helper list is not confused by common prefixes' '
+ mkdir -p dir1/b &&
+ (
+ cd dir1/b &&
+ git init &&
+ echo hi >testfile2 &&
+ git add . &&
+ git commit -m "test1"
+ ) &&
+ mkdir -p dir2/b &&
+ (
+ cd dir2/b &&
+ git init &&
+ echo hello >testfile1 &&
+ git add . &&
+ git commit -m "test2"
+ ) &&
+ git submodule add /dir1/b dir1/b &&
+ git submodule add /dir2/b dir2/b &&
+ git commit -m "first submodule commit" &&
+ git submodule--helper list dir1/b |cut -c51- >actual &&
+ echo "dir1/b" >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7409-submodule-detached-worktree.sh b/t/t7409-submodule-detached-work-tree.sh
index c20717181e..c20717181e 100755
--- a/t/t7409-submodule-detached-worktree.sh
+++ b/t/t7409-submodule-detached-work-tree.sh
diff --git a/t/t8005-blame-i18n.sh b/t/t8005-blame-i18n.sh
index 847d098c09..75da219ed1 100755
--- a/t/t8005-blame-i18n.sh
+++ b/t/t8005-blame-i18n.sh
@@ -33,11 +33,15 @@ author $SJIS_NAME
summary $SJIS_MSG
EOF
+filter_author_summary () {
+ sed -n -e '/^author /p' -e '/^summary /p' "$@"
+}
+
test_expect_success !MINGW \
'blame respects i18n.commitencoding' '
- git blame --incremental file | \
- egrep "^(author|summary) " > actual &&
- test_cmp actual expected
+ git blame --incremental file >output &&
+ filter_author_summary output >actual &&
+ test_cmp expected actual
'
cat >expected <<EOF
@@ -52,9 +56,9 @@ EOF
test_expect_success !MINGW \
'blame respects i18n.logoutputencoding' '
git config i18n.logoutputencoding eucJP &&
- git blame --incremental file | \
- egrep "^(author|summary) " > actual &&
- test_cmp actual expected
+ git blame --incremental file >output &&
+ filter_author_summary output >actual &&
+ test_cmp expected actual
'
cat >expected <<EOF
@@ -68,9 +72,9 @@ EOF
test_expect_success !MINGW \
'blame respects --encoding=UTF-8' '
- git blame --incremental --encoding=UTF-8 file | \
- egrep "^(author|summary) " > actual &&
- test_cmp actual expected
+ git blame --incremental --encoding=UTF-8 file >output &&
+ filter_author_summary output >actual &&
+ test_cmp expected actual
'
cat >expected <<EOF
@@ -84,9 +88,9 @@ EOF
test_expect_success !MINGW \
'blame respects --encoding=none' '
- git blame --incremental --encoding=none file | \
- egrep "^(author|summary) " > actual &&
- test_cmp actual expected
+ git blame --incremental --encoding=none file >output &&
+ filter_author_summary output >actual &&
+ test_cmp expected actual
'
test_done
diff --git a/t/t9108-git-svn-glob.sh b/t/t9108-git-svn-glob.sh
index a526d60379..a94286c8ec 100755
--- a/t/t9108-git-svn-glob.sh
+++ b/t/t9108-git-svn-glob.sh
@@ -86,9 +86,12 @@ test_expect_success 'test left-hand-side only globbing' '
test_cmp expect.two output.two
'
-echo "Only one set of wildcard directories" \
- "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three
-echo "" >> expect.three
+test_expect_success 'prepare test disallow multi-globs' "
+cat >expect.three <<EOF
+Only one set of wildcards (e.g. '*' or '*/*/*') is supported: branches/*/t/*
+
+EOF
+ "
test_expect_success 'test disallow multi-globs' '
git config --add svn-remote.three.url "$svnrepo" &&
diff --git a/t/t9109-git-svn-multi-glob.sh b/t/t9109-git-svn-multi-glob.sh
index f36b749242..8d99e848d4 100755
--- a/t/t9109-git-svn-multi-glob.sh
+++ b/t/t9109-git-svn-multi-glob.sh
@@ -135,9 +135,12 @@ test_expect_success 'test another branch' '
test_cmp expect.four output.four
'
-echo "Only one set of wildcard directories" \
- "(e.g. '*' or '*/*/*') is supported: 'branches/*/t/*'" > expect.three
-echo "" >> expect.three
+test_expect_success 'prepare test disallow multiple globs' "
+cat >expect.three <<EOF
+Only one set of wildcards (e.g. '*' or '*/*/*') is supported: branches/*/t/*
+
+EOF
+ "
test_expect_success 'test disallow multiple globs' '
git config --add svn-remote.three.url "$svnrepo" &&
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 0990f8d235..a87d3d3fc1 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -93,7 +93,7 @@ test_expect_success 'git svn rebase works inside a fresh-cloned repository' '
# > to special UNICODE characters in the range 0xf000 to 0xf0ff (the
# > "Private use area") when creating or accessing files.
prepare_a_utf8_locale
-test_expect_success UTF8 'svn.pathnameencoding=cp932 new file on dcommit' '
+test_expect_success UTF8,!MINGW,!UTF8_NFD_TO_NFC 'svn.pathnameencoding=cp932 new file on dcommit' '
LC_ALL=$a_utf8_locale &&
export LC_ALL &&
neq=$(printf "\201\202") &&
@@ -105,7 +105,7 @@ test_expect_success UTF8 'svn.pathnameencoding=cp932 new file on dcommit' '
'
# See the comment on the above test for setting of LC_ALL.
-test_expect_success 'svn.pathnameencoding=cp932 rename on dcommit' '
+test_expect_success !MINGW,!UTF8_NFD_TO_NFC 'svn.pathnameencoding=cp932 rename on dcommit' '
LC_ALL=$a_utf8_locale &&
export LC_ALL &&
inf=$(printf "\201\207") &&
diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh
index a66f43c6b1..69a675052e 100755
--- a/t/t9117-git-svn-init-clone.sh
+++ b/t/t9117-git-svn-init-clone.sh
@@ -119,4 +119,10 @@ test_expect_success 'clone with -s/-T/-b/-t and --prefix "" still works' '
rm -f warning
'
+test_expect_success 'init with -T as a full url works' '
+ test ! -d project &&
+ git svn init -T "$svnrepo"/project/trunk project &&
+ rm -rf project
+ '
+
test_done
diff --git a/t/t9168-git-svn-partially-globbed-names.sh b/t/t9168-git-svn-partially-globbed-names.sh
new file mode 100755
index 0000000000..8b22f2272c
--- /dev/null
+++ b/t/t9168-git-svn-partially-globbed-names.sh
@@ -0,0 +1,223 @@
+#!/bin/sh
+test_description='git svn globbing refspecs with prefixed globs'
+. ./lib-git-svn.sh
+
+test_expect_success 'prepare test refspec prefixed globbing' '
+ cat >expect.end <<EOF
+the end
+hi
+start a new branch
+initial
+EOF
+ '
+
+test_expect_success 'test refspec prefixed globbing' '
+ mkdir -p trunk/src/a trunk/src/b trunk/doc &&
+ echo "hello world" >trunk/src/a/readme &&
+ echo "goodbye world" >trunk/src/b/readme &&
+ svn_cmd import -m "initial" trunk "$svnrepo"/trunk &&
+ svn_cmd co "$svnrepo" tmp &&
+ (
+ cd tmp &&
+ mkdir branches tags &&
+ svn_cmd add branches tags &&
+ svn_cmd cp trunk branches/b_start &&
+ svn_cmd commit -m "start a new branch" &&
+ svn_cmd up &&
+ echo "hi" >>branches/b_start/src/b/readme &&
+ poke branches/b_start/src/b/readme &&
+ echo "hey" >>branches/b_start/src/a/readme &&
+ poke branches/b_start/src/a/readme &&
+ svn_cmd commit -m "hi" &&
+ svn_cmd up &&
+ svn_cmd cp branches/b_start tags/t_end &&
+ echo "bye" >>tags/t_end/src/b/readme &&
+ poke tags/t_end/src/b/readme &&
+ echo "aye" >>tags/t_end/src/a/readme &&
+ poke tags/t_end/src/a/readme &&
+ svn_cmd commit -m "the end" &&
+ echo "byebye" >>tags/t_end/src/b/readme &&
+ poke tags/t_end/src/b/readme &&
+ svn_cmd commit -m "nothing to see here"
+ ) &&
+ git config --add svn-remote.svn.url "$svnrepo" &&
+ git config --add svn-remote.svn.fetch \
+ "trunk/src/a:refs/remotes/trunk" &&
+ git config --add svn-remote.svn.branches \
+ "branches/b_*/src/a:refs/remotes/branches/b_*" &&
+ git config --add svn-remote.svn.tags\
+ "tags/t_*/src/a:refs/remotes/tags/t_*" &&
+ git svn multi-fetch &&
+ git log --pretty=oneline refs/remotes/tags/t_end | \
+ sed -e "s/^.\{41\}//" >output.end &&
+ test_cmp expect.end output.end &&
+ test "$(git rev-parse refs/remotes/tags/t_end~1)" = \
+ "$(git rev-parse refs/remotes/branches/b_start)" &&
+ test "$(git rev-parse refs/remotes/branches/b_start~2)" = \
+ "$(git rev-parse refs/remotes/trunk)" &&
+ test_must_fail git rev-parse refs/remotes/tags/t_end@3
+ '
+
+test_expect_success 'prepare test left-hand-side only prefixed globbing' '
+ echo try to try >expect.two &&
+ echo nothing to see here >>expect.two &&
+ cat expect.end >>expect.two
+ '
+
+test_expect_success 'test left-hand-side only prefixed globbing' '
+ git config --add svn-remote.two.url "$svnrepo" &&
+ git config --add svn-remote.two.fetch trunk:refs/remotes/two/trunk &&
+ git config --add svn-remote.two.branches \
+ "branches/b_*:refs/remotes/two/branches/*" &&
+ git config --add svn-remote.two.tags \
+ "tags/t_*:refs/remotes/two/tags/*" &&
+ (
+ cd tmp &&
+ echo "try try" >>tags/t_end/src/b/readme &&
+ poke tags/t_end/src/b/readme &&
+ svn_cmd commit -m "try to try"
+ ) &&
+ git svn fetch two &&
+ test $(git rev-list refs/remotes/two/tags/t_end | wc -l) -eq 6 &&
+ test $(git rev-list refs/remotes/two/branches/b_start | wc -l) -eq 3 &&
+ test $(git rev-parse refs/remotes/two/branches/b_start~2) = \
+ $(git rev-parse refs/remotes/two/trunk) &&
+ test $(git rev-parse refs/remotes/two/tags/t_end~3) = \
+ $(git rev-parse refs/remotes/two/branches/b_start) &&
+ git log --pretty=oneline refs/remotes/two/tags/t_end | \
+ sed -e "s/^.\{41\}//" >output.two &&
+ test_cmp expect.two output.two
+ '
+
+test_expect_success 'prepare test prefixed globs match just prefix' '
+ cat >expect.three <<EOF
+Tag commit to t_
+Branch commit to b_
+initial
+EOF
+ '
+
+test_expect_success 'test prefixed globs match just prefix' '
+ git config --add svn-remote.three.url "$svnrepo" &&
+ git config --add svn-remote.three.fetch \
+ trunk:refs/remotes/three/trunk &&
+ git config --add svn-remote.three.branches \
+ "branches/b_*:refs/remotes/three/branches/*" &&
+ git config --add svn-remote.three.tags \
+ "tags/t_*:refs/remotes/three/tags/*" &&
+ (
+ cd tmp &&
+ svn_cmd cp trunk branches/b_ &&
+ echo "Branch commit to b_" >>branches/b_/src/a/readme &&
+ poke branches/b_/src/a/readme &&
+ svn_cmd commit -m "Branch commit to b_" &&
+ svn_cmd up && svn_cmd cp branches/b_ tags/t_ &&
+ echo "Tag commit to t_" >>tags/t_/src/a/readme &&
+ poke tags/t_/src/a/readme &&
+ svn_cmd commit -m "Tag commit to t_" &&
+ svn_cmd up
+ ) &&
+ git svn fetch three &&
+ test $(git rev-list refs/remotes/three/branches/b_ | wc -l) -eq 2 &&
+ test $(git rev-list refs/remotes/three/tags/t_ | wc -l) -eq 3 &&
+ test $(git rev-parse refs/remotes/three/branches/b_~1) = \
+ $(git rev-parse refs/remotes/three/trunk) &&
+ test $(git rev-parse refs/remotes/three/tags/t_~1) = \
+ $(git rev-parse refs/remotes/three/branches/b_) &&
+ git log --pretty=oneline refs/remotes/three/tags/t_ | \
+ sed -e "s/^.\{41\}//" >output.three &&
+ test_cmp expect.three output.three
+ '
+
+test_expect_success 'prepare test disallow prefixed multi-globs' "
+cat >expect.four <<EOF
+Only one set of wildcards (e.g. '*' or '*/*/*') is supported: branches/b_*/t/*
+
+EOF
+ "
+
+test_expect_success 'test disallow prefixed multi-globs' '
+ git config --add svn-remote.four.url "$svnrepo" &&
+ git config --add svn-remote.four.fetch \
+ trunk:refs/remotes/four/trunk &&
+ git config --add svn-remote.four.branches \
+ "branches/b_*/t/*:refs/remotes/four/branches/*" &&
+ git config --add svn-remote.four.tags \
+ "tags/t_*/*:refs/remotes/four/tags/*" &&
+ (
+ cd tmp &&
+ echo "try try" >>tags/t_end/src/b/readme &&
+ poke tags/t_end/src/b/readme &&
+ svn_cmd commit -m "try to try"
+ ) &&
+ test_must_fail git svn fetch four 2>stderr.four &&
+ test_cmp expect.four stderr.four &&
+ git config --unset svn-remote.four.branches &&
+ git config --unset svn-remote.four.tags
+ '
+
+test_expect_success 'prepare test globbing in the middle of the word' '
+ cat >expect.five <<EOF
+Tag commit to fghij
+Branch commit to abcde
+initial
+EOF
+ '
+
+test_expect_success 'test globbing in the middle of the word' '
+ git config --add svn-remote.five.url "$svnrepo" &&
+ git config --add svn-remote.five.fetch \
+ trunk:refs/remotes/five/trunk &&
+ git config --add svn-remote.five.branches \
+ "branches/a*e:refs/remotes/five/branches/*" &&
+ git config --add svn-remote.five.tags \
+ "tags/f*j:refs/remotes/five/tags/*" &&
+ (
+ cd tmp &&
+ svn_cmd cp trunk branches/abcde &&
+ echo "Branch commit to abcde" >>branches/abcde/src/a/readme &&
+ poke branches/b_/src/a/readme &&
+ svn_cmd commit -m "Branch commit to abcde" &&
+ svn_cmd up &&
+ svn_cmd cp branches/abcde tags/fghij &&
+ echo "Tag commit to fghij" >>tags/fghij/src/a/readme &&
+ poke tags/fghij/src/a/readme &&
+ svn_cmd commit -m "Tag commit to fghij" &&
+ svn_cmd up
+ ) &&
+ git svn fetch five &&
+ test $(git rev-list refs/remotes/five/branches/abcde | wc -l) -eq 2 &&
+ test $(git rev-list refs/remotes/five/tags/fghij | wc -l) -eq 3 &&
+ test $(git rev-parse refs/remotes/five/branches/abcde~1) = \
+ $(git rev-parse refs/remotes/five/trunk) &&
+ test $(git rev-parse refs/remotes/five/tags/fghij~1) = \
+ $(git rev-parse refs/remotes/five/branches/abcde) &&
+ git log --pretty=oneline refs/remotes/five/tags/fghij | \
+ sed -e "s/^.\{41\}//" >output.five &&
+ test_cmp expect.five output.five
+ '
+
+test_expect_success 'prepare test disallow multiple asterisks in one word' "
+ echo \"Only one '*' is allowed in a pattern: 'a*c*e'\" >expect.six &&
+ echo \"\" >>expect.six
+ "
+
+test_expect_success 'test disallow multiple asterisks in one word' '
+ git config --add svn-remote.six.url "$svnrepo" &&
+ git config --add svn-remote.six.fetch \
+ trunk:refs/remotes/six/trunk &&
+ git config --add svn-remote.six.branches \
+ "branches/a*c*e:refs/remotes/six/branches/*" &&
+ git config --add svn-remote.six.tags \
+ "tags/f*h*j:refs/remotes/six/tags/*" &&
+ (
+ cd tmp &&
+ echo "try try" >>tags/fghij/src/b/readme &&
+ poke tags/fghij/src/b/readme &&
+ svn_cmd commit -m "try to try"
+ ) &&
+ test_must_fail git svn fetch six 2>stderr.six &&
+ test_cmp expect.six stderr.six
+ '
+
+test_done
diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh
index 5cfb9cfc52..bb879a527d 100755
--- a/t/t9200-git-cvsexportcommit.sh
+++ b/t/t9200-git-cvsexportcommit.sh
@@ -35,7 +35,7 @@ exit 1
check_entries () {
# $1 == directory, $2 == expected
- grep '^/' "$1/CVS/Entries" | sort | cut -d/ -f2,3,5 >actual
+ sed -ne '/^\//p' "$1/CVS/Entries" | sort | cut -d/ -f2,3,5 >actual
if test -z "$2"
then
>expected
diff --git a/t/t9700/test.pl b/t/t9700/test.pl
index 7e8c40b97b..1b75c91965 100755
--- a/t/t9700/test.pl
+++ b/t/t9700/test.pl
@@ -17,6 +17,12 @@ BEGIN {
use Cwd;
use File::Basename;
+sub adjust_dirsep {
+ my $path = shift;
+ $path =~ s{\\}{/}g;
+ return $path;
+}
+
BEGIN { use_ok('Git') }
# set up
@@ -33,7 +39,7 @@ is($r->config_int("test.int"), 2048, "config_int: integer");
is($r->config_int("test.nonexistent"), undef, "config_int: nonexistent");
ok($r->config_bool("test.booltrue"), "config_bool: true");
ok(!$r->config_bool("test.boolfalse"), "config_bool: false");
-is($r->config_path("test.path") =~ s/\\/\//gr, $r->config("test.pathexpanded"),
+is(adjust_dirsep($r->config_path("test.path")), $r->config("test.pathexpanded"),
"config_path: ~/foo expansion");
is_deeply([$r->config_path("test.pathmulti")], ["foo", "bar"],
"config_path: multiple values");
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index c64e5a5025..8d99eb303f 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -617,7 +617,7 @@ test_must_fail () {
return 0
elif test $exit_code -gt 129 && test $exit_code -le 192
then
- echo >&2 "test_must_fail: died by signal: $*"
+ echo >&2 "test_must_fail: died by signal $(($exit_code - 128)): $*"
return 1
elif test $exit_code -eq 127
then