diff options
Diffstat (limited to 't')
57 files changed, 1651 insertions, 241 deletions
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh index 5aa8adcf9c..75482254a3 100644 --- a/t/lib-git-p4.sh +++ b/t/lib-git-p4.sh @@ -69,7 +69,7 @@ start_p4d() { ( cd "$db" && { - p4d -q -p $P4DPORT & + p4d -q -p $P4DPORT "$@" & echo $! >"$pidfile" } ) && diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index e6adf2f82d..e9714467d0 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -30,6 +30,18 @@ # Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at> # +if test -n "$NO_CURL" +then + skip_all='skipping test, git built without http support' + test_done +fi + +if test -n "$NO_EXPAT" && test -n "$LIB_HTTPD_DAV" +then + skip_all='skipping test, git built without expat support' + test_done +fi + test_tristate GIT_TEST_HTTPD if test "$GIT_TEST_HTTPD" = false then diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index 8dc6939b90..4ef5ed484c 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -831,4 +831,14 @@ test_expect_success !MINGW,!CYGWIN 'correct handling of backslashes' ' test_cmp err.expect err ' +test_expect_success 'info/exclude trumps core.excludesfile' ' + echo >>global-excludes usually-ignored && + echo >>.git/info/exclude "!usually-ignored" && + >usually-ignored && + echo "?? usually-ignored" >expect && + + git status --porcelain usually-ignored >actual && + test_cmp expect actual +' + test_done diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index ca7d2a630a..e0200b9f33 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -204,6 +204,16 @@ test_expect_success 'filtering large input to small output should use little mem GIT_MMAP_LIMIT=1m GIT_ALLOC_LIMIT=1m git add 30MB ' +test_expect_success 'filter that does not read is fine' ' + test-genrandom foo $((128 * 1024 + 1)) >big && + echo "big filter=epipe" >.gitattributes && + git config filter.epipe.clean "echo xyzzy" && + git add big && + git cat-file blob :big >actual && + echo xyzzy >expect && + test_cmp expect actual +' + test_expect_success EXPENSIVE 'filter large file' ' git config filter.largefile.smudge cat && git config filter.largefile.clean cat && diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh index 452320df83..1a56e5e82e 100755 --- a/t/t0027-auto-crlf.sh +++ b/t/t0027-auto-crlf.sh @@ -57,28 +57,35 @@ create_gitattributes () { check_warning () { case "$1" in - LF_CRLF) grep "LF will be replaced by CRLF" $2;; - CRLF_LF) grep "CRLF will be replaced by LF" $2;; - '') - >expect - grep "will be replaced by" $2 >actual - test_cmp expect actual - ;; - *) false ;; + 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 ;; + *) echo >&2 "Illegal 1": "$1" ; return false ;; esac + grep "will be replaced by" "$2" | sed -e "s/\(.*\) in [^ ]*$/\1/" >"$2".actual + test_cmp "$2".expect "$2".actual } -create_file_in_repo () { +commit_check_warn () { crlf=$1 attr=$2 lfname=$3 crlfname=$4 - lfmixcrlf=$5 - lfmixcr=$6 - crlfnul=$7 - create_gitattributes "$attr" && + repoMIX=$5 + lfmixcrlf=$6 + lfmixcr=$7 + crlfnul=$8 pfx=crlf_${crlf}_attr_${attr} - for f in LF CRLF LF_mix_CR CRLF_mix_LF CRLF_nul + # Special handling for repoMIX: It should already be in the repo + # with CRLF + f=repoMIX + fname=${pfx}_$f.txt + echo >.gitattributes && + cp $f $fname && + git -c core.autocrlf=false add $fname 2>"${pfx}_$f.err" && + git commit -m "repoMIX" && + create_gitattributes "$attr" && + for f in LF CRLF repoMIX LF_mix_CR CRLF_mix_LF LF_nul CRLF_nul do fname=${pfx}_$f.txt && cp $f $fname && @@ -109,7 +116,7 @@ check_files_in_repo () { } -check_files_in_ws () { +checkout_files () { eol=$1 crlf=$2 attr=$3 @@ -122,7 +129,7 @@ check_files_in_ws () { git config core.autocrlf $crlf && pfx=eol_${eol}_crlf_${crlf}_attr_${attr}_ && src=crlf_false_attr__ && - for f in LF CRLF LF_mix_CR CRLF_mix_LF CRLF_nul + for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul do rm $src$f.txt && if test -z "$eol"; then @@ -144,8 +151,8 @@ check_files_in_ws () { test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF_mix_CR" " compare_ws_file $pfx $lfmixcr ${src}LF_mix_CR.txt " - test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=CRLF_nul" " - compare_ws_file $pfx $crlfnul ${src}CRLF_nul.txt + test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF_nul" " + compare_ws_file $pfx $crlfnul ${src}LF_nul.txt " } @@ -157,6 +164,7 @@ test_expect_success 'setup master' ' 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 && @@ -169,40 +177,55 @@ test_expect_success 'setup master' ' warn_LF_CRLF="LF will be replaced by CRLF" warn_CRLF_LF="CRLF will be replaced by LF" -test_expect_success 'add files empty attr' ' - create_file_in_repo false "" "" "" "" "" "" && - create_file_in_repo true "" "LF_CRLF" "" "LF_CRLF" "" "" && - create_file_in_repo input "" "" "CRLF_LF" "CRLF_LF" "" "" +# WILC stands for "Warn if (this OS) converts LF into CRLF". +# WICL: Warn if CRLF becomes LF +# WAMIX: Mixed line endings: either CRLF->LF or LF->CRLF +if test_have_prereq NATIVE_CRLF +then + WILC=LF_CRLF + WICL= + WAMIX=LF_CRLF +else + WILC= + WICL=CRLF_LF + WAMIX=CRLF_LF +fi + +# attr LF CRLF repoMIX CRLFmixLF LFmixCR CRLFNUL +test_expect_success 'commit files empty attr' ' + commit_check_warn false "" "" "" "" "" "" "" && + commit_check_warn true "" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" "" && + commit_check_warn input "" "" "CRLF_LF" "CRLF_LF" "CRLF_LF" "" "" ' -test_expect_success 'add files attr=auto' ' - create_file_in_repo false "auto" "" "CRLF_LF" "CRLF_LF" "" "" && - create_file_in_repo true "auto" "LF_CRLF" "" "LF_CRLF" "" "" && - create_file_in_repo input "auto" "" "CRLF_LF" "CRLF_LF" "" "" +test_expect_success 'commit files attr=auto' ' + commit_check_warn false "auto" "$WILC" "$WICL" "$WAMIX" "$WAMIX" "" "" && + commit_check_warn true "auto" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" "" && + commit_check_warn input "auto" "" "CRLF_LF" "CRLF_LF" "CRLF_LF" "" "" ' -test_expect_success 'add files attr=text' ' - create_file_in_repo false "text" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" && - create_file_in_repo true "text" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" && - create_file_in_repo input "text" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" +test_expect_success 'commit files attr=text' ' + commit_check_warn false "text" "$WILC" "$WICL" "$WAMIX" "$WAMIX" "$WILC" "$WICL" && + commit_check_warn true "text" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "LF_CRLF" "" && + commit_check_warn input "text" "" "CRLF_LF" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" ' -test_expect_success 'add files attr=-text' ' - create_file_in_repo false "-text" "" "" "" "" "" && - create_file_in_repo true "-text" "" "" "" "" "" && - create_file_in_repo input "-text" "" "" "" "" "" +test_expect_success 'commit files attr=-text' ' + commit_check_warn false "-text" "" "" "" "" "" "" && + commit_check_warn true "-text" "" "" "" "" "" "" && + commit_check_warn input "-text" "" "" "" "" "" "" ' -test_expect_success 'add files attr=lf' ' - create_file_in_repo false "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" && - create_file_in_repo true "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" && - create_file_in_repo input "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" +test_expect_success 'commit files attr=lf' ' + commit_check_warn false "lf" "" "CRLF_LF" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" && + commit_check_warn true "lf" "" "CRLF_LF" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" && + commit_check_warn input "lf" "" "CRLF_LF" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" ' -test_expect_success 'add files attr=crlf' ' - create_file_in_repo false "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" && - create_file_in_repo true "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" && - create_file_in_repo input "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" +test_expect_success 'commit files attr=crlf' ' + commit_check_warn false "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "LF_CRLF" "" && + commit_check_warn true "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "LF_CRLF" "" && + commit_check_warn input "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "LF_CRLF" "" ' test_expect_success 'create files cleanup' ' @@ -237,7 +260,7 @@ test_expect_success 'commit -text' ' ################################################################################ # Check how files in the repo are changed when they are checked out # How to read the table below: -# - check_files_in_ws will check multiple files with a combination of settings +# - 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 @@ -249,87 +272,89 @@ test_expect_success 'commit -text' ' # - 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 +# ----------------- 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: -if test_have_prereq MINGW +if test_have_prereq NATIVE_CRLF then MIX_CRLF_LF=CRLF MIX_LF_CR=CRLF_mix_CR NL=CRLF +LFNUL=CRLF_nul else MIX_CRLF_LF=CRLF_mix_LF MIX_LF_CR=LF_mix_CR NL=LF +LFNUL=LF_nul fi export CRLF_MIX_LF_CR MIX NL -check_files_in_ws lf false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf true "" CRLF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf input "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf false "auto" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf true "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul -check_files_in_ws lf input "auto" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf false "text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws lf input "text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf false "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf true "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf input "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws lf false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws lf true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws lf input "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - -check_files_in_ws crlf false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws crlf true "" CRLF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws crlf false "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul -check_files_in_ws crlf true "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul -check_files_in_ws crlf false "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws crlf true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws crlf false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws crlf true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws crlf false "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws crlf true "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws crlf false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws crlf true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - -check_files_in_ws "" false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" true "" CRLF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" input "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" false "auto" $NL CRLF $MIX_CRLF_LF LF_mix_CR CRLF_nul -check_files_in_ws "" true "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul -check_files_in_ws "" input "auto" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" false "text" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR CRLF_nul -check_files_in_ws "" true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws "" input "text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" false "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" true "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" input "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws "" false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws "" true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws "" input "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - -check_files_in_ws native false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws native true "" CRLF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws native false "auto" $NL CRLF $MIX_CRLF_LF LF_mix_CR CRLF_nul -check_files_in_ws native true "auto" CRLF CRLF CRLF LF_mix_CR CRLF_nul -check_files_in_ws native false "text" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR CRLF_nul -check_files_in_ws native true "text" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws native false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws native true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws native false "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws native true "lf" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_files_in_ws native false "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul -check_files_in_ws native true "crlf" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul +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 test_done diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index c0143a0a70..93605f42f2 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -19,6 +19,14 @@ relative_path() { "test \"\$(test-path-utils relative_path '$1' '$2')\" = '$expected'" } +test_git_path() { + test_expect_success "git-path $1 $2 => $3" " + $1 git rev-parse --git-path $2 >actual && + echo $3 >expect && + test_cmp expect actual + " +} + # On Windows, we are using MSYS's bash, which mangles the paths. # Absolute paths are anchored at the MSYS installation directory, # which means that the path / accounts for this many characters: @@ -244,4 +252,32 @@ relative_path "<null>" "<empty>" ./ relative_path "<null>" "<null>" ./ relative_path "<null>" /foo/a/b ./ +test_git_path A=B info/grafts .git/info/grafts +test_git_path GIT_GRAFT_FILE=foo info/grafts foo +test_git_path GIT_GRAFT_FILE=foo info/////grafts foo +test_git_path GIT_INDEX_FILE=foo index foo +test_git_path GIT_INDEX_FILE=foo index/foo .git/index/foo +test_git_path GIT_INDEX_FILE=foo index2 .git/index2 +test_expect_success 'setup fake objects directory foo' 'mkdir foo' +test_git_path GIT_OBJECT_DIRECTORY=foo objects foo +test_git_path GIT_OBJECT_DIRECTORY=foo objects/foo foo/foo +test_git_path GIT_OBJECT_DIRECTORY=foo objects2 .git/objects2 +test_expect_success 'setup common repository' 'git --git-dir=bar init' +test_git_path GIT_COMMON_DIR=bar index .git/index +test_git_path GIT_COMMON_DIR=bar HEAD .git/HEAD +test_git_path GIT_COMMON_DIR=bar logs/HEAD .git/logs/HEAD +test_git_path GIT_COMMON_DIR=bar objects bar/objects +test_git_path GIT_COMMON_DIR=bar objects/bar bar/objects/bar +test_git_path GIT_COMMON_DIR=bar info/exclude bar/info/exclude +test_git_path GIT_COMMON_DIR=bar info/grafts bar/info/grafts +test_git_path GIT_COMMON_DIR=bar info/sparse-checkout .git/info/sparse-checkout +test_git_path GIT_COMMON_DIR=bar remotes/bar bar/remotes/bar +test_git_path GIT_COMMON_DIR=bar branches/bar bar/branches/bar +test_git_path GIT_COMMON_DIR=bar logs/refs/heads/master bar/logs/refs/heads/master +test_git_path GIT_COMMON_DIR=bar refs/heads/master bar/refs/heads/master +test_git_path GIT_COMMON_DIR=bar hooks/me bar/hooks/me +test_git_path GIT_COMMON_DIR=bar config bar/config +test_git_path GIT_COMMON_DIR=bar packed-refs bar/packed-refs +test_git_path GIT_COMMON_DIR=bar shallow bar/shallow + test_done diff --git a/t/t0302-credential-store.sh b/t/t0302-credential-store.sh index f61b40c69b..0979df93a1 100755 --- a/t/t0302-credential-store.sh +++ b/t/t0302-credential-store.sh @@ -6,4 +6,118 @@ test_description='credential-store tests' helper_test store +test_expect_success 'when xdg file does not exist, xdg file not created' ' + test_path_is_missing "$HOME/.config/git/credentials" && + test -s "$HOME/.git-credentials" +' + +test_expect_success 'setup xdg file' ' + rm -f "$HOME/.git-credentials" && + mkdir -p "$HOME/.config/git" && + >"$HOME/.config/git/credentials" +' + +helper_test store + +test_expect_success 'when xdg file exists, home file not created' ' + test -s "$HOME/.config/git/credentials" && + test_path_is_missing "$HOME/.git-credentials" +' + +test_expect_success 'setup custom xdg file' ' + rm -f "$HOME/.git-credentials" && + rm -f "$HOME/.config/git/credentials" && + mkdir -p "$HOME/xdg/git" && + >"$HOME/xdg/git/credentials" +' + +XDG_CONFIG_HOME="$HOME/xdg" +export XDG_CONFIG_HOME +helper_test store +unset XDG_CONFIG_HOME + +test_expect_success 'if custom xdg file exists, home and xdg files not created' ' + test_when_finished "rm -f $HOME/xdg/git/credentials" && + test -s "$HOME/xdg/git/credentials" && + test_path_is_missing "$HOME/.git-credentials" && + test_path_is_missing "$HOME/.config/git/credentials" +' + +test_expect_success 'get: use home file if both home and xdg files have matches' ' + echo "https://home-user:home-pass@example.com" >"$HOME/.git-credentials" && + mkdir -p "$HOME/.config/git" && + echo "https://xdg-user:xdg-pass@example.com" >"$HOME/.config/git/credentials" && + check fill store <<-\EOF + protocol=https + host=example.com + -- + protocol=https + host=example.com + username=home-user + password=home-pass + -- + EOF +' + +test_expect_success 'get: use xdg file if home file has no matches' ' + >"$HOME/.git-credentials" && + mkdir -p "$HOME/.config/git" && + echo "https://xdg-user:xdg-pass@example.com" >"$HOME/.config/git/credentials" && + check fill store <<-\EOF + protocol=https + host=example.com + -- + protocol=https + host=example.com + username=xdg-user + password=xdg-pass + -- + EOF +' + +test_expect_success POSIXPERM 'get: use xdg file if home file is unreadable' ' + echo "https://home-user:home-pass@example.com" >"$HOME/.git-credentials" && + chmod -r "$HOME/.git-credentials" && + mkdir -p "$HOME/.config/git" && + echo "https://xdg-user:xdg-pass@example.com" >"$HOME/.config/git/credentials" && + check fill store <<-\EOF + protocol=https + host=example.com + -- + protocol=https + host=example.com + username=xdg-user + password=xdg-pass + -- + EOF +' + +test_expect_success 'store: if both xdg and home files exist, only store in home file' ' + >"$HOME/.git-credentials" && + mkdir -p "$HOME/.config/git" && + >"$HOME/.config/git/credentials" && + check approve store <<-\EOF && + protocol=https + host=example.com + username=store-user + password=store-pass + EOF + echo "https://store-user:store-pass@example.com" >expected && + test_cmp expected "$HOME/.git-credentials" && + test_must_be_empty "$HOME/.config/git/credentials" +' + + +test_expect_success 'erase: erase matching credentials from both xdg and home files' ' + echo "https://home-user:home-pass@example.com" >"$HOME/.git-credentials" && + mkdir -p "$HOME/.config/git" && + echo "https://xdg-user:xdg-pass@example.com" >"$HOME/.config/git/credentials" && + check reject store <<-\EOF && + protocol=https + host=example.com + EOF + test_must_be_empty "$HOME/.git-credentials" && + test_must_be_empty "$HOME/.config/git/credentials" +' + test_done diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index ab36b1eb72..4f225db9a7 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -47,6 +47,18 @@ $content" test_cmp expect actual ' + test_expect_success "Type of $type is correct using --allow-unknown-type" ' + echo $type >expect && + git cat-file -t --allow-unknown-type $sha1 >actual && + test_cmp expect actual + ' + + test_expect_success "Size of $type is correct using --allow-unknown-type" ' + echo $size >expect && + git cat-file -s --allow-unknown-type $sha1 >actual && + test_cmp expect actual + ' + test -z "$content" || test_expect_success "Content of $type is correct" ' maybe_remove_timestamp "$content" $no_ts >expect && @@ -296,4 +308,37 @@ test_expect_success '%(deltabase) reports packed delta bases' ' } ' +bogus_type="bogus" +bogus_content="bogus" +bogus_size=$(strlen "$bogus_content") +bogus_sha1=$(echo_without_newline "$bogus_content" | git hash-object -t $bogus_type --literally -w --stdin) + +test_expect_success "Type of broken object is correct" ' + echo $bogus_type >expect && + git cat-file -t --allow-unknown-type $bogus_sha1 >actual && + test_cmp expect actual +' + +test_expect_success "Size of broken object is correct" ' + echo $bogus_size >expect && + git cat-file -s --allow-unknown-type $bogus_sha1 >actual && + test_cmp expect actual +' +bogus_type="abcdefghijklmnopqrstuvwxyz1234679" +bogus_content="bogus" +bogus_size=$(strlen "$bogus_content") +bogus_sha1=$(echo_without_newline "$bogus_content" | git hash-object -t $bogus_type --literally -w --stdin) + +test_expect_success "Type of broken object is correct when type is large" ' + echo $bogus_type >expect && + git cat-file -t --allow-unknown-type $bogus_sha1 >actual && + test_cmp expect actual +' + +test_expect_success "Size of large broken object is correct when type is large" ' + echo $bogus_size >expect && + git cat-file -s --allow-unknown-type $bogus_sha1 >actual && + test_cmp expect actual +' + test_done diff --git a/t/t1007-hash-object.sh b/t/t1007-hash-object.sh index f83df8eb8b..7d2baa15bb 100755 --- a/t/t1007-hash-object.sh +++ b/t/t1007-hash-object.sh @@ -201,4 +201,23 @@ test_expect_success 'corrupt tag' ' test_must_fail git hash-object -t tag --stdin </dev/null ' +test_expect_success 'hash-object complains about bogus type name' ' + test_must_fail git hash-object -t bogus --stdin </dev/null +' + +test_expect_success 'hash-object complains about truncated type name' ' + test_must_fail git hash-object -t bl --stdin </dev/null +' + +test_expect_success '--literally' ' + t=1234567890 && + echo example | git hash-object -t $t --literally --stdin +' + +test_expect_success '--literally with extra-long type' ' + t=12345678901234567890123456789012345678901234567890 && + t="$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t$t" && + echo example | git hash-object -t $t --literally --stdin +' + test_done diff --git a/t/t1020-subdirectory.sh b/t/t1020-subdirectory.sh index 2edb4f2de5..8e22b03cdd 100755 --- a/t/t1020-subdirectory.sh +++ b/t/t1020-subdirectory.sh @@ -162,16 +162,20 @@ test_expect_success 'no file/rev ambiguity check inside .git' ' ) ' -test_expect_success 'no file/rev ambiguity check inside a bare repo' ' +test_expect_success 'no file/rev ambiguity check inside a bare repo (explicit GIT_DIR)' ' + test_when_finished "rm -fr foo.git" && git clone -s --bare .git foo.git && ( cd foo.git && + # older Git needed help by exporting GIT_DIR=. + # to realize that it is inside a bare repository. + # We keep this test around for regression testing. GIT_DIR=. git show -s HEAD ) ' -# This still does not work as it should... -: test_expect_success 'no file/rev ambiguity check inside a bare repo' ' +test_expect_success 'no file/rev ambiguity check inside a bare repo' ' + test_when_finished "rm -fr foo.git" && git clone -s --bare .git foo.git && ( cd foo.git && @@ -180,7 +184,6 @@ test_expect_success 'no file/rev ambiguity check inside a bare repo' ' ' test_expect_success SYMLINKS 'detection should not be fooled by a symlink' ' - rm -fr foo.git && git clone -s .git another && ln -s another yetanother && ( diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index 6805b9e6bb..ba89f4c009 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -519,7 +519,7 @@ test_expect_success 'stdin create ref works with path with space to blob' ' test_expect_success 'stdin update ref fails with wrong old value' ' echo "update $c $m $m~1" >stdin && test_must_fail git update-ref --stdin <stdin 2>err && - grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err && + grep "fatal: Cannot lock ref '"'"'$c'"'"'" err && test_must_fail git rev-parse --verify -q $c ' @@ -555,7 +555,7 @@ test_expect_success 'stdin update ref works with right old value' ' test_expect_success 'stdin delete ref fails with wrong old value' ' echo "delete $a $m~1" >stdin && test_must_fail git update-ref --stdin <stdin 2>err && - grep "fatal: Cannot lock the ref '"'"'$a'"'"'" err && + grep "fatal: Cannot lock ref '"'"'$a'"'"'" err && git rev-parse $m >expect && git rev-parse $a >actual && test_cmp expect actual @@ -688,7 +688,7 @@ test_expect_success 'stdin update refs fails with wrong old value' ' update $c '' EOF test_must_fail git update-ref --stdin <stdin 2>err && - grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err && + grep "fatal: Cannot lock ref '"'"'$c'"'"'" err && git rev-parse $m >expect && git rev-parse $a >actual && test_cmp expect actual && @@ -883,7 +883,7 @@ test_expect_success 'stdin -z create ref works with path with space to blob' ' test_expect_success 'stdin -z update ref fails with wrong old value' ' printf $F "update $c" "$m" "$m~1" >stdin && test_must_fail git update-ref -z --stdin <stdin 2>err && - grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err && + grep "fatal: Cannot lock ref '"'"'$c'"'"'" err && test_must_fail git rev-parse --verify -q $c ' @@ -899,7 +899,7 @@ test_expect_success 'stdin -z create ref fails when ref exists' ' git rev-parse "$c" >expect && printf $F "create $c" "$m~1" >stdin && test_must_fail git update-ref -z --stdin <stdin 2>err && - grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err && + grep "fatal: Cannot lock ref '"'"'$c'"'"'" err && git rev-parse "$c" >actual && test_cmp expect actual ' @@ -930,7 +930,7 @@ test_expect_success 'stdin -z update ref works with right old value' ' test_expect_success 'stdin -z delete ref fails with wrong old value' ' printf $F "delete $a" "$m~1" >stdin && test_must_fail git update-ref -z --stdin <stdin 2>err && - grep "fatal: Cannot lock the ref '"'"'$a'"'"'" err && + grep "fatal: Cannot lock ref '"'"'$a'"'"'" err && git rev-parse $m >expect && git rev-parse $a >actual && test_cmp expect actual @@ -1045,7 +1045,7 @@ test_expect_success 'stdin -z update refs fails with wrong old value' ' git update-ref $c $m && printf $F "update $a" "$m" "$m" "update $b" "$m" "$m" "update $c" "$m" "$Z" >stdin && test_must_fail git update-ref -z --stdin <stdin 2>err && - grep "fatal: Cannot lock the ref '"'"'$c'"'"'" err && + grep "fatal: Cannot lock ref '"'"'$c'"'"'" err && git rev-parse $m >expect && git rev-parse $a >actual && test_cmp expect actual && @@ -1065,4 +1065,32 @@ test_expect_success 'stdin -z delete refs works with packed and loose refs' ' test_must_fail git rev-parse --verify -q $c ' +run_with_limited_open_files () { + (ulimit -n 32 && "$@") +} + +test_lazy_prereq ULIMIT_FILE_DESCRIPTORS 'run_with_limited_open_files true' + +test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction creating branches does not burst open file limit' ' +( + for i in $(test_seq 33) + do + echo "create refs/heads/$i HEAD" + done >large_input && + run_with_limited_open_files git update-ref --stdin <large_input && + git rev-parse --verify -q refs/heads/33 +) +' + +test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches does not burst open file limit' ' +( + for i in $(test_seq 33) + do + echo "delete refs/heads/$i HEAD" + done >large_input && + run_with_limited_open_files git update-ref --stdin <large_input && + test_must_fail git rev-parse --verify -q refs/heads/33 +) +' + test_done diff --git a/t/t1404-update-ref-df-conflicts.sh b/t/t1404-update-ref-df-conflicts.sh new file mode 100755 index 0000000000..66bafb5cf4 --- /dev/null +++ b/t/t1404-update-ref-df-conflicts.sh @@ -0,0 +1,107 @@ +#!/bin/sh + +test_description='Test git update-ref with D/F conflicts' +. ./test-lib.sh + +test_update_rejected () { + prefix="$1" && + before="$2" && + pack="$3" && + create="$4" && + error="$5" && + printf "create $prefix/%s $C\n" $before | + git update-ref --stdin && + git for-each-ref $prefix >unchanged && + if $pack + then + git pack-refs --all + fi && + printf "create $prefix/%s $C\n" $create >input && + test_must_fail git update-ref --stdin <input 2>output.err && + grep -F "$error" output.err && + git for-each-ref $prefix >actual && + test_cmp unchanged actual +} + +Q="'" + +test_expect_success 'setup' ' + + git commit --allow-empty -m Initial && + C=$(git rev-parse HEAD) + +' + +test_expect_success 'existing loose ref is a simple prefix of new' ' + + prefix=refs/1l && + test_update_rejected $prefix "a c e" false "b c/x d" \ + "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q" + +' + +test_expect_success 'existing packed ref is a simple prefix of new' ' + + prefix=refs/1p && + test_update_rejected $prefix "a c e" true "b c/x d" \ + "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x$Q" + +' + +test_expect_success 'existing loose ref is a deeper prefix of new' ' + + prefix=refs/2l && + test_update_rejected $prefix "a c e" false "b c/x/y d" \ + "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q" + +' + +test_expect_success 'existing packed ref is a deeper prefix of new' ' + + prefix=refs/2p && + test_update_rejected $prefix "a c e" true "b c/x/y d" \ + "$Q$prefix/c$Q exists; cannot create $Q$prefix/c/x/y$Q" + +' + +test_expect_success 'new ref is a simple prefix of existing loose' ' + + prefix=refs/3l && + test_update_rejected $prefix "a c/x e" false "b c d" \ + "$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q" + +' + +test_expect_success 'new ref is a simple prefix of existing packed' ' + + prefix=refs/3p && + test_update_rejected $prefix "a c/x e" true "b c d" \ + "$Q$prefix/c/x$Q exists; cannot create $Q$prefix/c$Q" + +' + +test_expect_success 'new ref is a deeper prefix of existing loose' ' + + prefix=refs/4l && + test_update_rejected $prefix "a c/x/y e" false "b c d" \ + "$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q" + +' + +test_expect_success 'new ref is a deeper prefix of existing packed' ' + + prefix=refs/4p && + test_update_rejected $prefix "a c/x/y e" true "b c d" \ + "$Q$prefix/c/x/y$Q exists; cannot create $Q$prefix/c$Q" + +' + +test_expect_success 'one new ref is a simple prefix of another' ' + + prefix=refs/5 && + test_update_rejected $prefix "a e" false "b c c/x d" \ + "cannot process $Q$prefix/c$Q and $Q$prefix/c/x$Q at the same time" + +' + +test_done diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh index 468e85621a..16d0b8bd1a 100755 --- a/t/t1430-bad-ref-name.sh +++ b/t/t1430-bad-ref-name.sh @@ -68,6 +68,14 @@ test_expect_success 'branch -D cannot delete non-ref in .git dir' ' test_cmp expect .git/my-private-file ' +test_expect_success 'branch -D cannot delete ref in .git dir' ' + git rev-parse HEAD >.git/my-private-file && + git rev-parse HEAD >expect && + git branch foo/legit && + test_must_fail git branch -D foo////./././../../../my-private-file && + test_cmp expect .git/my-private-file +' + test_expect_success 'branch -D cannot delete absolute path' ' git branch -f extra && test_must_fail git branch -D "$(pwd)/.git/refs/heads/extra" && diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh index 8f36aa9fc4..cc5b870e58 100755 --- a/t/t1501-worktree.sh +++ b/t/t1501-worktree.sh @@ -346,4 +346,81 @@ test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' ' test_cmp expected actual ' +test_expect_success 'Multi-worktree setup' ' + mkdir work && + mkdir -p repo.git/repos/foo && + cp repo.git/HEAD repo.git/index repo.git/repos/foo && + test_might_fail cp repo.git/sharedindex.* repo.git/repos/foo && + sane_unset GIT_DIR GIT_CONFIG GIT_WORK_TREE +' + +test_expect_success 'GIT_DIR set (1)' ' + echo "gitdir: repo.git/repos/foo" >gitfile && + echo ../.. >repo.git/repos/foo/commondir && + ( + cd work && + GIT_DIR=../gitfile git rev-parse --git-common-dir >actual && + test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && + test_cmp expect actual + ) +' + +test_expect_success 'GIT_DIR set (2)' ' + echo "gitdir: repo.git/repos/foo" >gitfile && + echo "$(pwd)/repo.git" >repo.git/repos/foo/commondir && + ( + cd work && + GIT_DIR=../gitfile git rev-parse --git-common-dir >actual && + test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && + test_cmp expect actual + ) +' + +test_expect_success 'Auto discovery' ' + echo "gitdir: repo.git/repos/foo" >.git && + echo ../.. >repo.git/repos/foo/commondir && + ( + cd work && + git rev-parse --git-common-dir >actual && + test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && + test_cmp expect actual && + echo haha >data1 && + git add data1 && + git ls-files --full-name :/ | grep data1 >actual && + echo work/data1 >expect && + test_cmp expect actual + ) +' + +test_expect_success '$GIT_DIR/common overrides core.worktree' ' + mkdir elsewhere && + git --git-dir=repo.git config core.worktree "$TRASH_DIRECTORY/elsewhere" && + echo "gitdir: repo.git/repos/foo" >.git && + echo ../.. >repo.git/repos/foo/commondir && + ( + cd work && + git rev-parse --git-common-dir >actual && + test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect && + test_cmp expect actual && + echo haha >data2 && + git add data2 && + git ls-files --full-name :/ | grep data2 >actual && + echo work/data2 >expect && + test_cmp expect actual + ) +' + +test_expect_success '$GIT_WORK_TREE overrides $GIT_DIR/common' ' + echo "gitdir: repo.git/repos/foo" >.git && + echo ../.. >repo.git/repos/foo/commondir && + ( + cd work && + echo haha >data3 && + git --git-dir=../.git --work-tree=. add data3 && + git ls-files --full-name -- :/ | grep data3 >actual && + echo data3 >expect && + test_cmp expect actual + ) +' + test_done diff --git a/t/t1509/prepare-chroot.sh b/t/t1509/prepare-chroot.sh index 62691172e3..6d47e2c725 100755 --- a/t/t1509/prepare-chroot.sh +++ b/t/t1509/prepare-chroot.sh @@ -14,25 +14,45 @@ xmkdir() { R="$1" +[ "$(id -u)" -eq 0 ] && die "This script should not be run as root, what if it does rm -rf /?" [ -n "$R" ] || die "usage: prepare-chroot.sh <root>" [ -x git ] || die "This script needs to be executed at git source code's top directory" -[ -x /bin/busybox ] || die "You need busybox" +if [ -x /bin/busybox ]; then + BB=/bin/busybox +elif [ -x /usr/bin/busybox ]; then + BB=/usr/bin/busybox +else + die "You need busybox" +fi xmkdir "$R" "$R/bin" "$R/etc" "$R/lib" "$R/dev" -[ -c "$R/dev/null" ] || die "/dev/null is missing. Do mknod $R/dev/null c 1 3 && chmod 666 $R/dev/null" +touch "$R/dev/null" echo "root:x:0:0:root:/:/bin/sh" > "$R/etc/passwd" echo "$(id -nu):x:$(id -u):$(id -g)::$(pwd)/t:/bin/sh" >> "$R/etc/passwd" echo "root::0:root" > "$R/etc/group" echo "$(id -ng)::$(id -g):$(id -nu)" >> "$R/etc/group" -[ -x "$R/bin/busybox" ] || cp /bin/busybox "$R/bin/busybox" -[ -x "$R/bin/sh" ] || ln -s /bin/busybox "$R/bin/sh" -[ -x "$R/bin/su" ] || ln -s /bin/busybox "$R/bin/su" +[ -x "$R$BB" ] || cp $BB "$R/bin/busybox" +for cmd in sh su ls expr tr basename rm mkdir mv id uname dirname cat true sed diff; do + ln -f -s /bin/busybox "$R/bin/$cmd" +done mkdir -p "$R$(pwd)" rsync --exclude-from t/t1509/excludes -Ha . "$R$(pwd)" -ldd git | grep '/' | sed 's,.*\s\(/[^ ]*\).*,\1,' | while read i; do - mkdir -p "$R$(dirname $i)" - cp "$i" "$R/$i" +# Fake perl to reduce dependency, t1509 does not use perl, but some +# env might slip through, see test-lib.sh, unset.*PERL_PATH +sed 's|^PERL_PATH=.*|PERL_PATH=/bin/true|' GIT-BUILD-OPTIONS > "$R$(pwd)/GIT-BUILD-OPTIONS" +for cmd in git $BB;do + ldd $cmd | grep '/' | sed 's,.*\s\(/[^ ]*\).*,\1,' | while read i; do + mkdir -p "$R$(dirname $i)" + cp "$i" "$R/$i" + done done -echo "Execute this in root: 'chroot $R /bin/su - $(id -nu)'" +cat <<EOF +All is set up in $R, execute t1509 with the following commands: + +sudo chroot $R /bin/su - $(id -nu) +IKNOWWHATIAMDOING=YES ./t1509-root-worktree.sh -v -i + +When you are done, simply delete $R to clean up +EOF diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh index e1b2a99f10..33c1a587b3 100755 --- a/t/t1510-repo-setup.sh +++ b/t/t1510-repo-setup.sh @@ -106,6 +106,7 @@ setup_env () { expect () { cat >"$1/expected" <<-EOF setup: git_dir: $2 + setup: git_common_dir: $2 setup: worktree: $3 setup: cwd: $4 setup: prefix: $5 diff --git a/t/t2025-checkout-to.sh b/t/t2025-checkout-to.sh new file mode 100755 index 0000000000..f8e4df4818 --- /dev/null +++ b/t/t2025-checkout-to.sh @@ -0,0 +1,129 @@ +#!/bin/sh + +test_description='test git checkout --to' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit init +' + +test_expect_success 'checkout --to not updating paths' ' + test_must_fail git checkout --to -- init.t +' + +test_expect_success 'checkout --to an existing worktree' ' + mkdir -p existing/subtree && + test_must_fail git checkout --detach --to existing master +' + +test_expect_success 'checkout --to an existing empty worktree' ' + mkdir existing_empty && + git checkout --detach --to existing_empty master +' + +test_expect_success 'checkout --to refuses to checkout locked branch' ' + test_must_fail git checkout --to zere master && + ! test -d zere && + ! test -d .git/worktrees/zere +' + +test_expect_success 'checkout --to a new worktree' ' + git rev-parse HEAD >expect && + git checkout --detach --to here master && + ( + cd here && + test_cmp ../init.t init.t && + test_must_fail git symbolic-ref HEAD && + git rev-parse HEAD >actual && + test_cmp ../expect actual && + git fsck + ) +' + +test_expect_success 'checkout --to a new worktree from a subdir' ' + ( + mkdir sub && + cd sub && + git checkout --detach --to here master && + cd here && + test_cmp ../../init.t init.t + ) +' + +test_expect_success 'checkout --to from a linked checkout' ' + ( + cd here && + git checkout --detach --to nested-here master && + cd nested-here && + git fsck + ) +' + +test_expect_success 'checkout --to a new worktree creating new branch' ' + git checkout --to there -b newmaster master && + ( + cd there && + test_cmp ../init.t init.t && + git symbolic-ref HEAD >actual && + echo refs/heads/newmaster >expect && + test_cmp expect actual && + git fsck + ) +' + +test_expect_success 'die the same branch is already checked out' ' + ( + cd here && + test_must_fail git checkout newmaster + ) +' + +test_expect_success 'not die the same branch is already checked out' ' + ( + cd here && + git checkout --ignore-other-worktrees --to anothernewmaster newmaster + ) +' + +test_expect_success 'not die on re-checking out current branch' ' + ( + cd there && + git checkout newmaster + ) +' + +test_expect_success 'checkout --to from a bare repo' ' + ( + git clone --bare . bare && + cd bare && + git checkout --to ../there2 -b bare-master master + ) +' + +test_expect_success 'checkout from a bare repo without --to' ' + ( + cd bare && + test_must_fail git checkout master + ) +' + +test_expect_success 'checkout with grafts' ' + test_when_finished rm .git/info/grafts && + test_commit abc && + SHA1=`git rev-parse HEAD` && + test_commit def && + test_commit xyz && + echo "`git rev-parse HEAD` $SHA1" >.git/info/grafts && + cat >expected <<-\EOF && + xyz + abc + EOF + git log --format=%s -2 >actual && + test_cmp expected actual && + git checkout --detach --to grafted master && + git --git-dir=grafted/.git log --format=%s -2 >actual && + test_cmp expected actual +' + +test_done diff --git a/t/t2026-prune-linked-checkouts.sh b/t/t2026-prune-linked-checkouts.sh new file mode 100755 index 0000000000..1821a480c5 --- /dev/null +++ b/t/t2026-prune-linked-checkouts.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +test_description='prune $GIT_DIR/worktrees' + +. ./test-lib.sh + +test_expect_success initialize ' + git commit --allow-empty -m init +' + +test_expect_success 'prune --worktrees on normal repo' ' + git prune --worktrees && + test_must_fail git prune --worktrees abc +' + +test_expect_success 'prune files inside $GIT_DIR/worktrees' ' + mkdir .git/worktrees && + : >.git/worktrees/abc && + git prune --worktrees --verbose >actual && + cat >expect <<EOF && +Removing worktrees/abc: not a valid directory +EOF + test_i18ncmp expect actual && + ! test -f .git/worktrees/abc && + ! test -d .git/worktrees +' + +test_expect_success 'prune directories without gitdir' ' + mkdir -p .git/worktrees/def/abc && + : >.git/worktrees/def/def && + cat >expect <<EOF && +Removing worktrees/def: gitdir file does not exist +EOF + git prune --worktrees --verbose >actual && + test_i18ncmp expect actual && + ! test -d .git/worktrees/def && + ! test -d .git/worktrees +' + +test_expect_success SANITY 'prune directories with unreadable gitdir' ' + mkdir -p .git/worktrees/def/abc && + : >.git/worktrees/def/def && + : >.git/worktrees/def/gitdir && + chmod u-r .git/worktrees/def/gitdir && + git prune --worktrees --verbose >actual && + test_i18ngrep "Removing worktrees/def: unable to read gitdir file" actual && + ! test -d .git/worktrees/def && + ! test -d .git/worktrees +' + +test_expect_success 'prune directories with invalid gitdir' ' + mkdir -p .git/worktrees/def/abc && + : >.git/worktrees/def/def && + : >.git/worktrees/def/gitdir && + git prune --worktrees --verbose >actual && + test_i18ngrep "Removing worktrees/def: invalid gitdir file" actual && + ! test -d .git/worktrees/def && + ! test -d .git/worktrees +' + +test_expect_success 'prune directories with gitdir pointing to nowhere' ' + mkdir -p .git/worktrees/def/abc && + : >.git/worktrees/def/def && + echo "$(pwd)"/nowhere >.git/worktrees/def/gitdir && + git prune --worktrees --verbose >actual && + test_i18ngrep "Removing worktrees/def: gitdir file points to non-existent location" actual && + ! test -d .git/worktrees/def && + ! test -d .git/worktrees +' + +test_expect_success 'not prune locked checkout' ' + test_when_finished rm -r .git/worktrees && + mkdir -p .git/worktrees/ghi && + : >.git/worktrees/ghi/locked && + git prune --worktrees && + test -d .git/worktrees/ghi +' + +test_expect_success 'not prune recent checkouts' ' + test_when_finished rm -r .git/worktrees && + mkdir zz && + mkdir -p .git/worktrees/jlm && + echo "$(pwd)"/zz >.git/worktrees/jlm/gitdir && + rmdir zz && + git prune --worktrees --verbose --expire=2.days.ago && + test -d .git/worktrees/jlm +' + +test_expect_success 'not prune proper checkouts' ' + test_when_finished rm -r .git/worktrees && + git checkout "--to=$PWD/nop" --detach master && + git prune --worktrees && + test -d .git/worktrees/nop +' + +test_done diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index 2a4a749b4f..7c641bfaf4 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -5,10 +5,24 @@ test_description='Intent to add' . ./test-lib.sh test_expect_success 'intent to add' ' + test_commit 1 && + git rm 1.t && + echo hello >1.t && echo hello >file && echo hello >elif && git add -N file && - git add elif + git add elif && + git add -N 1.t +' + +test_expect_success 'git status' ' + git status --porcelain | grep -v actual >actual && + cat >expect <<-\EOF && + DA 1.t + A elif + A file + EOF + test_cmp expect actual ' test_expect_success 'check result of "add -N"' ' @@ -43,7 +57,8 @@ test_expect_success 'i-t-a entry is simply ignored' ' git add -N nitfol && git commit -m second && test $(git ls-tree HEAD -- nitfol | wc -l) = 0 && - test $(git diff --name-only HEAD -- nitfol | wc -l) = 1 + test $(git diff --name-only HEAD -- nitfol | wc -l) = 0 && + test $(git diff --name-only -- nitfol | wc -l) = 1 ' test_expect_success 'can commit with an unrelated i-t-a entry in index' ' @@ -72,13 +87,13 @@ test_expect_success 'cache-tree invalidates i-t-a paths' ' : >dir/bar && git add -N dir/bar && git diff --cached --name-only >actual && - echo dir/bar >expect && + >expect && test_cmp expect actual && git write-tree >/dev/null && git diff --cached --name-only >actual && - echo dir/bar >expect && + >expect && test_cmp expect actual ' diff --git a/t/t3033-merge-toplevel.sh b/t/t3033-merge-toplevel.sh new file mode 100755 index 0000000000..46aadc410b --- /dev/null +++ b/t/t3033-merge-toplevel.sh @@ -0,0 +1,136 @@ +#!/bin/sh + +test_description='"git merge" top-level frontend' + +. ./test-lib.sh + +t3033_reset () { + git checkout -B master two && + git branch -f left three && + git branch -f right four +} + +test_expect_success setup ' + test_commit one && + git branch left && + git branch right && + test_commit two && + git checkout left && + test_commit three && + git checkout right && + test_commit four && + git checkout master +' + +# Local branches + +test_expect_success 'merge an octopus into void' ' + t3033_reset && + git checkout --orphan test && + git rm -fr . && + test_must_fail git merge left right && + test_must_fail git rev-parse --verify HEAD && + git diff --quiet && + test_must_fail git rev-parse HEAD +' + +test_expect_success 'merge an octopus, fast-forward (ff)' ' + t3033_reset && + git reset --hard one && + git merge left right && + # one is ancestor of three (left) and four (right) + test_must_fail git rev-parse --verify HEAD^3 && + git rev-parse HEAD^1 HEAD^2 | sort >actual && + git rev-parse three four | sort >expect && + test_cmp expect actual +' + +test_expect_success 'merge octopus, non-fast-forward (ff)' ' + t3033_reset && + git reset --hard one && + git merge --no-ff left right && + # one is ancestor of three (left) and four (right) + test_must_fail git rev-parse --verify HEAD^4 && + git rev-parse HEAD^1 HEAD^2 HEAD^3 | sort >actual && + git rev-parse one three four | sort >expect && + test_cmp expect actual +' + +test_expect_success 'merge octopus, fast-forward (does not ff)' ' + t3033_reset && + git merge left right && + # two (master) is not an ancestor of three (left) and four (right) + test_must_fail git rev-parse --verify HEAD^4 && + git rev-parse HEAD^1 HEAD^2 HEAD^3 | sort >actual && + git rev-parse two three four | sort >expect && + test_cmp expect actual +' + +test_expect_success 'merge octopus, non-fast-forward' ' + t3033_reset && + git merge --no-ff left right && + test_must_fail git rev-parse --verify HEAD^4 && + git rev-parse HEAD^1 HEAD^2 HEAD^3 | sort >actual && + git rev-parse two three four | sort >expect && + test_cmp expect actual +' + +# The same set with FETCH_HEAD + +test_expect_success 'merge FETCH_HEAD octopus into void' ' + t3033_reset && + git checkout --orphan test && + git rm -fr . && + git fetch . left right && + test_must_fail git merge FETCH_HEAD && + test_must_fail git rev-parse --verify HEAD && + git diff --quiet && + test_must_fail git rev-parse HEAD +' + +test_expect_success 'merge FETCH_HEAD octopus fast-forward (ff)' ' + t3033_reset && + git reset --hard one && + git fetch . left right && + git merge FETCH_HEAD && + # one is ancestor of three (left) and four (right) + test_must_fail git rev-parse --verify HEAD^3 && + git rev-parse HEAD^1 HEAD^2 | sort >actual && + git rev-parse three four | sort >expect && + test_cmp expect actual +' + +test_expect_success 'merge FETCH_HEAD octopus non-fast-forward (ff)' ' + t3033_reset && + git reset --hard one && + git fetch . left right && + git merge --no-ff FETCH_HEAD && + # one is ancestor of three (left) and four (right) + test_must_fail git rev-parse --verify HEAD^4 && + git rev-parse HEAD^1 HEAD^2 HEAD^3 | sort >actual && + git rev-parse one three four | sort >expect && + test_cmp expect actual +' + +test_expect_success 'merge FETCH_HEAD octopus fast-forward (does not ff)' ' + t3033_reset && + git fetch . left right && + git merge FETCH_HEAD && + # two (master) is not an ancestor of three (left) and four (right) + test_must_fail git rev-parse --verify HEAD^4 && + git rev-parse HEAD^1 HEAD^2 HEAD^3 | sort >actual && + git rev-parse two three four | sort >expect && + test_cmp expect actual +' + +test_expect_success 'merge FETCH_HEAD octopus non-fast-forward' ' + t3033_reset && + git fetch . left right && + git merge --no-ff FETCH_HEAD && + test_must_fail git rev-parse --verify HEAD^4 && + git rev-parse HEAD^1 HEAD^2 HEAD^3 | sort >actual && + git rev-parse two three four | sort >expect && + test_cmp expect actual +' + +test_done diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index aa9eb3a3e5..8aae98d482 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -187,4 +187,21 @@ test_expect_success 'notice d/f conflict with existing ref' ' test_must_fail git branch foo/bar/baz/lots/of/extra/components ' +test_expect_success 'timeout if packed-refs.lock exists' ' + LOCK=.git/packed-refs.lock && + >"$LOCK" && + test_when_finished "rm -f $LOCK" && + test_must_fail git pack-refs --all --prune +' + +test_expect_success 'retry acquiring packed-refs.lock' ' + LOCK=.git/packed-refs.lock && + >"$LOCK" && + test_when_finished "wait; rm -f $LOCK" && + { + ( sleep 1 ; rm -f $LOCK ) & + } && + git -c core.packedrefstimeout=3000 pack-refs --all --prune +' + test_done diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh index 5a27ec9b5e..8f64505e4f 100755 --- a/t/t3402-rebase-merge.sh +++ b/t/t3402-rebase-merge.sh @@ -47,7 +47,7 @@ test_expect_success setup ' ' test_expect_success 'reference merge' ' - git merge -s recursive "reference merge" HEAD master + git merge -s recursive -m "reference merge" master ' PRE_REBASE=$(git rev-parse test-rebase) diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index eed76cca55..ac429a0bbb 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -1055,4 +1055,51 @@ test_expect_success 'todo count' ' grep "^# Rebase ..* onto ..* ([0-9]" actual ' +test_expect_success 'rebase -i commits that overwrite untracked files (pick)' ' + git checkout --force branch2 && + git clean -f && + set_fake_editor && + FAKE_LINES="edit 1 2" git rebase -i A && + test_cmp_rev HEAD F && + test_path_is_missing file6 && + >file6 && + test_must_fail git rebase --continue && + test_cmp_rev HEAD F && + rm file6 && + git rebase --continue && + test_cmp_rev HEAD I +' + +test_expect_success 'rebase -i commits that overwrite untracked files (squash)' ' + git checkout --force branch2 && + git clean -f && + git tag original-branch2 && + set_fake_editor && + FAKE_LINES="edit 1 squash 2" git rebase -i A && + test_cmp_rev HEAD F && + test_path_is_missing file6 && + >file6 && + test_must_fail git rebase --continue && + test_cmp_rev HEAD F && + rm file6 && + git rebase --continue && + test $(git cat-file commit HEAD | sed -ne \$p) = I && + git reset --hard original-branch2 +' + +test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' ' + git checkout --force branch2 && + git clean -f && + set_fake_editor && + FAKE_LINES="edit 1 2" git rebase -i --no-ff A && + test $(git cat-file commit HEAD | sed -ne \$p) = F && + test_path_is_missing file6 && + >file6 && + test_must_fail git rebase --continue && + test $(git cat-file commit HEAD | sed -ne \$p) = F && + rm file6 && + git rebase --continue && + test $(git cat-file commit HEAD | sed -ne \$p) = I +' + test_done diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 24ddd8a704..deae948c76 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -326,15 +326,34 @@ test_expect_success 'split hunk "add -p (edit)"' ' # 2. Correct version applies the (not)edited version, and asks # about the next hunk, against which we say q and program # exits. - for a in s e q n q q - do - echo $a - done | + printf "%s\n" s e q n q q | EDITOR=: git add -p && git diff >actual && ! grep "^+15" actual ' +test_expect_failure 'split hunk "add -p (no, yes, edit)"' ' + cat >test <<-\EOF && + 5 + 10 + 20 + 21 + 30 + 31 + 40 + 50 + 60 + EOF + git reset && + # test sequence is s(plit), n(o), y(es), e(dit) + # q n q q is there to make sure we exit at the end. + printf "%s\n" s n y e q n q q | + EDITOR=: git add -p 2>error && + test_must_be_empty error && + git diff >actual && + ! grep "^+31" actual +' + test_expect_success 'patch mode ignores unmerged entries' ' git reset --hard && test_commit conflict && diff --git a/t/t3702-add-edit.sh b/t/t3702-add-edit.sh index 4ee47cc9a8..3cb74ca296 100755 --- a/t/t3702-add-edit.sh +++ b/t/t3702-add-edit.sh @@ -118,4 +118,11 @@ test_expect_success 'add -e' ' ' +test_expect_success 'add -e notices editor failure' ' + git reset --hard && + echo change >>file && + test_must_fail env GIT_EDITOR=false git add -e && + test_expect_code 1 git diff --exit-code +' + test_done diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 1e29962fad..0746eeeff7 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -10,6 +10,8 @@ test_description='Test git stash' test_expect_success 'stash some dirty working directory' ' echo 1 > file && git add file && + echo unrelated >other-file && + git add other-file && test_tick && git commit -m initial && echo 2 > file && @@ -43,10 +45,15 @@ test_expect_success 'applying bogus stash does nothing' ' test_cmp expect file ' +test_expect_success 'apply requires a clean index' ' + test_when_finished "git reset --hard" && + echo changed >other-file && + git add other-file && + test_must_fail git stash apply +' + test_expect_success 'apply does not need clean working directory' ' echo 4 >other-file && - git add other-file && - echo 5 >other-file && git stash apply && echo 3 >expect && test_cmp expect file @@ -695,8 +702,8 @@ test_expect_success 'setup stash with index and worktree changes' ' ' test_expect_success 'stash list implies --first-parent -m' ' - cat >expect <<-\EOF && - stash@{0}: WIP on master: b27a2bc subdir + cat >expect <<-EOF && + stash@{0} diff --git a/file b/file index 257cc56..d26b33d 100644 @@ -706,13 +713,13 @@ test_expect_success 'stash list implies --first-parent -m' ' -foo +working EOF - git stash list -p >actual && + git stash list --format=%gd -p >actual && test_cmp expect actual ' test_expect_success 'stash list --cc shows combined diff' ' cat >expect <<-\EOF && - stash@{0}: WIP on master: b27a2bc subdir + stash@{0} diff --cc file index 257cc56,9015a7a..d26b33d @@ -723,7 +730,7 @@ test_expect_success 'stash list --cc shows combined diff' ' -index ++working EOF - git stash list -p --cc >actual && + git stash list --format=%gd -p --cc >actual && test_cmp expect actual ' diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh index 70655c1848..38e730090f 100755 --- a/t/t3904-stash-patch.sh +++ b/t/t3904-stash-patch.sh @@ -1,9 +1,15 @@ #!/bin/sh -test_description='git checkout --patch' +test_description='stash -p' . ./lib-patch-mode.sh -test_expect_success PERL 'setup' ' +if ! test_have_prereq PERL +then + skip_all='skipping stash -p tests, perl not available' + test_done +fi + +test_expect_success 'setup' ' mkdir dir && echo parent > dir/foo && echo dummy > bar && @@ -20,7 +26,7 @@ test_expect_success PERL 'setup' ' # note: order of files with unstaged changes: HEAD bar dir/foo -test_expect_success PERL 'saying "n" does nothing' ' +test_expect_success 'saying "n" does nothing' ' set_state HEAD HEADfile_work HEADfile_index && set_state dir/foo work index && (echo n; echo n; echo n) | test_must_fail git stash save -p && @@ -29,7 +35,7 @@ test_expect_success PERL 'saying "n" does nothing' ' verify_state dir/foo work index ' -test_expect_success PERL 'git stash -p' ' +test_expect_success 'git stash -p' ' (echo y; echo n; echo y) | git stash save -p && verify_state HEAD committed HEADfile_index && verify_saved_state bar && @@ -41,7 +47,7 @@ test_expect_success PERL 'git stash -p' ' verify_state dir/foo work head ' -test_expect_success PERL 'git stash -p --no-keep-index' ' +test_expect_success 'git stash -p --no-keep-index' ' set_state HEAD HEADfile_work HEADfile_index && set_state bar bar_work bar_index && set_state dir/foo work index && @@ -56,7 +62,7 @@ test_expect_success PERL 'git stash -p --no-keep-index' ' verify_state dir/foo work index ' -test_expect_success PERL 'git stash --no-keep-index -p' ' +test_expect_success 'git stash --no-keep-index -p' ' set_state HEAD HEADfile_work HEADfile_index && set_state bar bar_work bar_index && set_state dir/foo work index && @@ -71,8 +77,31 @@ test_expect_success PERL 'git stash --no-keep-index -p' ' verify_state dir/foo work index ' -test_expect_success PERL 'none of this moved HEAD' ' +test_expect_success 'none of this moved HEAD' ' verify_saved_head ' +test_expect_failure 'stash -p with split hunk' ' + git reset --hard && + cat >test <<-\EOF && + aaa + bbb + ccc + EOF + git add test && + git commit -m "initial" && + cat >test <<-\EOF && + aaa + added line 1 + bbb + added line 2 + ccc + EOF + printf "%s\n" s n y q | + test_might_fail git stash -p 2>error && + ! test_must_be_empty error && + grep "added line 1" test && + ! grep "added line 2" test +' + test_done diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index 13e7f621ab..7452fce0da 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -139,11 +139,13 @@ test_expect_success SYMLINKS 'setup symlinks with attributes' ' test_expect_success SYMLINKS 'symlinks do not respect userdiff config by path' ' cat >expect <<-\EOF && diff --git a/file.bin b/file.bin - index e69de29..d95f3ad 100644 - Binary files a/file.bin and b/file.bin differ + new file mode 100644 + index 0000000..d95f3ad + Binary files /dev/null and b/file.bin differ diff --git a/link.bin b/link.bin - index e69de29..dce41ec 120000 - --- a/link.bin + new file mode 120000 + index 0000000..dce41ec + --- /dev/null +++ b/link.bin @@ -0,0 +1 @@ +file.bin diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all index 44d45257da..b345b2ebfa 100644 --- a/t/t4013/diff.log_--decorate=full_--all +++ b/t/t4013/diff.log_--decorate=full_--all @@ -5,7 +5,7 @@ Date: Mon Jun 26 00:06:00 2006 +0000 Rearranged lines in dir/sub -commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD, refs/heads/master) +commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD -> refs/heads/master) Merge: 9a6d494 c7a2ab9 Author: A U Thor <author@example.com> Date: Mon Jun 26 00:04:00 2006 +0000 diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 075ece6db1..6eb83211b5 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -55,4 +55,38 @@ test_expect_success 'git diff --no-index executed outside repo gives correct err ) ' +test_expect_success 'diff D F and diff F D' ' + ( + cd repo && + echo in-repo >a && + echo non-repo >../non/git/a && + mkdir sub && + echo sub-repo >sub/a && + + test_must_fail git diff --no-index sub/a ../non/git/a >expect && + test_must_fail git diff --no-index sub/a ../non/git/ >actual && + test_cmp expect actual && + + test_must_fail git diff --no-index a ../non/git/a >expect && + test_must_fail git diff --no-index a ../non/git/ >actual && + test_cmp expect actual && + + test_must_fail git diff --no-index ../non/git/a a >expect && + test_must_fail git diff --no-index ../non/git a >actual && + test_cmp expect actual + ) +' + +test_expect_success 'turning a file into a directory' ' + ( + cd non/git && + mkdir d e e/sub && + echo 1 >d/sub && + echo 2 >e/sub/file && + printf "D\td/sub\nA\te/sub/file\n" >expect && + test_must_fail git diff --no-index --name-status d e >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index 0901b30982..4451127eb2 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -54,14 +54,14 @@ canned_test "-L 4:a.c -L 8,12:a.c simple" multiple-superset canned_test "-L 8,12:a.c -L 4:a.c simple" multiple-superset test_bad_opts "-L" "switch.*requires a value" -test_bad_opts "-L b.c" "argument.*not of the form" -test_bad_opts "-L 1:" "argument.*not of the form" +test_bad_opts "-L b.c" "argument not .start,end:file" +test_bad_opts "-L 1:" "argument not .start,end:file" test_bad_opts "-L 1:nonexistent" "There is no path" test_bad_opts "-L 1:simple" "There is no path" -test_bad_opts "-L '/foo:b.c'" "argument.*not of the form" +test_bad_opts "-L '/foo:b.c'" "argument not .start,end:file" test_bad_opts "-L 1000:b.c" "has only.*lines" test_bad_opts "-L 1,1000:b.c" "has only.*lines" -test_bad_opts "-L :b.c" "argument.*not of the form" +test_bad_opts "-L :b.c" "argument not .start,end:file" test_bad_opts "-L :foo:b.c" "no match" test_expect_success '-L X (X == nlines)' ' diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 227d293350..7efd45bc27 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -9,36 +9,27 @@ modify () { mv "$2.x" "$2" } -D=`pwd` - test_expect_success setup ' - echo file >file && git add file && git commit -a -m original - ' test_expect_success 'pulling into void' ' - mkdir cloned && - cd cloned && - git init && - git pull .. -' - -cd "$D" - -test_expect_success 'checking the results' ' + git init cloned && + ( + cd cloned && + git pull .. + ) && test -f file && test -f cloned/file && test_cmp file cloned/file ' test_expect_success 'pulling into void using master:master' ' - mkdir cloned-uho && + git init cloned-uho && ( cd cloned-uho && - git init && git pull .. master:master ) && test -f file && @@ -71,7 +62,6 @@ test_expect_success 'pulling into void does not overwrite staged files' ' ) ' - test_expect_success 'pulling into void does not remove new staged files' ' git init cloned-staged-new && ( @@ -86,6 +76,15 @@ test_expect_success 'pulling into void does not remove new staged files' ' ) ' +test_expect_success 'pulling into void must not create an octopus' ' + git init cloned-octopus && + ( + cd cloned-octopus && + test_must_fail git pull .. master master && + ! test -f file + ) +' + test_expect_success 'test . as a remote' ' git branch copy master && diff --git a/t/t5524-pull-msg.sh b/t/t5524-pull-msg.sh index 8cccecc2fc..c278adaa5a 100755 --- a/t/t5524-pull-msg.sh +++ b/t/t5524-pull-msg.sh @@ -17,6 +17,9 @@ test_expect_success setup ' git commit -m "add bfile" ) && test_tick && test_tick && + echo "second" >afile && + git add afile && + git commit -m "second commit" && echo "original $dollar" >afile && git add afile && git commit -m "do not clobber $dollar signs" @@ -32,4 +35,18 @@ test_expect_success pull ' ) ' +test_expect_success '--log=1 limits shortlog length' ' +( + cd cloned && + git reset --hard HEAD^ && + test "$(cat afile)" = original && + test "$(cat bfile)" = added && + git pull --log=1 && + git log -3 && + git cat-file commit HEAD >result && + grep Dollar result && + ! grep "second commit" result +) +' + test_done diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh index b46118846c..37a433504e 100755 --- a/t/t5539-fetch-http-shallow.sh +++ b/t/t5539-fetch-http-shallow.sh @@ -3,12 +3,6 @@ test_description='fetch/clone from a shallow clone over http' . ./test-lib.sh - -if test -n "$NO_CURL"; then - skip_all='skipping test, git built without http support' - test_done -fi - . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 9cf27e8c99..fd7d06b9a2 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -6,11 +6,6 @@ test_description='test smart pushing over http via http-backend' . ./test-lib.sh -if test -n "$NO_CURL"; then - skip_all='skipping test, git built without http support' - test_done -fi - ROOT_PATH="$PWD" . "$TEST_DIRECTORY"/lib-gpg.sh . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t5542-push-http-shallow.sh b/t/t5542-push-http-shallow.sh index 2a691e09eb..5165833157 100755 --- a/t/t5542-push-http-shallow.sh +++ b/t/t5542-push-http-shallow.sh @@ -3,12 +3,6 @@ test_description='push from/to a shallow clone over http' . ./test-lib.sh - -if test -n "$NO_CURL"; then - say 'skipping test, git built without http support' - test_done -fi - . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index 3d11b7a6bb..87a7aa04ae 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -2,12 +2,6 @@ test_description='test dumb fetching over http via static file' . ./test-lib.sh - -if test -n "$NO_CURL"; then - skip_all='skipping test, git built without http support' - test_done -fi - . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index 66439e58fc..2b29311901 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -2,12 +2,6 @@ test_description='test smart fetching over http via http-backend' . ./test-lib.sh - -if test -n "$NO_CURL"; then - skip_all='skipping test, git built without http support' - test_done -fi - . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh index d23fb02384..19afe96698 100755 --- a/t/t5561-http-backend.sh +++ b/t/t5561-http-backend.sh @@ -2,12 +2,6 @@ test_description='test git-http-backend' . ./test-lib.sh - -if test -n "$NO_CURL"; then - skip_all='skipping test, git built without http support' - test_done -fi - . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 1befc453a3..bfdaf75966 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -296,6 +296,12 @@ setup_ssh_wrapper () { ' } +copy_ssh_wrapper_as () { + cp "$TRASH_DIRECTORY/ssh-wrapper" "$1" && + GIT_SSH="$1" && + export GIT_SSH +} + expect_ssh () { test_when_finished ' (cd "$TRASH_DIRECTORY" && rm -f ssh-expect && >ssh-output) @@ -332,9 +338,36 @@ test_expect_success !MINGW,!CYGWIN 'clone local path foo:bar' ' test_expect_success 'bracketed hostnames are still ssh' ' git clone "[myhost:123]:src" ssh-bracket-clone && - expect_ssh myhost '-p 123' src + expect_ssh "-p 123" myhost src +' + +test_expect_success 'uplink is not treated as putty' ' + copy_ssh_wrapper_as "$TRASH_DIRECTORY/uplink" && + git clone "[myhost:123]:src" ssh-bracket-clone-uplink && + expect_ssh "-p 123" myhost src +' + +test_expect_success 'plink is treated specially (as putty)' ' + copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink" && + git clone "[myhost:123]:src" ssh-bracket-clone-plink-0 && + expect_ssh "-P 123" myhost src ' +test_expect_success 'plink.exe is treated specially (as putty)' ' + copy_ssh_wrapper_as "$TRASH_DIRECTORY/plink.exe" && + git clone "[myhost:123]:src" ssh-bracket-clone-plink-1 && + expect_ssh "-P 123" myhost src +' + +test_expect_success 'tortoiseplink is like putty, with extra arguments' ' + copy_ssh_wrapper_as "$TRASH_DIRECTORY/tortoiseplink" && + git clone "[myhost:123]:src" ssh-bracket-clone-plink-2 && + expect_ssh "-batch -P 123" myhost src +' + +# Reset the GIT_SSH environment variable for clone tests. +setup_ssh_wrapper + counter=0 # $1 url # $2 none|host diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh index 27c3d73961..2af1beec5f 100755 --- a/t/t6020-merge-df.sh +++ b/t/t6020-merge-df.sh @@ -24,7 +24,7 @@ test_expect_success 'prepare repository' ' ' test_expect_success 'Merge with d/f conflicts' ' - test_expect_code 1 git merge "merge msg" B master + test_expect_code 1 git merge -m "merge msg" master ' test_expect_success 'F/D conflict' ' diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh index d15b313d4b..213deecab1 100755 --- a/t/t6021-merge-criss-cross.sh +++ b/t/t6021-merge-criss-cross.sh @@ -48,7 +48,7 @@ echo "1 " > file && git commit -m "C3" file && git branch C3 && -git merge "pre E3 merge" B A && +git merge -m "pre E3 merge" A && echo "1 2 3 changed in E3, branch B. New file size @@ -61,7 +61,7 @@ echo "1 " > file && git commit -m "E3" file && git checkout A && -git merge "pre D8 merge" A C3 && +git merge -m "pre D8 merge" C3 && echo "1 2 3 changed in C3, branch B @@ -73,7 +73,7 @@ echo "1 9" > file && git commit -m D8 file' -test_expect_success 'Criss-cross merge' 'git merge "final merge" A B' +test_expect_success 'Criss-cross merge' 'git merge -m "final merge" B' cat > file-expect <<EOF 1 diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 66643e4bd7..855afda80a 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -394,4 +394,14 @@ test_expect_success 'replace submodule revision' ' test $orig_head != `git show-ref --hash --head HEAD` ' +test_expect_success 'filter commit message without trailing newline' ' + git reset --hard original && + commit=$(printf "no newline" | git commit-tree HEAD^{tree}) && + git update-ref refs/heads/no-newline $commit && + git filter-branch -f refs/heads/no-newline && + echo $commit >expect && + git rev-parse refs/heads/no-newline >actual && + test_cmp expect actual +' + test_done diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index fa207f3b8c..d1ff5c94f2 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1491,10 +1491,10 @@ run_with_limited_stack () { (ulimit -s 128 && "$@") } -test_lazy_prereq ULIMIT 'run_with_limited_stack true' +test_lazy_prereq ULIMIT_STACK_SIZE 'run_with_limited_stack true' # we require ulimit, this excludes Windows -test_expect_success ULIMIT '--contains works in a deep repo' ' +test_expect_success ULIMIT_STACK_SIZE '--contains works in a deep repo' ' >expect && i=1 && while test $i -lt 8000 diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh index 460789b4d8..cdc0747bf0 100755 --- a/t/t7061-wtstatus-ignore.sh +++ b/t/t7061-wtstatus-ignore.sh @@ -20,6 +20,15 @@ test_expect_success 'status untracked directory with --ignored' ' test_cmp expected actual ' +test_expect_success 'same with gitignore starting with BOM' ' + printf "\357\273\277ignored\n" >.gitignore && + mkdir -p untracked && + : >untracked/ignored && + : >untracked/uncommitted && + git status --porcelain --ignored >actual && + test_cmp expected actual +' + cat >expected <<\EOF ?? .gitignore ?? actual diff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh new file mode 100755 index 0000000000..8f30aed6cc --- /dev/null +++ b/t/t7410-submodule-checkout-to.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +test_description='Combination of submodules and multiple workdirs' + +. ./test-lib.sh + +base_path=$(pwd -P) + +test_expect_success 'setup: make origin' \ + 'mkdir -p origin/sub && ( cd origin/sub && git init && + echo file1 >file1 && + git add file1 && + git commit -m file1 ) && + mkdir -p origin/main && ( cd origin/main && git init && + git submodule add ../sub && + git commit -m "add sub" ) && + ( cd origin/sub && + echo file1updated >file1 && + git add file1 && + git commit -m "file1 updated" ) && + ( cd origin/main/sub && git pull ) && + ( cd origin/main && + git add sub && + git commit -m "sub updated" )' + +test_expect_success 'setup: clone' \ + 'mkdir clone && ( cd clone && + git clone --recursive "$base_path/origin/main")' + +rev1_hash_main=$(git --git-dir=origin/main/.git show --pretty=format:%h -q "HEAD~1") +rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1") + +test_expect_success 'checkout main' \ + 'mkdir default_checkout && + (cd clone/main && + git checkout --to "$base_path/default_checkout/main" "$rev1_hash_main")' + +test_expect_failure 'can see submodule diffs just after checkout' \ + '(cd default_checkout/main && git diff --submodule master"^!" | grep "file1 updated")' + +test_expect_success 'checkout main and initialize independed clones' \ + 'mkdir fully_cloned_submodule && + (cd clone/main && + git checkout --to "$base_path/fully_cloned_submodule/main" "$rev1_hash_main") && + (cd fully_cloned_submodule/main && git submodule update)' + +test_expect_success 'can see submodule diffs after independed cloning' \ + '(cd fully_cloned_submodule/main && git diff --submodule master"^!" | grep "file1 updated")' + +test_done diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index 051489ea33..2e0d557243 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -370,7 +370,7 @@ exit 0 EOF test_expect_success !AUTOIDENT 'do not fire editor when committer is bogus' ' - >.git/result + >.git/result && >expect && echo >>negative && diff --git a/t/t8003-blame-corner-cases.sh b/t/t8003-blame-corner-cases.sh index 32895e5acb..16f1442c1e 100755 --- a/t/t8003-blame-corner-cases.sh +++ b/t/t8003-blame-corner-cases.sh @@ -191,12 +191,24 @@ test_expect_success 'indent of line numbers, ten lines' ' test $(grep -c " " actual) = 9 ' -test_expect_success 'blaming files with CRLF newlines' ' +test_expect_success 'setup file with CRLF newlines' ' git config core.autocrlf false && - printf "testcase\r\n" >crlffile && + printf "testcase\n" >crlffile && git add crlffile && git commit -m testcase && - git -c core.autocrlf=input blame crlffile >actual && + printf "testcase\r\n" >crlffile +' + +test_expect_success 'blame file with CRLF core.autocrlf true' ' + git config core.autocrlf true && + git blame crlffile >actual && + grep "A U Thor" actual +' + +test_expect_success 'blame file with CRLF attributes text' ' + git config core.autocrlf false && + echo "crlffile text" >.gitattributes && + git blame crlffile >actual && grep "A U Thor" actual ' diff --git a/t/t9402-git-cvsserver-refs.sh b/t/t9402-git-cvsserver-refs.sh index 1e266effff..d00df08731 100755 --- a/t/t9402-git-cvsserver-refs.sh +++ b/t/t9402-git-cvsserver-refs.sh @@ -496,7 +496,7 @@ test_expect_success 'check [cvswork3] diff' ' ' test_expect_success 'merge early [cvswork3] b3 with b1' ' - ( cd gitwork3 && git merge "message" HEAD b1 ) && + ( cd gitwork3 && git merge -m "message" b1 ) && git fetch gitwork3 b3:b3 && git tag v3merged b3 && git push --tags gitcvs.git b3:b3 diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh index 2bf142d09c..0aafd03334 100755 --- a/t/t9801-git-p4-branch.sh +++ b/t/t9801-git-p4-branch.sh @@ -504,6 +504,112 @@ test_expect_success 'use-client-spec detect-branches skips files in branches' ' ) ' +test_expect_success 'restart p4d' ' + kill_p4d && + start_p4d +' + +# +# 1: //depot/branch1/base/file1 +# //depot/branch1/base/file2 +# //depot/branch1/base/dir/sub_file1 +# 2: integrate //depot/branch1/base/... -> //depot/branch2/base/... +# 3: //depot/branch1/base/file3 +# 4: //depot/branch1/base/file2 (edit) +# 5: integrate //depot/branch1/base/... -> //depot/branch3/base/... +# +# Note: the client view removes the "base" folder from the workspace +# and moves sub_file1 one level up. +test_expect_success 'add simple p4 branches with common base folder on each branch' ' + ( + cd "$cli" && + client_view "//depot/branch1/base/... //client/branch1/..." \ + "//depot/branch1/base/dir/sub_file1 //client/branch1/sub_file1" \ + "//depot/branch2/base/... //client/branch2/..." \ + "//depot/branch3/base/... //client/branch3/..." && + mkdir -p branch1 && + cd branch1 && + echo file1 >file1 && + echo file2 >file2 && + mkdir dir && + echo sub_file1 >sub_file1 && + p4 add file1 file2 sub_file1 && + p4 submit -d "Create branch1" && + p4 integrate //depot/branch1/base/... //depot/branch2/base/... && + p4 submit -d "Integrate branch2 from branch1" && + echo file3 >file3 && + p4 add file3 && + p4 submit -d "add file3 in branch1" && + p4 open file2 && + echo update >>file2 && + p4 submit -d "update file2 in branch1" && + p4 integrate //depot/branch1/base/... //depot/branch3/base/... && + p4 submit -d "Integrate branch3 from branch1" + ) +' + +# Configure branches through git-config and clone them. +# All files are tested to make sure branches were cloned correctly. +# Finally, make an update to branch1 on P4 side to check if it is imported +# correctly by git p4. +# git p4 is expected to use the client view to also not include the common +# "base" folder in the imported directory structure. +test_expect_success 'git p4 clone simple branches with base folder on server side' ' + test_create_repo "$git" && + ( + cd "$git" && + git config git-p4.branchList branch1:branch2 && + git config --add git-p4.branchList branch1:branch3 && + git p4 clone --dest=. --use-client-spec --detect-branches //depot@all && + git log --all --graph --decorate --stat && + git reset --hard p4/depot/branch1 && + test -f file1 && + test -f file2 && + test -f file3 && + test -f sub_file1 && + grep update file2 && + git reset --hard p4/depot/branch2 && + test -f file1 && + test -f file2 && + test ! -f file3 && + test -f sub_file1 && + ! grep update file2 && + git reset --hard p4/depot/branch3 && + test -f file1 && + test -f file2 && + test -f file3 && + test -f sub_file1 && + grep update file2 && + cd "$cli" && + cd branch1 && + p4 edit file2 && + echo file2_ >>file2 && + p4 submit -d "update file2 in branch1" && + cd "$git" && + git reset --hard p4/depot/branch1 && + git p4 rebase && + grep file2_ file2 + ) +' + +# Now update a file in one of the branches in git and submit to P4 +test_expect_success 'Update a file in git side and submit to P4 using client view' ' + test_when_finished cleanup_git && + ( + cd "$git" && + git reset --hard p4/depot/branch1 && + echo "client spec" >> file1 && + git add -u . && + git commit -m "update file1 in branch1" && + git config git-p4.skipSubmitEdit true && + git p4 submit --verbose && + cd "$cli" && + p4 sync ... && + cd branch1 && + grep "client spec" file1 + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh index 99bb71b89c..c89992cf95 100755 --- a/t/t9814-git-p4-rename.sh +++ b/t/t9814-git-p4-rename.sh @@ -226,14 +226,9 @@ test_expect_success 'detect copies' ' # See if configurables can be set, and in particular if the run.move.allow # variable exists, which allows admins to disable the "p4 move" command. -test_expect_success 'p4 configure command and run.move.allow are available' ' - p4 configure show run.move.allow >out ; retval=$? && - test $retval = 0 && - { - egrep ^run.move.allow: out && - test_set_prereq P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW || - true - } || true +test_lazy_prereq P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW ' + p4 configure show run.move.allow >out && + egrep ^run.move.allow: out ' # If move can be disabled, turn it off and test p4 move handling diff --git a/t/t9816-git-p4-locked.sh b/t/t9816-git-p4-locked.sh index e71e543343..d048bd33fa 100755 --- a/t/t9816-git-p4-locked.sh +++ b/t/t9816-git-p4-locked.sh @@ -35,13 +35,13 @@ test_expect_success 'edit with lock not taken' ' ) ' -test_expect_failure 'add with lock not taken' ' +test_expect_success 'add with lock not taken' ' test_when_finished cleanup_git && git p4 clone --dest="$git" //depot && ( cd "$git" && echo line1 >>add-lock-not-taken && - git add file2 && + git add add-lock-not-taken && git commit -m "add add-lock-not-taken" && git config git-p4.skipSubmitEdit true && git p4 submit --verbose @@ -107,7 +107,7 @@ test_expect_failure 'chmod with lock taken' ' ) ' -test_expect_failure 'copy with lock taken' ' +test_expect_success 'copy with lock taken' ' lock_in_another_client && test_when_finished cleanup_git && test_when_finished "cd \"$cli\" && p4 revert file2 && rm -f file2" && @@ -130,8 +130,8 @@ test_expect_failure 'move with lock taken' ' git p4 clone --dest="$git" //depot && ( cd "$git" && - git mv file1 file2 && - git commit -m "mv file1 to file2" && + git mv file1 file3 && + git commit -m "mv file1 to file3" && git config git-p4.skipSubmitEdit true && git config git-p4.detectRenames true && git p4 submit --verbose diff --git a/t/t9818-git-p4-block.sh b/t/t9818-git-p4-block.sh new file mode 100755 index 0000000000..153b20afbd --- /dev/null +++ b/t/t9818-git-p4-block.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +test_description='git p4 fetching changes in multiple blocks' + +. ./lib-git-p4.sh + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'Create a repo with ~100 changes' ' + ( + cd "$cli" && + >file.txt && + p4 add file.txt && + p4 submit -d "Add file.txt" && + for i in $(test_seq 0 9) + do + >outer$i.txt && + p4 add outer$i.txt && + p4 submit -d "Adding outer$i.txt" && + for j in $(test_seq 0 9) + do + p4 edit file.txt && + echo $i$j >file.txt && + p4 submit -d "Commit $i$j" || exit + done || exit + done + ) +' + +test_expect_success 'Clone the repo' ' + git p4 clone --dest="$git" --changes-block-size=10 --verbose //depot@all +' + +test_expect_success 'All files are present' ' + echo file.txt >expected && + test_write_lines outer0.txt outer1.txt outer2.txt outer3.txt outer4.txt >>expected && + test_write_lines outer5.txt outer6.txt outer7.txt outer8.txt outer9.txt >>expected && + ls "$git" >current && + test_cmp expected current +' + +test_expect_success 'file.txt is correct' ' + echo 99 >expected && + test_cmp expected "$git/file.txt" +' + +test_expect_success 'Correct number of commits' ' + (cd "$git" && git log --oneline) >log && + test_line_count = 111 log +' + +test_expect_success 'Previous version of file.txt is correct' ' + (cd "$git" && git checkout HEAD^^) && + echo 97 >expected && + test_cmp expected "$git/file.txt" +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done diff --git a/t/t9819-git-p4-case-folding.sh b/t/t9819-git-p4-case-folding.sh new file mode 100755 index 0000000000..78f1d0f92d --- /dev/null +++ b/t/t9819-git-p4-case-folding.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +test_description='interaction with P4 case-folding' + +. ./lib-git-p4.sh + +test_expect_success 'start p4d with case folding enabled' ' + start_p4d -C1 +' + +test_expect_success 'Create a repo, name is lowercase' ' + ( + client_view "//depot/... //client/..." && + cd "$cli" && + mkdir -p lc UC && + >lc/file.txt && >UC/file.txt && + p4 add lc/file.txt UC/file.txt && + p4 submit -d "Add initial lc and UC repos" + ) +' + +test_expect_success 'Check p4 is in case-folding mode' ' + ( + cd "$cli" && + >lc/FILE.TXT && + p4 add lc/FILE.TXT && + test_must_fail p4 submit -d "Cannot add file differing only in case" lc/FILE.TXT + ) +' + +# Check we created the repo properly +test_expect_success 'Clone lc repo using lc name' ' + git p4 clone //depot/lc/... && + test_path_is_file lc/file.txt && + git p4 clone //depot/UC/... && + test_path_is_file UC/file.txt +' + +# The clone should fail, since there is no repo called LC, but because +# we have case-insensitive p4d enabled, it appears to go ahead and work, +# but leaves an empty git repo in place. +test_expect_failure 'Clone lc repo using uc name' ' + test_must_fail git p4 clone //depot/LC/... +' + +test_expect_failure 'Clone UC repo with lc name' ' + test_must_fail git p4 clone //depot/uc/... +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 4a14a5892e..2ba62fbc17 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -370,6 +370,40 @@ test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from test_cmp expect actual ' +test_expect_success '__git_get_config_variables' ' + cat >expect <<-EOF && + name-1 + name-2 + EOF + test_config interesting.name-1 good && + test_config interesting.name-2 good && + test_config subsection.interesting.name-3 bad && + __git_get_config_variables interesting >actual && + test_cmp expect actual +' + +test_expect_success '__git_pretty_aliases' ' + cat >expect <<-EOF && + author + hash + EOF + test_config pretty.author "%an %ae" && + test_config pretty.hash %H && + __git_pretty_aliases >actual && + test_cmp expect actual +' + +test_expect_success '__git_aliases' ' + cat >expect <<-EOF && + ci + co + EOF + test_config alias.ci commit && + test_config alias.co checkout && + __git_aliases >actual && + test_cmp expect actual +' + test_expect_success 'basic' ' run_completion "git " && # built-in diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 0698ce7908..e8d3c0fdbc 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -348,11 +348,18 @@ test_declared_prereq () { return 1 } +test_verify_prereq () { + test -z "$test_prereq" || + expr >/dev/null "$test_prereq" : '[A-Z0-9_,!]*$' || + error "bug in the test script: '$test_prereq' does not look like a prereq" +} + test_expect_failure () { test_start_ test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test-expect-failure" + test_verify_prereq export test_prereq if ! test_skip "$@" then @@ -372,6 +379,7 @@ test_expect_success () { test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= test "$#" = 2 || error "bug in the test script: not 2 or 3 parameters to test-expect-success" + test_verify_prereq export test_prereq if ! test_skip "$@" then @@ -400,6 +408,7 @@ test_external () { error >&5 "bug in the test script: not 3 or 4 parameters to test_external" descr="$1" shift + test_verify_prereq export test_prereq if ! test_skip "$descr" "$@" then @@ -478,7 +487,7 @@ test_external_without_stderr () { test_path_is_file () { if ! test -f "$1" then - echo "File $1 doesn't exist. $*" + echo "File $1 doesn't exist. $2" false fi } @@ -486,7 +495,7 @@ test_path_is_file () { test_path_is_dir () { if ! test -d "$1" then - echo "Directory $1 doesn't exist. $*" + echo "Directory $1 doesn't exist. $2" false fi } diff --git a/t/test-lib.sh b/t/test-lib.sh index 4ea99a209d..39da9c2d99 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -529,7 +529,7 @@ test_run_ () { test_cleanup=: expecting_failure=$2 - if test "${GIT_TEST_CHAIN_LINT:-0}" != 0; then + if test "${GIT_TEST_CHAIN_LINT:-1}" != 0; then # 117 is magic because it is unlikely to match the exit # code of other programs test_eval_ "(exit 117) && $1" |