diff options
Diffstat (limited to 't')
57 files changed, 4468 insertions, 2013 deletions
@@ -563,6 +563,11 @@ library for your script to use. argument. This is primarily meant for use during the development of a new test script. + - debug <git-command> + + Run a git command inside a debugger. This is primarily meant for + use when debugging a failing test script. + - test_done Your test script must have test_done at the end. Its purpose diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index b1673b3e8f..093832fef1 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -68,6 +68,13 @@ test_expect_success 'blame 1 author' ' check_count A 2 ' +test_expect_success 'blame by tag objects' ' + git tag -m "test tag" testTag && + git tag -m "test tag #2" testTag2 testTag && + check_count -h testTag A 2 && + check_count -h testTag2 A 2 +' + test_expect_success 'setup B lines' ' echo "2A quick brown fox jumps over the" >>file && echo "lazy dog" >>file && diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh index 75482254a3..f9ae1d780d 100644 --- a/t/lib-git-p4.sh +++ b/t/lib-git-p4.sh @@ -6,6 +6,14 @@ # a subdirectory called "$git" TEST_NO_CREATE_REPO=NoThanks +# Some operations require multiple attempts to be successful. Define +# here the maximal retry timeout in seconds. +RETRY_TIMEOUT=60 + +# Sometimes p4d seems to hang. Terminate the p4d process automatically after +# the defined timeout in seconds. +P4D_TIMEOUT=300 + . ./test-lib.sh if ! test_have_prereq PYTHON @@ -36,6 +44,15 @@ native_path() { echo "$path" } +# On Solaris the 'date +%s' function is not supported and therefore we +# need this replacement. +# Attention: This function is not safe again against time offset updates +# at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)' +# function could fix that but it is not in Python until 3.3. +time_in_seconds() { + python -c 'import time; print int(time.time())' +} + # Try to pick a unique port: guess a large number, then hope # no more than one of each test is running. # @@ -57,6 +74,15 @@ cli="$TRASH_DIRECTORY/cli" git="$TRASH_DIRECTORY/git" pidfile="$TRASH_DIRECTORY/p4d.pid" +# Sometimes "prove" seems to hang on exit because p4d is still running +cleanup() { + if test -f "$pidfile" + then + kill -9 $(cat "$pidfile") 2>/dev/null && exit 255 + fi +} +trap cleanup EXIT + # git p4 submit generates a temp file, which will # not get cleaned up if the submission fails. Don't # clutter up /tmp on the test machine. @@ -81,6 +107,19 @@ start_p4d() { # will be caught with the "kill -0" check below. i=${P4D_START_PATIENCE:-300} pid=$(cat "$pidfile") + + timeout=$(($(time_in_seconds) + $P4D_TIMEOUT)) + while true + do + if test $(time_in_seconds) -gt $timeout + then + kill -9 $pid + exit 1 + fi + sleep 1 + done & + watchdog_pid=$! + ready= while test $i -gt 0 do @@ -121,22 +160,36 @@ p4_add_user() { EOF } +retry_until_success() { + timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT)) + until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout + do + sleep 1 + done +} + +retry_until_fail() { + timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT)) + until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout + do + sleep 1 + done +} + kill_p4d() { pid=$(cat "$pidfile") - # it had better exist for the first kill - kill $pid && - for i in 1 2 3 4 5 ; do - kill $pid >/dev/null 2>&1 || break - sleep 1 - done && + retry_until_fail kill $pid + retry_until_fail kill -9 $pid # complain if it would not die test_must_fail kill $pid >/dev/null 2>&1 && - rm -rf "$db" "$cli" "$pidfile" + rm -rf "$db" "$cli" "$pidfile" && + retry_until_fail kill -9 $watchdog_pid } cleanup_git() { - rm -rf "$git" && - mkdir "$git" + retry_until_success rm -r "$git" + test_must_fail test -d "$git" && + retry_until_success mkdir "$git" } marshal_dump() { diff --git a/t/perf/p7000-filter-branch.sh b/t/perf/p7000-filter-branch.sh new file mode 100755 index 0000000000..15ee5d1d53 --- /dev/null +++ b/t/perf/p7000-filter-branch.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +test_description='performance of filter-branch' +. ./perf-lib.sh + +test_perf_default_repo +test_checkout_worktree + +test_expect_success 'mark bases for tests' ' + git tag -f tip && + git tag -f base HEAD~100 +' + +test_perf 'noop filter' ' + git checkout --detach tip && + git filter-branch -f base..HEAD +' + +test_done diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 7de8d85ee8..295aa5949a 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -87,6 +87,23 @@ test_expect_success 'plain nested in bare through aliased command' ' check_config bare-ancestor-aliased.git/plain-nested/.git false unset ' +test_expect_success 'No extra GIT_* on alias scripts' ' + ( + env | sed -ne "/^GIT_/s/=.*//p" && + echo GIT_PREFIX && # setup.c + echo GIT_TEXTDOMAINDIR # wrapper-for-bin.sh + ) | sort | uniq >expected && + cat <<-\EOF >script && + #!/bin/sh + env | sed -ne "/^GIT_/s/=.*//p" | sort >actual + exit 0 + EOF + chmod 755 script && + git config alias.script \!./script && + ( mkdir sub && cd sub && git script ) && + test_cmp expected actual +' + test_expect_success 'plain with GIT_WORK_TREE' ' mkdir plain-wt && test_must_fail env GIT_WORK_TREE="$(pwd)/plain-wt" git init plain-wt @@ -202,8 +219,8 @@ test_expect_success 'init honors global core.sharedRepository' ' x$(git config -f shared-honor-global/.git/config core.sharedRepository) ' -test_expect_success 'init rejects insanely long --template' ' - test_must_fail git init --template=$(printf "x%09999dx" 1) test +test_expect_success 'init allows insanely long --template' ' + git init --template=$(printf "x%09999dx" 1) test ' test_expect_success 'init creates a new directory' ' diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh index 1a56e5e82e..b343651504 100755 --- a/t/t0027-auto-crlf.sh +++ b/t/t0027-auto-crlf.sh @@ -55,6 +55,26 @@ create_gitattributes () { esac } +create_NNO_files () { + lfname=$1 + crlfname=$2 + lfmixcrlf=$3 + lfmixcr=$4 + crlfnul=$5 + for crlf in false true input + do + for attr in "" auto text -text lf crlf + do + pfx=NNO_${crlf}_attr_${attr} && + cp $lfname ${pfx}_LF.txt && + cp $crlfname ${pfx}_CRLF.txt && + cp $lfmixcrlf ${pfx}_CRLF_mix_LF.txt && + cp $lfmixcr ${pfx}_LF_mix_CR.txt && + cp $crlfnul ${pfx}_CRLF_nul.txt + done + done +} + check_warning () { case "$1" in LF_CRLF) echo "warning: LF will be replaced by CRLF" >"$2".expect ;; @@ -62,7 +82,7 @@ check_warning () { '') >"$2".expect ;; *) echo >&2 "Illegal 1": "$1" ; return false ;; esac - grep "will be replaced by" "$2" | sed -e "s/\(.*\) in [^ ]*$/\1/" >"$2".actual + grep "will be replaced by" "$2" | sed -e "s/\(.*\) in [^ ]*$/\1/" | uniq >"$2".actual test_cmp "$2".expect "$2".actual } @@ -71,19 +91,10 @@ commit_check_warn () { attr=$2 lfname=$3 crlfname=$4 - repoMIX=$5 - lfmixcrlf=$6 - lfmixcr=$7 - crlfnul=$8 + lfmixcrlf=$5 + lfmixcr=$6 + crlfnul=$7 pfx=crlf_${crlf}_attr_${attr} - # 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 @@ -99,6 +110,45 @@ commit_check_warn () { check_warning "$crlfnul" ${pfx}_CRLF_nul.err } +commit_chk_wrnNNO () { + crlf=$1 + attr=$2 + lfwarn=$3 + crlfwarn=$4 + lfmixcrlf=$5 + lfmixcr=$6 + crlfnul=$7 + pfx=NNO_${crlf}_attr_${attr} + #Commit files on top of existing file + create_gitattributes "$attr" && + for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + do + fname=${pfx}_$f.txt && + cp $f $fname && + git -c core.autocrlf=$crlf add $fname 2>/dev/null && + git -c core.autocrlf=$crlf commit -m "commit_$fname" $fname >"${pfx}_$f.err" 2>&1 + done + + test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" ' + check_warning "$lfwarn" ${pfx}_LF.err + ' + test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF" ' + check_warning "$crlfwarn" ${pfx}_CRLF.err + ' + + test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_mix_LF" ' + check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err + ' + + test_expect_success "commit NNO files crlf=$crlf attr=$attr LF_mix_cr" ' + check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err + ' + + test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_nul" ' + check_warning "$crlfnul" ${pfx}_CRLF_nul.err + ' +} + check_files_in_repo () { crlf=$1 attr=$2 @@ -115,6 +165,31 @@ check_files_in_repo () { compare_files $crlfnul ${pfx}CRLF_nul.txt } +check_in_repo_NNO () { + crlf=$1 + attr=$2 + lfname=$3 + crlfname=$4 + lfmixcrlf=$5 + lfmixcr=$6 + crlfnul=$7 + pfx=NNO_${crlf}_attr_${attr}_ + test_expect_success "compare_files $lfname ${pfx}LF.txt" ' + compare_files $lfname ${pfx}LF.txt + ' + test_expect_success "compare_files $crlfname ${pfx}CRLF.txt" ' + compare_files $crlfname ${pfx}CRLF.txt + ' + test_expect_success "compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt" ' + compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt + ' + test_expect_success "compare_files $lfmixcr ${pfx}LF_mix_CR.txt" ' + compare_files $lfmixcr ${pfx}LF_mix_CR.txt + ' + test_expect_success "compare_files $crlfnul ${pfx}CRLF_nul.txt" ' + compare_files $crlfnul ${pfx}CRLF_nul.txt + ' +} checkout_files () { eol=$1 @@ -169,7 +244,11 @@ test_expect_success 'setup master' ' printf "line1\nline2\rline3" >LF_mix_CR && printf "line1\r\nline2\rline3" >CRLF_mix_CR && printf "line1Q\r\nline2\r\nline3" | q_to_nul >CRLF_nul && - printf "line1Q\nline2\nline3" | q_to_nul >LF_nul + printf "line1Q\nline2\nline3" | q_to_nul >LF_nul && + create_NNO_files CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF CRLF_mix_LF && + git -c core.autocrlf=false add NNO_*.txt && + git commit -m "mixed line endings" && + test_tick ' @@ -191,46 +270,72 @@ else WAMIX=CRLF_LF fi -# attr LF CRLF repoMIX CRLFmixLF LFmixCR CRLFNUL +# attr LF CRLF 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" "" "" + commit_check_warn false "" "" "" "" "" "" && + commit_check_warn true "" "LF_CRLF" "" "LF_CRLF" "" "" && + commit_check_warn input "" "" "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" "" "" + commit_check_warn false "auto" "$WILC" "$WICL" "$WAMIX" "" "" && + commit_check_warn true "auto" "LF_CRLF" "" "LF_CRLF" "" "" && + commit_check_warn input "auto" "" "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" + commit_check_warn false "text" "$WILC" "$WICL" "$WAMIX" "$WILC" "$WICL" && + commit_check_warn true "text" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" && + commit_check_warn input "text" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" ' test_expect_success 'commit files attr=-text' ' - commit_check_warn false "-text" "" "" "" "" "" "" && - commit_check_warn true "-text" "" "" "" "" "" "" && - commit_check_warn input "-text" "" "" "" "" "" "" + commit_check_warn false "-text" "" "" "" "" "" && + commit_check_warn true "-text" "" "" "" "" "" && + commit_check_warn input "-text" "" "" "" "" "" ' 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" + commit_check_warn false "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" && + commit_check_warn true "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" && + commit_check_warn input "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" ' 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" "" + commit_check_warn false "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" && + commit_check_warn true "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" && + commit_check_warn input "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" ' +# attr LF CRLF CRLFmixLF LF_mix_CR CRLFNUL +commit_chk_wrnNNO false "" "" "" "" "" "" +commit_chk_wrnNNO true "" "LF_CRLF" "" "" "" "" +commit_chk_wrnNNO input "" "" "" "" "" "" + + +commit_chk_wrnNNO false "auto" "$WILC" "$WICL" "$WAMIX" "" "" +commit_chk_wrnNNO true "auto" "LF_CRLF" "" "LF_CRLF" "" "" +commit_chk_wrnNNO input "auto" "" "CRLF_LF" "CRLF_LF" "" "" + +commit_chk_wrnNNO false "text" "$WILC" "$WICL" "$WAMIX" "$WILC" "$WICL" +commit_chk_wrnNNO true "text" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" +commit_chk_wrnNNO input "text" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" + +commit_chk_wrnNNO false "-text" "" "" "" "" "" +commit_chk_wrnNNO true "-text" "" "" "" "" "" +commit_chk_wrnNNO input "-text" "" "" "" "" "" + +commit_chk_wrnNNO false "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" +commit_chk_wrnNNO true "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" +commit_chk_wrnNNO input "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" + +commit_chk_wrnNNO false "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" +commit_chk_wrnNNO true "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" +commit_chk_wrnNNO input "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" + test_expect_success 'create files cleanup' ' rm -f *.txt && - git reset --hard + git -c core.autocrlf=false reset --hard ' test_expect_success 'commit empty gitattribues' ' @@ -257,6 +362,24 @@ test_expect_success 'commit -text' ' check_files_in_repo input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul ' +# attr LF CRLF CRLF_mix_LF LF_mix_CR CRLFNUL +check_in_repo_NNO false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul +check_in_repo_NNO true "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul +check_in_repo_NNO input "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + +check_in_repo_NNO false "auto" LF LF LF LF_mix_CR CRLF_nul +check_in_repo_NNO true "auto" LF LF LF LF_mix_CR CRLF_nul +check_in_repo_NNO input "auto" LF LF LF LF_mix_CR CRLF_nul + +check_in_repo_NNO false "text" LF LF LF LF_mix_CR LF_nul +check_in_repo_NNO true "text" LF LF LF LF_mix_CR LF_nul +check_in_repo_NNO input "text" LF LF LF LF_mix_CR LF_nul + +check_in_repo_NNO false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul +check_in_repo_NNO true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul +check_in_repo_NNO input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + + ################################################################################ # Check how files in the repo are changed when they are checked out # How to read the table below: diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 93605f42f2..627ef854d5 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -266,15 +266,21 @@ 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 logs/refs/bisect/foo .git/logs/refs/bisect/foo +test_git_path GIT_COMMON_DIR=bar logs/refs/bisec/foo bar/logs/refs/bisec/foo +test_git_path GIT_COMMON_DIR=bar logs/refs/bisec bar/logs/refs/bisec +test_git_path GIT_COMMON_DIR=bar logs/refs/bisectfoo bar/logs/refs/bisectfoo 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 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 refs/bisect/foo .git/refs/bisect/foo 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 diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index 9acf628726..12228b4aa6 100755 --- a/t/t0061-run-command.sh +++ b/t/t0061-run-command.sh @@ -47,4 +47,57 @@ test_expect_success POSIXPERM,SANITY 'unreadable directory in PATH' ' test_cmp expect actual ' +cat >expect <<-EOF +preloaded output of a child +Hello +World +preloaded output of a child +Hello +World +preloaded output of a child +Hello +World +preloaded output of a child +Hello +World +EOF + +test_expect_success 'run_command runs in parallel with more jobs available than tasks' ' + test-run-command run-command-parallel 5 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual && + test_cmp expect actual +' + +test_expect_success 'run_command runs in parallel with as many jobs as tasks' ' + test-run-command run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual && + test_cmp expect actual +' + +test_expect_success 'run_command runs in parallel with more tasks than jobs available' ' + test-run-command run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual && + test_cmp expect actual +' + +cat >expect <<-EOF +preloaded output of a child +asking for a quick stop +preloaded output of a child +asking for a quick stop +preloaded output of a child +asking for a quick stop +EOF + +test_expect_success 'run_command is asked to abort gracefully' ' + test-run-command run-command-abort 3 false 2>actual && + test_cmp expect actual +' + +cat >expect <<-EOF +no further jobs available +EOF + +test_expect_success 'run_command outputs ' ' + test-run-command run-command-no-jobs 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual && + test_cmp expect actual +' + test_done diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index 97406fa4b1..af1b20dd5c 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -1130,4 +1130,23 @@ test_expect_success ULIMIT_FILE_DESCRIPTORS 'large transaction deleting branches ) ' +test_expect_success 'handle per-worktree refs in refs/bisect' ' + git commit --allow-empty -m "initial commit" && + git worktree add -b branch worktree && + ( + cd worktree && + git commit --allow-empty -m "test commit" && + git for-each-ref >for-each-ref.out && + ! grep refs/bisect for-each-ref.out && + git update-ref refs/bisect/something HEAD && + git rev-parse refs/bisect/something >../worktree-head && + git for-each-ref | grep refs/bisect/something + ) && + test_path_is_missing .git/refs/bisect && + test_must_fail git rev-parse refs/bisect/something && + git update-ref refs/bisect/something HEAD && + git rev-parse refs/bisect/something >main-head && + ! test_cmp main-head worktree-head +' + test_done diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 36378b0e3f..1f0dff3a0b 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -63,4 +63,55 @@ test_expect_success 'symbolic-ref fails to delete real ref' ' ' reset_to_sane +test_expect_success 'create large ref name' ' + # make 256+ character ref; some systems may not handle that, + # so be gentle + long=0123456789abcdef && + long=$long/$long/$long/$long && + long=$long/$long/$long/$long && + long_ref=refs/heads/$long && + tree=$(git write-tree) && + commit=$(echo foo | git commit-tree $tree) && + if git update-ref $long_ref $commit; then + test_set_prereq LONG_REF + else + echo >&2 "long refs not supported" + fi +' + +test_expect_success LONG_REF 'symbolic-ref can point to large ref name' ' + git symbolic-ref HEAD $long_ref && + echo $long_ref >expect && + git symbolic-ref HEAD >actual && + test_cmp expect actual +' + +test_expect_success LONG_REF 'we can parse long symbolic ref' ' + echo $commit >expect && + git rev-parse --verify HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'symbolic-ref reports failure in exit code' ' + test_when_finished "rm -f .git/HEAD.lock" && + >.git/HEAD.lock && + test_must_fail git symbolic-ref HEAD refs/heads/whatever +' + +test_expect_success 'symbolic-ref writes reflog entry' ' + git checkout -b log1 && + test_commit one && + git checkout -b log2 && + test_commit two && + git checkout --orphan orphan && + git symbolic-ref -m create HEAD refs/heads/log1 && + git symbolic-ref -m update HEAD refs/heads/log2 && + cat >expect <<-\EOF && + update + create + EOF + git log --format=%gs -g >actual && + test_cmp expect actual +' + test_done diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index b79049f6f6..17a194bfa6 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -325,4 +325,17 @@ test_expect_success 'parsing reverse reflogs at BUFSIZ boundaries' ' test_cmp expect actual ' +test_expect_success 'no segfaults for reflog containing non-commit sha1s' ' + git update-ref --create-reflog -m "Creating ref" \ + refs/tests/tree-in-reflog HEAD && + git update-ref -m "Forcing tree" refs/tests/tree-in-reflog HEAD^{tree} && + git update-ref -m "Restoring to commit" refs/tests/tree-in-reflog HEAD && + git reflog refs/tests/tree-in-reflog +' + +test_expect_failure 'reflog with non-commit entries displays all entries' ' + git reflog refs/tests/tree-in-reflog >actual && + test_line_count = 3 actual +' + test_done diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh index 16d0b8bd1a..c465abe8e3 100755 --- a/t/t1430-bad-ref-name.sh +++ b/t/t1430-bad-ref-name.sh @@ -38,18 +38,20 @@ test_expect_success 'fast-import: fail on invalid branch name "bad[branch]name"' test_must_fail git fast-import <input ' -test_expect_success 'git branch shows badly named ref' ' +test_expect_success 'git branch shows badly named ref as warning' ' cp .git/refs/heads/master .git/refs/heads/broken...ref && test_when_finished "rm -f .git/refs/heads/broken...ref" && - git branch >output && - grep -e "broken\.\.\.ref" output + git branch >output 2>error && + grep -e "broken\.\.\.ref" error && + ! grep -e "broken\.\.\.ref" output ' test_expect_success 'branch -d can delete badly named ref' ' cp .git/refs/heads/master .git/refs/heads/broken...ref && test_when_finished "rm -f .git/refs/heads/broken...ref" && git branch -d broken...ref && - git branch >output && + git branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' @@ -57,7 +59,8 @@ test_expect_success 'branch -D can delete badly named ref' ' cp .git/refs/heads/master .git/refs/heads/broken...ref && test_when_finished "rm -f .git/refs/heads/broken...ref" && git branch -D broken...ref && - git branch >output && + git branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' @@ -85,7 +88,8 @@ test_expect_success 'branch -D cannot delete absolute path' ' test_expect_success 'git branch cannot create a badly named ref' ' test_when_finished "rm -f .git/refs/heads/broken...ref" && test_must_fail git branch broken...ref && - git branch >output && + git branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' @@ -95,7 +99,8 @@ test_expect_success 'branch -m cannot rename to a bad ref name' ' git branch goodref && test_must_fail git branch -m goodref broken...ref && test_cmp_rev master goodref && - git branch >output && + git branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' @@ -104,14 +109,16 @@ test_expect_failure 'branch -m can rename from a bad ref name' ' test_when_finished "rm -f .git/refs/heads/broken...ref" && git branch -m broken...ref renamed && test_cmp_rev master renamed && - git branch >output && + git branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' test_expect_success 'push cannot create a badly named ref' ' test_when_finished "rm -f .git/refs/heads/broken...ref" && test_must_fail git push "file://$(pwd)" HEAD:refs/heads/broken...ref && - git branch >output && + git branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' @@ -131,7 +138,8 @@ test_expect_failure 'push --mirror can delete badly named ref' ' cp .git/refs/heads/master .git/refs/heads/broken...ref ) && git -C src push --mirror "file://$top/dest" && - git -C dest branch >output && + git -C dest branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' @@ -159,7 +167,8 @@ test_expect_success 'update-ref -d can delete broken name' ' cp .git/refs/heads/master .git/refs/heads/broken...ref && test_when_finished "rm -f .git/refs/heads/broken...ref" && git update-ref -d refs/heads/broken...ref && - git branch >output && + git branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index dc09797021..e66b7cb697 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -176,6 +176,18 @@ test_expect_success 'integer overflow in timestamps is reported' ' grep "error in commit $new.*integer overflow" out ' +test_expect_success 'commit with NUL in header' ' + git cat-file commit HEAD >basis && + sed "s/author ./author Q/" <basis | q_to_nul >commit-NUL-header && + new=$(git hash-object -t commit -w --stdin <commit-NUL-header) && + test_when_finished "remove_object $new" && + git update-ref refs/heads/bogus "$new" && + test_when_finished "git update-ref -d refs/heads/bogus" && + test_must_fail git fsck 2>out && + cat out && + grep "error in commit $new.*unterminated header: NUL at offset" out +' + test_expect_success 'malformatted tree object' ' test_when_finished "git update-ref -d refs/tags/wrong" && test_when_finished "remove_object \$T" && @@ -276,6 +288,26 @@ test_expect_success 'tag with bad tagger' ' grep "error in tag .*: invalid author/committer" out ' +test_expect_success 'tag with NUL in header' ' + sha=$(git rev-parse HEAD) && + q_to_nul >tag-NUL-header <<-EOF && + object $sha + type commit + tag contains-Q-in-header + tagger T A Gger <tagger@example.com> 1234567890 -0000 + + This is an invalid tag. + EOF + + tag=$(git hash-object --literally -t tag -w --stdin <tag-NUL-header) && + test_when_finished "remove_object $tag" && + echo $tag >.git/refs/tags/wrong && + test_when_finished "git update-ref -d refs/tags/wrong" && + test_must_fail git fsck --tags 2>out && + cat out && + grep "error in tag $tag.*unterminated header: NUL at offset" out +' + test_expect_success 'cleaned up' ' git fsck >actual 2>&1 && test_cmp empty actual diff --git a/t/t2027-worktree-list.sh b/t/t2027-worktree-list.sh new file mode 100755 index 0000000000..75ebb1b4a0 --- /dev/null +++ b/t/t2027-worktree-list.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +test_description='test git worktree list' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit init +' + +test_expect_success '"list" all worktrees from main' ' + echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect && + test_when_finished "rm -rf here && git worktree prune" && + git worktree add --detach here master && + echo "$(git -C here rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >>expect && + git worktree list | sed "s/ */ /g" >actual && + test_cmp expect actual +' + +test_expect_success '"list" all worktrees from linked' ' + echo "$(git rev-parse --show-toplevel) $(git rev-parse --short HEAD) [$(git symbolic-ref --short HEAD)]" >expect && + test_when_finished "rm -rf here && git worktree prune" && + git worktree add --detach here master && + echo "$(git -C here rev-parse --show-toplevel) $(git rev-parse --short HEAD) (detached HEAD)" >>expect && + git -C here worktree list | sed "s/ */ /g" >actual && + test_cmp expect actual +' + +test_expect_success '"list" all worktrees --porcelain' ' + echo "worktree $(git rev-parse --show-toplevel)" >expect && + echo "HEAD $(git rev-parse HEAD)" >>expect && + echo "branch $(git symbolic-ref HEAD)" >>expect && + echo >>expect && + test_when_finished "rm -rf here && git worktree prune" && + git worktree add --detach here master && + echo "worktree $(git -C here rev-parse --show-toplevel)" >>expect && + echo "HEAD $(git rev-parse HEAD)" >>expect && + echo "detached" >>expect && + echo >>expect && + git worktree list --porcelain >actual && + test_cmp expect actual +' + +test_expect_success 'bare repo setup' ' + git init --bare bare1 && + echo "data" >file1 && + git add file1 && + git commit -m"File1: add data" && + git push bare1 master && + git reset --hard HEAD^ +' + +test_expect_success '"list" all worktrees from bare main' ' + test_when_finished "rm -rf there && git -C bare1 worktree prune" && + git -C bare1 worktree add --detach ../there master && + echo "$(pwd)/bare1 (bare)" >expect && + echo "$(git -C there rev-parse --show-toplevel) $(git -C there rev-parse --short HEAD) (detached HEAD)" >>expect && + git -C bare1 worktree list | sed "s/ */ /g" >actual && + test_cmp expect actual +' + +test_expect_success '"list" all worktrees --porcelain from bare main' ' + test_when_finished "rm -rf there && git -C bare1 worktree prune" && + git -C bare1 worktree add --detach ../there master && + echo "worktree $(pwd)/bare1" >expect && + echo "bare" >>expect && + echo >>expect && + echo "worktree $(git -C there rev-parse --show-toplevel)" >>expect && + echo "HEAD $(git -C there rev-parse HEAD)" >>expect && + echo "detached" >>expect && + echo >>expect && + git -C bare1 worktree list --porcelain >actual && + test_cmp expect actual +' + +test_expect_success '"list" all worktrees from linked with a bare main' ' + test_when_finished "rm -rf there && git -C bare1 worktree prune" && + git -C bare1 worktree add --detach ../there master && + echo "$(pwd)/bare1 (bare)" >expect && + echo "$(git -C there rev-parse --show-toplevel) $(git -C there rev-parse --short HEAD) (detached HEAD)" >>expect && + git -C there worktree list | sed "s/ */ /g" >actual && + test_cmp expect actual +' + +test_expect_success 'bare repo cleanup' ' + rm -rf bare1 +' + +test_done diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index 16efe7af03..d3913f9088 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -156,4 +156,24 @@ EOF test_i18ncmp expect actual ' +test_expect_success 'git branch `--sort` option' ' + cat >expect <<-\EOF && + * (HEAD detached from fromtag) + branch-two + branch-one + master + EOF + git branch --sort=objectsize >actual && + test_i18ncmp expect actual +' + +test_expect_success 'git branch --points-at option' ' + cat >expect <<-\EOF && + branch-one + master + EOF + git branch --points-at=branch-one >actual && + test_cmp expect actual +' + test_done diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index 7b5b6d452e..db244d2f88 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -160,6 +160,13 @@ test_expect_success 'pack ref directly below refs/' ' test_path_is_missing .git/refs/top ' +test_expect_success 'do not pack ref in refs/bisect' ' + git update-ref refs/bisect/local HEAD && + git pack-refs --all --prune && + ! grep refs/bisect/local .git/packed-refs >/dev/null && + test_path_is_file .git/refs/bisect/local +' + test_expect_success 'disable reflogs' ' git config core.logallrefupdates false && rm -rf .git/logs diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index cd70274ea5..2d200fdf36 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -83,6 +83,16 @@ test_expect_success 'edit existing notes' ' test_must_fail git notes show HEAD^ ' +test_expect_success 'show notes from treeish' ' + test "b3" = "$(git notes --ref commits^{tree} show)" && + test "b4" = "$(git notes --ref commits@{1} show)" +' + +test_expect_success 'cannot edit notes from non-ref' ' + test_must_fail git notes --ref commits^{tree} edit && + test_must_fail git notes --ref commits@{1} edit +' + test_expect_success 'cannot "git notes add -m" where notes already exists' ' test_must_fail git notes add -m "b2" && test_path_is_missing .git/NOTES_EDITMSG && diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 98eb49ac23..544f9ad508 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -1006,6 +1006,22 @@ test_expect_success 'rebase -i with --strategy and -X' ' test $(cat file1) = Z ' +test_expect_success 'interrupted rebase -i with --strategy and -X' ' + git checkout -b conflict-merge-use-theirs-interrupted conflict-branch && + git reset --hard HEAD^ && + >breakpoint && + git add breakpoint && + git commit -m "breakpoint for interactive mode" && + echo five >conflict && + echo Z >file1 && + git commit -a -m "one file conflict" && + set_fake_editor && + FAKE_LINES="edit 1 2" git rebase -i --strategy=recursive -Xours conflict-branch && + git rebase --continue && + test $(git show conflict-branch:conflict) = $(cat conflict) && + test $(cat file1) = Z +' + test_expect_success 'rebase -i error on commits with \ in message' ' current_head=$(git rev-parse HEAD) && test_when_finished "git rebase --abort; git reset --hard $current_head; rm -f error" && @@ -1234,7 +1250,7 @@ test_expect_success 'tabs and spaces are accepted in the todolist' ' # Turn single spaces into space/tab mix sed "1s/ / /g; 2s/ / /g; 3s/ / /g" "$1" printf "\n\t# comment\n #more\n\t # comment\n" - ) >$1.new + ) >"$1.new" mv "$1.new" "$1" EOF test_set_editor "$(pwd)/add-indent.sh" && diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh index d783f03d3f..944154b2e0 100755 --- a/t/t3420-rebase-autostash.sh +++ b/t/t3420-rebase-autostash.sh @@ -37,6 +37,16 @@ testrebase() { type=$1 dotest=$2 + test_expect_success "rebase$type: dirty worktree, --no-autostash" ' + test_config rebase.autostash true && + git reset --hard && + git checkout -b rebased-feature-branch feature-branch && + test_when_finished git branch -D rebased-feature-branch && + test_when_finished git checkout feature-branch && + echo dirty >>file3 && + test_must_fail git rebase$type --no-autostash unrelated-onto-branch + ' + test_expect_success "rebase$type: dirty worktree, non-conflicting rebase" ' test_config rebase.autostash true && git reset --hard && diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 890db1174f..646c4750ec 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1431,4 +1431,18 @@ test_expect_success 'cover letter auto user override' ' test_line_count = 2 list ' +test_expect_success 'format-patch --zero-commit' ' + git format-patch --zero-commit --stdout v2..v1 >patch2 && + grep "^From " patch2 | sort | uniq >actual && + echo "From $_z40 Mon Sep 17 00:00:00 2001" >expect && + test_cmp expect actual +' + +test_expect_success 'From line has expected format' ' + git format-patch --stdout v2..v1 >patch2 && + grep "^From " patch2 >from && + grep "^From $_x40 Mon Sep 17 00:00:00 2001$" patch2 >filtered && + test_cmp from filtered +' + test_done diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 6ede0692f6..cb82eb7e66 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -908,4 +908,33 @@ test_expect_success 'log diagnoses bogus HEAD' ' test_i18ngrep broken stderr ' +test_expect_success 'set up --source tests' ' + git checkout --orphan source-a && + test_commit one && + test_commit two && + git checkout -b source-b HEAD^ && + test_commit three +' + +test_expect_success 'log --source paints branch names' ' + cat >expect <<-\EOF && + 09e12a9 source-b three + 8e393e1 source-a two + 1ac6c77 source-b one + EOF + git log --oneline --source source-a source-b >actual && + test_cmp expect actual +' + +test_expect_success 'log --source paints tag names' ' + git tag -m tagged source-tag && + cat >expect <<-\EOF && + 09e12a9 source-tag three + 8e393e1 source-a two + 1ac6c77 source-tag one + EOF + git log --oneline --source source-tag source-a >actual && + test_cmp expect actual +' + test_done diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index 023d7c6f7b..def203c724 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -219,6 +219,7 @@ test_expect_success 'gc: prune old objects after local clone' ' test_expect_success 'garbage report in count-objects -v' ' test_when_finished "rm -f .git/objects/pack/fake*" && + test_when_finished "rm -f .git/objects/pack/foo*" && : >.git/objects/pack/foo && : >.git/objects/pack/foo.bar && : >.git/objects/pack/foo.keep && @@ -244,6 +245,26 @@ EOF test_cmp expected actual ' +test_expect_success 'clean pack garbage with gc' ' + test_when_finished "rm -f .git/objects/pack/fake*" && + test_when_finished "rm -f .git/objects/pack/foo*" && + : >.git/objects/pack/foo.keep && + : >.git/objects/pack/foo.pack && + : >.git/objects/pack/fake.idx && + : >.git/objects/pack/fake2.keep && + : >.git/objects/pack/fake2.idx && + : >.git/objects/pack/fake3.keep && + git gc && + git count-objects -v 2>stderr && + grep "^warning:" stderr | sort >actual && + cat >expected <<\EOF && +warning: no corresponding .idx or .pack: .git/objects/pack/fake3.keep +warning: no corresponding .idx: .git/objects/pack/foo.keep +warning: no corresponding .idx: .git/objects/pack/foo.pack +EOF + test_cmp expected actual +' + test_expect_success 'prune .git/shallow' ' SHA1=`echo hi|git commit-tree HEAD^{tree}` && echo $SHA1 >.git/shallow && diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index 44f3d5fb28..89224edcc5 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -100,7 +100,7 @@ test_expect_success 'push with receive.fsckobjects' ' git config receive.fsckobjects true && git config transfer.fsckobjects false ) && - test_must_fail git push --porcelain dst master:refs/heads/test >act && + test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act && test_cmp exp act ' @@ -111,8 +111,7 @@ test_expect_success 'push with transfer.fsckobjects' ' cd dst && git config transfer.fsckobjects true ) && - test_must_fail git push --porcelain dst master:refs/heads/test >act && - test_cmp exp act + test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act ' cat >bogus-commit <<\EOF diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 7a8499ce66..dfaf9d9f68 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -919,6 +919,19 @@ test_expect_success 'new remote' ' cmp expect actual ' +get_url_test () { + cat >expect && + git remote get-url "$@" >actual && + test_cmp expect actual +} + +test_expect_success 'get-url on new remote' ' + echo foo | get_url_test someremote && + echo foo | get_url_test --all someremote && + echo foo | get_url_test --push someremote && + echo foo | get_url_test --push --all someremote +' + test_expect_success 'remote set-url bar' ' git remote set-url someremote bar && echo bar >expect && @@ -961,6 +974,13 @@ test_expect_success 'remote set-url --push zot' ' cmp expect actual ' +test_expect_success 'get-url with different urls' ' + echo baz | get_url_test someremote && + echo baz | get_url_test --all someremote && + echo zot | get_url_test --push someremote && + echo zot | get_url_test --push --all someremote +' + test_expect_success 'remote set-url --push qux zot' ' git remote set-url --push someremote qux zot && echo qux >expect && @@ -995,6 +1015,14 @@ test_expect_success 'remote set-url --push --add aaa' ' cmp expect actual ' +test_expect_success 'get-url on multi push remote' ' + echo foo | get_url_test --push someremote && + get_url_test --push --all someremote <<-\EOF + foo + aaa + EOF +' + test_expect_success 'remote set-url --push bar aaa' ' git remote set-url --push someremote bar aaa && echo foo >expect && @@ -1039,6 +1067,14 @@ test_expect_success 'remote set-url --add bbb' ' cmp expect actual ' +test_expect_success 'get-url on multi fetch remote' ' + echo baz | get_url_test someremote && + get_url_test --all someremote <<-\EOF + baz + bbb + EOF +' + test_expect_success 'remote set-url --delete .*' ' test_must_fail git remote set-url --delete someremote .\* && echo "YYY" >expect && @@ -1108,6 +1144,7 @@ test_extra_arg rename origin newname test_extra_arg remove origin test_extra_arg set-head origin master # set-branches takes any number of args +test_extra_arg get-url origin newurl test_extra_arg set-url origin newurl oldurl # show takes any number of args # prune takes any number of args diff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh index cc0b31f6b0..bc44ac36d5 100755 --- a/t/t5509-fetch-push-namespaces.sh +++ b/t/t5509-fetch-push-namespaces.sh @@ -82,4 +82,45 @@ test_expect_success 'mirroring a repository using a ref namespace' ' ) ' +test_expect_success 'hide namespaced refs with transfer.hideRefs' ' + GIT_NAMESPACE=namespace \ + git -C pushee -c transfer.hideRefs=refs/tags \ + ls-remote "ext::git %s ." >actual && + printf "$commit1\trefs/heads/master\n" >expected && + test_cmp expected actual +' + +test_expect_success 'check that transfer.hideRefs does not match unstripped refs' ' + GIT_NAMESPACE=namespace \ + git -C pushee -c transfer.hideRefs=refs/namespaces/namespace/refs/tags \ + ls-remote "ext::git %s ." >actual && + printf "$commit1\trefs/heads/master\n" >expected && + printf "$commit0\trefs/tags/0\n" >>expected && + printf "$commit1\trefs/tags/1\n" >>expected && + test_cmp expected actual +' + +test_expect_success 'hide full refs with transfer.hideRefs' ' + GIT_NAMESPACE=namespace \ + git -C pushee -c transfer.hideRefs="^refs/namespaces/namespace/refs/tags" \ + ls-remote "ext::git %s ." >actual && + printf "$commit1\trefs/heads/master\n" >expected && + test_cmp expected actual +' + +test_expect_success 'try to update a hidden ref' ' + test_config -C pushee transfer.hideRefs refs/heads/master && + test_must_fail git -C original push pushee-namespaced master +' + +test_expect_success 'try to update a ref that is not hidden' ' + test_config -C pushee transfer.hideRefs refs/namespaces/namespace/refs/heads/master && + git -C original push pushee-namespaced master +' + +test_expect_success 'try to update a hidden full ref' ' + test_config -C pushee transfer.hideRefs "^refs/namespaces/namespace/refs/heads/master" && + test_must_fail git -C original push pushee-namespaced master +' + test_done diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index ec22c98445..0a87e195ea 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -1162,15 +1162,15 @@ do mk_empty shallow && ( cd shallow && - test_must_fail git fetch ../testrepo/.git $SHA1_3 && - test_must_fail git fetch ../testrepo/.git $SHA1_1 && + test_must_fail ok=sigpipe git fetch ../testrepo/.git $SHA1_3 && + test_must_fail ok=sigpipe git fetch ../testrepo/.git $SHA1_1 && git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true && git fetch ../testrepo/.git $SHA1_1 && git cat-file commit $SHA1_1 && test_must_fail git cat-file commit $SHA1_2 && git fetch ../testrepo/.git $SHA1_2 && git cat-file commit $SHA1_2 && - test_must_fail git fetch ../testrepo/.git $SHA1_3 + test_must_fail ok=sigpipe git fetch ../testrepo/.git $SHA1_3 ) ' done diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh index a4532b00d6..1241146227 100755 --- a/t/t5526-fetch-submodules.sh +++ b/t/t5526-fetch-submodules.sh @@ -16,7 +16,8 @@ add_upstream_commit() { git add subfile && git commit -m new subfile && head2=$(git rev-parse --short HEAD) && - echo "From $pwd/submodule" > ../expect.err && + echo "Fetching submodule submodule" > ../expect.err && + echo "From $pwd/submodule" >> ../expect.err && echo " $head1..$head2 master -> origin/master" >> ../expect.err ) && ( @@ -27,6 +28,7 @@ add_upstream_commit() { git add deepsubfile && git commit -m new deepsubfile && head2=$(git rev-parse --short HEAD) && + echo "Fetching submodule submodule/subdir/deepsubmodule" >> ../expect.err echo "From $pwd/deepsubmodule" >> ../expect.err && echo " $head1..$head2 master -> origin/master" >> ../expect.err ) @@ -56,9 +58,7 @@ test_expect_success setup ' ( cd downstream && git submodule update --init --recursive - ) && - echo "Fetching submodule submodule" > expect.out && - echo "Fetching submodule submodule/subdir/deepsubmodule" >> expect.out + ) ' test_expect_success "fetch --recurse-submodules recurses into submodules" ' @@ -67,10 +67,21 @@ test_expect_success "fetch --recurse-submodules recurses into submodules" ' cd downstream && git fetch --recurse-submodules >../actual.out 2>../actual.err ) && - test_i18ncmp expect.out actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err actual.err ' +test_expect_success "fetch --recurse-submodules -j2 has the same output behaviour" ' + add_upstream_commit && + ( + cd downstream && + GIT_TRACE=$(pwd)/../trace.out git fetch --recurse-submodules -j2 2>../actual.err + ) && + test_must_be_empty actual.out && + test_i18ncmp expect.err actual.err && + grep "2 tasks" trace.out +' + test_expect_success "fetch alone only fetches superproject" ' add_upstream_commit && ( @@ -96,7 +107,7 @@ test_expect_success "using fetchRecurseSubmodules=true in .gitmodules recurses i git config -f .gitmodules submodule.submodule.fetchRecurseSubmodules true && git fetch >../actual.out 2>../actual.err ) && - test_i18ncmp expect.out actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err actual.err ' @@ -127,7 +138,7 @@ test_expect_success "--recurse-submodules overrides fetchRecurseSubmodules setti git config --unset -f .gitmodules submodule.submodule.fetchRecurseSubmodules && git config --unset submodule.submodule.fetchRecurseSubmodules ) && - test_i18ncmp expect.out actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err actual.err ' @@ -140,13 +151,22 @@ test_expect_success "--quiet propagates to submodules" ' ! test -s actual.err ' +test_expect_success "--quiet propagates to parallel submodules" ' + ( + cd downstream && + git fetch --recurse-submodules -j 2 --quiet >../actual.out 2>../actual.err + ) && + ! test -s actual.out && + ! test -s actual.err +' + test_expect_success "--dry-run propagates to submodules" ' add_upstream_commit && ( cd downstream && git fetch --recurse-submodules --dry-run >../actual.out 2>../actual.err ) && - test_i18ncmp expect.out actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err actual.err ' @@ -155,7 +175,7 @@ test_expect_success "Without --dry-run propagates to submodules" ' cd downstream && git fetch --recurse-submodules >../actual.out 2>../actual.err ) && - test_i18ncmp expect.out actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err actual.err ' @@ -166,7 +186,7 @@ test_expect_success "recurseSubmodules=true propagates into submodules" ' git config fetch.recurseSubmodules true git fetch >../actual.out 2>../actual.err ) && - test_i18ncmp expect.out actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err actual.err ' @@ -180,7 +200,7 @@ test_expect_success "--recurse-submodules overrides config in submodule" ' ) && git fetch --recurse-submodules >../actual.out 2>../actual.err ) && - test_i18ncmp expect.out actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err actual.err ' @@ -214,16 +234,15 @@ test_expect_success "Recursion stops when no new submodule commits are fetched" git add submodule && git commit -m "new submodule" && head2=$(git rev-parse --short HEAD) && - echo "Fetching submodule submodule" > expect.out.sub && echo "From $pwd/." > expect.err.sub && echo " $head1..$head2 master -> origin/master" >>expect.err.sub && - head -2 expect.err >> expect.err.sub && + head -3 expect.err >> expect.err.sub && ( cd downstream && git fetch >../actual.out 2>../actual.err ) && test_i18ncmp expect.err.sub actual.err && - test_i18ncmp expect.out.sub actual.out + test_must_be_empty actual.out ' test_expect_success "Recursion doesn't happen when new superproject commits don't change any submodules" ' @@ -269,7 +288,7 @@ test_expect_success "Recursion picks up config in submodule" ' ) ) && test_i18ncmp expect.err.sub actual.err && - test_i18ncmp expect.out actual.out + test_must_be_empty actual.out ' test_expect_success "Recursion picks up all submodules when necessary" ' @@ -285,7 +304,8 @@ test_expect_success "Recursion picks up all submodules when necessary" ' git add subdir/deepsubmodule && git commit -m "new deepsubmodule" head2=$(git rev-parse --short HEAD) && - echo "From $pwd/submodule" > ../expect.err.sub && + echo "Fetching submodule submodule" > ../expect.err.sub && + echo "From $pwd/submodule" >> ../expect.err.sub && echo " $head1..$head2 master -> origin/master" >> ../expect.err.sub ) && head1=$(git rev-parse --short HEAD) && @@ -295,13 +315,13 @@ test_expect_success "Recursion picks up all submodules when necessary" ' echo "From $pwd/." > expect.err.2 && echo " $head1..$head2 master -> origin/master" >> expect.err.2 && cat expect.err.sub >> expect.err.2 && - tail -2 expect.err >> expect.err.2 && + tail -3 expect.err >> expect.err.2 && ( cd downstream && git fetch >../actual.out 2>../actual.err ) && test_i18ncmp expect.err.2 actual.err && - test_i18ncmp expect.out actual.out + test_must_be_empty actual.out ' test_expect_success "'--recurse-submodules=on-demand' doesn't recurse when no new commits are fetched in the superproject (and ignores config)" ' @@ -317,7 +337,8 @@ test_expect_success "'--recurse-submodules=on-demand' doesn't recurse when no ne git add subdir/deepsubmodule && git commit -m "new deepsubmodule" && head2=$(git rev-parse --short HEAD) && - echo "From $pwd/submodule" > ../expect.err.sub && + echo Fetching submodule submodule > ../expect.err.sub && + echo "From $pwd/submodule" >> ../expect.err.sub && echo " $head1..$head2 master -> origin/master" >> ../expect.err.sub ) && ( @@ -335,7 +356,7 @@ test_expect_success "'--recurse-submodules=on-demand' recurses as deep as necess git add submodule && git commit -m "new submodule" && head2=$(git rev-parse --short HEAD) && - tail -2 expect.err > expect.err.deepsub && + tail -3 expect.err > expect.err.deepsub && echo "From $pwd/." > expect.err && echo " $head1..$head2 master -> origin/master" >>expect.err && cat expect.err.sub >> expect.err && @@ -354,7 +375,7 @@ test_expect_success "'--recurse-submodules=on-demand' recurses as deep as necess git config --unset -f .gitmodules submodule.subdir/deepsubmodule.fetchRecursive ) ) && - test_i18ncmp expect.out actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err actual.err ' @@ -388,7 +409,7 @@ test_expect_success "'fetch.recurseSubmodules=on-demand' overrides global config head2=$(git rev-parse --short HEAD) && echo "From $pwd/." > expect.err.2 && echo " $head1..$head2 master -> origin/master" >>expect.err.2 && - head -2 expect.err >> expect.err.2 && + head -3 expect.err >> expect.err.2 && ( cd downstream && git config fetch.recurseSubmodules on-demand && @@ -399,7 +420,7 @@ test_expect_success "'fetch.recurseSubmodules=on-demand' overrides global config cd downstream && git config --unset fetch.recurseSubmodules ) && - test_i18ncmp expect.out.sub actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err.2 actual.err ' @@ -416,7 +437,7 @@ test_expect_success "'submodule.<sub>.fetchRecurseSubmodules=on-demand' override head2=$(git rev-parse --short HEAD) && echo "From $pwd/." > expect.err.2 && echo " $head1..$head2 master -> origin/master" >>expect.err.2 && - head -2 expect.err >> expect.err.2 && + head -3 expect.err >> expect.err.2 && ( cd downstream && git config submodule.submodule.fetchRecurseSubmodules on-demand && @@ -427,7 +448,7 @@ test_expect_success "'submodule.<sub>.fetchRecurseSubmodules=on-demand' override cd downstream && git config --unset submodule.submodule.fetchRecurseSubmodules ) && - test_i18ncmp expect.out.sub actual.out && + test_must_be_empty actual.out && test_i18ncmp expect.err.2 actual.err ' diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index 6507487c1a..198ce84754 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -64,7 +64,12 @@ test_expect_success 'push fails if submodule commit not on remote' ' cd work && git add gar/bage && git commit -m "Third commit for gar/bage" && - test_must_fail git push --recurse-submodules=check ../pub.git master + # the push should fail with --recurse-submodules=check + # on the command line... + test_must_fail git push --recurse-submodules=check ../pub.git master && + + # ...or if specified in the configuration.. + test_must_fail git -c push.recurseSubmodules=check push ../pub.git master ) ' @@ -79,6 +84,216 @@ test_expect_success 'push succeeds after commit was pushed to remote' ' ) ' +test_expect_success 'push succeeds if submodule commit not on remote but using on-demand on command line' ' + ( + cd work/gar/bage && + >recurse-on-demand-on-command-line && + git add recurse-on-demand-on-command-line && + git commit -m "Recurse on-demand on command line junk" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse on-demand on command line for gar/bage" && + git push --recurse-submodules=on-demand ../pub.git master && + # Check that the supermodule commit got there + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + # Check that the submodule commit got there too + cd gar/bage && + git diff --quiet origin/master master + ) +' + +test_expect_success 'push succeeds if submodule commit not on remote but using on-demand from config' ' + ( + cd work/gar/bage && + >recurse-on-demand-from-config && + git add recurse-on-demand-from-config && + git commit -m "Recurse on-demand from config junk" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse on-demand from config for gar/bage" && + git -c push.recurseSubmodules=on-demand push ../pub.git master && + # Check that the supermodule commit got there + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + # Check that the submodule commit got there too + cd gar/bage && + git diff --quiet origin/master master + ) +' + +test_expect_success 'push recurse-submodules on command line overrides config' ' + ( + cd work/gar/bage && + >recurse-check-on-command-line-overriding-config && + git add recurse-check-on-command-line-overriding-config && + git commit -m "Recurse on command-line overriding config junk" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse on command-line overriding config for gar/bage" && + + # Ensure that we can override on-demand in the config + # to just check submodules + test_must_fail git -c push.recurseSubmodules=on-demand push --recurse-submodules=check ../pub.git master && + # Check that the supermodule commit did not get there + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master^ && + # Check that the submodule commit did not get there + (cd gar/bage && git diff --quiet origin/master master^) && + + # Ensure that we can override check in the config to + # disable submodule recursion entirely + (cd gar/bage && git diff --quiet origin/master master^) && + git -c push.recurseSubmodules=on-demand push --recurse-submodules=no ../pub.git master && + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + (cd gar/bage && git diff --quiet origin/master master^) && + + # Ensure that we can override check in the config to + # disable submodule recursion entirely (alternative form) + git -c push.recurseSubmodules=on-demand push --no-recurse-submodules ../pub.git master && + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + (cd gar/bage && git diff --quiet origin/master master^) && + + # Ensure that we can override check in the config to + # push the submodule too + git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master && + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + (cd gar/bage && git diff --quiet origin/master master) + ) +' + +test_expect_success 'push recurse-submodules last one wins on command line' ' + ( + cd work/gar/bage && + >recurse-check-on-command-line-overriding-earlier-command-line && + git add recurse-check-on-command-line-overriding-earlier-command-line && + git commit -m "Recurse on command-line overridiing earlier command-line junk" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse on command-line overriding earlier command-line for gar/bage" && + + # should result in "check" + test_must_fail git push --recurse-submodules=on-demand --recurse-submodules=check ../pub.git master && + # Check that the supermodule commit did not get there + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master^ && + # Check that the submodule commit did not get there + (cd gar/bage && git diff --quiet origin/master master^) && + + # should result in "no" + git push --recurse-submodules=on-demand --recurse-submodules=no ../pub.git master && + # Check that the supermodule commit did get there + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + # Check that the submodule commit did not get there + (cd gar/bage && git diff --quiet origin/master master^) && + + # should result in "no" + git push --recurse-submodules=on-demand --no-recurse-submodules ../pub.git master && + # Check that the submodule commit did not get there + (cd gar/bage && git diff --quiet origin/master master^) && + + # But the options in the other order should push the submodule + git push --recurse-submodules=check --recurse-submodules=on-demand ../pub.git master && + # Check that the submodule commit did get there + git fetch ../pub.git && + (cd gar/bage && git diff --quiet origin/master master) + ) +' + +test_expect_success 'push succeeds if submodule commit not on remote using on-demand from cmdline overriding config' ' + ( + cd work/gar/bage && + >recurse-on-demand-on-command-line-overriding-config && + git add recurse-on-demand-on-command-line-overriding-config && + git commit -m "Recurse on-demand on command-line overriding config junk" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse on-demand on command-line overriding config for gar/bage" && + git -c push.recurseSubmodules=check push --recurse-submodules=on-demand ../pub.git master && + # Check that the supermodule commit got there + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + # Check that the submodule commit got there + cd gar/bage && + git diff --quiet origin/master master + ) +' + +test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline overriding config' ' + ( + cd work/gar/bage && + >recurse-disable-on-command-line-overriding-config && + git add recurse-disable-on-command-line-overriding-config && + git commit -m "Recurse disable on command-line overriding config junk" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse disable on command-line overriding config for gar/bage" && + git -c push.recurseSubmodules=check push --recurse-submodules=no ../pub.git master && + # Check that the supermodule commit got there + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + # But that the submodule commit did not + ( cd gar/bage && git diff --quiet origin/master master^ ) && + # Now push it to avoid confusing future tests + git push --recurse-submodules=on-demand ../pub.git master + ) +' + +test_expect_success 'push succeeds if submodule commit disabling recursion from cmdline (alternative form) overriding config' ' + ( + cd work/gar/bage && + >recurse-disable-on-command-line-alt-overriding-config && + git add recurse-disable-on-command-line-alt-overriding-config && + git commit -m "Recurse disable on command-line alternative overriding config junk" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse disable on command-line alternative overriding config for gar/bage" && + git -c push.recurseSubmodules=check push --no-recurse-submodules ../pub.git master && + # Check that the supermodule commit got there + git fetch ../pub.git && + git diff --quiet FETCH_HEAD master && + # But that the submodule commit did not + ( cd gar/bage && git diff --quiet origin/master master^ ) && + # Now push it to avoid confusing future tests + git push --recurse-submodules=on-demand ../pub.git master + ) +' + +test_expect_success 'push fails if recurse submodules option passed as yes' ' + ( + cd work/gar/bage && + >recurse-push-fails-if-recurse-submodules-passed-as-yes && + git add recurse-push-fails-if-recurse-submodules-passed-as-yes && + git commit -m "Recurse push fails if recurse submodules option passed as yes" + ) && + ( + cd work && + git add gar/bage && + git commit -m "Recurse push fails if recurse submodules option passed as yes for gar/bage" && + test_must_fail git push --recurse-submodules=yes ../pub.git master && + test_must_fail git -c push.recurseSubmodules=yes push ../pub.git master && + git push --recurse-submodules=on-demand ../pub.git master + ) +' + test_expect_success 'push fails when commit on multiple branches if one branch has no remote' ' ( cd work/gar/bage && diff --git a/t/t5571-pre-push-hook.sh b/t/t5571-pre-push-hook.sh index 6f9916a390..ba975bb355 100755 --- a/t/t5571-pre-push-hook.sh +++ b/t/t5571-pre-push-hook.sh @@ -109,23 +109,20 @@ test_expect_success 'push to URL' ' diff expected actual ' -# Test that filling pipe buffers doesn't cause failure -# Too slow to leave enabled for general use -if false -then - printf 'parent1\nrepo1\n' >expected - nr=1000 - while test $nr -lt 2000 - do - nr=$(( $nr + 1 )) - git branch b/$nr $COMMIT3 - echo "refs/heads/b/$nr $COMMIT3 refs/heads/b/$nr $_z40" >>expected - done - - test_expect_success 'push many refs' ' - git push parent1 "refs/heads/b/*:refs/heads/b/*" && - diff expected actual - ' -fi +test_expect_success 'set up many-ref tests' ' + { + nr=1000 + while test $nr -lt 2000 + do + nr=$(( $nr + 1 )) + echo "create refs/heads/b/$nr $COMMIT3" + done + } | git update-ref --stdin +' + +test_expect_success 'sigpipe does not cause pre-push hook failure' ' + echo "exit 0" | write_script "$HOOK" && + git push parent1 "refs/heads/b/*:refs/heads/b/*" +' test_done diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 9b34f3c615..31b46582d7 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -65,6 +65,29 @@ test_expect_success 'clone respects GIT_WORK_TREE' ' ' +test_expect_success 'clone from hooks' ' + + test_create_repo r0 && + cd r0 && + test_commit initial && + cd .. && + git init r1 && + cd r1 && + cat >.git/hooks/pre-commit <<-\EOF && + #!/bin/sh + git clone ../r0 ../r2 + exit 1 + EOF + chmod u+x .git/hooks/pre-commit && + : >file && + git add file && + test_must_fail git commit -m invoke-hook && + cd .. && + test_cmp r0/.git/HEAD r2/.git/HEAD && + test_cmp r0/initial.t r2/initial.t + +' + test_expect_success 'clone creates intermediate directories' ' git clone src long/path/to/dst && diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh index 2250ef4fe2..dfa1bf79c5 100755 --- a/t/t5700-clone-reference.sh +++ b/t/t5700-clone-reference.sh @@ -210,4 +210,15 @@ test_expect_success 'clone, dissociate from partial reference and repack' ' test_line_count = 1 packs.txt ' +test_expect_success 'clone, dissociate from alternates' ' + rm -fr A B C && + test_create_repo A && + commit_in A file1 && + git clone --reference=A A B && + test_line_count = 1 B/.git/objects/info/alternates && + git clone --local --dissociate B C && + ! test -f C/.git/objects/info/alternates && + ( cd C && git fsck ) +' + test_done diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index c9d3ed14c3..362b1581e0 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -242,13 +242,6 @@ clean_mark () { sort >$(basename "$1") } -cmp_marks () { - test_when_finished "rm -rf git.marks testgit.marks" && - clean_mark ".git/testgit/$1/git.marks" && - clean_mark ".git/testgit/$1/testgit.marks" && - test_cmp git.marks testgit.marks -} - test_expect_success 'proper failure checks for fetching' ' (cd local && test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git fetch 2>error && @@ -258,12 +251,15 @@ test_expect_success 'proper failure checks for fetching' ' ' test_expect_success 'proper failure checks for pushing' ' + test_when_finished "rm -rf local/git.marks local/testgit.marks" && (cd local && git checkout -b crash master && echo crash >>file && git commit -a -m crash && test_must_fail env GIT_REMOTE_TESTGIT_FAILURE=1 git push --all && - cmp_marks origin + clean_mark ".git/testgit/origin/git.marks" && + clean_mark ".git/testgit/origin/testgit.marks" && + test_cmp git.marks testgit.marks ) ' diff --git a/t/t5802-connect-helper.sh b/t/t5802-connect-helper.sh index 878faf2b63..b7a7f9d588 100755 --- a/t/t5802-connect-helper.sh +++ b/t/t5802-connect-helper.sh @@ -69,4 +69,32 @@ test_expect_success 'update backfilled tag without primary transfer' ' test_cmp expect actual ' + +test_expect_success 'set up fake git-daemon' ' + mkdir remote && + git init --bare remote/one.git && + mkdir remote/host && + git init --bare remote/host/two.git && + write_script fake-daemon <<-\EOF && + git daemon --inetd \ + --informative-errors \ + --export-all \ + --base-path="$TRASH_DIRECTORY/remote" \ + --interpolated-path="$TRASH_DIRECTORY/remote/%H%D" \ + "$TRASH_DIRECTORY/remote" + EOF + export TRASH_DIRECTORY && + PATH=$TRASH_DIRECTORY:$PATH +' + +test_expect_success 'ext command can connect to git daemon (no vhost)' ' + rm -rf dst && + git clone "ext::fake-daemon %G/one.git" dst +' + +test_expect_success 'ext command can connect to git daemon (vhost)' ' + rm -rf dst && + git clone "ext::fake-daemon %G/two.git %Vhost" dst +' + test_done diff --git a/t/t5813-proto-disable-ssh.sh b/t/t5813-proto-disable-ssh.sh index ad877d774a..a954ead8af 100755 --- a/t/t5813-proto-disable-ssh.sh +++ b/t/t5813-proto-disable-ssh.sh @@ -14,7 +14,7 @@ test_expect_success 'setup repository to clone' ' ' test_proto "host:path" ssh "remote:repo.git" -test_proto "ssh://" ssh "ssh://remote/$PWD/remote/repo.git" -test_proto "git+ssh://" ssh "git+ssh://remote/$PWD/remote/repo.git" +test_proto "ssh://" ssh "ssh://remote$PWD/remote/repo.git" +test_proto "git+ssh://" ssh "git+ssh://remote$PWD/remote/repo.git" test_done diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 9e2c203747..e74662ba5c 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -759,4 +759,139 @@ test_expect_success '"git bisect bad HEAD" behaves as "git bisect bad"' ' git bisect reset ' +test_expect_success 'bisect starts with only one new' ' + git bisect reset && + git bisect start && + git bisect new $HASH4 && + git bisect next +' + +test_expect_success 'bisect does not start with only one old' ' + git bisect reset && + git bisect start && + git bisect old $HASH1 && + test_must_fail git bisect next +' + +test_expect_success 'bisect start with one new and old' ' + git bisect reset && + git bisect start && + git bisect old $HASH1 && + git bisect new $HASH4 && + git bisect new && + git bisect new >bisect_result && + grep "$HASH2 is the first new commit" bisect_result && + git bisect log >log_to_replay.txt && + git bisect reset +' + +test_expect_success 'bisect replay with old and new' ' + git bisect replay log_to_replay.txt >bisect_result && + grep "$HASH2 is the first new commit" bisect_result && + git bisect reset +' + +test_expect_success 'bisect cannot mix old/new and good/bad' ' + git bisect start && + git bisect bad $HASH4 && + test_must_fail git bisect old $HASH1 +' + +test_expect_success 'bisect terms needs 0 or 1 argument' ' + git bisect reset && + test_must_fail git bisect terms only-one && + test_must_fail git bisect terms 1 2 && + test_must_fail git bisect terms 2>actual && + echo "no terms defined" >expected && + test_cmp expected actual +' + +test_expect_success 'bisect terms shows good/bad after start' ' + git bisect reset && + git bisect start HEAD $HASH1 && + git bisect terms --term-good >actual && + echo good >expected && + test_cmp expected actual && + git bisect terms --term-bad >actual && + echo bad >expected && + test_cmp expected actual +' + +test_expect_success 'bisect start with one term1 and term2' ' + git bisect reset && + git bisect start --term-old term2 --term-new term1 && + git bisect term2 $HASH1 && + git bisect term1 $HASH4 && + git bisect term1 && + git bisect term1 >bisect_result && + grep "$HASH2 is the first term1 commit" bisect_result && + git bisect log >log_to_replay.txt && + git bisect reset +' + +test_expect_success 'bisect replay with term1 and term2' ' + git bisect replay log_to_replay.txt >bisect_result && + grep "$HASH2 is the first term1 commit" bisect_result && + git bisect reset +' + +test_expect_success 'bisect start term1 term2' ' + git bisect reset && + git bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 && + git bisect term1 && + git bisect term1 >bisect_result && + grep "$HASH2 is the first term1 commit" bisect_result && + git bisect log >log_to_replay.txt && + git bisect reset +' + +test_expect_success 'bisect cannot mix terms' ' + git bisect reset && + git bisect start --term-good term1 --term-bad term2 $HASH4 $HASH1 && + test_must_fail git bisect a && + test_must_fail git bisect b && + test_must_fail git bisect bad && + test_must_fail git bisect good && + test_must_fail git bisect new && + test_must_fail git bisect old +' + +test_expect_success 'bisect terms rejects invalid terms' ' + git bisect reset && + test_must_fail git bisect start --term-good invalid..term && + test_must_fail git bisect terms --term-bad invalid..term && + test_must_fail git bisect terms --term-good bad && + test_must_fail git bisect terms --term-good old && + test_must_fail git bisect terms --term-good skip && + test_must_fail git bisect terms --term-good reset && + test_path_is_missing .git/BISECT_TERMS +' + +test_expect_success 'bisect start --term-* does store terms' ' + git bisect reset && + git bisect start --term-bad=one --term-good=two && + git bisect terms >actual && + cat <<-EOF >expected && + Your current terms are two for the old state + and one for the new state. + EOF + test_cmp expected actual && + git bisect terms --term-bad >actual && + echo one >expected && + test_cmp expected actual && + git bisect terms --term-good >actual && + echo two >expected && + test_cmp expected actual +' + +test_expect_success 'bisect start takes options and revs in any order' ' + git bisect reset && + git bisect start --term-good one $HASH4 \ + --term-good two --term-bad bad-term \ + $HASH1 --term-good three -- && + (git bisect terms --term-bad && git bisect terms --term-good) >actual && + printf "%s\n%s\n" bad-term three >expected && + test_cmp expected actual +' + test_done diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index 4d5a25eedf..c630aba657 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -351,11 +351,15 @@ test_expect_success 'test --format long' ' test_cmp expected actual ' -test_expect_success 'setup a fake editor' ' - write_script fakeeditor <<-\EOF +test_expect_success 'setup fake editors' ' + write_script fakeeditor <<-\EOF && sed -e "s/A U Thor/A fake Thor/" "$1" >"$1.new" mv "$1.new" "$1" EOF + write_script failingfakeeditor <<-\EOF + ./fakeeditor "$@" + false + EOF ' test_expect_success '--edit with and without already replaced object' ' @@ -372,7 +376,7 @@ test_expect_success '--edit with and without already replaced object' ' test_expect_success '--edit and change nothing or command failed' ' git replace -d "$PARA3" && test_must_fail env GIT_EDITOR=true git replace --edit "$PARA3" && - test_must_fail env GIT_EDITOR="./fakeeditor;false" git replace --edit "$PARA3" && + test_must_fail env GIT_EDITOR="./failingfakeeditor" git replace --edit "$PARA3" && GIT_EDITOR=./fakeeditor git replace --edit "$PARA3" && git replace -l | grep "$PARA3" && git cat-file commit "$PARA3" | grep "A fake Thor" diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 7c9bec7630..03873b09d1 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -8,8 +8,8 @@ test_description='for-each-ref test' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh -# Mon Jul 3 15:18:43 2006 +0000 -datestamp=1151939923 +# Mon Jul 3 23:18:43 2006 +0000 +datestamp=1151968723 setdate_and_increment () { GIT_COMMITTER_DATE="$datestamp +0200" datestamp=$(expr "$datestamp" + 1) @@ -61,21 +61,21 @@ test_atom head object '' test_atom head type '' test_atom head '*objectname' '' test_atom head '*objecttype' '' -test_atom head author 'A U Thor <author@example.com> 1151939924 +0200' +test_atom head author 'A U Thor <author@example.com> 1151968724 +0200' test_atom head authorname 'A U Thor' test_atom head authoremail '<author@example.com>' -test_atom head authordate 'Mon Jul 3 17:18:44 2006 +0200' -test_atom head committer 'C O Mitter <committer@example.com> 1151939923 +0200' +test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200' +test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200' test_atom head committername 'C O Mitter' test_atom head committeremail '<committer@example.com>' -test_atom head committerdate 'Mon Jul 3 17:18:43 2006 +0200' +test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200' test_atom head tag '' test_atom head tagger '' test_atom head taggername '' test_atom head taggeremail '' test_atom head taggerdate '' -test_atom head creator 'C O Mitter <committer@example.com> 1151939923 +0200' -test_atom head creatordate 'Mon Jul 3 17:18:43 2006 +0200' +test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200' +test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200' test_atom head subject 'Initial' test_atom head contents:subject 'Initial' test_atom head body '' @@ -96,7 +96,7 @@ test_atom tag parent '' test_atom tag numparent '' test_atom tag object $(git rev-parse refs/tags/testtag^0) test_atom tag type 'commit' -test_atom tag '*objectname' '67a36f10722846e891fbada1ba48ed035de75581' +test_atom tag '*objectname' 'ea122842f48be4afb2d1fc6a4b96c05885ab7463' test_atom tag '*objecttype' 'commit' test_atom tag author '' test_atom tag authorname '' @@ -107,18 +107,18 @@ test_atom tag committername '' test_atom tag committeremail '' test_atom tag committerdate '' test_atom tag tag 'testtag' -test_atom tag tagger 'C O Mitter <committer@example.com> 1151939925 +0200' +test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200' test_atom tag taggername 'C O Mitter' test_atom tag taggeremail '<committer@example.com>' -test_atom tag taggerdate 'Mon Jul 3 17:18:45 2006 +0200' -test_atom tag creator 'C O Mitter <committer@example.com> 1151939925 +0200' -test_atom tag creatordate 'Mon Jul 3 17:18:45 2006 +0200' -test_atom tag subject 'Tagging at 1151939927' -test_atom tag contents:subject 'Tagging at 1151939927' +test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200' +test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200' +test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200' +test_atom tag subject 'Tagging at 1151968727' +test_atom tag contents:subject 'Tagging at 1151968727' test_atom tag body '' test_atom tag contents:body '' test_atom tag contents:signature '' -test_atom tag contents 'Tagging at 1151939927 +test_atom tag contents 'Tagging at 1151968727 ' test_atom tag HEAD ' ' @@ -146,95 +146,123 @@ test_expect_success 'Check invalid format specifiers are errors' ' test_must_fail git for-each-ref --format="%(authordate:INVALID)" refs/heads ' -cat >expected <<\EOF -'refs/heads/master' 'Mon Jul 3 17:18:43 2006 +0200' 'Mon Jul 3 17:18:44 2006 +0200' -'refs/tags/testtag' 'Mon Jul 3 17:18:45 2006 +0200' -EOF +test_date () { + f=$1 && + committer_date=$2 && + author_date=$3 && + tagger_date=$4 && + cat >expected <<-EOF && + 'refs/heads/master' '$committer_date' '$author_date' + 'refs/tags/testtag' '$tagger_date' + EOF + ( + git for-each-ref --shell \ + --format="%(refname) %(committerdate${f:+:$f}) %(authordate${f:+:$f})" \ + refs/heads && + git for-each-ref --shell \ + --format="%(refname) %(taggerdate${f:+:$f})" \ + refs/tags + ) >actual && + test_cmp expected actual +} test_expect_success 'Check unformatted date fields output' ' - (git for-each-ref --shell --format="%(refname) %(committerdate) %(authordate)" refs/heads && - git for-each-ref --shell --format="%(refname) %(taggerdate)" refs/tags) >actual && - test_cmp expected actual + test_date "" \ + "Tue Jul 4 01:18:43 2006 +0200" \ + "Tue Jul 4 01:18:44 2006 +0200" \ + "Tue Jul 4 01:18:45 2006 +0200" ' test_expect_success 'Check format "default" formatted date fields output' ' - f=default && - (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && - git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && - test_cmp expected actual + test_date default \ + "Tue Jul 4 01:18:43 2006 +0200" \ + "Tue Jul 4 01:18:44 2006 +0200" \ + "Tue Jul 4 01:18:45 2006 +0200" +' + +test_expect_success 'Check format "default-local" date fields output' ' + test_date default-local "Mon Jul 3 23:18:43 2006" "Mon Jul 3 23:18:44 2006" "Mon Jul 3 23:18:45 2006" ' # Don't know how to do relative check because I can't know when this script # is going to be run and can't fake the current time to git, and hence can't # provide expected output. Instead, I'll just make sure that "relative" # doesn't exit in error -# -#cat >expected <<\EOF -# -#EOF -# test_expect_success 'Check format "relative" date fields output' ' f=relative && (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual ' -cat >expected <<\EOF -'refs/heads/master' '2006-07-03' '2006-07-03' -'refs/tags/testtag' '2006-07-03' -EOF +# We just check that this is the same as "relative" for now. +test_expect_success 'Check format "relative-local" date fields output' ' + test_date relative-local \ + "$(git for-each-ref --format="%(committerdate:relative)" refs/heads)" \ + "$(git for-each-ref --format="%(authordate:relative)" refs/heads)" \ + "$(git for-each-ref --format="%(taggerdate:relative)" refs/tags)" +' test_expect_success 'Check format "short" date fields output' ' - f=short && - (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && - git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && - test_cmp expected actual + test_date short 2006-07-04 2006-07-04 2006-07-04 ' -cat >expected <<\EOF -'refs/heads/master' 'Mon Jul 3 15:18:43 2006' 'Mon Jul 3 15:18:44 2006' -'refs/tags/testtag' 'Mon Jul 3 15:18:45 2006' -EOF +test_expect_success 'Check format "short-local" date fields output' ' + test_date short-local 2006-07-03 2006-07-03 2006-07-03 +' test_expect_success 'Check format "local" date fields output' ' - f=local && - (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && - git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && - test_cmp expected actual + test_date local \ + "Mon Jul 3 23:18:43 2006" \ + "Mon Jul 3 23:18:44 2006" \ + "Mon Jul 3 23:18:45 2006" ' -cat >expected <<\EOF -'refs/heads/master' '2006-07-03 17:18:43 +0200' '2006-07-03 17:18:44 +0200' -'refs/tags/testtag' '2006-07-03 17:18:45 +0200' -EOF - test_expect_success 'Check format "iso8601" date fields output' ' - f=iso8601 && - (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && - git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && - test_cmp expected actual + test_date iso8601 \ + "2006-07-04 01:18:43 +0200" \ + "2006-07-04 01:18:44 +0200" \ + "2006-07-04 01:18:45 +0200" ' -cat >expected <<\EOF -'refs/heads/master' 'Mon, 3 Jul 2006 17:18:43 +0200' 'Mon, 3 Jul 2006 17:18:44 +0200' -'refs/tags/testtag' 'Mon, 3 Jul 2006 17:18:45 +0200' -EOF +test_expect_success 'Check format "iso8601-local" date fields output' ' + test_date iso8601-local "2006-07-03 23:18:43 +0000" "2006-07-03 23:18:44 +0000" "2006-07-03 23:18:45 +0000" +' test_expect_success 'Check format "rfc2822" date fields output' ' - f=rfc2822 && - (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && - git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual && - test_cmp expected actual + test_date rfc2822 \ + "Tue, 4 Jul 2006 01:18:43 +0200" \ + "Tue, 4 Jul 2006 01:18:44 +0200" \ + "Tue, 4 Jul 2006 01:18:45 +0200" +' + +test_expect_success 'Check format "rfc2822-local" date fields output' ' + test_date rfc2822-local "Mon, 3 Jul 2006 23:18:43 +0000" "Mon, 3 Jul 2006 23:18:44 +0000" "Mon, 3 Jul 2006 23:18:45 +0000" +' + +test_expect_success 'Check format "raw" date fields output' ' + test_date raw "1151968723 +0200" "1151968724 +0200" "1151968725 +0200" +' + +test_expect_success 'Check format "raw-local" date fields output' ' + test_date raw-local "1151968723 +0000" "1151968724 +0000" "1151968725 +0000" ' test_expect_success 'Check format of strftime date fields' ' - echo "my date is 2006-07-03" >expected && + echo "my date is 2006-07-04" >expected && git for-each-ref \ --format="%(authordate:format:my date is %Y-%m-%d)" \ refs/heads >actual && test_cmp expected actual ' +test_expect_success 'Check format of strftime-local date fields' ' + echo "my date is 2006-07-03" >expected && + git for-each-ref \ + --format="%(authordate:format-local:my date is %Y-%m-%d)" \ + refs/heads >actual && + test_cmp expected actual +' + test_expect_success 'exercise strftime with odd fields' ' echo >expected && git for-each-ref --format="%(authordate:format:)" refs/heads >actual && @@ -546,8 +574,8 @@ body contents $sig" cat >expected <<EOF -$(git rev-parse refs/tags/master) <committer@example.com> refs/tags/master $(git rev-parse refs/tags/bogo) <committer@example.com> refs/tags/bogo +$(git rev-parse refs/tags/master) <committer@example.com> refs/tags/master EOF test_expect_success 'Verify sort with multiple keys' ' diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh new file mode 100755 index 0000000000..fe4796cc9c --- /dev/null +++ b/t/t6302-for-each-ref-filter.sh @@ -0,0 +1,258 @@ +#!/bin/sh + +test_description='test for-each-refs usage of ref-filter APIs' + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-gpg.sh + +if ! test_have_prereq GPG +then + skip_all="skipping for-each-ref tests, GPG not available" + test_done +fi + +test_expect_success 'setup some history and refs' ' + test_commit one && + test_commit two && + test_commit three && + git checkout -b side && + test_commit four && + git tag -s -m "A signed tag message" signed-tag && + git tag -s -m "Annonated doubly" double-tag signed-tag && + git checkout master && + git update-ref refs/odd/spot master +' + +test_expect_success 'filtering with --points-at' ' + cat >expect <<-\EOF && + refs/heads/master + refs/odd/spot + refs/tags/three + EOF + git for-each-ref --format="%(refname)" --points-at=master >actual && + test_cmp expect actual +' + +test_expect_success 'check signed tags with --points-at' ' + sed -e "s/Z$//" >expect <<-\EOF && + refs/heads/side Z + refs/tags/four Z + refs/tags/signed-tag four + EOF + git for-each-ref --format="%(refname) %(*subject)" --points-at=side >actual && + test_cmp expect actual +' + +test_expect_success 'filtering with --merged' ' + cat >expect <<-\EOF && + refs/heads/master + refs/odd/spot + refs/tags/one + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --merged=master >actual && + test_cmp expect actual +' + +test_expect_success 'filtering with --no-merged' ' + cat >expect <<-\EOF && + refs/heads/side + refs/tags/double-tag + refs/tags/four + refs/tags/signed-tag + EOF + git for-each-ref --format="%(refname)" --no-merged=master >actual && + test_cmp expect actual +' + +test_expect_success 'filtering with --contains' ' + cat >expect <<-\EOF && + refs/heads/master + refs/heads/side + refs/odd/spot + refs/tags/double-tag + refs/tags/four + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --contains=two >actual && + test_cmp expect actual +' + +test_expect_success '%(color) must fail' ' + test_must_fail git for-each-ref --format="%(color)%(refname)" +' + +test_expect_success 'left alignment is default' ' + cat >expect <<-\EOF && + refname is refs/heads/master |refs/heads/master + refname is refs/heads/side |refs/heads/side + refname is refs/odd/spot |refs/odd/spot + refname is refs/tags/double-tag|refs/tags/double-tag + refname is refs/tags/four |refs/tags/four + refname is refs/tags/one |refs/tags/one + refname is refs/tags/signed-tag|refs/tags/signed-tag + refname is refs/tags/three |refs/tags/three + refname is refs/tags/two |refs/tags/two + EOF + git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual && + test_cmp expect actual +' + +test_expect_success 'middle alignment' ' + cat >expect <<-\EOF && + | refname is refs/heads/master |refs/heads/master + | refname is refs/heads/side |refs/heads/side + | refname is refs/odd/spot |refs/odd/spot + |refname is refs/tags/double-tag|refs/tags/double-tag + | refname is refs/tags/four |refs/tags/four + | refname is refs/tags/one |refs/tags/one + |refname is refs/tags/signed-tag|refs/tags/signed-tag + | refname is refs/tags/three |refs/tags/three + | refname is refs/tags/two |refs/tags/two + EOF + git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual && + test_cmp expect actual +' + +test_expect_success 'right alignment' ' + cat >expect <<-\EOF && + | refname is refs/heads/master|refs/heads/master + | refname is refs/heads/side|refs/heads/side + | refname is refs/odd/spot|refs/odd/spot + |refname is refs/tags/double-tag|refs/tags/double-tag + | refname is refs/tags/four|refs/tags/four + | refname is refs/tags/one|refs/tags/one + |refname is refs/tags/signed-tag|refs/tags/signed-tag + | refname is refs/tags/three|refs/tags/three + | refname is refs/tags/two|refs/tags/two + EOF + git for-each-ref --format="|%(align:30,right)refname is %(refname)%(end)|%(refname)" >actual && + test_cmp expect actual +' + +# Individual atoms inside %(align:...) and %(end) must not be quoted. + +test_expect_success 'alignment with format quote' " + cat >expect <<-\EOF && + |' '\''master| A U Thor'\'' '| + |' '\''side| A U Thor'\'' '| + |' '\''odd/spot| A U Thor'\'' '| + |' '\''double-tag| '\'' '| + |' '\''four| A U Thor'\'' '| + |' '\''one| A U Thor'\'' '| + |' '\''signed-tag| '\'' '| + |' '\''three| A U Thor'\'' '| + |' '\''two| A U Thor'\'' '| + EOF + git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual && + test_cmp expect actual +" + +test_expect_success 'nested alignment with quote formatting' " + cat >expect <<-\EOF && + |' master '| + |' side '| + |' odd/spot '| + |' double-tag '| + |' four '| + |' one '| + |' signed-tag '| + |' three '| + |' two '| + EOF + git for-each-ref --shell --format='|%(align:30,left)%(align:15,right)%(refname:short)%(end)%(end)|' >actual && + test_cmp expect actual +" + +test_expect_success 'check `%(contents:lines=1)`' ' + cat >expect <<-\EOF && + master |three + side |four + odd/spot |three + double-tag |Annonated doubly + four |four + one |one + signed-tag |A signed tag message + three |three + two |two + EOF + git for-each-ref --format="%(refname:short) |%(contents:lines=1)" >actual && + test_cmp expect actual +' + +test_expect_success 'check `%(contents:lines=0)`' ' + cat >expect <<-\EOF && + master | + side | + odd/spot | + double-tag | + four | + one | + signed-tag | + three | + two | + EOF + git for-each-ref --format="%(refname:short) |%(contents:lines=0)" >actual && + test_cmp expect actual +' + +test_expect_success 'check `%(contents:lines=99999)`' ' + cat >expect <<-\EOF && + master |three + side |four + odd/spot |three + double-tag |Annonated doubly + four |four + one |one + signed-tag |A signed tag message + three |three + two |two + EOF + git for-each-ref --format="%(refname:short) |%(contents:lines=99999)" >actual && + test_cmp expect actual +' + +test_expect_success '`%(contents:lines=-1)` should fail' ' + test_must_fail git for-each-ref --format="%(refname:short) |%(contents:lines=-1)" +' + +test_expect_success 'setup for version sort' ' + test_commit foo1.3 && + test_commit foo1.6 && + test_commit foo1.10 +' + +test_expect_success 'version sort' ' + git for-each-ref --sort=version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual && + cat >expect <<-\EOF && + foo1.3 + foo1.6 + foo1.10 + EOF + test_cmp expect actual +' + +test_expect_success 'version sort (shortened)' ' + git for-each-ref --sort=v:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual && + cat >expect <<-\EOF && + foo1.3 + foo1.6 + foo1.10 + EOF + test_cmp expect actual +' + +test_expect_success 'reverse version sort' ' + git for-each-ref --sort=-version:refname --format="%(refname:short)" refs/tags/ | grep "foo" >actual && + cat >expect <<-\EOF && + foo1.10 + foo1.6 + foo1.3 + EOF + test_cmp expect actual +' + +test_done diff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh index 377c648e04..869e0bf073 100755 --- a/t/t7003-filter-branch.sh +++ b/t/t7003-filter-branch.sh @@ -418,4 +418,11 @@ test_expect_success 'filter commit message without trailing newline' ' test_cmp expect actual ' +test_expect_success 'tree-filter deals with object name vs pathname ambiguity' ' + test_when_finished "git reset --hard original" && + ambiguous=$(git rev-list -1 HEAD) && + git filter-branch --tree-filter "mv file.t $ambiguous" HEAD^.. && + git show HEAD:$ambiguous +' + test_done diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index d31788cc6c..3dd2f51e49 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1462,13 +1462,7 @@ test_expect_success 'invalid sort parameter on command line' ' test_expect_success 'invalid sort parameter in configuratoin' ' git config tag.sort "v:notvalid" && - git tag -l "foo*" >actual && - cat >expect <<-\EOF && - foo1.10 - foo1.3 - foo1.6 - EOF - test_cmp expect actual + test_must_fail git tag -l "foo*" ' test_expect_success 'version sort with prerelease reordering' ' @@ -1525,4 +1519,43 @@ EOF" test_cmp expect actual ' +test_expect_success '--format should list tags as per format given' ' + cat >expect <<-\EOF && + refname : refs/tags/foo1.10 + refname : refs/tags/foo1.3 + refname : refs/tags/foo1.6 + refname : refs/tags/foo1.6-rc1 + refname : refs/tags/foo1.6-rc2 + EOF + git tag -l --format="refname : %(refname)" "foo*" >actual && + test_cmp expect actual +' + +test_expect_success 'setup --merged test tags' ' + git tag mergetest-1 HEAD~2 && + git tag mergetest-2 HEAD~1 && + git tag mergetest-3 HEAD +' + +test_expect_success '--merged cannot be used in non-list mode' ' + test_must_fail git tag --merged=mergetest-2 foo +' + +test_expect_success '--merged shows merged tags' ' + cat >expect <<-\EOF && + mergetest-1 + mergetest-2 + EOF + git tag -l --merged=mergetest-2 mergetest-* >actual && + test_cmp expect actual +' + +test_expect_success '--no-merged show unmerged tags' ' + cat >expect <<-\EOF && + mergetest-3 + EOF + git tag -l --no-merged=mergetest-2 mergetest-* >actual && + test_cmp expect actual +' + test_done diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index 7eeb207b32..6f12b235b3 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -174,9 +174,9 @@ test_expect_success 'mergetool skips autoresolved' ' ' test_expect_success 'mergetool merges all from subdir' ' + test_config rerere.enabled false && ( cd subdir && - test_config rerere.enabled false && test_must_fail git merge master && ( yes "r" | git mergetool ../submod ) && ( yes "d" "d" | git mergetool --no-prompt ) && diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index ea35a0241c..ec8bc8c765 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -492,12 +492,31 @@ test_expect_success PERL 'difftool --no-symlinks detects conflict ' ' test_expect_success PERL 'difftool properly honors gitlink and core.worktree' ' git submodule add ./. submod/ule && + test_config -C submod/ule diff.tool checktrees && + test_config -C submod/ule difftool.checktrees.cmd '\'' + test -d "$LOCAL" && test -d "$REMOTE" && echo good + '\'' && ( cd submod/ule && - test_config diff.tool checktrees && - test_config difftool.checktrees.cmd '\'' - test -d "$LOCAL" && test -d "$REMOTE" && echo good - '\'' && + echo good >expect && + git difftool --tool=checktrees --dir-diff HEAD~ >actual && + test_cmp expect actual + ) +' + +test_expect_success PERL,SYMLINKS 'difftool --dir-diff symlinked directories' ' + git init dirlinks && + ( + cd dirlinks && + git config diff.tool checktrees && + git config difftool.checktrees.cmd "echo good" && + mkdir foo && + : >foo/bar && + git add foo/bar && + test_commit symlink-one && + ln -s foo link && + git add link && + test_commit symlink-two && echo good >expect && git difftool --tool=checktrees --dir-diff HEAD~ >actual && test_cmp expect actual diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 028ffe4a05..b540944408 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -791,12 +791,12 @@ test_expect_success 'outside of git repository' ' } >non/expect.full && echo file2:world >non/expect.sub && ( - GIT_CEILING_DIRECTORIES="$(pwd)/non/git" && + GIT_CEILING_DIRECTORIES="$(pwd)/non" && export GIT_CEILING_DIRECTORIES && cd non/git && test_must_fail git grep o && git grep --no-index o >../actual.full && - test_cmp ../expect.full ../actual.full + test_cmp ../expect.full ../actual.full && cd sub && test_must_fail git grep o && git grep --no-index o >../../actual.sub && @@ -805,7 +805,7 @@ test_expect_success 'outside of git repository' ' echo ".*o*" >non/git/.gitignore && ( - GIT_CEILING_DIRECTORIES="$(pwd)/non/git" && + GIT_CEILING_DIRECTORIES="$(pwd)/non" && export GIT_CEILING_DIRECTORIES && cd non/git && test_must_fail git grep o && @@ -813,7 +813,7 @@ test_expect_success 'outside of git repository' ' test_cmp ../expect.full ../actual.full && { - echo ".gitignore:.*o*" + echo ".gitignore:.*o*" && cat ../expect.full } >../expect.with.ignored && git grep --no-index --no-exclude o >../actual.full && @@ -821,6 +821,47 @@ test_expect_success 'outside of git repository' ' ) ' +test_expect_success 'outside of git repository with fallbackToNoIndex' ' + rm -fr non && + mkdir -p non/git/sub && + echo hello >non/git/file1 && + echo world >non/git/sub/file2 && + cat <<-\EOF >non/expect.full && + file1:hello + sub/file2:world + EOF + echo file2:world >non/expect.sub && + ( + GIT_CEILING_DIRECTORIES="$(pwd)/non" && + export GIT_CEILING_DIRECTORIES && + cd non/git && + test_must_fail git -c grep.fallbackToNoIndex=false grep o && + git -c grep.fallbackToNoIndex=true grep o >../actual.full && + test_cmp ../expect.full ../actual.full && + cd sub && + test_must_fail git -c grep.fallbackToNoIndex=false grep o && + git -c grep.fallbackToNoIndex=true grep o >../../actual.sub && + test_cmp ../../expect.sub ../../actual.sub + ) && + + echo ".*o*" >non/git/.gitignore && + ( + GIT_CEILING_DIRECTORIES="$(pwd)/non" && + export GIT_CEILING_DIRECTORIES && + cd non/git && + test_must_fail git -c grep.fallbackToNoIndex=false grep o && + git -c grep.fallbackToNoIndex=true grep --exclude-standard o >../actual.full && + test_cmp ../expect.full ../actual.full && + + { + echo ".gitignore:.*o*" && + cat ../expect.full + } >../expect.with.ignored && + git -c grep.fallbackToNoIndex grep --no-exclude o >../actual.full && + test_cmp ../expect.with.ignored ../actual.full + ) +' + test_expect_success 'inside git repository but with --no-index' ' rm -fr is && mkdir -p is/git/sub && diff --git a/t/t8009-blame-vs-topicbranches.sh b/t/t8009-blame-vs-topicbranches.sh new file mode 100755 index 0000000000..72596e38b2 --- /dev/null +++ b/t/t8009-blame-vs-topicbranches.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +test_description='blaming trough history with topic branches' +. ./test-lib.sh + +# Creates the history shown below. '*'s mark the first parent in the merges. +# The only line of file.t is changed in commit B2 +# +# +---C1 +# / \ +# A0--A1--*A2--*A3 +# \ / +# B1-B2 +# +test_expect_success setup ' + test_commit A0 file.t line0 && + test_commit A1 && + git reset --hard A0 && + test_commit B1 && + test_commit B2 file.t line0changed && + git reset --hard A1 && + test_merge A2 B2 && + git reset --hard A1 && + test_commit C1 && + git reset --hard A2 && + test_merge A3 C1 + ' + +test_expect_success 'blame --reverse --first-parent finds A1' ' + git blame --porcelain --reverse --first-parent A0..A3 -- file.t >actual_full && + head -n 1 <actual_full | sed -e "s/ .*//" >actual && + git rev-parse A1 >expect && + test_cmp expect actual + ' + +test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 5b4a5ce06b..834d91a691 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1527,6 +1527,21 @@ test_expect_success $PREREQ 'cccover adds Cc to all mail' ' test_cover_addresses "Cc" ' +test_expect_success $PREREQ 'escaped quotes in sendemail.aliasfiletype=mutt' ' + clean_fake_sendmail && + echo "alias sbd \\\"Dot U. Sir\\\" <somebody@example.org>" >.mutt && + git config --replace-all sendemail.aliasesfile "$(pwd)/.mutt" && + git config sendemail.aliasfiletype mutt && + git send-email \ + --from="Example <nobody@example.com>" \ + --to=sbd \ + --smtp-server="$(pwd)/fake.sendmail" \ + outdir/0001-*.patch \ + 2>errors >out && + grep "^!somebody@example\.org!$" commandline1 && + grep -F "To: \"Dot U. Sir\" <somebody@example.org>" out +' + test_expect_success $PREREQ 'sendemail.aliasfiletype=mailrc' ' clean_fake_sendmail && echo "alias sbd somebody@example.org" >.mailrc && @@ -1555,6 +1570,88 @@ test_expect_success $PREREQ 'sendemail.aliasfile=~/.mailrc' ' grep "^!someone@example\.org!$" commandline1 ' +test_dump_aliases () { + msg="$1" && shift && + filetype="$1" && shift && + printf '%s\n' "$@" >expect && + cat >.tmp-email-aliases && + + test_expect_success $PREREQ "$msg" ' + clean_fake_sendmail && rm -fr outdir && + git config --replace-all sendemail.aliasesfile \ + "$(pwd)/.tmp-email-aliases" && + git config sendemail.aliasfiletype "$filetype" && + git send-email --dump-aliases 2>errors >actual && + test_cmp expect actual + ' +} + +test_dump_aliases '--dump-aliases sendmail format' \ + 'sendmail' \ + 'abgroup' \ + 'alice' \ + 'bcgrp' \ + 'bob' \ + 'chloe' <<-\EOF + alice: Alice W Land <awol@example.com> + bob: Robert Bobbyton <bob@example.com> + chloe: chloe@example.com + abgroup: alice, bob + bcgrp: bob, chloe, Other <o@example.com> + EOF + +test_dump_aliases '--dump-aliases mutt format' \ + 'mutt' \ + 'alice' \ + 'bob' \ + 'chloe' \ + 'donald' <<-\EOF + alias alice Alice W Land <awol@example.com> + alias donald Donald C Carlton <donc@example.com> + alias bob Robert Bobbyton <bob@example.com> + alias chloe chloe@example.com + EOF + +test_dump_aliases '--dump-aliases mailrc format' \ + 'mailrc' \ + 'alice' \ + 'bob' \ + 'chloe' \ + 'eve' <<-\EOF + alias alice Alice W Land <awol@example.com> + alias eve Eve <eve@example.com> + alias bob Robert Bobbyton <bob@example.com> + alias chloe chloe@example.com + EOF + +test_dump_aliases '--dump-aliases pine format' \ + 'pine' \ + 'alice' \ + 'bob' \ + 'chloe' \ + 'eve' <<-\EOF + alice Alice W Land <awol@example.com> + eve Eve <eve@example.com> + bob Robert Bobbyton <bob@example.com> + chloe chloe@example.com + EOF + +test_dump_aliases '--dump-aliases gnus format' \ + 'gnus' \ + 'alice' \ + 'bob' \ + 'chloe' \ + 'eve' <<-\EOF + (define-mail-alias "alice" "awol@example.com") + (define-mail-alias "eve" "eve@example.com") + (define-mail-alias "bob" "bob@example.com") + (define-mail-alias "chloe" "chloe@example.com") + EOF + +test_expect_success '--dump-aliases must be used alone' ' + test_must_fail git send-email --dump-aliases --to=janice@example.com -1 refs/heads/accounting +' + test_sendmail_aliases () { msg="$1" && shift && expect="$@" && diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 9984c48b5a..14a938402e 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -47,1077 +47,1075 @@ file5_data='an inline file. file6_data='#!/bin/sh echo "$@"' ->empty - ### ### series A ### -test_tick - test_expect_success 'empty stream succeeds' ' git fast-import </dev/null ' -cat >input <<INPUT_END -blob -mark :2 -data <<EOF -$file2_data -EOF - -blob -mark :3 -data <<END -$file3_data -END - -blob -mark :4 -data $file4_len -$file4_data -commit refs/heads/master -mark :5 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -initial -COMMIT - -M 644 :2 file2 -M 644 :3 file3 -M 755 :4 file4 - -tag series-A -from :5 -data <<EOF -An annotated tag without a tagger -EOF - -tag series-A-blob -from :3 -data <<EOF -An annotated tag that annotates a blob. -EOF - -INPUT_END -test_expect_success \ - 'A: create pack from stdin' \ - 'git fast-import --export-marks=marks.out <input && - git whatchanged master' +test_expect_success 'A: create pack from stdin' ' + test_tick && + cat >input <<-INPUT_END && + blob + mark :2 + data <<EOF + $file2_data + EOF + + blob + mark :3 + data <<END + $file3_data + END + + blob + mark :4 + data $file4_len + $file4_data + commit refs/heads/master + mark :5 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + initial + COMMIT + + M 644 :2 file2 + M 644 :3 file3 + M 755 :4 file4 + + tag series-A + from :5 + data <<EOF + An annotated tag without a tagger + EOF + + tag series-A-blob + from :3 + data <<EOF + An annotated tag that annotates a blob. + EOF + + INPUT_END + git fast-import --export-marks=marks.out <input && + git whatchanged master +' test_expect_success 'A: verify pack' ' verify_packs ' -cat >expect <<EOF -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -initial -EOF -test_expect_success \ - 'A: verify commit' \ - 'git cat-file commit master | sed 1d >actual && - test_cmp expect actual' - -cat >expect <<EOF -100644 blob file2 -100644 blob file3 -100755 blob file4 -EOF -test_expect_success \ - 'A: verify tree' \ - 'git cat-file -p master^{tree} | sed "s/ [0-9a-f]* / /" >actual && - test_cmp expect actual' - -echo "$file2_data" >expect -test_expect_success \ - 'A: verify file2' \ - 'git cat-file blob master:file2 >actual && test_cmp expect actual' - -echo "$file3_data" >expect -test_expect_success \ - 'A: verify file3' \ - 'git cat-file blob master:file3 >actual && test_cmp expect actual' - -printf "$file4_data" >expect -test_expect_success \ - 'A: verify file4' \ - 'git cat-file blob master:file4 >actual && test_cmp expect actual' - -cat >expect <<EOF -object $(git rev-parse refs/heads/master) -type commit -tag series-A - -An annotated tag without a tagger -EOF +test_expect_success 'A: verify commit' ' + cat >expect <<-EOF && + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + initial + EOF + git cat-file commit master | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'A: verify tree' ' + cat >expect <<-EOF && + 100644 blob file2 + 100644 blob file3 + 100755 blob file4 + EOF + git cat-file -p master^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual +' + +test_expect_success 'A: verify file2' ' + echo "$file2_data" >expect && + git cat-file blob master:file2 >actual && + test_cmp expect actual +' + +test_expect_success 'A: verify file3' ' + echo "$file3_data" >expect && + git cat-file blob master:file3 >actual && + test_cmp expect actual +' + +test_expect_success 'A: verify file4' ' + printf "$file4_data" >expect && + git cat-file blob master:file4 >actual && + test_cmp expect actual +' + test_expect_success 'A: verify tag/series-A' ' + cat >expect <<-EOF && + object $(git rev-parse refs/heads/master) + type commit + tag series-A + + An annotated tag without a tagger + EOF git cat-file tag tags/series-A >actual && test_cmp expect actual ' -cat >expect <<EOF -object $(git rev-parse refs/heads/master:file3) -type blob -tag series-A-blob - -An annotated tag that annotates a blob. -EOF test_expect_success 'A: verify tag/series-A-blob' ' + cat >expect <<-EOF && + object $(git rev-parse refs/heads/master:file3) + type blob + tag series-A-blob + + An annotated tag that annotates a blob. + EOF git cat-file tag tags/series-A-blob >actual && test_cmp expect actual ' -cat >expect <<EOF -:2 `git rev-parse --verify master:file2` -:3 `git rev-parse --verify master:file3` -:4 `git rev-parse --verify master:file4` -:5 `git rev-parse --verify master^0` -EOF -test_expect_success \ - 'A: verify marks output' \ - 'test_cmp expect marks.out' +test_expect_success 'A: verify marks output' ' + cat >expect <<-EOF && + :2 `git rev-parse --verify master:file2` + :3 `git rev-parse --verify master:file3` + :4 `git rev-parse --verify master:file4` + :5 `git rev-parse --verify master^0` + EOF + test_cmp expect marks.out +' -test_expect_success \ - 'A: verify marks import' \ - 'git fast-import \ +test_expect_success 'A: verify marks import' ' + git fast-import \ --import-marks=marks.out \ --export-marks=marks.new \ </dev/null && - test_cmp expect marks.new' - -test_tick -new_blob=$(echo testing | git hash-object --stdin) -cat >input <<INPUT_END -tag series-A-blob-2 -from $(git rev-parse refs/heads/master:file3) -data <<EOF -Tag blob by sha1. -EOF - -blob -mark :6 -data <<EOF -testing -EOF - -commit refs/heads/new_blob -committer <> 0 +0000 -data 0 -M 644 :6 new_blob -#pretend we got sha1 from fast-import -ls "new_blob" - -tag series-A-blob-3 -from $new_blob -data <<EOF -Tag new_blob. -EOF -INPUT_END - -cat >expect <<EOF -object $(git rev-parse refs/heads/master:file3) -type blob -tag series-A-blob-2 - -Tag blob by sha1. -object $new_blob -type blob -tag series-A-blob-3 - -Tag new_blob. -EOF - -test_expect_success \ - 'A: tag blob by sha1' \ - 'git fast-import <input && + test_cmp expect marks.new +' + +test_expect_success 'A: tag blob by sha1' ' + test_tick && + new_blob=$(echo testing | git hash-object --stdin) && + cat >input <<-INPUT_END && + tag series-A-blob-2 + from $(git rev-parse refs/heads/master:file3) + data <<EOF + Tag blob by sha1. + EOF + + blob + mark :6 + data <<EOF + testing + EOF + + commit refs/heads/new_blob + committer <> 0 +0000 + data 0 + M 644 :6 new_blob + #pretend we got sha1 from fast-import + ls "new_blob" + + tag series-A-blob-3 + from $new_blob + data <<EOF + Tag new_blob. + EOF + INPUT_END + + cat >expect <<-EOF && + object $(git rev-parse refs/heads/master:file3) + type blob + tag series-A-blob-2 + + Tag blob by sha1. + object $new_blob + type blob + tag series-A-blob-3 + + Tag new_blob. + EOF + + git fast-import <input && git cat-file tag tags/series-A-blob-2 >actual && git cat-file tag tags/series-A-blob-3 >>actual && - test_cmp expect actual' + test_cmp expect actual +' + +test_expect_success 'A: verify marks import does not crash' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/verify--import-marks + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + recreate from :5 + COMMIT -test_tick -cat >input <<INPUT_END -commit refs/heads/verify--import-marks -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -recreate from :5 -COMMIT + from :5 + M 755 :2 copy-of-file2 -from :5 -M 755 :2 copy-of-file2 + INPUT_END -INPUT_END -test_expect_success \ - 'A: verify marks import does not crash' \ - 'git fast-import --import-marks=marks.out <input && - git whatchanged verify--import-marks' + git fast-import --import-marks=marks.out <input && + git whatchanged verify--import-marks +' test_expect_success 'A: verify pack' ' verify_packs ' -cat >expect <<EOF -:000000 100755 0000000000000000000000000000000000000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 A copy-of-file2 -EOF -git diff-tree -M -r master verify--import-marks >actual -test_expect_success \ - 'A: verify diff' \ - 'compare_diff_raw expect actual && - test `git rev-parse --verify master:file2` \ - = `git rev-parse --verify verify--import-marks:copy-of-file2`' - -test_tick -mt=$(git hash-object --stdin < /dev/null) -: >input.blob -: >marks.exp -: >tree.exp - -cat >input.commit <<EOF -commit refs/heads/verify--dump-marks -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -test the sparse array dumping routines with exponentially growing marks -COMMIT -EOF - -i=0 -l=4 -m=6 -n=7 -while test "$i" -lt 27; do - cat >>input.blob <<EOF -blob -mark :$l -data 0 -blob -mark :$m -data 0 -blob -mark :$n -data 0 -EOF - echo "M 100644 :$l l$i" >>input.commit - echo "M 100644 :$m m$i" >>input.commit - echo "M 100644 :$n n$i" >>input.commit - - echo ":$l $mt" >>marks.exp - echo ":$m $mt" >>marks.exp - echo ":$n $mt" >>marks.exp - - printf "100644 blob $mt\tl$i\n" >>tree.exp - printf "100644 blob $mt\tm$i\n" >>tree.exp - printf "100644 blob $mt\tn$i\n" >>tree.exp - - l=$(($l + $l)) - m=$(($m + $m)) - n=$(($l + $n)) - - i=$((1 + $i)) -done - -sort tree.exp > tree.exp_s +test_expect_success 'A: verify diff' ' + cat >expect <<-EOF && + :000000 100755 0000000000000000000000000000000000000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 A copy-of-file2 + EOF + git diff-tree -M -r master verify--import-marks >actual && + compare_diff_raw expect actual && + test `git rev-parse --verify master:file2` \ + = `git rev-parse --verify verify--import-marks:copy-of-file2` +' test_expect_success 'A: export marks with large values' ' + test_tick && + mt=$(git hash-object --stdin < /dev/null) && + >input.blob && + >marks.exp && + >tree.exp && + + cat >input.commit <<-EOF && + commit refs/heads/verify--dump-marks + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + test the sparse array dumping routines with exponentially growing marks + COMMIT + EOF + + i=0 l=4 m=6 n=7 && + while test "$i" -lt 27 + do + cat >>input.blob <<-EOF && + blob + mark :$l + data 0 + blob + mark :$m + data 0 + blob + mark :$n + data 0 + EOF + echo "M 100644 :$l l$i" >>input.commit && + echo "M 100644 :$m m$i" >>input.commit && + echo "M 100644 :$n n$i" >>input.commit && + + echo ":$l $mt" >>marks.exp && + echo ":$m $mt" >>marks.exp && + echo ":$n $mt" >>marks.exp && + + printf "100644 blob $mt\tl$i\n" >>tree.exp && + printf "100644 blob $mt\tm$i\n" >>tree.exp && + printf "100644 blob $mt\tn$i\n" >>tree.exp && + + l=$(($l + $l)) && + m=$(($m + $m)) && + n=$(($l + $n)) && + + i=$((1 + $i)) || return 1 + done && + + sort tree.exp > tree.exp_s && + cat input.blob input.commit | git fast-import --export-marks=marks.large && git ls-tree refs/heads/verify--dump-marks >tree.out && test_cmp tree.exp_s tree.out && - test_cmp marks.exp marks.large' + test_cmp marks.exp marks.large +' ### ### series B ### -test_tick -cat >input <<INPUT_END -commit refs/heads/branch -mark :1 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -corrupt -COMMIT +test_expect_success 'B: fail on invalid blob sha1' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/branch + mark :1 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + corrupt + COMMIT + + from refs/heads/master + M 755 0000000000000000000000000000000000000001 zero1 -from refs/heads/master -M 755 0000000000000000000000000000000000000001 zero1 + INPUT_END + + test_when_finished "rm -f .git/objects/pack_* .git/objects/index_*" && + test_must_fail git fast-import <input +' + +test_expect_success 'B: accept branch name "TEMP_TAG"' ' + cat >input <<-INPUT_END && + commit TEMP_TAG + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + tag base + COMMIT + + from refs/heads/master + + INPUT_END + + test_when_finished "rm -f .git/TEMP_TAG + git gc + git prune" && + git fast-import <input && + test -f .git/TEMP_TAG && + test `git rev-parse master` = `git rev-parse TEMP_TAG^` +' -INPUT_END -test_expect_success 'B: fail on invalid blob sha1' ' - test_must_fail git fast-import <input -' -rm -f .git/objects/pack_* .git/objects/index_* - -cat >input <<INPUT_END -commit TEMP_TAG -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -tag base -COMMIT - -from refs/heads/master - -INPUT_END -test_expect_success \ - 'B: accept branch name "TEMP_TAG"' \ - 'git fast-import <input && - test -f .git/TEMP_TAG && - test `git rev-parse master` = `git rev-parse TEMP_TAG^`' -rm -f .git/TEMP_TAG - -git gc 2>/dev/null >/dev/null -git prune 2>/dev/null >/dev/null - -cat >input <<INPUT_END -commit refs/heads/empty-committer-1 -committer <> $GIT_COMMITTER_DATE -data <<COMMIT -empty commit -COMMIT -INPUT_END test_expect_success 'B: accept empty committer' ' + cat >input <<-INPUT_END && + commit refs/heads/empty-committer-1 + committer <> $GIT_COMMITTER_DATE + data <<COMMIT + empty commit + COMMIT + INPUT_END + + test_when_finished "git update-ref -d refs/heads/empty-committer-1 + git gc + git prune" && git fast-import <input && out=$(git fsck) && echo "$out" && test -z "$out" ' -git update-ref -d refs/heads/empty-committer-1 || true - -git gc 2>/dev/null >/dev/null -git prune 2>/dev/null >/dev/null -cat >input <<INPUT_END -commit refs/heads/empty-committer-2 -committer <a@b.com> $GIT_COMMITTER_DATE -data <<COMMIT -empty commit -COMMIT -INPUT_END test_expect_success 'B: accept and fixup committer with no name' ' + cat >input <<-INPUT_END && + commit refs/heads/empty-committer-2 + committer <a@b.com> $GIT_COMMITTER_DATE + data <<COMMIT + empty commit + COMMIT + INPUT_END + + test_when_finished "git update-ref -d refs/heads/empty-committer-2 + git gc + git prune" && git fast-import <input && out=$(git fsck) && echo "$out" && test -z "$out" ' -git update-ref -d refs/heads/empty-committer-2 || true -git gc 2>/dev/null >/dev/null -git prune 2>/dev/null >/dev/null - -cat >input <<INPUT_END -commit refs/heads/invalid-committer -committer Name email> $GIT_COMMITTER_DATE -data <<COMMIT -empty commit -COMMIT -INPUT_END test_expect_success 'B: fail on invalid committer (1)' ' + cat >input <<-INPUT_END && + commit refs/heads/invalid-committer + committer Name email> $GIT_COMMITTER_DATE + data <<COMMIT + empty commit + COMMIT + INPUT_END + + test_when_finished "git update-ref -d refs/heads/invalid-committer" && test_must_fail git fast-import <input ' -git update-ref -d refs/heads/invalid-committer || true -cat >input <<INPUT_END -commit refs/heads/invalid-committer -committer Name <e<mail> $GIT_COMMITTER_DATE -data <<COMMIT -empty commit -COMMIT -INPUT_END test_expect_success 'B: fail on invalid committer (2)' ' + cat >input <<-INPUT_END && + commit refs/heads/invalid-committer + committer Name <e<mail> $GIT_COMMITTER_DATE + data <<COMMIT + empty commit + COMMIT + INPUT_END + + test_when_finished "git update-ref -d refs/heads/invalid-committer" && test_must_fail git fast-import <input ' -git update-ref -d refs/heads/invalid-committer || true -cat >input <<INPUT_END -commit refs/heads/invalid-committer -committer Name <email>> $GIT_COMMITTER_DATE -data <<COMMIT -empty commit -COMMIT -INPUT_END test_expect_success 'B: fail on invalid committer (3)' ' + cat >input <<-INPUT_END && + commit refs/heads/invalid-committer + committer Name <email>> $GIT_COMMITTER_DATE + data <<COMMIT + empty commit + COMMIT + INPUT_END + + test_when_finished "git update-ref -d refs/heads/invalid-committer" && test_must_fail git fast-import <input ' -git update-ref -d refs/heads/invalid-committer || true -cat >input <<INPUT_END -commit refs/heads/invalid-committer -committer Name <email $GIT_COMMITTER_DATE -data <<COMMIT -empty commit -COMMIT -INPUT_END test_expect_success 'B: fail on invalid committer (4)' ' + cat >input <<-INPUT_END && + commit refs/heads/invalid-committer + committer Name <email $GIT_COMMITTER_DATE + data <<COMMIT + empty commit + COMMIT + INPUT_END + + test_when_finished "git update-ref -d refs/heads/invalid-committer" && test_must_fail git fast-import <input ' -git update-ref -d refs/heads/invalid-committer || true -cat >input <<INPUT_END -commit refs/heads/invalid-committer -committer Name<email> $GIT_COMMITTER_DATE -data <<COMMIT -empty commit -COMMIT -INPUT_END test_expect_success 'B: fail on invalid committer (5)' ' + cat >input <<-INPUT_END && + commit refs/heads/invalid-committer + committer Name<email> $GIT_COMMITTER_DATE + data <<COMMIT + empty commit + COMMIT + INPUT_END + + test_when_finished "git update-ref -d refs/heads/invalid-committer" && test_must_fail git fast-import <input ' -git update-ref -d refs/heads/invalid-committer || true ### ### series C ### -newf=`echo hi newf | git hash-object -w --stdin` -oldf=`git rev-parse --verify master:file2` -test_tick -cat >input <<INPUT_END -commit refs/heads/branch -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -second -COMMIT - -from refs/heads/master -M 644 $oldf file2/oldf -M 755 $newf file2/newf -D file3 - -INPUT_END -test_expect_success \ - 'C: incremental import create pack from stdin' \ - 'git fast-import <input && - git whatchanged branch' +test_expect_success 'C: incremental import create pack from stdin' ' + newf=`echo hi newf | git hash-object -w --stdin` && + oldf=`git rev-parse --verify master:file2` && + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/branch + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + second + COMMIT + + from refs/heads/master + M 644 $oldf file2/oldf + M 755 $newf file2/newf + D file3 + + INPUT_END + + git fast-import <input && + git whatchanged branch +' test_expect_success 'C: verify pack' ' verify_packs ' -test_expect_success \ - 'C: validate reuse existing blob' \ - 'test $newf = `git rev-parse --verify branch:file2/newf` && - test $oldf = `git rev-parse --verify branch:file2/oldf`' - -cat >expect <<EOF -parent `git rev-parse --verify master^0` -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -second -EOF -test_expect_success \ - 'C: verify commit' \ - 'git cat-file commit branch | sed 1d >actual && - test_cmp expect actual' - -cat >expect <<EOF -:000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A file2/newf -:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2 file2/oldf -:100644 000000 0d92e9f3374ae2947c23aa477cbc68ce598135f1 0000000000000000000000000000000000000000 D file3 -EOF -git diff-tree -M -r master branch >actual -test_expect_success \ - 'C: validate rename result' \ - 'compare_diff_raw expect actual' +test_expect_success 'C: validate reuse existing blob' ' + test $newf = `git rev-parse --verify branch:file2/newf` && + test $oldf = `git rev-parse --verify branch:file2/oldf` +' + +test_expect_success 'C: verify commit' ' + cat >expect <<-EOF && + parent `git rev-parse --verify master^0` + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + second + EOF + + git cat-file commit branch | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'C: validate rename result' ' + cat >expect <<-EOF && + :000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A file2/newf + :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2 file2/oldf + :100644 000000 0d92e9f3374ae2947c23aa477cbc68ce598135f1 0000000000000000000000000000000000000000 D file3 + EOF + git diff-tree -M -r master branch >actual && + compare_diff_raw expect actual +' ### ### series D ### -test_tick -cat >input <<INPUT_END -commit refs/heads/branch -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -third -COMMIT - -from refs/heads/branch^0 -M 644 inline newdir/interesting -data <<EOF -$file5_data -EOF - -M 755 inline newdir/exec.sh -data <<EOF -$file6_data -EOF - -INPUT_END -test_expect_success \ - 'D: inline data in commit' \ - 'git fast-import <input && - git whatchanged branch' +test_expect_success 'D: inline data in commit' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/branch + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + third + COMMIT + + from refs/heads/branch^0 + M 644 inline newdir/interesting + data <<EOF + $file5_data + EOF + + M 755 inline newdir/exec.sh + data <<EOF + $file6_data + EOF + + INPUT_END + + git fast-import <input && + git whatchanged branch +' test_expect_success 'D: verify pack' ' verify_packs ' -cat >expect <<EOF -:000000 100755 0000000000000000000000000000000000000000 e74b7d465e52746be2b4bae983670711e6e66657 A newdir/exec.sh -:000000 100644 0000000000000000000000000000000000000000 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 A newdir/interesting -EOF -git diff-tree -M -r branch^ branch >actual -test_expect_success \ - 'D: validate new files added' \ - 'compare_diff_raw expect actual' +test_expect_success 'D: validate new files added' ' + cat >expect <<-EOF && + :000000 100755 0000000000000000000000000000000000000000 e74b7d465e52746be2b4bae983670711e6e66657 A newdir/exec.sh + :000000 100644 0000000000000000000000000000000000000000 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 A newdir/interesting + EOF + git diff-tree -M -r branch^ branch >actual && + compare_diff_raw expect actual +' -echo "$file5_data" >expect -test_expect_success \ - 'D: verify file5' \ - 'git cat-file blob branch:newdir/interesting >actual && - test_cmp expect actual' +test_expect_success 'D: verify file5' ' + echo "$file5_data" >expect && + git cat-file blob branch:newdir/interesting >actual && + test_cmp expect actual +' -echo "$file6_data" >expect -test_expect_success \ - 'D: verify file6' \ - 'git cat-file blob branch:newdir/exec.sh >actual && - test_cmp expect actual' +test_expect_success 'D: verify file6' ' + echo "$file6_data" >expect && + git cat-file blob branch:newdir/exec.sh >actual && + test_cmp expect actual +' ### ### series E ### -cat >input <<INPUT_END -commit refs/heads/branch -author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> Tue Feb 6 11:22:18 2007 -0500 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> Tue Feb 6 12:35:02 2007 -0500 -data <<COMMIT -RFC 2822 type date -COMMIT +test_expect_success 'E: rfc2822 date, --date-format=raw' ' + cat >input <<-INPUT_END && + commit refs/heads/branch + author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> Tue Feb 6 11:22:18 2007 -0500 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> Tue Feb 6 12:35:02 2007 -0500 + data <<COMMIT + RFC 2822 type date + COMMIT -from refs/heads/branch^0 + from refs/heads/branch^0 -INPUT_END -test_expect_success 'E: rfc2822 date, --date-format=raw' ' - test_must_fail git fast-import --date-format=raw <input + INPUT_END + + test_must_fail git fast-import --date-format=raw <input +' +test_expect_success 'E: rfc2822 date, --date-format=rfc2822' ' + git fast-import --date-format=rfc2822 <input ' -test_expect_success \ - 'E: rfc2822 date, --date-format=rfc2822' \ - 'git fast-import --date-format=rfc2822 <input' test_expect_success 'E: verify pack' ' verify_packs ' -cat >expect <<EOF -author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 1170778938 -0500 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1170783302 -0500 +test_expect_success 'E: verify commit' ' + cat >expect <<-EOF && + author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 1170778938 -0500 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1170783302 -0500 -RFC 2822 type date -EOF -test_expect_success \ - 'E: verify commit' \ - 'git cat-file commit branch | sed 1,2d >actual && - test_cmp expect actual' + RFC 2822 type date + EOF + git cat-file commit branch | sed 1,2d >actual && + test_cmp expect actual +' ### ### series F ### -old_branch=`git rev-parse --verify branch^0` -test_tick -cat >input <<INPUT_END -commit refs/heads/branch -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -losing things already? -COMMIT - -from refs/heads/branch~1 - -reset refs/heads/other -from refs/heads/branch - -INPUT_END -test_expect_success \ - 'F: non-fast-forward update skips' \ - 'if git fast-import <input - then - echo BAD gfi did not fail - return 1 - else - if test $old_branch = `git rev-parse --verify branch^0` - then - : branch unaffected and failure returned - return 0 - else - echo BAD gfi changed branch $old_branch - return 1 - fi - fi - ' +test_expect_success 'F: non-fast-forward update skips' ' + old_branch=`git rev-parse --verify branch^0` && + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/branch + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + losing things already? + COMMIT + + from refs/heads/branch~1 + + reset refs/heads/other + from refs/heads/branch + + INPUT_END + + test_must_fail git fast-import <input && + # branch must remain unaffected + test $old_branch = `git rev-parse --verify branch^0` +' test_expect_success 'F: verify pack' ' verify_packs ' -cat >expect <<EOF -tree `git rev-parse branch~1^{tree}` -parent `git rev-parse branch~1` -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE +test_expect_success 'F: verify other commit' ' + cat >expect <<-EOF && + tree `git rev-parse branch~1^{tree}` + parent `git rev-parse branch~1` + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -losing things already? -EOF -test_expect_success \ - 'F: verify other commit' \ - 'git cat-file commit other >actual && - test_cmp expect actual' + losing things already? + EOF + git cat-file commit other >actual && + test_cmp expect actual +' ### ### series G ### -old_branch=`git rev-parse --verify branch^0` -test_tick -cat >input <<INPUT_END -commit refs/heads/branch -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -losing things already? -COMMIT +test_expect_success 'G: non-fast-forward update forced' ' + old_branch=`git rev-parse --verify branch^0` && + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/branch + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + losing things already? + COMMIT -from refs/heads/branch~1 + from refs/heads/branch~1 -INPUT_END -test_expect_success \ - 'G: non-fast-forward update forced' \ - 'git fast-import --force <input' + INPUT_END + git fast-import --force <input +' test_expect_success 'G: verify pack' ' verify_packs ' -test_expect_success \ - 'G: branch changed, but logged' \ - 'test $old_branch != `git rev-parse --verify branch^0` && - test $old_branch = `git rev-parse --verify branch@{1}`' +test_expect_success 'G: branch changed, but logged' ' + test $old_branch != `git rev-parse --verify branch^0` && + test $old_branch = `git rev-parse --verify branch@{1}` +' ### ### series H ### -test_tick -cat >input <<INPUT_END -commit refs/heads/H -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -third -COMMIT - -from refs/heads/branch^0 -M 644 inline i-will-die -data <<EOF -this file will never exist. -EOF - -deleteall -M 644 inline h/e/l/lo -data <<EOF -$file5_data -EOF - -INPUT_END -test_expect_success \ - 'H: deletall, add 1' \ - 'git fast-import <input && - git whatchanged H' +test_expect_success 'H: deletall, add 1' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/H + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + third + COMMIT + + from refs/heads/branch^0 + M 644 inline i-will-die + data <<EOF + this file will never exist. + EOF + + deleteall + M 644 inline h/e/l/lo + data <<EOF + $file5_data + EOF + + INPUT_END + git fast-import <input && + git whatchanged H +' test_expect_success 'H: verify pack' ' verify_packs ' -cat >expect <<EOF -:100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file2/newf -:100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file2/oldf -:100755 000000 85df50785d62d3b05ab03d9cbf7e4a0b49449730 0000000000000000000000000000000000000000 D file4 -:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting h/e/l/lo -:100755 000000 e74b7d465e52746be2b4bae983670711e6e66657 0000000000000000000000000000000000000000 D newdir/exec.sh -EOF -git diff-tree -M -r H^ H >actual -test_expect_success \ - 'H: validate old files removed, new files added' \ - 'compare_diff_raw expect actual' - -echo "$file5_data" >expect -test_expect_success \ - 'H: verify file' \ - 'git cat-file blob H:h/e/l/lo >actual && - test_cmp expect actual' +test_expect_success 'H: validate old files removed, new files added' ' + cat >expect <<-EOF && + :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file2/newf + :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file2/oldf + :100755 000000 85df50785d62d3b05ab03d9cbf7e4a0b49449730 0000000000000000000000000000000000000000 D file4 + :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting h/e/l/lo + :100755 000000 e74b7d465e52746be2b4bae983670711e6e66657 0000000000000000000000000000000000000000 D newdir/exec.sh + EOF + git diff-tree -M -r H^ H >actual && + compare_diff_raw expect actual +' + +test_expect_success 'H: verify file' ' + echo "$file5_data" >expect && + git cat-file blob H:h/e/l/lo >actual && + test_cmp expect actual +' ### ### series I ### -cat >input <<INPUT_END -commit refs/heads/export-boundary -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -we have a border. its only 40 characters wide. -COMMIT +test_expect_success 'I: export-pack-edges' ' + cat >input <<-INPUT_END && + commit refs/heads/export-boundary + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + we have a border. its only 40 characters wide. + COMMIT -from refs/heads/branch + from refs/heads/branch -INPUT_END -test_expect_success \ - 'I: export-pack-edges' \ - 'git fast-import --export-pack-edges=edges.list <input' + INPUT_END + git fast-import --export-pack-edges=edges.list <input +' -cat >expect <<EOF -.git/objects/pack/pack-.pack: `git rev-parse --verify export-boundary` -EOF -test_expect_success \ - 'I: verify edge list' \ - 'sed -e s/pack-.*pack/pack-.pack/ edges.list >actual && - test_cmp expect actual' +test_expect_success 'I: verify edge list' ' + cat >expect <<-EOF && + .git/objects/pack/pack-.pack: `git rev-parse --verify export-boundary` + EOF + sed -e s/pack-.*pack/pack-.pack/ edges.list >actual && + test_cmp expect actual +' ### ### series J ### -cat >input <<INPUT_END -commit refs/heads/J -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -create J -COMMIT - -from refs/heads/branch - -reset refs/heads/J - -commit refs/heads/J -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -initialize J -COMMIT - -INPUT_END -test_expect_success \ - 'J: reset existing branch creates empty commit' \ - 'git fast-import <input' -test_expect_success \ - 'J: branch has 1 commit, empty tree' \ - 'test 1 = `git rev-list J | wc -l` && - test 0 = `git ls-tree J | wc -l`' - -cat >input <<INPUT_END -reset refs/heads/J2 - -tag wrong_tag -from refs/heads/J2 -data <<EOF -Tag branch that was reset. -EOF -INPUT_END -test_expect_success \ - 'J: tag must fail on empty branch' \ - 'test_must_fail git fast-import <input' +test_expect_success 'J: reset existing branch creates empty commit' ' + cat >input <<-INPUT_END && + commit refs/heads/J + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + create J + COMMIT + + from refs/heads/branch + + reset refs/heads/J + + commit refs/heads/J + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + initialize J + COMMIT + + INPUT_END + git fast-import <input +' +test_expect_success 'J: branch has 1 commit, empty tree' ' + test 1 = `git rev-list J | wc -l` && + test 0 = `git ls-tree J | wc -l` +' + +test_expect_success 'J: tag must fail on empty branch' ' + cat >input <<-INPUT_END && + reset refs/heads/J2 + + tag wrong_tag + from refs/heads/J2 + data <<EOF + Tag branch that was reset. + EOF + INPUT_END + test_must_fail git fast-import <input +' + ### ### series K ### -cat >input <<INPUT_END -commit refs/heads/K -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -create K -COMMIT +test_expect_success 'K: reinit branch with from' ' + cat >input <<-INPUT_END && + commit refs/heads/K + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + create K + COMMIT -from refs/heads/branch + from refs/heads/branch -commit refs/heads/K -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -redo K -COMMIT + commit refs/heads/K + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + redo K + COMMIT -from refs/heads/branch^1 + from refs/heads/branch^1 -INPUT_END -test_expect_success \ - 'K: reinit branch with from' \ - 'git fast-import <input' -test_expect_success \ - 'K: verify K^1 = branch^1' \ - 'test `git rev-parse --verify branch^1` \ - = `git rev-parse --verify K^1`' + INPUT_END + git fast-import <input +' +test_expect_success 'K: verify K^1 = branch^1' ' + test `git rev-parse --verify branch^1` \ + = `git rev-parse --verify K^1` +' ### ### series L ### -cat >input <<INPUT_END -blob -mark :1 -data <<EOF -some data -EOF - -blob -mark :2 -data <<EOF -other data -EOF - -commit refs/heads/L -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -create L -COMMIT - -M 644 :1 b. -M 644 :1 b/other -M 644 :1 ba - -commit refs/heads/L -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -update L -COMMIT - -M 644 :2 b. -M 644 :2 b/other -M 644 :2 ba -INPUT_END - -cat >expect <<EXPECT_END -:100644 100644 4268632... 55d3a52... M b. -:040000 040000 0ae5cac... 443c768... M b -:100644 100644 4268632... 55d3a52... M ba -EXPECT_END - -test_expect_success \ - 'L: verify internal tree sorting' \ - 'git fast-import <input && - git diff-tree --abbrev --raw L^ L >output && - test_cmp expect output' - -cat >input <<INPUT_END -blob -mark :1 -data <<EOF -the data -EOF - -commit refs/heads/L2 -committer C O Mitter <committer@example.com> 1112912473 -0700 -data <<COMMIT -init L2 -COMMIT -M 644 :1 a/b/c -M 644 :1 a/b/d -M 644 :1 a/e/f - -commit refs/heads/L2 -committer C O Mitter <committer@example.com> 1112912473 -0700 -data <<COMMIT -update L2 -COMMIT -C a g -C a/e g/b -M 644 :1 g/b/h -INPUT_END - -cat <<EOF >expect -g/b/f -g/b/h -EOF - -test_expect_success \ - 'L: nested tree copy does not corrupt deltas' \ - 'git fast-import <input && +test_expect_success 'L: verify internal tree sorting' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + some data + EOF + + blob + mark :2 + data <<EOF + other data + EOF + + commit refs/heads/L + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + create L + COMMIT + + M 644 :1 b. + M 644 :1 b/other + M 644 :1 ba + + commit refs/heads/L + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + update L + COMMIT + + M 644 :2 b. + M 644 :2 b/other + M 644 :2 ba + INPUT_END + + cat >expect <<-EXPECT_END && + :100644 100644 4268632... 55d3a52... M b. + :040000 040000 0ae5cac... 443c768... M b + :100644 100644 4268632... 55d3a52... M ba + EXPECT_END + + git fast-import <input && + git diff-tree --abbrev --raw L^ L >output && + test_cmp expect output +' + +test_expect_success 'L: nested tree copy does not corrupt deltas' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + the data + EOF + + commit refs/heads/L2 + committer C O Mitter <committer@example.com> 1112912473 -0700 + data <<COMMIT + init L2 + COMMIT + M 644 :1 a/b/c + M 644 :1 a/b/d + M 644 :1 a/e/f + + commit refs/heads/L2 + committer C O Mitter <committer@example.com> 1112912473 -0700 + data <<COMMIT + update L2 + COMMIT + C a g + C a/e g/b + M 644 :1 g/b/h + INPUT_END + + cat >expect <<-\EOF && + g/b/f + g/b/h + EOF + + test_when_finished "git update-ref -d refs/heads/L2" && + git fast-import <input && git ls-tree L2 g/b/ >tmp && cat tmp | cut -f 2 >actual && test_cmp expect actual && - git fsck `git rev-parse L2`' - -git update-ref -d refs/heads/L2 + git fsck `git rev-parse L2` +' ### ### series M ### -test_tick -cat >input <<INPUT_END -commit refs/heads/M1 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -file rename -COMMIT - -from refs/heads/branch^0 -R file2/newf file2/n.e.w.f - -INPUT_END - -cat >expect <<EOF -:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf file2/n.e.w.f -EOF -test_expect_success \ - 'M: rename file in same subdirectory' \ - 'git fast-import <input && - git diff-tree -M -r M1^ M1 >actual && - compare_diff_raw expect actual' - -cat >input <<INPUT_END -commit refs/heads/M2 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -file rename -COMMIT - -from refs/heads/branch^0 -R file2/newf i/am/new/to/you - -INPUT_END - -cat >expect <<EOF -:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf i/am/new/to/you -EOF -test_expect_success \ - 'M: rename file to new subdirectory' \ - 'git fast-import <input && - git diff-tree -M -r M2^ M2 >actual && - compare_diff_raw expect actual' - -cat >input <<INPUT_END -commit refs/heads/M3 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -file rename -COMMIT - -from refs/heads/M2^0 -R i other/sub - -INPUT_END - -cat >expect <<EOF -:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you other/sub/am/new/to/you -EOF -test_expect_success \ - 'M: rename subdirectory to new subdirectory' \ - 'git fast-import <input && - git diff-tree -M -r M3^ M3 >actual && - compare_diff_raw expect actual' - -cat >input <<INPUT_END -commit refs/heads/M4 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -rename root -COMMIT - -from refs/heads/M2^0 -R "" sub - -INPUT_END - -cat >expect <<EOF -:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2/oldf sub/file2/oldf -:100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 R100 file4 sub/file4 -:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you sub/i/am/new/to/you -:100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 R100 newdir/exec.sh sub/newdir/exec.sh -:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting sub/newdir/interesting -EOF -test_expect_success \ - 'M: rename root to subdirectory' \ - 'git fast-import <input && - git diff-tree -M -r M4^ M4 >actual && - cat actual && - compare_diff_raw expect actual' +test_expect_success 'M: rename file in same subdirectory' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/M1 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + file rename + COMMIT + + from refs/heads/branch^0 + R file2/newf file2/n.e.w.f + + INPUT_END + + cat >expect <<-EOF && + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf file2/n.e.w.f + EOF + git fast-import <input && + git diff-tree -M -r M1^ M1 >actual && + compare_diff_raw expect actual +' + +test_expect_success 'M: rename file to new subdirectory' ' + cat >input <<-INPUT_END && + commit refs/heads/M2 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + file rename + COMMIT + + from refs/heads/branch^0 + R file2/newf i/am/new/to/you + + INPUT_END + + cat >expect <<-EOF && + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 file2/newf i/am/new/to/you + EOF + git fast-import <input && + git diff-tree -M -r M2^ M2 >actual && + compare_diff_raw expect actual +' + +test_expect_success 'M: rename subdirectory to new subdirectory' ' + cat >input <<-INPUT_END && + commit refs/heads/M3 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + file rename + COMMIT + + from refs/heads/M2^0 + R i other/sub + + INPUT_END + + cat >expect <<-EOF && + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you other/sub/am/new/to/you + EOF + git fast-import <input && + git diff-tree -M -r M3^ M3 >actual && + compare_diff_raw expect actual +' + +test_expect_success 'M: rename root to subdirectory' ' + cat >input <<-INPUT_END && + commit refs/heads/M4 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + rename root + COMMIT + + from refs/heads/M2^0 + R "" sub + + INPUT_END + + cat >expect <<-EOF && + :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 R100 file2/oldf sub/file2/oldf + :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 R100 file4 sub/file4 + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc R100 i/am/new/to/you sub/i/am/new/to/you + :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 R100 newdir/exec.sh sub/newdir/exec.sh + :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 R100 newdir/interesting sub/newdir/interesting + EOF + git fast-import <input && + git diff-tree -M -r M4^ M4 >actual && + cat actual && + compare_diff_raw expect actual +' ### ### series N ### -test_tick -cat >input <<INPUT_END -commit refs/heads/N1 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -file copy -COMMIT - -from refs/heads/branch^0 -C file2/newf file2/n.e.w.f - -INPUT_END - -cat >expect <<EOF -:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file2/n.e.w.f -EOF -test_expect_success \ - 'N: copy file in same subdirectory' \ - 'git fast-import <input && - git diff-tree -C --find-copies-harder -r N1^ N1 >actual && - compare_diff_raw expect actual' - -cat >input <<INPUT_END -commit refs/heads/N2 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -clean directory copy -COMMIT - -from refs/heads/branch^0 -C file2 file3 - -commit refs/heads/N2 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -modify directory copy -COMMIT - -M 644 inline file3/file5 -data <<EOF -$file5_data -EOF - -INPUT_END - -cat >expect <<EOF -:100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 -:100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf -:100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf -EOF -test_expect_success \ - 'N: copy then modify subdirectory' \ - 'git fast-import <input && - git diff-tree -C --find-copies-harder -r N2^^ N2 >actual && - compare_diff_raw expect actual' - -cat >input <<INPUT_END -commit refs/heads/N3 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -dirty directory copy -COMMIT - -from refs/heads/branch^0 -M 644 inline file2/file5 -data <<EOF -$file5_data -EOF - -C file2 file3 -D file2/file5 - -INPUT_END - -test_expect_success \ - 'N: copy dirty subdirectory' \ - 'git fast-import <input && - test `git rev-parse N2^{tree}` = `git rev-parse N3^{tree}`' - -test_expect_success \ - 'N: copy directory by id' \ - 'cat >expect <<-\EOF && +test_expect_success 'N: copy file in same subdirectory' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/N1 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + file copy + COMMIT + + from refs/heads/branch^0 + C file2/newf file2/n.e.w.f + + INPUT_END + + cat >expect <<-EOF && + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file2/n.e.w.f + EOF + git fast-import <input && + git diff-tree -C --find-copies-harder -r N1^ N1 >actual && + compare_diff_raw expect actual +' + +test_expect_success 'N: copy then modify subdirectory' ' + cat >input <<-INPUT_END && + commit refs/heads/N2 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + clean directory copy + COMMIT + + from refs/heads/branch^0 + C file2 file3 + + commit refs/heads/N2 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + modify directory copy + COMMIT + + M 644 inline file3/file5 + data <<EOF + $file5_data + EOF + + INPUT_END + + cat >expect <<-EOF && + :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf EOF - subdir=$(git rev-parse refs/heads/branch^0:file2) && - cat >input <<-INPUT_END && + git fast-import <input && + git diff-tree -C --find-copies-harder -r N2^^ N2 >actual && + compare_diff_raw expect actual +' + +test_expect_success 'N: copy dirty subdirectory' ' + cat >input <<-INPUT_END && + commit refs/heads/N3 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + dirty directory copy + COMMIT + + from refs/heads/branch^0 + M 644 inline file2/file5 + data <<EOF + $file5_data + EOF + + C file2 file3 + D file2/file5 + + INPUT_END + + git fast-import <input && + test `git rev-parse N2^{tree}` = `git rev-parse N3^{tree}` +' + +test_expect_success 'N: copy directory by id' ' + cat >expect <<-\EOF && + :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf + :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf + EOF + subdir=$(git rev-parse refs/heads/branch^0:file2) && + cat >input <<-INPUT_END && commit refs/heads/N4 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1127,9 +1125,10 @@ test_expect_success \ from refs/heads/branch^0 M 040000 $subdir file3 INPUT_END - git fast-import <input && - git diff-tree -C --find-copies-harder -r N4^ N4 >actual && - compare_diff_raw expect actual' + git fast-import <input && + git diff-tree -C --find-copies-harder -r N4^ N4 >actual && + compare_diff_raw expect actual +' test_expect_success PIPE 'N: read and copy directory' ' cat >expect <<-\EOF && @@ -1202,14 +1201,13 @@ test_expect_success PIPE 'N: empty directory reads as missing' ' test_cmp expect actual ' -test_expect_success \ - 'N: copy root directory by tree hash' \ - 'cat >expect <<-\EOF && +test_expect_success 'N: copy root directory by tree hash' ' + cat >expect <<-\EOF && :100755 000000 f1fb5da718392694d0076d677d6d0e364c79b0bc 0000000000000000000000000000000000000000 D file3/newf :100644 000000 7123f7f44e39be127c5eb701e5968176ee9d78b1 0000000000000000000000000000000000000000 D file3/oldf EOF - root=$(git rev-parse refs/heads/branch^0^{tree}) && - cat >input <<-INPUT_END && + root=$(git rev-parse refs/heads/branch^0^{tree}) && + cat >input <<-INPUT_END && commit refs/heads/N6 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1219,20 +1217,20 @@ test_expect_success \ from refs/heads/branch^0 M 040000 $root "" INPUT_END - git fast-import <input && - git diff-tree -C --find-copies-harder -r N4 N6 >actual && - compare_diff_raw expect actual' + git fast-import <input && + git diff-tree -C --find-copies-harder -r N4 N6 >actual && + compare_diff_raw expect actual +' -test_expect_success \ - 'N: copy root by path' \ - 'cat >expect <<-\EOF && +test_expect_success 'N: copy root by path' ' + cat >expect <<-\EOF && :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf oldroot/file2/newf :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf oldroot/file2/oldf :100755 100755 85df50785d62d3b05ab03d9cbf7e4a0b49449730 85df50785d62d3b05ab03d9cbf7e4a0b49449730 C100 file4 oldroot/file4 :100755 100755 e74b7d465e52746be2b4bae983670711e6e66657 e74b7d465e52746be2b4bae983670711e6e66657 C100 newdir/exec.sh oldroot/newdir/exec.sh :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting oldroot/newdir/interesting EOF - cat >input <<-INPUT_END && + cat >input <<-INPUT_END && commit refs/heads/N-copy-root-path committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1242,21 +1240,21 @@ test_expect_success \ from refs/heads/branch^0 C "" oldroot INPUT_END - git fast-import <input && - git diff-tree -C --find-copies-harder -r branch N-copy-root-path >actual && - compare_diff_raw expect actual' + git fast-import <input && + git diff-tree -C --find-copies-harder -r branch N-copy-root-path >actual && + compare_diff_raw expect actual +' -test_expect_success \ - 'N: delete directory by copying' \ - 'cat >expect <<-\EOF && +test_expect_success 'N: delete directory by copying' ' + cat >expect <<-\EOF && OBJID :100644 000000 OBJID OBJID D foo/bar/qux OBJID :000000 100644 OBJID OBJID A foo/bar/baz :000000 100644 OBJID OBJID A foo/bar/qux EOF - empty_tree=$(git mktree </dev/null) && - cat >input <<-INPUT_END && + empty_tree=$(git mktree </dev/null) && + cat >input <<-INPUT_END && commit refs/heads/N-delete committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1282,21 +1280,21 @@ test_expect_success \ M 040000 $empty_tree foo/bar/qux INPUT_END - git fast-import <input && - git rev-list N-delete | + git fast-import <input && + git rev-list N-delete | git diff-tree -r --stdin --root --always | sed -e "s/$_x40/OBJID/g" >actual && - test_cmp expect actual' + test_cmp expect actual +' -test_expect_success \ - 'N: modify copied tree' \ - 'cat >expect <<-\EOF && +test_expect_success 'N: modify copied tree' ' + cat >expect <<-\EOF && :100644 100644 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 fcf778cda181eaa1cbc9e9ce3a2e15ee9f9fe791 C100 newdir/interesting file3/file5 :100755 100755 f1fb5da718392694d0076d677d6d0e364c79b0bc f1fb5da718392694d0076d677d6d0e364c79b0bc C100 file2/newf file3/newf :100644 100644 7123f7f44e39be127c5eb701e5968176ee9d78b1 7123f7f44e39be127c5eb701e5968176ee9d78b1 C100 file2/oldf file3/oldf EOF - subdir=$(git rev-parse refs/heads/branch^0:file2) && - cat >input <<-INPUT_END && + subdir=$(git rev-parse refs/heads/branch^0:file2) && + cat >input <<-INPUT_END && commit refs/heads/N5 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1317,14 +1315,14 @@ test_expect_success \ $file5_data EOF INPUT_END - git fast-import <input && - git diff-tree -C --find-copies-harder -r N5^^ N5 >actual && - compare_diff_raw expect actual' - -test_expect_success \ - 'N: reject foo/ syntax' \ - 'subdir=$(git rev-parse refs/heads/branch^0:file2) && - test_must_fail git fast-import <<-INPUT_END + git fast-import <input && + git diff-tree -C --find-copies-harder -r N5^^ N5 >actual && + compare_diff_raw expect actual +' + +test_expect_success 'N: reject foo/ syntax' ' + subdir=$(git rev-parse refs/heads/branch^0:file2) && + test_must_fail git fast-import <<-INPUT_END commit refs/heads/N5B committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1333,11 +1331,11 @@ test_expect_success \ from refs/heads/branch^0 M 040000 $subdir file3/ - INPUT_END' + INPUT_END +' -test_expect_success \ - 'N: reject foo/ syntax in copy source' \ - 'test_must_fail git fast-import <<-INPUT_END +test_expect_success 'N: reject foo/ syntax in copy source' ' + test_must_fail git fast-import <<-INPUT_END commit refs/heads/N5C committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1346,11 +1344,11 @@ test_expect_success \ from refs/heads/branch^0 C file2/ file3 - INPUT_END' + INPUT_END +' -test_expect_success \ - 'N: reject foo/ syntax in rename source' \ - 'test_must_fail git fast-import <<-INPUT_END +test_expect_success 'N: reject foo/ syntax in rename source' ' + test_must_fail git fast-import <<-INPUT_END commit refs/heads/N5D committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1359,11 +1357,11 @@ test_expect_success \ from refs/heads/branch^0 R file2/ file3 - INPUT_END' + INPUT_END +' -test_expect_success \ - 'N: reject foo/ syntax in ls argument' \ - 'test_must_fail git fast-import <<-INPUT_END +test_expect_success 'N: reject foo/ syntax in ls argument' ' + test_must_fail git fast-import <<-INPUT_END commit refs/heads/N5E committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1372,13 +1370,13 @@ test_expect_success \ from refs/heads/branch^0 ls "file2/" - INPUT_END' + INPUT_END +' -test_expect_success \ - 'N: copy to root by id and modify' \ - 'echo "hello, world" >expect.foo && - echo hello >expect.bar && - git fast-import <<-SETUP_END && +test_expect_success 'N: copy to root by id and modify' ' + echo "hello, world" >expect.foo && + echo hello >expect.bar && + git fast-import <<-SETUP_END && commit refs/heads/N7 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1392,8 +1390,8 @@ test_expect_success \ EOF SETUP_END - tree=$(git rev-parse --verify N7:) && - git fast-import <<-INPUT_END && + tree=$(git rev-parse --verify N7:) && + git fast-import <<-INPUT_END && commit refs/heads/N8 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1406,15 +1404,15 @@ test_expect_success \ hello, world EOF INPUT_END - git show N8:foo/foo >actual.foo && - git show N8:foo/bar >actual.bar && - test_cmp expect.foo actual.foo && - test_cmp expect.bar actual.bar' - -test_expect_success \ - 'N: extract subtree' \ - 'branch=$(git rev-parse --verify refs/heads/branch^{tree}) && - cat >input <<-INPUT_END && + git show N8:foo/foo >actual.foo && + git show N8:foo/bar >actual.bar && + test_cmp expect.foo actual.foo && + test_cmp expect.bar actual.bar +' + +test_expect_success 'N: extract subtree' ' + branch=$(git rev-parse --verify refs/heads/branch^{tree}) && + cat >input <<-INPUT_END && commit refs/heads/N9 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1424,14 +1422,14 @@ test_expect_success \ M 040000 $branch "" C "newdir" "" INPUT_END - git fast-import <input && - git diff --exit-code branch:newdir N9' - -test_expect_success \ - 'N: modify subtree, extract it, and modify again' \ - 'echo hello >expect.baz && - echo hello, world >expect.qux && - git fast-import <<-SETUP_END && + git fast-import <input && + git diff --exit-code branch:newdir N9 +' + +test_expect_success 'N: modify subtree, extract it, and modify again' ' + echo hello >expect.baz && + echo hello, world >expect.qux && + git fast-import <<-SETUP_END && commit refs/heads/N10 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1445,8 +1443,8 @@ test_expect_success \ EOF SETUP_END - tree=$(git rev-parse --verify N10:) && - git fast-import <<-INPUT_END && + tree=$(git rev-parse --verify N10:) && + git fast-import <<-INPUT_END && commit refs/heads/N11 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE data <<COMMIT @@ -1461,676 +1459,692 @@ test_expect_success \ R "foo" "" C "bar/qux" "bar/quux" INPUT_END - git show N11:bar/baz >actual.baz && - git show N11:bar/qux >actual.qux && - git show N11:bar/quux >actual.quux && - test_cmp expect.baz actual.baz && - test_cmp expect.qux actual.qux && - test_cmp expect.qux actual.quux' + git show N11:bar/baz >actual.baz && + git show N11:bar/qux >actual.qux && + git show N11:bar/quux >actual.quux && + test_cmp expect.baz actual.baz && + test_cmp expect.qux actual.qux && + test_cmp expect.qux actual.quux' ### ### series O ### -cat >input <<INPUT_END -#we will -commit refs/heads/O1 -# -- ignore all of this text -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -# $GIT_COMMITTER_NAME has inserted here for his benefit. -data <<COMMIT -dirty directory copy -COMMIT - -# don't forget the import blank line! -# -# yes, we started from our usual base of branch^0. -# i like branch^0. -from refs/heads/branch^0 -# and we need to reuse file2/file5 from N3 above. -M 644 inline file2/file5 -# otherwise the tree will be different -data <<EOF -$file5_data -EOF - -# don't forget to copy file2 to file3 -C file2 file3 -# -# or to delete file5 from file2. -D file2/file5 -# are we done yet? - -INPUT_END - -test_expect_success \ - 'O: comments are all skipped' \ - 'git fast-import <input && - test `git rev-parse N3` = `git rev-parse O1`' - -cat >input <<INPUT_END -commit refs/heads/O2 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -dirty directory copy -COMMIT -from refs/heads/branch^0 -M 644 inline file2/file5 -data <<EOF -$file5_data -EOF -C file2 file3 -D file2/file5 - -INPUT_END - -test_expect_success \ - 'O: blank lines not necessary after data commands' \ - 'git fast-import <input && - test `git rev-parse N3` = `git rev-parse O2`' - -test_expect_success \ - 'O: repack before next test' \ - 'git repack -a -d' - -cat >input <<INPUT_END -commit refs/heads/O3 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -zstring -COMMIT -commit refs/heads/O3 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -zof -COMMIT -checkpoint -commit refs/heads/O3 -mark :5 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -zempty -COMMIT -checkpoint -commit refs/heads/O3 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -zcommits -COMMIT -reset refs/tags/O3-2nd -from :5 -reset refs/tags/O3-3rd -from :5 -INPUT_END - -cat >expect <<INPUT_END -string -of -empty -commits -INPUT_END -test_expect_success \ - 'O: blank lines not necessary after other commands' \ - 'git fast-import <input && - test 8 = `find .git/objects/pack -type f | wc -l` && - test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` && - git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual && - test_cmp expect actual' - -cat >input <<INPUT_END -commit refs/heads/O4 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -zstring -COMMIT -commit refs/heads/O4 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -zof -COMMIT -progress Two commits down, 2 to go! -commit refs/heads/O4 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -zempty -COMMIT -progress Three commits down, 1 to go! -commit refs/heads/O4 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -zcommits -COMMIT -progress I'm done! -INPUT_END -test_expect_success \ - 'O: progress outputs as requested by input' \ - 'git fast-import <input >actual && - grep "progress " <input >expect && - test_cmp expect actual' +test_expect_success 'O: comments are all skipped' ' + cat >input <<-INPUT_END && + #we will + commit refs/heads/O1 + # -- ignore all of this text + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + # $GIT_COMMITTER_NAME has inserted here for his benefit. + data <<COMMIT + dirty directory copy + COMMIT + + # do not forget the import blank line! + # + # yes, we started from our usual base of branch^0. + # i like branch^0. + from refs/heads/branch^0 + # and we need to reuse file2/file5 from N3 above. + M 644 inline file2/file5 + # otherwise the tree will be different + data <<EOF + $file5_data + EOF + + # do not forget to copy file2 to file3 + C file2 file3 + # + # or to delete file5 from file2. + D file2/file5 + # are we done yet? + + INPUT_END + + git fast-import <input && + test `git rev-parse N3` = `git rev-parse O1` +' + +test_expect_success 'O: blank lines not necessary after data commands' ' + cat >input <<-INPUT_END && + commit refs/heads/O2 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + dirty directory copy + COMMIT + from refs/heads/branch^0 + M 644 inline file2/file5 + data <<EOF + $file5_data + EOF + C file2 file3 + D file2/file5 + + INPUT_END + + git fast-import <input && + test `git rev-parse N3` = `git rev-parse O2` +' + +test_expect_success 'O: repack before next test' ' + git repack -a -d +' + +test_expect_success 'O: blank lines not necessary after other commands' ' + cat >input <<-INPUT_END && + commit refs/heads/O3 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + zstring + COMMIT + commit refs/heads/O3 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + zof + COMMIT + checkpoint + commit refs/heads/O3 + mark :5 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + zempty + COMMIT + checkpoint + commit refs/heads/O3 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + zcommits + COMMIT + reset refs/tags/O3-2nd + from :5 + reset refs/tags/O3-3rd + from :5 + INPUT_END + + cat >expect <<-INPUT_END && + string + of + empty + commits + INPUT_END + + git fast-import <input && + test 8 = `find .git/objects/pack -type f | wc -l` && + test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` && + git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual && + test_cmp expect actual +' + +test_expect_success 'O: progress outputs as requested by input' ' + cat >input <<-INPUT_END && + commit refs/heads/O4 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + zstring + COMMIT + commit refs/heads/O4 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + zof + COMMIT + progress Two commits down, 2 to go! + commit refs/heads/O4 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + zempty + COMMIT + progress Three commits down, 1 to go! + commit refs/heads/O4 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + zcommits + COMMIT + progress done! + INPUT_END + git fast-import <input >actual && + grep "progress " <input >expect && + test_cmp expect actual +' ### ### series P (gitlinks) ### -cat >input <<INPUT_END -blob -mark :1 -data 10 -test file - -reset refs/heads/sub -commit refs/heads/sub -mark :2 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data 12 -sub_initial -M 100644 :1 file - -blob -mark :3 -data <<DATAEND -[submodule "sub"] - path = sub - url = "`pwd`/sub" -DATAEND - -commit refs/heads/subuse1 -mark :4 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data 8 -initial -from refs/heads/master -M 100644 :3 .gitmodules -M 160000 :2 sub - -blob -mark :5 -data 20 -test file -more data - -commit refs/heads/sub -mark :6 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data 11 -sub_second -from :2 -M 100644 :5 file - -commit refs/heads/subuse1 -mark :7 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data 7 -second -from :4 -M 160000 :6 sub - -INPUT_END - -test_expect_success \ - 'P: superproject & submodule mix' \ - 'git fast-import <input && - git checkout subuse1 && - rm -rf sub && mkdir sub && (cd sub && - git init && - git fetch --update-head-ok .. refs/heads/sub:refs/heads/master && - git checkout master) && - git submodule init && - git submodule update' - -SUBLAST=$(git rev-parse --verify sub) -SUBPREV=$(git rev-parse --verify sub^) - -cat >input <<INPUT_END -blob -mark :1 -data <<DATAEND -[submodule "sub"] - path = sub - url = "`pwd`/sub" -DATAEND - -commit refs/heads/subuse2 -mark :2 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data 8 -initial -from refs/heads/master -M 100644 :1 .gitmodules -M 160000 $SUBPREV sub - -commit refs/heads/subuse2 -mark :3 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data 7 -second -from :2 -M 160000 $SUBLAST sub - -INPUT_END - -test_expect_success \ - 'P: verbatim SHA gitlinks' \ - 'git branch -D sub && - git gc && git prune && - git fast-import <input && - test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)' - -test_tick -cat >input <<INPUT_END -commit refs/heads/subuse3 -mark :1 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -corrupt -COMMIT - -from refs/heads/subuse2 -M 160000 inline sub -data <<DATA -$SUBPREV -DATA - -INPUT_END +test_expect_success 'P: superproject & submodule mix' ' + cat >input <<-INPUT_END && + blob + mark :1 + data 10 + test file -test_expect_success 'P: fail on inline gitlink' ' - test_must_fail git fast-import <input' + reset refs/heads/sub + commit refs/heads/sub + mark :2 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data 12 + sub_initial + M 100644 :1 file + + blob + mark :3 + data <<DATAEND + [submodule "sub"] + path = sub + url = "`pwd`/sub" + DATAEND + + commit refs/heads/subuse1 + mark :4 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data 8 + initial + from refs/heads/master + M 100644 :3 .gitmodules + M 160000 :2 sub + + blob + mark :5 + data 20 + test file + more data + + commit refs/heads/sub + mark :6 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data 11 + sub_second + from :2 + M 100644 :5 file + + commit refs/heads/subuse1 + mark :7 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data 7 + second + from :4 + M 160000 :6 sub + + INPUT_END + + git fast-import <input && + git checkout subuse1 && + rm -rf sub && + mkdir sub && + ( + cd sub && + git init && + git fetch --update-head-ok .. refs/heads/sub:refs/heads/master && + git checkout master + ) && + git submodule init && + git submodule update +' -test_tick -cat >input <<INPUT_END -blob -mark :1 -data <<DATA -$SUBPREV -DATA +test_expect_success 'P: verbatim SHA gitlinks' ' + SUBLAST=$(git rev-parse --verify sub) && + SUBPREV=$(git rev-parse --verify sub^) && -commit refs/heads/subuse3 -mark :2 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -corrupt -COMMIT + cat >input <<-INPUT_END && + blob + mark :1 + data <<DATAEND + [submodule "sub"] + path = sub + url = "`pwd`/sub" + DATAEND -from refs/heads/subuse2 -M 160000 :1 sub + commit refs/heads/subuse2 + mark :2 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data 8 + initial + from refs/heads/master + M 100644 :1 .gitmodules + M 160000 $SUBPREV sub -INPUT_END + commit refs/heads/subuse2 + mark :3 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data 7 + second + from :2 + M 160000 $SUBLAST sub + + INPUT_END + + git branch -D sub && + git gc && + git prune && + git fast-import <input && + test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1) +' + +test_expect_success 'P: fail on inline gitlink' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/subuse3 + mark :1 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + corrupt + COMMIT + + from refs/heads/subuse2 + M 160000 inline sub + data <<DATA + $SUBPREV + DATA + + INPUT_END + + test_must_fail git fast-import <input +' test_expect_success 'P: fail on blob mark in gitlink' ' - test_must_fail git fast-import <input' + test_tick && + cat >input <<-INPUT_END && + blob + mark :1 + data <<DATA + $SUBPREV + DATA + + commit refs/heads/subuse3 + mark :2 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + corrupt + COMMIT + + from refs/heads/subuse2 + M 160000 :1 sub + + INPUT_END + + test_must_fail git fast-import <input +' ### ### series Q (notes) ### -note1_data="The first note for the first commit" -note2_data="The first note for the second commit" -note3_data="The first note for the third commit" -note1b_data="The second note for the first commit" -note1c_data="The third note for the first commit" -note2b_data="The second note for the second commit" - -test_tick -cat >input <<INPUT_END -blob -mark :2 -data <<EOF -$file2_data -EOF - -commit refs/heads/notes-test -mark :3 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -first (:3) -COMMIT - -M 644 :2 file2 - -blob -mark :4 -data $file4_len -$file4_data -commit refs/heads/notes-test -mark :5 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -second (:5) -COMMIT - -M 644 :4 file4 - -commit refs/heads/notes-test -mark :6 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -third (:6) -COMMIT - -M 644 inline file5 -data <<EOF -$file5_data -EOF - -M 755 inline file6 -data <<EOF -$file6_data -EOF - -blob -mark :7 -data <<EOF -$note1_data -EOF - -blob -mark :8 -data <<EOF -$note2_data -EOF - -commit refs/notes/foobar -mark :9 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -notes (:9) -COMMIT - -N :7 :3 -N :8 :5 -N inline :6 -data <<EOF -$note3_data -EOF - -commit refs/notes/foobar -mark :10 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -notes (:10) -COMMIT - -N inline :3 -data <<EOF -$note1b_data -EOF - -commit refs/notes/foobar2 -mark :11 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -notes (:11) -COMMIT - -N inline :3 -data <<EOF -$note1c_data -EOF - -commit refs/notes/foobar -mark :12 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -notes (:12) -COMMIT - -deleteall -N inline :5 -data <<EOF -$note2b_data -EOF - -INPUT_END - -test_expect_success \ - 'Q: commit notes' \ - 'git fast-import <input && - git whatchanged notes-test' +test_expect_success 'Q: commit notes' ' + note1_data="The first note for the first commit" && + note2_data="The first note for the second commit" && + note3_data="The first note for the third commit" && + note1b_data="The second note for the first commit" && + note1c_data="The third note for the first commit" && + note2b_data="The second note for the second commit" && + + test_tick && + cat >input <<-INPUT_END && + blob + mark :2 + data <<EOF + $file2_data + EOF + + commit refs/heads/notes-test + mark :3 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + first (:3) + COMMIT + + M 644 :2 file2 + + blob + mark :4 + data $file4_len + $file4_data + commit refs/heads/notes-test + mark :5 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + second (:5) + COMMIT + + M 644 :4 file4 + + commit refs/heads/notes-test + mark :6 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + third (:6) + COMMIT + + M 644 inline file5 + data <<EOF + $file5_data + EOF + + M 755 inline file6 + data <<EOF + $file6_data + EOF + + blob + mark :7 + data <<EOF + $note1_data + EOF + + blob + mark :8 + data <<EOF + $note2_data + EOF + + commit refs/notes/foobar + mark :9 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + notes (:9) + COMMIT + + N :7 :3 + N :8 :5 + N inline :6 + data <<EOF + $note3_data + EOF + + commit refs/notes/foobar + mark :10 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + notes (:10) + COMMIT + + N inline :3 + data <<EOF + $note1b_data + EOF + + commit refs/notes/foobar2 + mark :11 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + notes (:11) + COMMIT + + N inline :3 + data <<EOF + $note1c_data + EOF + + commit refs/notes/foobar + mark :12 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + notes (:12) + COMMIT + + deleteall + N inline :5 + data <<EOF + $note2b_data + EOF + + INPUT_END + + git fast-import <input && + git whatchanged notes-test +' test_expect_success 'Q: verify pack' ' verify_packs ' -commit1=$(git rev-parse notes-test~2) -commit2=$(git rev-parse notes-test^) -commit3=$(git rev-parse notes-test) - -cat >expect <<EOF -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -first (:3) -EOF -test_expect_success \ - 'Q: verify first commit' \ - 'git cat-file commit notes-test~2 | sed 1d >actual && - test_cmp expect actual' - -cat >expect <<EOF -parent $commit1 -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -second (:5) -EOF -test_expect_success \ - 'Q: verify second commit' \ - 'git cat-file commit notes-test^ | sed 1d >actual && - test_cmp expect actual' - -cat >expect <<EOF -parent $commit2 -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -third (:6) -EOF -test_expect_success \ - 'Q: verify third commit' \ - 'git cat-file commit notes-test | sed 1d >actual && - test_cmp expect actual' - -cat >expect <<EOF -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -notes (:9) -EOF -test_expect_success \ - 'Q: verify first notes commit' \ - 'git cat-file commit refs/notes/foobar~2 | sed 1d >actual && - test_cmp expect actual' - -cat >expect.unsorted <<EOF -100644 blob $commit1 -100644 blob $commit2 -100644 blob $commit3 -EOF -cat expect.unsorted | sort >expect -test_expect_success \ - 'Q: verify first notes tree' \ - 'git cat-file -p refs/notes/foobar~2^{tree} | sed "s/ [0-9a-f]* / /" >actual && - test_cmp expect actual' - -echo "$note1_data" >expect -test_expect_success \ - 'Q: verify first note for first commit' \ - 'git cat-file blob refs/notes/foobar~2:$commit1 >actual && test_cmp expect actual' - -echo "$note2_data" >expect -test_expect_success \ - 'Q: verify first note for second commit' \ - 'git cat-file blob refs/notes/foobar~2:$commit2 >actual && test_cmp expect actual' - -echo "$note3_data" >expect -test_expect_success \ - 'Q: verify first note for third commit' \ - 'git cat-file blob refs/notes/foobar~2:$commit3 >actual && test_cmp expect actual' - -cat >expect <<EOF -parent `git rev-parse --verify refs/notes/foobar~2` -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -notes (:10) -EOF -test_expect_success \ - 'Q: verify second notes commit' \ - 'git cat-file commit refs/notes/foobar^ | sed 1d >actual && - test_cmp expect actual' - -cat >expect.unsorted <<EOF -100644 blob $commit1 -100644 blob $commit2 -100644 blob $commit3 -EOF -cat expect.unsorted | sort >expect -test_expect_success \ - 'Q: verify second notes tree' \ - 'git cat-file -p refs/notes/foobar^^{tree} | sed "s/ [0-9a-f]* / /" >actual && - test_cmp expect actual' - -echo "$note1b_data" >expect -test_expect_success \ - 'Q: verify second note for first commit' \ - 'git cat-file blob refs/notes/foobar^:$commit1 >actual && test_cmp expect actual' - -echo "$note2_data" >expect -test_expect_success \ - 'Q: verify first note for second commit' \ - 'git cat-file blob refs/notes/foobar^:$commit2 >actual && test_cmp expect actual' - -echo "$note3_data" >expect -test_expect_success \ - 'Q: verify first note for third commit' \ - 'git cat-file blob refs/notes/foobar^:$commit3 >actual && test_cmp expect actual' - -cat >expect <<EOF -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -notes (:11) -EOF -test_expect_success \ - 'Q: verify third notes commit' \ - 'git cat-file commit refs/notes/foobar2 | sed 1d >actual && - test_cmp expect actual' - -cat >expect.unsorted <<EOF -100644 blob $commit1 -EOF -cat expect.unsorted | sort >expect -test_expect_success \ - 'Q: verify third notes tree' \ - 'git cat-file -p refs/notes/foobar2^{tree} | sed "s/ [0-9a-f]* / /" >actual && - test_cmp expect actual' - -echo "$note1c_data" >expect -test_expect_success \ - 'Q: verify third note for first commit' \ - 'git cat-file blob refs/notes/foobar2:$commit1 >actual && test_cmp expect actual' - -cat >expect <<EOF -parent `git rev-parse --verify refs/notes/foobar^` -author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE - -notes (:12) -EOF -test_expect_success \ - 'Q: verify fourth notes commit' \ - 'git cat-file commit refs/notes/foobar | sed 1d >actual && - test_cmp expect actual' - -cat >expect.unsorted <<EOF -100644 blob $commit2 -EOF -cat expect.unsorted | sort >expect -test_expect_success \ - 'Q: verify fourth notes tree' \ - 'git cat-file -p refs/notes/foobar^{tree} | sed "s/ [0-9a-f]* / /" >actual && - test_cmp expect actual' - -echo "$note2b_data" >expect -test_expect_success \ - 'Q: verify second note for second commit' \ - 'git cat-file blob refs/notes/foobar:$commit2 >actual && test_cmp expect actual' - -cat >input <<EOF -reset refs/heads/Q0 - -commit refs/heads/note-Q0 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -Note for an empty branch. -COMMIT - -N inline refs/heads/Q0 -data <<NOTE -some note -NOTE -EOF -test_expect_success \ - 'Q: deny note on empty branch' \ - 'test_must_fail git fast-import <input' +test_expect_success 'Q: verify first commit' ' + commit1=$(git rev-parse notes-test~2) && + commit2=$(git rev-parse notes-test^) && + commit3=$(git rev-parse notes-test) && + + cat >expect <<-EOF && + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + first (:3) + EOF + git cat-file commit notes-test~2 | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify second commit' ' + cat >expect <<-EOF && + parent $commit1 + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + second (:5) + EOF + git cat-file commit notes-test^ | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify third commit' ' + cat >expect <<-EOF && + parent $commit2 + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + third (:6) + EOF + git cat-file commit notes-test | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify first notes commit' ' + cat >expect <<-EOF && + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + notes (:9) + EOF + git cat-file commit refs/notes/foobar~2 | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify first notes tree' ' + cat >expect.unsorted <<-EOF && + 100644 blob $commit1 + 100644 blob $commit2 + 100644 blob $commit3 + EOF + cat expect.unsorted | sort >expect && + git cat-file -p refs/notes/foobar~2^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify first note for first commit' ' + echo "$note1_data" >expect && + git cat-file blob refs/notes/foobar~2:$commit1 >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify first note for second commit' ' + echo "$note2_data" >expect && + git cat-file blob refs/notes/foobar~2:$commit2 >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify first note for third commit' ' + echo "$note3_data" >expect && + git cat-file blob refs/notes/foobar~2:$commit3 >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify second notes commit' ' + cat >expect <<-EOF && + parent `git rev-parse --verify refs/notes/foobar~2` + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + notes (:10) + EOF + git cat-file commit refs/notes/foobar^ | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify second notes tree' ' + cat >expect.unsorted <<-EOF && + 100644 blob $commit1 + 100644 blob $commit2 + 100644 blob $commit3 + EOF + cat expect.unsorted | sort >expect && + git cat-file -p refs/notes/foobar^^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify second note for first commit' ' + echo "$note1b_data" >expect && + git cat-file blob refs/notes/foobar^:$commit1 >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify first note for second commit' ' + echo "$note2_data" >expect && + git cat-file blob refs/notes/foobar^:$commit2 >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify first note for third commit' ' + echo "$note3_data" >expect && + git cat-file blob refs/notes/foobar^:$commit3 >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify third notes commit' ' + cat >expect <<-EOF && + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + notes (:11) + EOF + git cat-file commit refs/notes/foobar2 | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify third notes tree' ' + cat >expect.unsorted <<-EOF && + 100644 blob $commit1 + EOF + cat expect.unsorted | sort >expect && + git cat-file -p refs/notes/foobar2^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify third note for first commit' ' + echo "$note1c_data" >expect && + git cat-file blob refs/notes/foobar2:$commit1 >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify fourth notes commit' ' + cat >expect <<-EOF && + parent `git rev-parse --verify refs/notes/foobar^` + author $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + + notes (:12) + EOF + git cat-file commit refs/notes/foobar | sed 1d >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify fourth notes tree' ' + cat >expect.unsorted <<-EOF && + 100644 blob $commit2 + EOF + cat expect.unsorted | sort >expect && + git cat-file -p refs/notes/foobar^{tree} | sed "s/ [0-9a-f]* / /" >actual && + test_cmp expect actual +' + +test_expect_success 'Q: verify second note for second commit' ' + echo "$note2b_data" >expect && + git cat-file blob refs/notes/foobar:$commit2 >actual && + test_cmp expect actual +' + +test_expect_success 'Q: deny note on empty branch' ' + cat >input <<-EOF && + reset refs/heads/Q0 + + commit refs/heads/note-Q0 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + Note for an empty branch. + COMMIT + + N inline refs/heads/Q0 + data <<NOTE + some note + NOTE + EOF + test_must_fail git fast-import <input +' ### ### series R (feature and option) ### -cat >input <<EOF -feature no-such-feature-exists -EOF - test_expect_success 'R: abort on unsupported feature' ' + cat >input <<-EOF && + feature no-such-feature-exists + EOF + test_must_fail git fast-import <input ' -cat >input <<EOF -feature date-format=now -EOF - test_expect_success 'R: supported feature is accepted' ' + cat >input <<-EOF && + feature date-format=now + EOF + git fast-import <input ' -cat >input << EOF -blob -data 3 -hi -feature date-format=now -EOF - test_expect_success 'R: abort on receiving feature after data command' ' + cat >input <<-EOF && + blob + data 3 + hi + feature date-format=now + EOF + test_must_fail git fast-import <input ' -cat >input << EOF -feature import-marks=git.marks -feature import-marks=git2.marks -EOF - test_expect_success 'R: only one import-marks feature allowed per stream' ' + cat >input <<-EOF && + feature import-marks=git.marks + feature import-marks=git2.marks + EOF + test_must_fail git fast-import <input ' -cat >input << EOF -feature export-marks=git.marks -blob -mark :1 -data 3 -hi +test_expect_success 'R: export-marks feature results in a marks file being created' ' + cat >input <<-EOF && + feature export-marks=git.marks + blob + mark :1 + data 3 + hi -EOF + EOF -test_expect_success \ - 'R: export-marks feature results in a marks file being created' \ - 'cat input | git fast-import && - grep :1 git.marks' + cat input | git fast-import && + grep :1 git.marks +' -test_expect_success \ - 'R: export-marks options can be overridden by commandline options' \ - 'cat input | git fast-import --export-marks=other.marks && - grep :1 other.marks' +test_expect_success 'R: export-marks options can be overridden by commandline options' ' + cat input | git fast-import --export-marks=other.marks && + grep :1 other.marks +' test_expect_success 'R: catch typo in marks file name' ' test_must_fail git fast-import --import-marks=nonexistent.marks </dev/null && @@ -2234,62 +2248,62 @@ test_expect_success 'R: feature import-marks-if-exists' ' test_cmp expect io.marks ' -cat >input << EOF -feature import-marks=marks.out -feature export-marks=marks.new -EOF - -test_expect_success \ - 'R: import to output marks works without any content' \ - 'cat input | git fast-import && - test_cmp marks.out marks.new' +test_expect_success 'R: import to output marks works without any content' ' + cat >input <<-EOF && + feature import-marks=marks.out + feature export-marks=marks.new + EOF -cat >input <<EOF -feature import-marks=nonexistent.marks -feature export-marks=marks.new -EOF + cat input | git fast-import && + test_cmp marks.out marks.new +' -test_expect_success \ - 'R: import marks prefers commandline marks file over the stream' \ - 'cat input | git fast-import --import-marks=marks.out && - test_cmp marks.out marks.new' +test_expect_success 'R: import marks prefers commandline marks file over the stream' ' + cat >input <<-EOF && + feature import-marks=nonexistent.marks + feature export-marks=marks.new + EOF + cat input | git fast-import --import-marks=marks.out && + test_cmp marks.out marks.new +' -cat >input <<EOF -feature import-marks=nonexistent.marks -feature export-marks=combined.marks -EOF test_expect_success 'R: multiple --import-marks= should be honoured' ' - head -n2 marks.out > one.marks && - tail -n +3 marks.out > two.marks && - git fast-import --import-marks=one.marks --import-marks=two.marks <input && - test_cmp marks.out combined.marks -' + cat >input <<-EOF && + feature import-marks=nonexistent.marks + feature export-marks=combined.marks + EOF -cat >input <<EOF -feature relative-marks -feature import-marks=relative.in -feature export-marks=relative.out -EOF + head -n2 marks.out > one.marks && + tail -n +3 marks.out > two.marks && + git fast-import --import-marks=one.marks --import-marks=two.marks <input && + test_cmp marks.out combined.marks +' test_expect_success 'R: feature relative-marks should be honoured' ' - mkdir -p .git/info/fast-import/ && - cp marks.new .git/info/fast-import/relative.in && - git fast-import <input && - test_cmp marks.new .git/info/fast-import/relative.out -' + cat >input <<-EOF && + feature relative-marks + feature import-marks=relative.in + feature export-marks=relative.out + EOF -cat >input <<EOF -feature relative-marks -feature import-marks=relative.in -feature no-relative-marks -feature export-marks=non-relative.out -EOF + mkdir -p .git/info/fast-import/ && + cp marks.new .git/info/fast-import/relative.in && + git fast-import <input && + test_cmp marks.new .git/info/fast-import/relative.out +' test_expect_success 'R: feature no-relative-marks should be honoured' ' - git fast-import <input && - test_cmp marks.new non-relative.out + cat >input <<-EOF && + feature relative-marks + feature import-marks=relative.in + feature no-relative-marks + feature export-marks=non-relative.out + EOF + + git fast-import <input && + test_cmp marks.new non-relative.out ' test_expect_success 'R: feature ls supported' ' @@ -2330,12 +2344,12 @@ test_expect_success !MINGW 'R: in-stream cat-blob-fd not respected' ' cat-blob $blob EOF test_cmp expect actual.3 && - test_cmp empty actual.1 && + test_must_be_empty actual.1 && git fast-import 3>actual.3 >actual.1 <<-EOF && option cat-blob-fd=3 cat-blob $blob EOF - test_cmp empty actual.3 && + test_must_be_empty actual.3 && test_cmp expect actual.1 ' @@ -2549,17 +2563,17 @@ test_expect_success PIPE 'R: print staged blob within commit' ' test_cmp expect actual ' -cat >input << EOF -option git quiet -blob -data 3 -hi +test_expect_success 'R: quiet option results in no stats being output' ' + cat >input <<-EOF && + option git quiet + blob + data 3 + hi -EOF + EOF -test_expect_success 'R: quiet option results in no stats being output' ' - cat input | git fast-import 2> output && - test_cmp empty output + cat input | git fast-import 2> output && + test_must_be_empty output ' test_expect_success 'R: feature done means terminating "done" is mandatory' ' @@ -2604,16 +2618,16 @@ test_expect_success 'R: terminating "done" within commit' ' test_cmp expect actual ' -cat >input <<EOF -option git non-existing-option -EOF - test_expect_success 'R: die on unknown option' ' - test_must_fail git fast-import <input + cat >input <<-EOF && + option git non-existing-option + EOF + + test_must_fail git fast-import <input ' test_expect_success 'R: unknown commandline options are rejected' '\ - test_must_fail git fast-import --non-existing-option < /dev/null + test_must_fail git fast-import --non-existing-option < /dev/null ' test_expect_success 'R: die on invalid option argument' ' @@ -2624,41 +2638,41 @@ test_expect_success 'R: die on invalid option argument' ' test_must_fail git fast-import --depth="5 elephants" </dev/null ' -cat >input <<EOF -option non-existing-vcs non-existing-option -EOF - test_expect_success 'R: ignore non-git options' ' - git fast-import <input + cat >input <<-EOF && + option non-existing-vcs non-existing-option + EOF + + git fast-import <input ' ## ## R: very large blobs ## -blobsize=$((2*1024*1024 + 53)) -test-genrandom bar $blobsize >expect -cat >input <<INPUT_END -commit refs/heads/big-file -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -R - big file -COMMIT - -M 644 inline big1 -data $blobsize -INPUT_END -cat expect >>input -cat >>input <<INPUT_END -M 644 inline big2 -data $blobsize -INPUT_END -cat expect >>input -echo >>input - -test_expect_success \ - 'R: blob bigger than threshold' \ - 'test_create_repo R && - git --git-dir=R/.git fast-import --big-file-threshold=1 <input' +test_expect_success 'R: blob bigger than threshold' ' + blobsize=$((2*1024*1024 + 53)) && + test-genrandom bar $blobsize >expect && + cat >input <<-INPUT_END && + commit refs/heads/big-file + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + R - big file + COMMIT + + M 644 inline big1 + data $blobsize + INPUT_END + cat expect >>input && + cat >>input <<-INPUT_END && + M 644 inline big2 + data $blobsize + INPUT_END + cat expect >>input && + echo >>input && + + test_create_repo R && + git --git-dir=R/.git fast-import --big-file-threshold=1 <input +' test_expect_success 'R: verify created pack' ' ( @@ -2667,17 +2681,18 @@ test_expect_success 'R: verify created pack' ' ) ' -test_expect_success \ - 'R: verify written objects' \ - 'git --git-dir=R/.git cat-file blob big-file:big1 >actual && - test_cmp_bin expect actual && - a=$(git --git-dir=R/.git rev-parse big-file:big1) && - b=$(git --git-dir=R/.git rev-parse big-file:big2) && - test $a = $b' -test_expect_success \ - 'R: blob appears only once' \ - 'n=$(grep $a verify | wc -l) && - test 1 = $n' +test_expect_success 'R: verify written objects' ' + git --git-dir=R/.git cat-file blob big-file:big1 >actual && + test_cmp_bin expect actual && + a=$(git --git-dir=R/.git rev-parse big-file:big1) && + b=$(git --git-dir=R/.git rev-parse big-file:big2) && + test $a = $b +' + +test_expect_success 'R: blob appears only once' ' + n=$(grep $a verify | wc -l) && + test 1 = $n +' ### ### series S @@ -2710,46 +2725,46 @@ test_expect_success \ # # Invalid dataref .. # -test_tick - -cat >input <<INPUT_END -commit refs/heads/S -mark :301 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -commit 1 -COMMIT -M 100644 inline hello.c -data <<BLOB -blob 1 -BLOB - -commit refs/heads/S -mark :302 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -commit 2 -COMMIT -from :301 -M 100644 inline hello.c -data <<BLOB -blob 2 -BLOB - -blob -mark :403 -data <<BLOB -blob 3 -BLOB - -blob -mark :202 -data <<BLOB -note 2 -BLOB -INPUT_END - test_expect_success 'S: initialize for S tests' ' + test_tick && + + cat >input <<-INPUT_END && + commit refs/heads/S + mark :301 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + commit 1 + COMMIT + M 100644 inline hello.c + data <<BLOB + blob 1 + BLOB + + commit refs/heads/S + mark :302 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + commit 2 + COMMIT + from :301 + M 100644 inline hello.c + data <<BLOB + blob 2 + BLOB + + blob + mark :403 + data <<BLOB + blob 3 + BLOB + + blob + mark :202 + data <<BLOB + note 2 + BLOB + INPUT_END + git fast-import --export-marks=marks <input ' @@ -3001,103 +3016,103 @@ test_expect_success 'T: empty reset doesnt delete branch' ' ### series U (filedelete) ### -cat >input <<INPUT_END -commit refs/heads/U -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -test setup -COMMIT -M 100644 inline hello.c -data <<BLOB -blob 1 -BLOB -M 100644 inline good/night.txt -data <<BLOB -sleep well -BLOB -M 100644 inline good/bye.txt -data <<BLOB -au revoir -BLOB - -INPUT_END - test_expect_success 'U: initialize for U tests' ' + cat >input <<-INPUT_END && + commit refs/heads/U + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + test setup + COMMIT + M 100644 inline hello.c + data <<BLOB + blob 1 + BLOB + M 100644 inline good/night.txt + data <<BLOB + sleep well + BLOB + M 100644 inline good/bye.txt + data <<BLOB + au revoir + BLOB + + INPUT_END + git fast-import <input ' -cat >input <<INPUT_END -commit refs/heads/U -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -delete good/night.txt -COMMIT -from refs/heads/U^0 -D good/night.txt +test_expect_success 'U: filedelete file succeeds' ' + cat >input <<-INPUT_END && + commit refs/heads/U + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + delete good/night.txt + COMMIT + from refs/heads/U^0 + D good/night.txt -INPUT_END + INPUT_END -test_expect_success 'U: filedelete file succeeds' ' git fast-import <input ' -cat >expect <<EOF -:100644 000000 2907ebb4bf85d91bf0716bb3bd8a68ef48d6da76 0000000000000000000000000000000000000000 D good/night.txt -EOF +test_expect_success 'U: validate file delete result' ' + cat >expect <<-EOF && + :100644 000000 2907ebb4bf85d91bf0716bb3bd8a68ef48d6da76 0000000000000000000000000000000000000000 D good/night.txt + EOF -git diff-tree -M -r U^1 U >actual + git diff-tree -M -r U^1 U >actual && -test_expect_success 'U: validate file delete result' ' compare_diff_raw expect actual ' -cat >input <<INPUT_END -commit refs/heads/U -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -delete good dir -COMMIT -from refs/heads/U^0 -D good +test_expect_success 'U: filedelete directory succeeds' ' + cat >input <<-INPUT_END && + commit refs/heads/U + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + delete good dir + COMMIT + from refs/heads/U^0 + D good -INPUT_END + INPUT_END -test_expect_success 'U: filedelete directory succeeds' ' git fast-import <input ' -cat >expect <<EOF -:100644 000000 69cb75792f55123d8389c156b0b41c2ff00ed507 0000000000000000000000000000000000000000 D good/bye.txt -EOF +test_expect_success 'U: validate directory delete result' ' + cat >expect <<-EOF && + :100644 000000 69cb75792f55123d8389c156b0b41c2ff00ed507 0000000000000000000000000000000000000000 D good/bye.txt + EOF -git diff-tree -M -r U^1 U >actual + git diff-tree -M -r U^1 U >actual && -test_expect_success 'U: validate directory delete result' ' compare_diff_raw expect actual ' -cat >input <<INPUT_END -commit refs/heads/U -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE -data <<COMMIT -must succeed -COMMIT -from refs/heads/U^0 -D "" +test_expect_success 'U: filedelete root succeeds' ' + cat >input <<-INPUT_END && + commit refs/heads/U + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + must succeed + COMMIT + from refs/heads/U^0 + D "" -INPUT_END + INPUT_END -test_expect_success 'U: filedelete root succeeds' ' - git fast-import <input + git fast-import <input ' -cat >expect <<EOF -:100644 000000 c18147dc648481eeb65dc5e66628429a64843327 0000000000000000000000000000000000000000 D hello.c -EOF +test_expect_success 'U: validate root delete result' ' + cat >expect <<-EOF && + :100644 000000 c18147dc648481eeb65dc5e66628429a64843327 0000000000000000000000000000000000000000 D hello.c + EOF -git diff-tree -M -r U^1 U >actual + git diff-tree -M -r U^1 U >actual && -test_expect_success 'U: validate root delete result' ' compare_diff_raw expect actual ' diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh index 90d41ed954..0730f18d0f 100755 --- a/t/t9800-git-p4-basic.sh +++ b/t/t9800-git-p4-basic.sh @@ -241,6 +241,22 @@ test_expect_success 'unresolvable host in P4PORT should display error' ' ) ' +test_expect_success 'submit from detached head' ' + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + git checkout p4/master && + >detached_head_test && + git add detached_head_test && + git commit -m "add detached_head" && + git config git-p4.skipSubmitEdit true && + git p4 submit && + git p4 rebase && + git log p4/master | grep detached_head + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh index 1f74a88385..593152817d 100755 --- a/t/t9807-git-p4-submit.sh +++ b/t/t9807-git-p4-submit.sh @@ -389,7 +389,7 @@ test_expect_success 'description with Jobs section and bogus following text' ' ( cd "$cli" && p4 revert desc6 && - rm desc6 + rm -f desc6 ) ' diff --git a/t/t9815-git-p4-submit-fail.sh b/t/t9815-git-p4-submit-fail.sh index 4cff6a760f..37b42d03a2 100755 --- a/t/t9815-git-p4-submit-fail.sh +++ b/t/t9815-git-p4-submit-fail.sh @@ -417,11 +417,8 @@ test_expect_success 'cleanup chmod after submit cancel' ' ! p4 fstat -T action text && test_path_is_file text+x && ! p4 fstat -T action text+x && - if test_have_prereq !CYGWIN - then - stat --format=%A text | egrep ^-r-- && - stat --format=%A text+x | egrep ^-r-x - fi + ls -l text | egrep ^-r-- && + ls -l text+x | egrep ^-r-x ) ' diff --git a/t/t9818-git-p4-block.sh b/t/t9818-git-p4-block.sh index 3b3ae1f59a..8840a183ac 100755 --- a/t/t9818-git-p4-block.sh +++ b/t/t9818-git-p4-block.sh @@ -84,7 +84,7 @@ p4_add_file() { (cd "$cli" && >$1 && p4 add $1 && - p4 submit -d "Added a file" $1 + p4 submit -d "Added file $1" $1 ) } @@ -112,6 +112,32 @@ test_expect_success 'Syncing files' ' ) ' +# Handling of multiple depot paths: +# git p4 clone //depot/pathA //depot/pathB +# +test_expect_success 'Create a repo with multiple depot paths' ' + client_view "//depot/pathA/... //client/pathA/..." \ + "//depot/pathB/... //client/pathB/..." && + mkdir -p "$cli/pathA" "$cli/pathB" && + for p in pathA pathB + do + for i in $(test_seq 1 10) + do + p4_add_file "$p/file$p$i" + done + done +' + +test_expect_success 'Clone repo with multiple depot paths' ' + ( + cd "$git" && + git p4 clone --changes-block-size=4 //depot/pathA@all //depot/pathB@all \ + --destination=dest && + ls -1 dest >log && + test_line_count = 20 log + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9819-git-p4-case-folding.sh b/t/t9819-git-p4-case-folding.sh index 78f1d0f92d..d808c008c1 100755 --- a/t/t9819-git-p4-case-folding.sh +++ b/t/t9819-git-p4-case-folding.sh @@ -4,6 +4,12 @@ test_description='interaction with P4 case-folding' . ./lib-git-p4.sh +if test_have_prereq CASE_INSENSITIVE_FS +then + skip_all='skipping P4 case-folding tests; case insensitive file system detected' + test_done +fi + test_expect_success 'start p4d with case folding enabled' ' start_p4d -C1 ' diff --git a/t/t9822-git-p4-path-encoding.sh b/t/t9822-git-p4-path-encoding.sh new file mode 100755 index 0000000000..7b83e696a9 --- /dev/null +++ b/t/t9822-git-p4-path-encoding.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +test_description='Clone repositories with non ASCII paths' + +. ./lib-git-p4.sh + +UTF8_ESCAPED="a-\303\244_o-\303\266_u-\303\274.txt" +ISO8859_ESCAPED="a-\344_o-\366_u-\374.txt" + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'Create a repo containing iso8859-1 encoded paths' ' + ( + cd "$cli" && + ISO8859="$(printf "$ISO8859_ESCAPED")" && + echo content123 >"$ISO8859" && + p4 add "$ISO8859" && + p4 submit -d "test commit" + ) +' + +test_expect_failure 'Clone auto-detects depot with iso8859-1 paths' ' + git p4 clone --destination="$git" //depot && + test_when_finished cleanup_git && + ( + cd "$git" && + UTF8="$(printf "$UTF8_ESCAPED")" && + echo "$UTF8" >expect && + git -c core.quotepath=false ls-files >actual && + test_cmp expect actual + ) +' + +test_expect_success 'Clone repo containing iso8859-1 encoded paths with git-p4.pathEncoding' ' + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.pathEncoding iso8859-1 && + git p4 clone --use-client-spec --destination="$git" //depot && + UTF8="$(printf "$UTF8_ESCAPED")" && + echo "$UTF8" >expect && + git -c core.quotepath=false ls-files >actual && + test_cmp expect actual && + + echo content123 >expect && + cat "$UTF8" >actual && + test_cmp expect actual + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done diff --git a/t/t9823-git-p4-mock-lfs.sh b/t/t9823-git-p4-mock-lfs.sh new file mode 100755 index 0000000000..1f2dc369bf --- /dev/null +++ b/t/t9823-git-p4-mock-lfs.sh @@ -0,0 +1,192 @@ +#!/bin/sh + +test_description='Clone repositories and store files in Mock LFS' + +. ./lib-git-p4.sh + +test_file_is_not_in_mock_lfs () { + FILE="$1" && + CONTENT="$2" && + echo "$CONTENT" >expect_content && + test_path_is_file "$FILE" && + test_cmp expect_content "$FILE" +} + +test_file_is_in_mock_lfs () { + FILE="$1" && + CONTENT="$2" && + LOCAL_STORAGE=".git/mock-storage/local/$CONTENT" && + SERVER_STORAGE=".git/mock-storage/remote/$CONTENT" && + echo "pointer-$CONTENT" >expect_pointer && + echo "$CONTENT" >expect_content && + test_path_is_file "$FILE" && + test_path_is_file "$LOCAL_STORAGE" && + test_path_is_file "$SERVER_STORAGE" && + test_cmp expect_pointer "$FILE" && + test_cmp expect_content "$LOCAL_STORAGE" && + test_cmp expect_content "$SERVER_STORAGE" +} + +test_file_is_deleted_in_mock_lfs () { + FILE="$1" && + CONTENT="$2" && + LOCAL_STORAGE=".git/mock-storage/local/$CONTENT" && + SERVER_STORAGE=".git/mock-storage/remote/$CONTENT" && + echo "pointer-$CONTENT" >expect_pointer && + echo "$CONTENT" >expect_content && + test_path_is_missing "$FILE" && + test_path_is_file "$LOCAL_STORAGE" && + test_path_is_file "$SERVER_STORAGE" && + test_cmp expect_content "$LOCAL_STORAGE" && + test_cmp expect_content "$SERVER_STORAGE" +} + +test_file_count_in_dir () { + DIR="$1" && + EXPECTED_COUNT="$2" && + find "$DIR" -type f >actual && + test_line_count = $EXPECTED_COUNT actual +} + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'Create repo with binary files' ' + client_view "//depot/... //client/..." && + ( + cd "$cli" && + + echo "content 1 txt 23 bytes" >file1.txt && + p4 add file1.txt && + echo "content 2-3 bin 25 bytes" >file2.dat && + p4 add file2.dat && + p4 submit -d "Add text and binary file" && + + mkdir "path with spaces" && + echo "content 2-3 bin 25 bytes" >"path with spaces/file3.bin" && + p4 add "path with spaces/file3.bin" && + p4 submit -d "Add another binary file with same content and spaces in path" && + + echo "content 4 bin 26 bytes XX" >file4.bin && + p4 add file4.bin && + p4 submit -d "Add another binary file with different content" + ) +' + +test_expect_success 'Store files in Mock LFS based on size (>24 bytes)' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem MockLFS && + git config git-p4.largeFileThreshold 24 && + git config git-p4.largeFilePush True && + git p4 clone --destination="$git" //depot@all && + + test_file_is_not_in_mock_lfs file1.txt "content 1 txt 23 bytes" && + test_file_is_in_mock_lfs file2.dat "content 2-3 bin 25 bytes" && + test_file_is_in_mock_lfs "path with spaces/file3.bin" "content 2-3 bin 25 bytes" && + test_file_is_in_mock_lfs file4.bin "content 4 bin 26 bytes XX" && + + test_file_count_in_dir ".git/mock-storage/local" 2 && + test_file_count_in_dir ".git/mock-storage/remote" 2 + ) +' + +test_expect_success 'Store files in Mock LFS based on extension (dat)' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem MockLFS && + git config git-p4.largeFileExtensions dat && + git config git-p4.largeFilePush True && + git p4 clone --destination="$git" //depot@all && + + test_file_is_not_in_mock_lfs file1.txt "content 1 txt 23 bytes" && + test_file_is_in_mock_lfs file2.dat "content 2-3 bin 25 bytes" && + test_file_is_not_in_mock_lfs "path with spaces/file3.bin" "content 2-3 bin 25 bytes" && + test_file_is_not_in_mock_lfs file4.bin "content 4 bin 26 bytes XX" && + + test_file_count_in_dir ".git/mock-storage/local" 1 && + test_file_count_in_dir ".git/mock-storage/remote" 1 + ) +' + +test_expect_success 'Store files in Mock LFS based on extension (dat) and use git p4 sync and no client spec' ' + test_when_finished cleanup_git && + ( + cd "$git" && + git init && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem MockLFS && + git config git-p4.largeFileExtensions dat && + git config git-p4.largeFilePush True && + git p4 sync //depot && + git checkout p4/master && + + test_file_is_not_in_mock_lfs file1.txt "content 1 txt 23 bytes" && + test_file_is_in_mock_lfs file2.dat "content 2-3 bin 25 bytes" && + test_file_is_not_in_mock_lfs "path with spaces/file3.bin" "content 2-3 bin 25 bytes" && + test_file_is_not_in_mock_lfs file4.bin "content 4 bin 26 bytes XX" && + + test_file_count_in_dir ".git/mock-storage/local" 1 && + test_file_count_in_dir ".git/mock-storage/remote" 1 + ) +' + +test_expect_success 'Remove file from repo and store files in Mock LFS based on size (>24 bytes)' ' + client_view "//depot/... //client/..." && + ( + cd "$cli" && + p4 delete file4.bin && + p4 submit -d "Remove file" + ) && + + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem MockLFS && + git config git-p4.largeFileThreshold 24 && + git config git-p4.largeFilePush True && + git p4 clone --destination="$git" //depot@all && + + test_file_is_not_in_mock_lfs file1.txt "content 1 txt 23 bytes" && + test_file_is_in_mock_lfs file2.dat "content 2-3 bin 25 bytes" && + test_file_is_in_mock_lfs "path with spaces/file3.bin" "content 2-3 bin 25 bytes" && + test_file_is_deleted_in_mock_lfs file4.bin "content 4 bin 26 bytes XX" && + + test_file_count_in_dir ".git/mock-storage/local" 2 && + test_file_count_in_dir ".git/mock-storage/remote" 2 + ) +' + +test_expect_success 'Run git p4 submit in repo configured with large file system' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem MockLFS && + git config git-p4.largeFileThreshold 24 && + git config git-p4.largeFilePush True && + git p4 clone --destination="$git" //depot@all && + + test_must_fail git p4 submit + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done diff --git a/t/t9824-git-p4-git-lfs.sh b/t/t9824-git-p4-git-lfs.sh new file mode 100755 index 0000000000..0b664a377c --- /dev/null +++ b/t/t9824-git-p4-git-lfs.sh @@ -0,0 +1,288 @@ +#!/bin/sh + +test_description='Clone repositories and store files in Git LFS' + +. ./lib-git-p4.sh + +git lfs help >/dev/null 2>&1 || { + skip_all='skipping git p4 Git LFS tests; Git LFS not found' + test_done +} + +test_file_in_lfs () { + FILE="$1" && + SIZE="$2" && + EXPECTED_CONTENT="$3" && + cat "$FILE" | grep "size $SIZE" && + HASH=$(cat "$FILE" | grep "oid sha256:" | sed -e "s/oid sha256://g") && + LFS_FILE=".git/lfs/objects/$(echo "$HASH" | cut -c1-2)/$(echo "$HASH" | cut -c3-4)/$HASH" && + echo $EXPECTED_CONTENT >expect && + test_path_is_file "$FILE" && + test_path_is_file "$LFS_FILE" && + test_cmp expect "$LFS_FILE" +} + +test_file_count_in_dir () { + DIR="$1" && + EXPECTED_COUNT="$2" && + find "$DIR" -type f >actual && + test_line_count = $EXPECTED_COUNT actual +} + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'Create repo with binary files' ' + client_view "//depot/... //client/..." && + ( + cd "$cli" && + + echo "content 1 txt 23 bytes" >file1.txt && + p4 add file1.txt && + echo "content 2-3 bin 25 bytes" >file2.dat && + p4 add file2.dat && + p4 submit -d "Add text and binary file" && + + mkdir "path with spaces" && + echo "content 2-3 bin 25 bytes" >"path with spaces/file3.bin" && + p4 add "path with spaces/file3.bin" && + p4 submit -d "Add another binary file with same content and spaces in path" && + + echo "content 4 bin 26 bytes XX" >file4.bin && + p4 add file4.bin && + p4 submit -d "Add another binary file with different content" + ) +' + +test_expect_success 'Store files in LFS based on size (>24 bytes)' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem GitLFS && + git config git-p4.largeFileThreshold 24 && + git p4 clone --destination="$git" //depot@all && + + test_file_in_lfs file2.dat 25 "content 2-3 bin 25 bytes" && + test_file_in_lfs "path with spaces/file3.bin" 25 "content 2-3 bin 25 bytes" && + test_file_in_lfs file4.bin 26 "content 4 bin 26 bytes XX" && + + test_file_count_in_dir ".git/lfs/objects" 2 && + + cat >expect <<-\EOF && + + # + # Git LFS (see https://git-lfs.github.com/) + # + /file2.dat filter=lfs -text + /file4.bin filter=lfs -text + /path[[:space:]]with[[:space:]]spaces/file3.bin filter=lfs -text + EOF + test_path_is_file .gitattributes && + test_cmp expect .gitattributes + ) +' + +test_expect_success 'Store files in LFS based on size (>25 bytes)' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem GitLFS && + git config git-p4.largeFileThreshold 25 && + git p4 clone --destination="$git" //depot@all && + + test_file_in_lfs file4.bin 26 "content 4 bin 26 bytes XX" && + test_file_count_in_dir ".git/lfs/objects" 1 && + + cat >expect <<-\EOF && + + # + # Git LFS (see https://git-lfs.github.com/) + # + /file4.bin filter=lfs -text + EOF + test_path_is_file .gitattributes && + test_cmp expect .gitattributes + ) +' + +test_expect_success 'Store files in LFS based on extension (dat)' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem GitLFS && + git config git-p4.largeFileExtensions dat && + git p4 clone --destination="$git" //depot@all && + + test_file_in_lfs file2.dat 25 "content 2-3 bin 25 bytes" && + test_file_count_in_dir ".git/lfs/objects" 1 && + + cat >expect <<-\EOF && + + # + # Git LFS (see https://git-lfs.github.com/) + # + *.dat filter=lfs -text + EOF + test_path_is_file .gitattributes && + test_cmp expect .gitattributes + ) +' + +test_expect_success 'Store files in LFS based on size (>25 bytes) and extension (dat)' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem GitLFS && + git config git-p4.largeFileExtensions dat && + git config git-p4.largeFileThreshold 25 && + git p4 clone --destination="$git" //depot@all && + + test_file_in_lfs file2.dat 25 "content 2-3 bin 25 bytes" && + test_file_in_lfs file4.bin 26 "content 4 bin 26 bytes XX" && + test_file_count_in_dir ".git/lfs/objects" 2 && + + cat >expect <<-\EOF && + + # + # Git LFS (see https://git-lfs.github.com/) + # + *.dat filter=lfs -text + /file4.bin filter=lfs -text + EOF + test_path_is_file .gitattributes && + test_cmp expect .gitattributes + ) +' + +test_expect_success 'Remove file from repo and store files in LFS based on size (>24 bytes)' ' + client_view "//depot/... //client/..." && + ( + cd "$cli" && + p4 delete file4.bin && + p4 submit -d "Remove file" + ) && + + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem GitLFS && + git config git-p4.largeFileThreshold 24 && + git p4 clone --destination="$git" //depot@all && + + test_file_in_lfs file2.dat 25 "content 2-3 bin 25 bytes" && + test_file_in_lfs "path with spaces/file3.bin" 25 "content 2-3 bin 25 bytes" && + test_path_is_missing file4.bin && + test_file_count_in_dir ".git/lfs/objects" 2 && + + cat >expect <<-\EOF && + + # + # Git LFS (see https://git-lfs.github.com/) + # + /file2.dat filter=lfs -text + /path[[:space:]]with[[:space:]]spaces/file3.bin filter=lfs -text + EOF + test_path_is_file .gitattributes && + test_cmp expect .gitattributes + ) +' + +test_expect_success 'Add .gitattributes and store files in LFS based on size (>24 bytes)' ' + client_view "//depot/... //client/..." && + ( + cd "$cli" && + echo "*.txt text" >.gitattributes && + p4 add .gitattributes && + p4 submit -d "Add .gitattributes" + ) && + + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem GitLFS && + git config git-p4.largeFileThreshold 24 && + git p4 clone --destination="$git" //depot@all && + + test_file_in_lfs file2.dat 25 "content 2-3 bin 25 bytes" && + test_file_in_lfs "path with spaces/file3.bin" 25 "content 2-3 bin 25 bytes" && + test_path_is_missing file4.bin && + test_file_count_in_dir ".git/lfs/objects" 2 && + + cat >expect <<-\EOF && + *.txt text + + # + # Git LFS (see https://git-lfs.github.com/) + # + /file2.dat filter=lfs -text + /path[[:space:]]with[[:space:]]spaces/file3.bin filter=lfs -text + EOF + test_path_is_file .gitattributes && + test_cmp expect .gitattributes + ) +' + +test_expect_success 'Add big files to repo and store files in LFS based on compressed size (>28 bytes)' ' + client_view "//depot/... //client/..." && + ( + cd "$cli" && + echo "content 5 bin 40 bytes XXXXXXXXXXXXXXXX" >file5.bin && + p4 add file5.bin && + p4 submit -d "Add file with small footprint after compression" && + + echo "content 6 bin 39 bytes XXXXXYYYYYZZZZZ" >file6.bin && + p4 add file6.bin && + p4 submit -d "Add file with large footprint after compression" + ) && + + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.useClientSpec true && + git config git-p4.largeFileSystem GitLFS && + git config git-p4.largeFileCompressedThreshold 28 && + # We only import HEAD here ("@all" is missing!) + git p4 clone --destination="$git" //depot && + + test_file_in_lfs file6.bin 13 "content 6 bin 39 bytes XXXXXYYYYYZZZZZ" + test_file_count_in_dir ".git/lfs/objects" 1 && + + cat >expect <<-\EOF && + *.txt text + + # + # Git LFS (see https://git-lfs.github.com/) + # + /file6.bin filter=lfs -text + EOF + test_path_is_file .gitattributes && + test_cmp expect .gitattributes + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done diff --git a/t/t9826-git-p4-keep-empty-commits.sh b/t/t9826-git-p4-keep-empty-commits.sh new file mode 100755 index 0000000000..be12960d39 --- /dev/null +++ b/t/t9826-git-p4-keep-empty-commits.sh @@ -0,0 +1,134 @@ +#!/bin/sh + +test_description='Clone repositories and keep empty commits' + +. ./lib-git-p4.sh + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'Create a repo' ' + client_view "//depot/... //client/..." && + ( + cd "$cli" && + + mkdir -p subdir && + + >subdir/file1.txt && + p4 add subdir/file1.txt && + p4 submit -d "Add file 1" && + + >file2.txt && + p4 add file2.txt && + p4 submit -d "Add file 2" && + + >subdir/file3.txt && + p4 add subdir/file3.txt && + p4 submit -d "Add file 3" && + + >file4.txt && + p4 add file4.txt && + p4 submit -d "Add file 4" && + + p4 delete subdir/file3.txt && + p4 submit -d "Remove file 3" && + + p4 delete file4.txt && + p4 submit -d "Remove file 4" + ) +' + +test_expect_success 'Clone repo root path with all history' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git p4 clone --use-client-spec --destination="$git" //depot@all && + cat >expect <<-\EOF && +Remove file 4 +[git-p4: depot-paths = "//depot/": change = 6] + +Remove file 3 +[git-p4: depot-paths = "//depot/": change = 5] + +Add file 4 +[git-p4: depot-paths = "//depot/": change = 4] + +Add file 3 +[git-p4: depot-paths = "//depot/": change = 3] + +Add file 2 +[git-p4: depot-paths = "//depot/": change = 2] + +Add file 1 +[git-p4: depot-paths = "//depot/": change = 1] + + EOF + git log --format=%B >actual && + test_cmp expect actual + ) +' + +test_expect_success 'Clone repo subdir with all history but keep empty commits' ' + client_view "//depot/subdir/... //client/subdir/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git config git-p4.keepEmptyCommits true && + git p4 clone --use-client-spec --destination="$git" //depot@all && + cat >expect <<-\EOF && +Remove file 4 +[git-p4: depot-paths = "//depot/": change = 6] + +Remove file 3 +[git-p4: depot-paths = "//depot/": change = 5] + +Add file 4 +[git-p4: depot-paths = "//depot/": change = 4] + +Add file 3 +[git-p4: depot-paths = "//depot/": change = 3] + +Add file 2 +[git-p4: depot-paths = "//depot/": change = 2] + +Add file 1 +[git-p4: depot-paths = "//depot/": change = 1] + + EOF + git log --format=%B >actual && + test_cmp expect actual + ) +' + +test_expect_success 'Clone repo subdir with all history' ' + client_view "//depot/subdir/... //client/subdir/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git p4 clone --use-client-spec --destination="$git" --verbose //depot@all && + cat >expect <<-\EOF && +Remove file 3 +[git-p4: depot-paths = "//depot/": change = 5] + +Add file 3 +[git-p4: depot-paths = "//depot/": change = 3] + +Add file 1 +[git-p4: depot-paths = "//depot/": change = 1] + + EOF + git log --format=%B >actual && + test_cmp expect actual + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index 6b68777b98..af82049f82 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -273,11 +273,36 @@ test_expect_success 'prompt - dirty status indicator - dirty index and worktree' test_cmp expected "$actual" ' -test_expect_success 'prompt - dirty status indicator - before root commit' ' - printf " (master #)" >expected && +test_expect_success 'prompt - dirty status indicator - orphan branch - clean' ' + printf " (orphan #)" >expected && + test_when_finished "git checkout master" && + git checkout --orphan orphan && + git reset --hard && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + __git_ps1 >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - orphan branch - dirty index' ' + printf " (orphan +)" >expected && + test_when_finished "git checkout master" && + git checkout --orphan orphan && + ( + GIT_PS1_SHOWDIRTYSTATE=y && + __git_ps1 >"$actual" + ) && + test_cmp expected "$actual" +' + +test_expect_success 'prompt - dirty status indicator - orphan branch - dirty index and worktree' ' + printf " (orphan *+)" >expected && + test_when_finished "git checkout master" && + git checkout --orphan orphan && + >file && ( GIT_PS1_SHOWDIRTYSTATE=y && - cd otherrepo && __git_ps1 >"$actual" ) && test_cmp expected "$actual" diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index e8d3c0fdbc..c64e5a5025 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -145,6 +145,14 @@ test_pause () { fi } +# Wrap git in gdb. Adding this to a command can make it easier to +# understand what is going on in a failing test. +# +# Example: "debug git checkout master". +debug () { + GIT_TEST_GDB=1 "$@" +} + # Call test_commit with the arguments "<message> [<file> [<contents> [<tag>]]]" # # This will commit a file with the given contents and the given commit @@ -201,7 +209,14 @@ test_chmod () { # Unset a configuration variable, but don't fail if it doesn't exist. test_unconfig () { - git config --unset-all "$@" + config_dir= + if test "$1" = -C + then + shift + config_dir=$1 + shift + fi + git ${config_dir:+-C "$config_dir"} config --unset-all "$@" config_status=$? case "$config_status" in 5) # ok, nothing to unset @@ -213,8 +228,15 @@ test_unconfig () { # Set git config, automatically unsetting it after the test is over. test_config () { - test_when_finished "test_unconfig '$1'" && - git config "$@" + config_dir= + if test "$1" = -C + then + shift + config_dir=$1 + shift + fi + test_when_finished "test_unconfig ${config_dir:+-C '$config_dir'} '$1'" && + git ${config_dir:+-C "$config_dir"} config "$@" } test_config_global () { @@ -547,6 +569,21 @@ test_line_count () { fi } +# Returns success if a comma separated string of keywords ($1) contains a +# given keyword ($2). +# Examples: +# `list_contains "foo,bar" bar` returns 0 +# `list_contains "foo" bar` returns 1 + +list_contains () { + case ",$1," in + *,$2,*) + return 0 + ;; + esac + return 1 +} + # This is not among top-level (test_expect_success | test_expect_failure) # but is a prefix that can be used in the test script, like: # @@ -560,18 +597,34 @@ test_line_count () { # the failure could be due to a segv. We want a controlled failure. test_must_fail () { + case "$1" in + ok=*) + _test_ok=${1#ok=} + shift + ;; + *) + _test_ok= + ;; + esac "$@" exit_code=$? - if test $exit_code = 0; then + if test $exit_code -eq 0 && ! list_contains "$_test_ok" success + then echo >&2 "test_must_fail: command succeeded: $*" return 1 - elif test $exit_code -gt 129 && test $exit_code -le 192; then + elif test $exit_code -eq 141 && list_contains "$_test_ok" sigpipe + then + return 0 + elif test $exit_code -gt 129 && test $exit_code -le 192 + then echo >&2 "test_must_fail: died by signal: $*" return 1 - elif test $exit_code = 127; then + elif test $exit_code -eq 127 + then echo >&2 "test_must_fail: command not found: $*" return 1 - elif test $exit_code = 126; then + elif test $exit_code -eq 126 + then echo >&2 "test_must_fail: valgrind error: $*" return 1 fi @@ -590,16 +643,7 @@ test_must_fail () { # because we want to notice if it fails due to segv. test_might_fail () { - "$@" - exit_code=$? - if test $exit_code -gt 129 && test $exit_code -le 192; then - echo >&2 "test_might_fail: died by signal: $*" - return 1 - elif test $exit_code = 127; then - echo >&2 "test_might_fail: command not found: $*" - return 1 - fi - return 0 + test_must_fail ok=success "$@" } # Similar to test_must_fail and test_might_fail, but check that a @@ -722,6 +766,11 @@ test_seq () { # what went wrong. test_when_finished () { + # We cannot detect when we are in a subshell in general, but by + # doing so on Bash is better than nothing (the test will + # silently pass on other shells). + test "${BASH_SUBSHELL-0}" = 0 || + error "bug in test script: test_when_finished does nothing in a subshell" test_cleanup="{ $* } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup" } |