diff options
Diffstat (limited to 't')
-rw-r--r-- | t/lib-git-p4.sh | 2 | ||||
-rwxr-xr-x | t/t0027-auto-crlf.sh | 243 | ||||
-rwxr-xr-x | t/t0060-path-utils.sh | 36 | ||||
-rwxr-xr-x | t/t0302-credential-store.sh | 114 | ||||
-rwxr-xr-x | t/t1007-hash-object.sh | 19 | ||||
-rwxr-xr-x | t/t1430-bad-ref-name.sh | 8 | ||||
-rwxr-xr-x | t/t1501-worktree.sh | 77 | ||||
-rwxr-xr-x | t/t1509/prepare-chroot.sh | 38 | ||||
-rwxr-xr-x | t/t1510-repo-setup.sh | 1 | ||||
-rwxr-xr-x | t/t2025-checkout-to.sh | 129 | ||||
-rwxr-xr-x | t/t2026-prune-linked-checkouts.sh | 96 | ||||
-rwxr-xr-x | t/t3701-add-interactive.sh | 27 | ||||
-rwxr-xr-x | t/t3904-stash-patch.sh | 43 | ||||
-rwxr-xr-x | t/t7003-filter-branch.sh | 10 | ||||
-rwxr-xr-x | t/t7061-wtstatus-ignore.sh | 9 | ||||
-rwxr-xr-x | t/t7410-submodule-checkout-to.sh | 50 | ||||
-rwxr-xr-x | t/t8003-blame-corner-cases.sh | 18 | ||||
-rwxr-xr-x | t/t9801-git-p4-branch.sh | 106 | ||||
-rwxr-xr-x | t/t9814-git-p4-rename.sh | 11 | ||||
-rwxr-xr-x | t/t9816-git-p4-locked.sh | 10 | ||||
-rwxr-xr-x | t/t9818-git-p4-block.sh | 64 | ||||
-rwxr-xr-x | t/t9819-git-p4-case-folding.sh | 54 | ||||
-rw-r--r-- | t/test-lib-functions.sh | 4 |
23 files changed, 1021 insertions, 148 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/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/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/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/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/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/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/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/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/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/test-lib-functions.sh b/t/test-lib-functions.sh index 0698ce7908..8f8858a5f0 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -478,7 +478,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 +486,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 } |