diff options
Diffstat (limited to 't')
73 files changed, 1767 insertions, 707 deletions
@@ -84,9 +84,9 @@ appropriately before running "make". -x:: Turn on shell tracing (i.e., `set -x`) during the tests - themselves. Implies `--verbose`. Note that this can cause - failures in some tests which redirect and test the - output of shell functions. Use with caution. + themselves. Implies `--verbose`. Note that in non-bash shells, + this can cause failures in some tests which redirect and test + the output of shell functions. Use with caution. -d:: --debug:: diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c index 37a196781d..2c63298fab 100644 --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -7,16 +7,25 @@ static int integer = 0; static unsigned long magnitude = 0; static unsigned long timestamp; static int abbrev = 7; -static int verbose = 0, dry_run = 0, quiet = 0; +static int verbose = -1; /* unspecified */ +static int dry_run = 0, quiet = 0; static char *string = NULL; static char *file = NULL; static int ambiguous; static struct string_list list = STRING_LIST_INIT_NODUP; +static struct { + int called; + const char *arg; + int unset; +} length_cb; + static int length_callback(const struct option *opt, const char *arg, int unset) { - printf("Callback: \"%s\", %d\n", - (arg ? arg : "not set"), unset); + length_cb.called = 1; + length_cb.arg = arg; + length_cb.unset = unset; + if (unset) return 1; /* do not support unset */ @@ -30,6 +39,61 @@ static int number_callback(const struct option *opt, const char *arg, int unset) return 0; } +static int collect_expect(const struct option *opt, const char *arg, int unset) +{ + struct string_list *expect; + struct string_list_item *item; + struct strbuf label = STRBUF_INIT; + const char *colon; + + if (!arg || unset) + die("malformed --expect option"); + + expect = (struct string_list *)opt->value; + colon = strchr(arg, ':'); + if (!colon) + die("malformed --expect option, lacking a colon"); + strbuf_add(&label, arg, colon - arg); + item = string_list_insert(expect, strbuf_detach(&label, NULL)); + if (item->util) + die("malformed --expect option, duplicate %s", label.buf); + item->util = (void *)arg; + return 0; +} + +__attribute__((format (printf,3,4))) +static void show(struct string_list *expect, int *status, const char *fmt, ...) +{ + struct string_list_item *item; + struct strbuf buf = STRBUF_INIT; + va_list args; + + va_start(args, fmt); + strbuf_vaddf(&buf, fmt, args); + va_end(args); + + if (!expect->nr) + printf("%s\n", buf.buf); + else { + char *colon = strchr(buf.buf, ':'); + if (!colon) + die("malformed output format, output lacking colon: %s", fmt); + *colon = '\0'; + item = string_list_lookup(expect, buf.buf); + *colon = ':'; + if (!item) + ; /* not among entries being checked */ + else { + if (strcmp((const char *)item->util, buf.buf)) { + printf("-%s\n", (char *)item->util); + printf("+%s\n", buf.buf); + *status = 1; + } + } + } + strbuf_release(&buf); +} + int main(int argc, char **argv) { const char *prefix = "prefix/"; @@ -37,6 +101,7 @@ int main(int argc, char **argv) "test-parse-options <options>", NULL }; + struct string_list expect = STRING_LIST_INIT_NODUP; struct option options[] = { OPT_BOOL(0, "yes", &boolean, "get a boolean"), OPT_BOOL('D', "no-doubt", &boolean, "begins with 'no-'"), @@ -77,28 +142,38 @@ int main(int argc, char **argv) OPT__VERBOSE(&verbose, "be verbose"), OPT__DRY_RUN(&dry_run, "dry run"), OPT__QUIET(&quiet, "be quiet"), + OPT_CALLBACK(0, "expect", &expect, "string", + "expected output in the variable dump", + collect_expect), OPT_END(), }; int i; + int ret = 0; argc = parse_options(argc, (const char **)argv, prefix, options, usage, 0); - printf("boolean: %d\n", boolean); - printf("integer: %d\n", integer); - printf("magnitude: %lu\n", magnitude); - printf("timestamp: %lu\n", timestamp); - printf("string: %s\n", string ? string : "(not set)"); - printf("abbrev: %d\n", abbrev); - printf("verbose: %d\n", verbose); - printf("quiet: %s\n", quiet ? "yes" : "no"); - printf("dry run: %s\n", dry_run ? "yes" : "no"); - printf("file: %s\n", file ? file : "(not set)"); + if (length_cb.called) { + const char *arg = length_cb.arg; + int unset = length_cb.unset; + show(&expect, &ret, "Callback: \"%s\", %d", + (arg ? arg : "not set"), unset); + } + show(&expect, &ret, "boolean: %d", boolean); + show(&expect, &ret, "integer: %d", integer); + show(&expect, &ret, "magnitude: %lu", magnitude); + show(&expect, &ret, "timestamp: %lu", timestamp); + show(&expect, &ret, "string: %s", string ? string : "(not set)"); + show(&expect, &ret, "abbrev: %d", abbrev); + show(&expect, &ret, "verbose: %d", verbose); + show(&expect, &ret, "quiet: %d", quiet); + show(&expect, &ret, "dry run: %s", dry_run ? "yes" : "no"); + show(&expect, &ret, "file: %s", file ? file : "(not set)"); for (i = 0; i < list.nr; i++) - printf("list: %s\n", list.items[i].string); + show(&expect, &ret, "list: %s", list.items[i].string); for (i = 0; i < argc; i++) - printf("arg %02d: %s\n", i, argv[i]); + show(&expect, &ret, "arg %02d: %s", i, argv[i]); - return 0; + return ret; } diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index 6a50b8793e..fb8823224e 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -1,8 +1,5 @@ . ./test-lib.sh -remotes_git_svn=remotes/git""-svn -git_svn_id=git""-svn-id - if test -n "$NO_SVN_TESTS" then skip_all='skipping git svn tests, NO_SVN_TESTS defined' diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index b8ed96fac6..018a83a5a1 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -103,10 +103,6 @@ Alias /auth/dumb/ www/auth/dumb/ Header set Set-Cookie name=value </LocationMatch> <LocationMatch /smart_headers/> - <RequireAll> - Require expr %{HTTP:x-magic-one} == 'abra' - Require expr %{HTTP:x-magic-two} == 'cadabra' - </RequireAll> SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} SetEnv GIT_HTTP_EXPORT_ALL </LocationMatch> @@ -136,6 +132,18 @@ RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302] RewriteRule ^/loop-redir/x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-(.*) /$1 [R=302] RewriteRule ^/loop-redir/(.*)$ /loop-redir/x-$1 [R=302] +# Apache 2.2 does not understand <RequireAll>, so we use RewriteCond. +# And as RewriteCond does not allow testing for non-matches, we match +# the desired case first (one has abra, two has cadabra), and let it +# pass by marking the RewriteRule as [L], "last rule, do not process +# any other matching RewriteRules after this"), and then have another +# RewriteRule that matches all other cases and lets them fail via '[F]', +# "fail the request". +RewriteCond %{HTTP:x-magic-one} =abra +RewriteCond %{HTTP:x-magic-two} =cadabra +RewriteRule ^/smart_headers/.* - [L] +RewriteRule ^/smart_headers/.* - [F] + <IfDefine SSL> LoadModule ssl_module modules/mod_ssl.so diff --git a/t/perf/p3404-rebase-interactive.sh b/t/perf/p3404-rebase-interactive.sh new file mode 100755 index 0000000000..88f47de282 --- /dev/null +++ b/t/perf/p3404-rebase-interactive.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +test_description='Tests rebase -i performance' +. ./perf-lib.sh + +test_perf_default_repo + +# This commit merges a sufficiently long topic branch for reasonable +# performance testing +branch_merge=ba5312da19c6fdb6c6747d479f58932aae6e900c^{commit} +export branch_merge + +git rev-parse --verify $branch_merge >/dev/null 2>&1 || { + skip_all='skipping because $branch_merge was not found' + test_done +} + +write_script swap-first-two.sh <<\EOF +case "$1" in +*/COMMIT_EDITMSG) + mv "$1" "$1".bak && + sed -e '1{h;d}' -e 2G <"$1".bak >"$1" + ;; +esac +EOF + +test_expect_success 'setup' ' + git config core.editor "\"$PWD"/swap-first-two.sh\" && + git checkout -f $branch_merge^2 +' + +test_perf 'rebase -i' ' + git rebase -i $branch_merge^ +' + +test_done diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index 5cf74eddec..18c363ea7f 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -80,23 +80,29 @@ test_perf_create_repo_from () { error "bug in the test script: not 2 parameters to test-create-repo" repo="$1" source="$2" - source_git=$source/$(cd "$source" && git rev-parse --git-dir) + source_git="$(git -C "$source" rev-parse --git-dir)" + objects_dir="$(git -C "$source" rev-parse --git-path objects)" mkdir -p "$repo/.git" ( - cd "$repo/.git" && - { cp -Rl "$source_git/objects" . 2>/dev/null || - cp -R "$source_git/objects" .; } && + cd "$source" && + { cp -Rl "$objects_dir" "$repo/.git/" 2>/dev/null || + cp -R "$objects_dir" "$repo/.git/"; } && for stuff in "$source_git"/*; do case "$stuff" in - */objects|*/hooks|*/config) + */objects|*/hooks|*/config|*/commondir) ;; *) - cp -R "$stuff" . || exit 1 + cp -R "$stuff" "$repo/.git/" || exit 1 ;; esac - done && - cd .. && - git init -q && + done + ) && + ( + cd "$repo" && + git init -q && { + test_have_prereq SYMLINKS || + git config core.symlinks false + } && mv .git/hooks .git/hooks-disabled 2>/dev/null ) || error "failed to copy repository '$source' to '$repo'" } diff --git a/t/t0001-init.sh b/t/t0001-init.sh index a5b9e7a4c7..a6fdd5ef3a 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -354,4 +354,34 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' ' test_path_is_dir realgitdir/refs ' +# Tests for the hidden file attribute on windows +is_hidden () { + # Use the output of `attrib`, ignore the absolute path + case "$(attrib "$1")" in *H*?:*) return 0;; esac + return 1 +} + +test_expect_success MINGW '.git hidden' ' + rm -rf newdir && + ( + unset GIT_DIR GIT_WORK_TREE + mkdir newdir && + cd newdir && + git init && + is_hidden .git + ) && + check_config newdir/.git false unset +' + +test_expect_success MINGW 'bare git dir not hidden' ' + rm -rf newdir && + ( + unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + mkdir newdir && + cd newdir && + git --bare init + ) && + ! is_hidden newdir +' + test_done diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index 89544dd833..b425f3a0d2 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -605,7 +605,7 @@ cat <<-EOF >expected-verbose a/b/.gitignore:8:!on* a/b/one a/b/.gitignore:8:!on* a/b/one one a/b/.gitignore:8:!on* a/b/one two - a/b/.gitignore:8:!on* "a/b/one\"three" + a/b/.gitignore:8:!on* "a/b/one\\"three" a/b/.gitignore:9:!two a/b/two a/.gitignore:1:two* a/b/twooo $global_excludes:2:!globaltwo globaltwo @@ -686,7 +686,7 @@ cat <<-EOF >expected-all a/b/.gitignore:8:!on* b/one a/b/.gitignore:8:!on* b/one one a/b/.gitignore:8:!on* b/one two - a/b/.gitignore:8:!on* "b/one\"three" + a/b/.gitignore:8:!on* "b/one\\"three" a/b/.gitignore:9:!two b/two :: b/not-ignored a/.gitignore:1:two* b/twooo diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh index f33962b178..93725895a4 100755 --- a/t/t0027-auto-crlf.sh +++ b/t/t0027-auto-crlf.sh @@ -12,7 +12,7 @@ fi compare_files () { tr '\015\000' QN <"$1" >"$1".expect && - tr '\015\000' QN <"$2" >"$2".actual && + tr '\015\000' QN <"$2" | tr -d 'Z' >"$2".actual && test_cmp "$1".expect "$2".actual && rm "$1".expect "$2".actual } @@ -52,14 +52,17 @@ create_gitattributes () { create_NNO_files () { for crlf in false true input do - for attr in "" auto text -text lf crlf + for attr in "" auto text -text do - pfx=NNO_${crlf}_attr_${attr} && - cp CRLF_mix_LF ${pfx}_LF.txt && - cp CRLF_mix_LF ${pfx}_CRLF.txt && - cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt && - cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt && - cp CRLF_mix_LF ${pfx}_CRLF_nul.txt + for aeol in "" lf crlf + do + pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf} + cp CRLF_mix_LF ${pfx}_LF.txt && + cp CRLF_mix_LF ${pfx}_CRLF.txt && + cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt && + cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt && + cp CRLF_mix_LF ${pfx}_CRLF_nul.txt + done done done } @@ -100,20 +103,22 @@ commit_check_warn () { } commit_chk_wrnNNO () { - crlf=$1 - attr=$2 - lfwarn=$3 - crlfwarn=$4 - lfmixcrlf=$5 - lfmixcr=$6 - crlfnul=$7 - pfx=NNO_${crlf}_attr_${attr} + attr=$1 ; shift + aeol=$1 ; shift + crlf=$1 ; shift + lfwarn=$1 ; shift + crlfwarn=$1 ; shift + lfmixcrlf=$1 ; shift + lfmixcr=$1 ; shift + crlfnul=$1 ; shift + pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf} #Commit files on top of existing file - create_gitattributes "$attr" && + create_gitattributes "$attr" $aeol && for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul do fname=${pfx}_$f.txt && cp $f $fname && + printf Z >>"$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 @@ -121,19 +126,19 @@ commit_chk_wrnNNO () { 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" ' + test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF" ' check_warning "$crlfwarn" ${pfx}_CRLF.err ' - test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_mix_LF" ' + test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_mix_LF" ' check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err ' - test_expect_success "commit NNO files crlf=$crlf attr=$attr LF_mix_cr" ' + test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf LF_mix_cr" ' check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err ' - test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_nul" ' + test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_nul" ' check_warning "$crlfnul" ${pfx}_CRLF_nul.err ' } @@ -162,6 +167,7 @@ stats_ascii () { # contruct the attr/ returned by git ls-files --eol # Take none (=empty), one or two args +# convert.c: eol=XX overrides text=auto attr_ascii () { case $1,$2 in -text,*) echo "-text" ;; @@ -169,8 +175,8 @@ attr_ascii () { text,lf) echo "text eol=lf" ;; text,crlf) echo "text eol=crlf" ;; auto,) echo "text=auto" ;; - auto,lf) echo "text=auto eol=lf" ;; - auto,crlf) echo "text=auto eol=crlf" ;; + auto,lf) echo "text eol=lf" ;; + auto,crlf) echo "text eol=crlf" ;; lf,) echo "text eol=lf" ;; crlf,) echo "text eol=crlf" ;; ,) echo "" ;; @@ -195,28 +201,29 @@ check_files_in_repo () { } 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 + attr=$1 ; shift + aeol=$1 ; shift + crlf=$1 ; shift + lfname=$1 ; shift + crlfname=$1 ; shift + lfmixcrlf=$1 ; shift + lfmixcr=$1 ; shift + crlfnul=$1 ; shift + pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf} + 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 $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 $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 $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 + test_expect_success "compare_files $crlfnul ${pfx}_CRLF_nul.txt" ' + compare_files $crlfnul ${pfx}_CRLF_nul.txt ' } @@ -231,7 +238,7 @@ checkout_files () { lfmixcrlf=$1 ; shift lfmixcr=$1 ; shift crlfnul=$1 ; shift - create_gitattributes "$attr" "$ident" && + create_gitattributes "$attr" $ident $aeol && git config core.autocrlf $crlf && pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ && for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul @@ -244,7 +251,7 @@ checkout_files () { fi done - test_expect_success "ls-files --eol attr=$attr $ident $aeol core.autocrlf=$crlf core.eol=$ceol" ' + test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" ' test_when_finished "rm expect actual" && sort <<-EOF >expect && i/crlf w/$(stats_ascii $crlfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF.txt @@ -259,19 +266,19 @@ checkout_files () { sort >actual && test_cmp expect actual ' - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF" " compare_ws_file $pfx $lfname crlf_false_attr__LF.txt " - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" " compare_ws_file $pfx $crlfname crlf_false_attr__CRLF.txt " - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" " compare_ws_file $pfx $lfmixcrlf crlf_false_attr__CRLF_mix_LF.txt " - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" " compare_ws_file $pfx $lfmixcr crlf_false_attr__LF_mix_CR.txt " - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" " compare_ws_file $pfx $crlfnul crlf_false_attr__LF_nul.txt " } @@ -385,31 +392,31 @@ test_expect_success 'commit files attr=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 "" "" "" "" "" "" - +# 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 "auto" "" false "$WILC" "$WICL" "$WAMIX" "" "" +commit_chk_wrnNNO "auto" "" true LF_CRLF "" LF_CRLF "" "" +commit_chk_wrnNNO "auto" "" input "" 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" +for crlf in true false input +do + commit_chk_wrnNNO -text "" $crlf "" "" "" "" "" + commit_chk_wrnNNO -text lf $crlf "" "" "" "" "" + commit_chk_wrnNNO -text crlf $crlf "" "" "" "" "" + commit_chk_wrnNNO "" lf $crlf "" CRLF_LF CRLF_LF "" CRLF_LF + commit_chk_wrnNNO "" crlf $crlf LF_CRLF "" LF_CRLF LF_CRLF "" + commit_chk_wrnNNO auto lf $crlf "" CRLF_LF CRLF_LF "" CRLF_LF + commit_chk_wrnNNO auto crlf $crlf LF_CRLF "" LF_CRLF LF_CRLF "" + commit_chk_wrnNNO text lf $crlf "" CRLF_LF CRLF_LF "" CRLF_LF + commit_chk_wrnNNO text crlf $crlf LF_CRLF "" LF_CRLF LF_CRLF "" +done -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" "" +commit_chk_wrnNNO "text" "" false "$WILC" "$WICL" "$WAMIX" "$WILC" "$WICL" +commit_chk_wrnNNO "text" "" true LF_CRLF "" LF_CRLF LF_CRLF "" +commit_chk_wrnNNO "text" "" input "" CRLF_LF CRLF_LF "" CRLF_LF test_expect_success 'create files cleanup' ' rm -f *.txt && @@ -440,24 +447,20 @@ 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 - - +for crlf in true false input +do + # attr aeol LF CRLF CRLF_mix_LF LF_mix_CR CRLFNUL + check_in_repo_NNO "" "" $crlf LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + check_in_repo_NNO -text "" $crlf LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + check_in_repo_NNO -text lf $crlf LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + check_in_repo_NNO -text crlf $crlf LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + check_in_repo_NNO auto "" $crlf LF LF LF LF_mix_CR CRLF_nul + check_in_repo_NNO auto lf $crlf LF LF LF LF_mix_CR LF_nul + check_in_repo_NNO auto crlf $crlf LF LF LF LF_mix_CR LF_nul + check_in_repo_NNO text "" $crlf LF LF LF LF_mix_CR LF_nul + check_in_repo_NNO text lf $crlf LF LF LF LF_mix_CR LF_nul + check_in_repo_NNO text crlf $crlf LF LF LF LF_mix_CR LF_nul +done ################################################################################ # Check how files in the repo are changed when they are checked out # How to read the table below: @@ -489,89 +492,47 @@ LFNUL=LF_nul fi export CRLF_MIX_LF_CR MIX NL -checkout_files "" "" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" true crlf CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" true lf CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" true native CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" false "" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" false crlf CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" "" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" false native $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" true "" CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" "" "" true crlf CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" "" "" true lf CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" "" "" true native CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" ident "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - -for id in "" ident; +# Same handling with and without ident +for id in "" ident do - checkout_files "crlf" "$id" "" false "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" false crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" false lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" false native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" input "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" input lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" true "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" true crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" true lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" true native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "lf" "$id" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "text" "$id" "" false "" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL - checkout_files "text" "$id" "" false crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "text" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "text" "$id" "" false native $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL - checkout_files "text" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "text" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "text" "$id" "" true "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "text" "$id" "" true crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "text" "$id" "" true lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "text" "$id" "" true native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "-text" "$id" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + for ceol in lf crlf native + do + for crlf in true false input + do + # -text overrides core.autocrlf and core.eol + # text and eol=crlf or eol=lf override core.autocrlf and core.eol + checkout_files -text "$id" "" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files -text "$id" "lf" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files -text "$id" "crlf" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # text + checkout_files text "$id" "lf" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files text "$id" "crlf" "$crlf" "$ceol" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul + # currently the same as text, eol=XXX + checkout_files auto "$id" "lf" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files auto "$id" "crlf" "$crlf" "$ceol" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul + done + + # core.autocrlf false, different core.eol + checkout_files "" "$id" "" false "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # core.autocrlf true + checkout_files "" "$id" "" true "$ceol" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # text: core.autocrlf = true overrides core.eol + checkout_files auto "$id" "" true "$ceol" CRLF CRLF CRLF LF_mix_CR LF_nul + checkout_files text "$id" "" true "$ceol" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul + # text: core.autocrlf = input overrides core.eol + checkout_files text "$id" "" input "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files auto "$id" "" input "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # text=auto + eol=XXX + done + # text: core.autocrlf=false uses core.eol + checkout_files text "$id" "" false crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul + checkout_files text "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # text: core.autocrlf=false and core.eol unset(or native) uses native eol + checkout_files text "$id" "" false "" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL + checkout_files text "$id" "" false native $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL + # auto: core.autocrlf=false and core.eol unset(or native) uses native eol + checkout_files auto "$id" "" false "" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul + checkout_files auto "$id" "" false native $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul done # Should be the last test case: remove some files from the worktree diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 9be6411104..db5f60d0c5 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -7,7 +7,7 @@ test_description='our own option parser' . ./test-lib.sh -cat > expect << EOF +cat >expect <<\EOF usage: test-parse-options <options> --yes get a boolean @@ -45,63 +45,24 @@ Standard options -v, --verbose be verbose -n, --dry-run dry run -q, --quiet be quiet + --expect <string> expected output in the variable dump EOF test_expect_success 'test help' ' - test_must_fail test-parse-options -h > output 2> output.err && + test_must_fail test-parse-options -h >output 2>output.err && test_must_be_empty output.err && test_i18ncmp expect output ' mv expect expect.err -cat >expect.template <<EOF -boolean: 0 -integer: 0 -magnitude: 0 -timestamp: 0 -string: (not set) -abbrev: 7 -verbose: 0 -quiet: no -dry run: no -file: (not set) -EOF - -check() { +check () { what="$1" && shift && expect="$1" && shift && - sed "s/^$what .*/$what $expect/" <expect.template >expect && - test-parse-options $* >output 2>output.err && - test_must_be_empty output.err && - test_cmp expect output -} - -check_i18n() { - what="$1" && - shift && - expect="$1" && - shift && - sed "s/^$what .*/$what $expect/" <expect.template >expect && - test-parse-options $* >output 2>output.err && - test_must_be_empty output.err && - test_i18ncmp expect output -} - -check_unknown() { - case "$1" in - --*) - echo error: unknown option \`${1#--}\' >expect ;; - -*) - echo error: unknown switch \`${1#-}\' >expect ;; - esac && - cat expect.err >>expect && - test_must_fail test-parse-options $* >output 2>output.err && - test_must_be_empty output && - test_cmp expect output.err + test-parse-options --expect="$what $expect" "$@" } check_unknown_i18n() { @@ -156,7 +117,7 @@ test_expect_success 'OPT_MAGNITUDE() 3giga' ' check magnitude: 3221225472 -m 3g ' -cat > expect << EOF +cat >expect <<\EOF boolean: 2 integer: 1729 magnitude: 16384 @@ -164,7 +125,7 @@ timestamp: 0 string: 123 abbrev: 7 verbose: 2 -quiet: no +quiet: 0 dry run: yes file: prefix/my.file EOF @@ -176,7 +137,7 @@ test_expect_success 'short options' ' test_must_be_empty output.err ' -cat > expect << EOF +cat >expect <<\EOF boolean: 2 integer: 1729 magnitude: 16384 @@ -184,7 +145,7 @@ timestamp: 0 string: 321 abbrev: 10 verbose: 2 -quiet: no +quiet: 0 dry run: no file: prefix/fi.le EOF @@ -204,15 +165,15 @@ test_expect_success 'missing required value' ' test_expect_code 129 test-parse-options --file ' -cat > expect << EOF +cat >expect <<\EOF boolean: 1 integer: 13 magnitude: 0 timestamp: 0 string: 123 abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) arg 00: a1 @@ -222,32 +183,32 @@ EOF test_expect_success 'intermingled arguments' ' test-parse-options a1 --string 123 b1 --boolean -j 13 -- --boolean \ - > output 2> output.err && + >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect << EOF +cat >expect <<\EOF boolean: 0 integer: 2 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'unambiguously abbreviated option' ' - test-parse-options --int 2 --boolean --no-bo > output 2> output.err && + test-parse-options --int 2 --boolean --no-bo >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'unambiguously abbreviated option with "="' ' - test-parse-options --int=2 > output 2> output.err && + test-parse-options --int=2 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' @@ -256,74 +217,74 @@ test_expect_success 'ambiguously abbreviated option' ' test_expect_code 129 test-parse-options --strin 123 ' -cat > expect << EOF +cat >expect <<\EOF boolean: 0 integer: 0 magnitude: 0 timestamp: 0 string: 123 abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'non ambiguous option (after two options it abbreviates)' ' - test-parse-options --st 123 > output 2> output.err && + test-parse-options --st 123 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > typo.err << EOF -error: did you mean \`--boolean\` (with two dashes ?) +cat >typo.err <<\EOF +error: did you mean `--boolean` (with two dashes ?) EOF test_expect_success 'detect possible typos' ' - test_must_fail test-parse-options -boolean > output 2> output.err && + test_must_fail test-parse-options -boolean >output 2>output.err && test_must_be_empty output && test_cmp typo.err output.err ' -cat > typo.err << EOF -error: did you mean \`--ambiguous\` (with two dashes ?) +cat >typo.err <<\EOF +error: did you mean `--ambiguous` (with two dashes ?) EOF test_expect_success 'detect possible typos' ' - test_must_fail test-parse-options -ambiguous > output 2> output.err && + test_must_fail test-parse-options -ambiguous >output 2>output.err && test_must_be_empty output && test_cmp typo.err output.err ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 0 integer: 0 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) arg 00: --quux EOF test_expect_success 'keep some options as arguments' ' - test-parse-options --quux > output 2> output.err && + test-parse-options --quux >output 2>output.err && test_must_be_empty output.err && - test_cmp expect output + test_cmp expect output ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 0 integer: 0 magnitude: 0 timestamp: 1 string: (not set) abbrev: 7 -verbose: 0 -quiet: yes +verbose: -1 +quiet: 1 dry run: no file: (not set) arg 00: foo @@ -331,12 +292,12 @@ EOF test_expect_success 'OPT_DATE() works' ' test-parse-options -t "1970-01-01 00:00:01 +0000" \ - foo -q > output 2> output.err && + foo -q >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect <<EOF +cat >expect <<\EOF Callback: "four", 0 boolean: 5 integer: 4 @@ -344,112 +305,110 @@ magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' ' - test-parse-options --length=four -b -4 > output 2> output.err && + test-parse-options --length=four -b -4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect <<EOF -Callback: "not set", 1 -EOF +>expect test_expect_success 'OPT_CALLBACK() and callback errors work' ' - test_must_fail test-parse-options --no-length > output 2> output.err && + test_must_fail test-parse-options --no-length >output 2>output.err && test_i18ncmp expect output && test_i18ncmp expect.err output.err ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 1 integer: 23 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'OPT_BIT() and OPT_SET_INT() work' ' - test-parse-options --set23 -bbbbb --no-or4 > output 2> output.err && + test-parse-options --set23 -bbbbb --no-or4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' ' - test-parse-options --set23 -bbbbb --neg-or4 > output 2> output.err && + test-parse-options --set23 -bbbbb --neg-or4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 6 integer: 0 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'OPT_BIT() works' ' - test-parse-options -bb --or4 > output 2> output.err && + test-parse-options -bb --or4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_NEGBIT() works' ' - test-parse-options -bb --no-neg-or4 > output 2> output.err && + test-parse-options -bb --no-neg-or4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' ' - test-parse-options + + + + + + > output 2> output.err && + test-parse-options + + + + + + >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 0 integer: 12345 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'OPT_NUMBER_CALLBACK() works' ' - test-parse-options -12345 > output 2> output.err && + test-parse-options -12345 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat >expect <<EOF +cat >expect <<\EOF boolean: 0 integer: 0 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF @@ -460,7 +419,7 @@ test_expect_success 'negation of OPT_NONEG flags is not ambiguous' ' test_cmp expect output ' -cat >>expect <<'EOF' +cat >>expect <<\EOF list: foo list: bar list: baz @@ -476,4 +435,118 @@ test_expect_success '--no-list resets list' ' test_cmp expect output ' +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: -1 +quiet: 3 +dry run: no +file: (not set) +EOF + +test_expect_success 'multiple quiet levels' ' + test-parse-options -q -q -q >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 3 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success 'multiple verbose levels' ' + test-parse-options -v -v -v >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: -1 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success '--no-quiet sets --quiet to 0' ' + test-parse-options --no-quiet >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: -1 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success '--no-quiet resets multiple -q to 0' ' + test-parse-options -q -q -q --no-quiet >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success '--no-verbose sets verbose to 0' ' + test-parse-options --no-verbose >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success '--no-verbose resets multiple verbose to 0' ' + test-parse-options -v -v -v --no-verbose >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + test_done diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 417eecc3af..ca3fa406c3 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -110,7 +110,7 @@ test_expect_success 'symbolic-ref writes reflog entry' ' update create EOF - git log --format=%gs -g >actual && + git log --format=%gs -g -2 >actual && test_cmp expect actual ' diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 9cf91dc6d2..dd2be049ec 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -348,4 +348,26 @@ test_expect_success 'reflog expire operates on symref not referrent' ' git reflog expire --expire=all the_symref ' +test_expect_success 'continue walking past root commits' ' + git init orphanage && + ( + cd orphanage && + cat >expect <<-\EOF && + HEAD@{0} commit (initial): orphan2-1 + HEAD@{1} commit: orphan1-2 + HEAD@{2} commit (initial): orphan1-1 + HEAD@{3} commit (initial): initial + EOF + test_commit initial && + git reflog && + git checkout --orphan orphan1 && + test_commit orphan1-1 && + test_commit orphan1-2 && + git checkout --orphan orphan2 && + test_commit orphan2-1 && + git log -g --format="%gd %gs" >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index e66b7cb697..7ee8ea004f 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -427,6 +427,24 @@ test_expect_success 'fsck allows .Ňit' ' ) ' +test_expect_success 'NUL in commit' ' + rm -fr nul-in-commit && + git init nul-in-commit && + ( + cd nul-in-commit && + git commit --allow-empty -m "initial commitQNUL after message" && + git cat-file commit HEAD >original && + q_to_nul <original >munged && + git hash-object -w -t commit --stdin <munged >name && + git branch bad $(cat name) && + + test_must_fail git -c fsck.nulInCommit=error fsck 2>warn.1 && + grep nulInCommit warn.1 && + git fsck 2>warn.2 && + grep nulInCommit warn.2 + ) +' + # create a static test repo which is broken by omitting # one particular object ($1, which is looked up via rev-parse # in the new repository). diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 48ee07779d..038e24c401 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -3,85 +3,88 @@ test_description='test git rev-parse' . ./test-lib.sh -test_rev_parse() { - name=$1 - shift - - test_expect_success "$name: is-bare-repository" \ - "test '$1' = \"\$(git rev-parse --is-bare-repository)\"" - shift - [ $# -eq 0 ] && return - - test_expect_success "$name: is-inside-git-dir" \ - "test '$1' = \"\$(git rev-parse --is-inside-git-dir)\"" - shift - [ $# -eq 0 ] && return +# usage: [options] label is-bare is-inside-git is-inside-work prefix git-dir +test_rev_parse () { + d= + bare= + gitdir= + while : + do + case "$1" in + -C) d="$2"; shift; shift ;; + -b) case "$2" in + [tfu]*) bare="$2"; shift; shift ;; + *) error "test_rev_parse: bogus core.bare value '$2'" ;; + esac ;; + -g) gitdir="$2"; shift; shift ;; + -*) error "test_rev_parse: unrecognized option '$1'" ;; + *) break ;; + esac + done - test_expect_success "$name: is-inside-work-tree" \ - "test '$1' = \"\$(git rev-parse --is-inside-work-tree)\"" - shift - [ $# -eq 0 ] && return - - test_expect_success "$name: prefix" \ - "test '$1' = \"\$(git rev-parse --show-prefix)\"" + name=$1 shift - [ $# -eq 0 ] && return - test_expect_success "$name: git-dir" \ - "test '$1' = \"\$(git rev-parse --git-dir)\"" - shift - [ $# -eq 0 ] && return + for o in --is-bare-repository \ + --is-inside-git-dir \ + --is-inside-work-tree \ + --show-prefix \ + --git-dir + do + test $# -eq 0 && break + expect="$1" + test_expect_success "$name: $o" ' + if test -n "$gitdir" + then + test_when_finished "unset GIT_DIR" && + GIT_DIR="$gitdir" && + export GIT_DIR + fi && + + case "$bare" in + t*) test_config ${d:+-C} ${d:+"$d"} core.bare true ;; + f*) test_config ${d:+-C} ${d:+"$d"} core.bare false ;; + u*) test_unconfig ${d:+-C} ${d:+"$d"} core.bare ;; + esac && + + echo "$expect" >expect && + git ${d:+-C} ${d:+"$d"} rev-parse $o >actual && + test_cmp expect actual + ' + shift + done } -# label is-bare is-inside-git is-inside-work prefix git-dir - ROOT=$(pwd) +test_expect_success 'setup' ' + mkdir -p sub/dir work && + cp -R .git repo.git +' + test_rev_parse toplevel false false true '' .git -cd .git || exit 1 -test_rev_parse .git/ false true false '' . -cd objects || exit 1 -test_rev_parse .git/objects/ false true false '' "$ROOT/.git" -cd ../.. || exit 1 +test_rev_parse -C .git .git/ false true false '' . +test_rev_parse -C .git/objects .git/objects/ false true false '' "$ROOT/.git" -mkdir -p sub/dir || exit 1 -cd sub/dir || exit 1 -test_rev_parse subdirectory false false true sub/dir/ "$ROOT/.git" -cd ../.. || exit 1 +test_rev_parse -C sub/dir subdirectory false false true sub/dir/ "$ROOT/.git" -git config core.bare true -test_rev_parse 'core.bare = true' true false false +test_rev_parse -b t 'core.bare = true' true false false -git config --unset core.bare -test_rev_parse 'core.bare undefined' false false true +test_rev_parse -b u 'core.bare undefined' false false true -mkdir work || exit 1 -cd work || exit 1 -GIT_DIR=../.git -GIT_CONFIG="$(pwd)"/../.git/config -export GIT_DIR GIT_CONFIG -git config core.bare false -test_rev_parse 'GIT_DIR=../.git, core.bare = false' false false true '' +test_rev_parse -C work -g ../.git -b f 'GIT_DIR=../.git, core.bare = false' false false true '' -git config core.bare true -test_rev_parse 'GIT_DIR=../.git, core.bare = true' true false false '' +test_rev_parse -C work -g ../.git -b t 'GIT_DIR=../.git, core.bare = true' true false false '' -git config --unset core.bare -test_rev_parse 'GIT_DIR=../.git, core.bare undefined' false false true '' +test_rev_parse -C work -g ../.git -b u 'GIT_DIR=../.git, core.bare undefined' false false true '' -mv ../.git ../repo.git || exit 1 -GIT_DIR=../repo.git -GIT_CONFIG="$(pwd)"/../repo.git/config -git config core.bare false -test_rev_parse 'GIT_DIR=../repo.git, core.bare = false' false false true '' +test_rev_parse -C work -g ../repo.git -b f 'GIT_DIR=../repo.git, core.bare = false' false false true '' -git config core.bare true -test_rev_parse 'GIT_DIR=../repo.git, core.bare = true' true false false '' +test_rev_parse -C work -g ../repo.git -b t 'GIT_DIR=../repo.git, core.bare = true' true false false '' -git config --unset core.bare -test_rev_parse 'GIT_DIR=../repo.git, core.bare undefined' false false true '' +test_rev_parse -C work -g ../repo.git -b u 'GIT_DIR=../repo.git, core.bare undefined' false false true '' test_done diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh index 3acb9926f2..4bcc335a19 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2025-worktree-add.sh @@ -4,6 +4,8 @@ test_description='test git worktree add' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + test_expect_success 'setup' ' test_commit init ' @@ -18,6 +20,22 @@ test_expect_success '"add" an existing empty worktree' ' git worktree add --detach existing_empty master ' +test_expect_success '"add" using shorthand - fails when no previous branch' ' + test_must_fail git worktree add existing_short - +' + +test_expect_success '"add" using - shorthand' ' + git checkout -b newbranch && + echo hello >myworld && + git add myworld && + git commit -m myworld && + git checkout master && + git worktree add short-hand - && + echo refs/heads/newbranch >expect && + git -C short-hand rev-parse --symbolic-full-name HEAD >actual && + test_cmp expect actual +' + test_expect_success '"add" refuses to checkout locked branch' ' test_must_fail git worktree add zere master && ! test -d zere && @@ -225,4 +243,61 @@ test_expect_success '"add" worktree with --checkout' ' test_cmp init.t swamp2/init.t ' +test_expect_success 'put a worktree under rebase' ' + git worktree add under-rebase && + ( + cd under-rebase && + set_fake_editor && + FAKE_LINES="edit 1" git rebase -i HEAD^ && + git worktree list | grep "under-rebase.*detached HEAD" + ) +' + +test_expect_success 'add a worktree, checking out a rebased branch' ' + test_must_fail git worktree add new-rebase under-rebase && + ! test -d new-rebase +' + +test_expect_success 'checking out a rebased branch from another worktree' ' + git worktree add new-place && + test_must_fail git -C new-place checkout under-rebase +' + +test_expect_success 'not allow to delete a branch under rebase' ' + ( + cd under-rebase && + test_must_fail git branch -D under-rebase + ) +' + +test_expect_success 'rename a branch under rebase not allowed' ' + test_must_fail git branch -M under-rebase rebase-with-new-name +' + +test_expect_success 'check out from current worktree branch ok' ' + ( + cd under-rebase && + git checkout under-rebase && + git checkout - && + git rebase --abort + ) +' + +test_expect_success 'checkout a branch under bisect' ' + git worktree add under-bisect && + ( + cd under-bisect && + git bisect start && + git bisect bad && + git bisect good HEAD~2 && + git worktree list | grep "under-bisect.*detached HEAD" && + test_must_fail git worktree add new-bisect under-bisect && + ! test -d new-bisect + ) +' + +test_expect_success 'rename a branch under bisect not allowed' ' + test_must_fail git branch -M under-bisect bisect-with-new-name +' + test_done diff --git a/t/t2300-cd-to-toplevel.sh b/t/t2300-cd-to-toplevel.sh index 9965bc5c92..cccd7d923a 100755 --- a/t/t2300-cd-to-toplevel.sh +++ b/t/t2300-cd-to-toplevel.sh @@ -8,7 +8,8 @@ test_cd_to_toplevel () { test_expect_success $3 "$2" ' ( cd '"'$1'"' && - . "$(git --exec-path)"/git-sh-setup && + PATH="$(git --exec-path):$PATH" && + . git-sh-setup && cd_to_toplevel && [ "$(pwd -P)" = "$TOPLEVEL" ] ) diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh index 217dd79b2e..49f548cdb9 100755 --- a/t/t3419-rebase-patch-id.sh +++ b/t/t3419-rebase-patch-id.sh @@ -73,17 +73,17 @@ do_tests () { run git format-patch --stdout --ignore-if-in-upstream master " - test_expect_success $pr 'detect upstream patch' " + test_expect_success $pr 'detect upstream patch' ' git checkout -q master && scramble file && git add file && - git commit -q -m 'change big file again' && + git commit -q -m "change big file again" && git checkout -q other^{} && git rebase master && - test_must_fail test -n \"\$(git rev-list master...HEAD~)\" - " + test_must_fail test -n "$(git rev-list master...HEAD~)" + ' - test_expect_success $pr 'do not drop patch' " + test_expect_success $pr 'do not drop patch' ' git branch -f squashed master && git checkout -q -f squashed && git reset -q --soft HEAD~2 && @@ -91,7 +91,7 @@ do_tests () { git checkout -q other^{} && test_must_fail git rebase squashed && rm -rf .git/rebase-apply - " + ' } do_tests 500 diff --git a/t/t3700-add.sh b/t/t3700-add.sh index f14a665356..4865304ebb 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -332,4 +332,34 @@ test_expect_success 'git add --dry-run --ignore-missing of non-existing file out test_i18ncmp expect.err actual.err ' +test_expect_success 'git add --chmod=+x stages a non-executable file with +x' ' + echo foo >foo1 && + git add --chmod=+x foo1 && + case "$(git ls-files --stage foo1)" in + 100755" "*foo1) echo pass;; + *) echo fail; git ls-files --stage foo1; (exit 1);; + esac +' + +test_expect_success 'git add --chmod=-x stages an executable file with -x' ' + echo foo >xfoo1 && + chmod 755 xfoo1 && + git add --chmod=-x xfoo1 && + case "$(git ls-files --stage xfoo1)" in + 100644" "*xfoo1) echo pass;; + *) echo fail; git ls-files --stage xfoo1; (exit 1);; + esac +' + +test_expect_success POSIXPERM,SYMLINKS 'git add --chmod=+x with symlinks' ' + git config core.filemode 1 && + git config core.symlinks 1 && + echo foo >foo2 && + git add --chmod=+x foo2 && + case "$(git ls-files --stage foo2)" in + 100755" "*foo2) echo pass;; + *) echo fail; git ls-files --stage foo2; (exit 1);; + esac +' + test_done diff --git a/t/t3910-mac-os-precompose.sh b/t/t3910-mac-os-precompose.sh index 831935665e..26dd5b7f78 100755 --- a/t/t3910-mac-os-precompose.sh +++ b/t/t3910-mac-os-precompose.sh @@ -49,12 +49,54 @@ test_expect_success "setup" ' test_expect_success "setup case mac" ' git checkout -b mac_os ' +# This will test nfd2nfc in git diff +test_expect_success "git diff f.Adiar" ' + touch f.$Adiarnfc && + git add f.$Adiarnfc && + echo f.Adiarnfc >f.$Adiarnfc && + git diff f.$Adiarnfd >expect && + git diff f.$Adiarnfc >actual && + test_cmp expect actual && + git reset HEAD f.Adiarnfc && + rm f.$Adiarnfc expect actual +' +# This will test nfd2nfc in git diff-files +test_expect_success "git diff-files f.Adiar" ' + touch f.$Adiarnfc && + git add f.$Adiarnfc && + echo f.Adiarnfc >f.$Adiarnfc && + git diff-files f.$Adiarnfd >expect && + git diff-files f.$Adiarnfc >actual && + test_cmp expect actual && + git reset HEAD f.Adiarnfc && + rm f.$Adiarnfc expect actual +' +# This will test nfd2nfc in git diff-index +test_expect_success "git diff-index f.Adiar" ' + touch f.$Adiarnfc && + git add f.$Adiarnfc && + echo f.Adiarnfc >f.$Adiarnfc && + git diff-index HEAD f.$Adiarnfd >expect && + git diff-index HEAD f.$Adiarnfc >actual && + test_cmp expect actual && + git reset HEAD f.Adiarnfc && + rm f.$Adiarnfc expect actual +' # This will test nfd2nfc in readdir() test_expect_success "add file Adiarnfc" ' echo f.Adiarnfc >f.$Adiarnfc && git add f.$Adiarnfc && git commit -m "add f.$Adiarnfc" ' +# This will test nfd2nfc in git diff-tree +test_expect_success "git diff-tree f.Adiar" ' + echo f.Adiarnfc >>f.$Adiarnfc && + git diff-tree HEAD f.$Adiarnfd >expect && + git diff-tree HEAD f.$Adiarnfc >actual && + test_cmp expect actual && + git checkout f.$Adiarnfc && + rm expect actual +' # This will test nfd2nfc in git stage() test_expect_success "stage file d.Adiarnfd/f.Adiarnfd" ' mkdir d.$Adiarnfd && diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index eed2981b96..805dc9012d 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1072,7 +1072,7 @@ test_expect_success '--from omits redundant in-body header' ' ' test_expect_success 'in-body headers trigger content encoding' ' - GIT_AUTHOR_NAME="éxötìc" test_commit exotic && + test_env GIT_AUTHOR_NAME="éxötìc" test_commit exotic && test_when_finished "git reset --hard HEAD^" && git format-patch -1 --stdout --from >patch && cat >expect <<-\EOF && @@ -1460,4 +1460,109 @@ test_expect_success 'format-patch -o overrides format.outputDirectory' ' test_path_is_dir patchset ' +test_expect_success 'format-patch --base' ' + git checkout side && + git format-patch --stdout --base=HEAD~3 -1 >patch && + grep "^base-commit:" patch >actual && + grep "^prerequisite-patch-id:" patch >>actual && + echo "base-commit: $(git rev-parse HEAD~3)" >expected && + echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected && + echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected && + test_cmp expected actual +' + +test_expect_success 'format-patch --base errors out when base commit is in revision list' ' + test_must_fail git format-patch --base=HEAD -2 && + test_must_fail git format-patch --base=HEAD~1 -2 && + git format-patch --stdout --base=HEAD~2 -2 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(git rev-parse HEAD~2)" >expected && + test_cmp expected actual +' + +test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' ' + # For history as below: + # + # ---Q---P---Z---Y---*---X + # \ / + # ------------W + # + # If "format-patch Z..X" is given, P and Z can not be specified as the base commit + git checkout -b topic1 master && + git rev-parse HEAD >commit-id-base && + test_commit P && + git rev-parse HEAD >commit-id-P && + test_commit Z && + git rev-parse HEAD >commit-id-Z && + test_commit Y && + git checkout -b topic2 master && + test_commit W && + git merge topic1 && + test_commit X && + test_must_fail git format-patch --base=$(cat commit-id-P) -3 && + test_must_fail git format-patch --base=$(cat commit-id-Z) -3 && + git format-patch --stdout --base=$(cat commit-id-base) -3 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(cat commit-id-base)" >expected && + test_cmp expected actual +' + +test_expect_success 'format-patch --base=auto' ' + git checkout -b upstream master && + git checkout -b local upstream && + git branch --set-upstream-to=upstream && + test_commit N1 && + test_commit N2 && + git format-patch --stdout --base=auto -2 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(git rev-parse upstream)" >expected && + test_cmp expected actual +' + +test_expect_success 'format-patch errors out when history involves criss-cross' ' + # setup criss-cross history + # + # B---M1---D + # / \ / + # A X + # \ / \ + # C---M2---E + # + git checkout master && + test_commit A && + git checkout -b xb master && + test_commit B && + git checkout -b xc master && + test_commit C && + git checkout -b xbc xb -- && + git merge xc && + git checkout -b xcb xc -- && + git branch --set-upstream-to=xbc && + git merge xb && + git checkout xbc && + test_commit D && + git checkout xcb && + test_commit E && + test_must_fail git format-patch --base=auto -1 +' + +test_expect_success 'format-patch format.useAutoBaseoption' ' + test_when_finished "git config --unset format.useAutoBase" && + git checkout local && + git config format.useAutoBase true && + git format-patch --stdout -1 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(git rev-parse upstream)" >expected && + test_cmp expected actual +' + +test_expect_success 'format-patch --base overrides format.useAutoBase' ' + test_when_finished "git config --unset format.useAutoBase" && + git config format.useAutoBase true && + git format-patch --stdout --base=HEAD~1 -1 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(git rev-parse HEAD~1)" >expected && + test_cmp expected actual +' + test_done diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 67373dc44e..1795ffc3aa 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -30,6 +30,7 @@ diffpatterns=" bibtex cpp csharp + css fortran fountain html diff --git a/t/t4018/css-brace-in-col-1 b/t/t4018/css-brace-in-col-1 new file mode 100644 index 0000000000..7831577506 --- /dev/null +++ b/t/t4018/css-brace-in-col-1 @@ -0,0 +1,5 @@ +RIGHT label.control-label +{ + margin-top: 10px!important; + border : 10px ChangeMe #C6C6C6; +} diff --git a/t/t4018/css-colon-eol b/t/t4018/css-colon-eol new file mode 100644 index 0000000000..5a30553d29 --- /dev/null +++ b/t/t4018/css-colon-eol @@ -0,0 +1,4 @@ +RIGHT h1 { +color: +ChangeMe; +} diff --git a/t/t4018/css-colon-selector b/t/t4018/css-colon-selector new file mode 100644 index 0000000000..c6d71fb42d --- /dev/null +++ b/t/t4018/css-colon-selector @@ -0,0 +1,5 @@ +RIGHT a:hover { + margin-top: + 10px!important; + border : 10px ChangeMe #C6C6C6; +} diff --git a/t/t4018/css-common b/t/t4018/css-common new file mode 100644 index 0000000000..84ed754b33 --- /dev/null +++ b/t/t4018/css-common @@ -0,0 +1,4 @@ +RIGHT label.control-label { + margin-top: 10px!important; + border : 10px ChangeMe #C6C6C6; +} diff --git a/t/t4018/css-long-selector-list b/t/t4018/css-long-selector-list new file mode 100644 index 0000000000..7ccd25d9ed --- /dev/null +++ b/t/t4018/css-long-selector-list @@ -0,0 +1,6 @@ +p.header, +label.control-label, +div ul#RIGHT { + margin-top: 10px!important; + border : 10px ChangeMe #C6C6C6; +} diff --git a/t/t4018/css-prop-sans-indent b/t/t4018/css-prop-sans-indent new file mode 100644 index 0000000000..a9e3c86b3c --- /dev/null +++ b/t/t4018/css-prop-sans-indent @@ -0,0 +1,5 @@ +RIGHT, label.control-label { +margin-top: 10px!important; +padding: 0; +border : 10px ChangeMe #C6C6C6; +} diff --git a/t/t4018/css-short-selector-list b/t/t4018/css-short-selector-list new file mode 100644 index 0000000000..6a0bdee336 --- /dev/null +++ b/t/t4018/css-short-selector-list @@ -0,0 +1,4 @@ +label.control, div ul#RIGHT { + margin-top: 10px!important; + border : 10px ChangeMe #C6C6C6; +} diff --git a/t/t4018/css-trailing-space b/t/t4018/css-trailing-space new file mode 100644 index 0000000000..32b5606c70 --- /dev/null +++ b/t/t4018/css-trailing-space @@ -0,0 +1,5 @@ +RIGHT label.control-label { + margin:10px; + padding:10px; + border : 10px ChangeMe #C6C6C6; +} diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index f2f55fc51c..912df91226 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -302,6 +302,7 @@ test_language_driver ada test_language_driver bibtex test_language_driver cpp test_language_driver csharp +test_language_driver css test_language_driver fortran test_language_driver html test_language_driver java diff --git a/t/t4034/css/expect b/t/t4034/css/expect new file mode 100644 index 0000000000..ed10393bda --- /dev/null +++ b/t/t4034/css/expect @@ -0,0 +1,16 @@ +<BOLD>diff --git a/pre b/post<RESET> +<BOLD>index b8ae0bb..fe500b7 100644<RESET> +<BOLD>--- a/pre<RESET> +<BOLD>+++ b/post<RESET> +<CYAN>@@ -1,10 +1,10 @@<RESET> +.<RED>class-form<RESET><GREEN>other-form<RESET> label.control-label { + margin-top: <RED>10<RESET><GREEN>15<RESET>px!important; + border : 10px <RED>dashed<RESET><GREEN>dotted<RESET> #C6C6C6; +}<RESET> +<RED>#CCCCCC<RESET><GREEN>#CCCCCB<RESET> +10em<RESET> +<RED>padding-bottom<RESET><GREEN>margin-left<RESET> +150<RED>px<RESET><GREEN>em<RESET> +10px +<RED>!important<RESET> +<RED>div<RESET><GREEN>li<RESET>.class#id diff --git a/t/t4034/css/post b/t/t4034/css/post new file mode 100644 index 0000000000..fe500b7a4f --- /dev/null +++ b/t/t4034/css/post @@ -0,0 +1,10 @@ +.other-form label.control-label { + margin-top: 15px!important; + border : 10px dotted #C6C6C6; +} +#CCCCCB +10em +margin-left +150em +10px +li.class#id diff --git a/t/t4034/css/pre b/t/t4034/css/pre new file mode 100644 index 0000000000..b8ae0bb48f --- /dev/null +++ b/t/t4034/css/pre @@ -0,0 +1,10 @@ +.class-form label.control-label { + margin-top: 10px!important; + border : 10px dashed #C6C6C6; +} +#CCCCCC +10em +padding-bottom +150px +10px!important +div.class#id diff --git a/t/t4051-diff-function-context.sh b/t/t4051-diff-function-context.sh index 001d678e09..b79b87790b 100755 --- a/t/t4051-diff-function-context.sh +++ b/t/t4051-diff-function-context.sh @@ -3,90 +3,180 @@ test_description='diff function context' . ./test-lib.sh -. "$TEST_DIRECTORY"/diff-lib.sh +dir="$TEST_DIRECTORY/t4051" -cat <<\EOF >hello.c -#include <stdio.h> - -static int a(void) -{ - /* - * Dummy. - */ +commit_and_tag () { + tag=$1 && + shift && + git add "$@" && + test_tick && + git commit -m "$tag" && + git tag "$tag" } -static int hello_world(void) -{ - /* Classic. */ - printf("Hello world.\n"); - - /* Success! */ - return 0; +first_context_line () { + awk ' + found {print; exit} + /^@@/ {found = 1} + ' } -static int b(void) -{ - /* - * Dummy, too. - */ + +last_context_line () { + sed -ne \$p } -int main(int argc, char **argv) -{ - a(); - b(); - return hello_world(); +check_diff () { + name=$1 + desc=$2 + options="-W $3" + + test_expect_success "$desc" ' + git diff $options "$name^" "$name" >"$name.diff" + ' + + test_expect_success ' diff applies' ' + test_when_finished "git reset --hard" && + git checkout --detach "$name^" && + git apply --index "$name.diff" && + git diff --exit-code "$name" + ' } -EOF test_expect_success 'setup' ' - git add hello.c && - test_tick && - git commit -m initial && - - grep -v Classic <hello.c >hello.c.new && - mv hello.c.new hello.c -' - -cat <<\EOF >expected -diff --git a/hello.c b/hello.c ---- a/hello.c -+++ b/hello.c -@@ -10,8 +10,7 @@ static int a(void) - static int hello_world(void) - { -- /* Classic. */ - printf("Hello world.\n"); - - /* Success! */ - return 0; - } -EOF - -test_expect_success 'diff -U0 -W' ' - git diff -U0 -W >actual && - compare_diff_patch actual expected -' - -cat <<\EOF >expected -diff --git a/hello.c b/hello.c ---- a/hello.c -+++ b/hello.c -@@ -9,9 +9,8 @@ static int a(void) - - static int hello_world(void) - { -- /* Classic. */ - printf("Hello world.\n"); - - /* Success! */ - return 0; - } -EOF - -test_expect_success 'diff -W' ' - git diff -W >actual && - compare_diff_patch actual expected + cat "$dir/includes.c" "$dir/dummy.c" "$dir/dummy.c" "$dir/hello.c" \ + "$dir/dummy.c" "$dir/dummy.c" >file.c && + commit_and_tag initial file.c && + + grep -v "delete me from hello" <file.c >file.c.new && + mv file.c.new file.c && + commit_and_tag changed_hello file.c && + + grep -v "delete me from includes" <file.c >file.c.new && + mv file.c.new file.c && + commit_and_tag changed_includes file.c && + + cat "$dir/appended1.c" >>file.c && + commit_and_tag appended file.c && + + cat "$dir/appended2.c" >>file.c && + commit_and_tag extended file.c && + + grep -v "Begin of second part" <file.c >file.c.new && + mv file.c.new file.c && + commit_and_tag long_common_tail file.c && + + git checkout initial && + grep -v "delete me from hello" <file.c >file.c.new && + mv file.c.new file.c && + cat "$dir/appended1.c" >>file.c && + commit_and_tag changed_hello_appended file.c +' + +check_diff changed_hello 'changed function' + +test_expect_success ' context includes begin' ' + grep "^ .*Begin of hello" changed_hello.diff +' + +test_expect_success ' context includes end' ' + grep "^ .*End of hello" changed_hello.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" changed_hello.diff) -le 1 +' + +test_expect_success ' context does not include preceding empty lines' ' + test "$(first_context_line <changed_hello.diff)" != " " +' + +test_expect_success ' context does not include trailing empty lines' ' + test "$(last_context_line <changed_hello.diff)" != " " +' + +check_diff changed_includes 'changed includes' + +test_expect_success ' context includes begin' ' + grep "^ .*Begin.h" changed_includes.diff +' + +test_expect_success ' context includes end' ' + grep "^ .*End.h" changed_includes.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" changed_includes.diff) -le 1 +' + +test_expect_success ' context does not include trailing empty lines' ' + test "$(last_context_line <changed_includes.diff)" != " " +' + +check_diff appended 'appended function' + +test_expect_success ' context includes begin' ' + grep "^[+].*Begin of first part" appended.diff +' + +test_expect_success ' context includes end' ' + grep "^[+].*End of first part" appended.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" appended.diff) -le 1 +' + +check_diff extended 'appended function part' + +test_expect_success ' context includes begin' ' + grep "^ .*Begin of first part" extended.diff +' + +test_expect_success ' context includes end' ' + grep "^[+].*End of second part" extended.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" extended.diff) -le 2 +' + +test_expect_success ' context does not include preceding empty lines' ' + test "$(first_context_line <extended.diff)" != " " +' + +check_diff long_common_tail 'change with long common tail and no context' -U0 + +test_expect_success ' context includes begin' ' + grep "^ .*Begin of first part" long_common_tail.diff +' + +test_expect_success ' context includes end' ' + grep "^ .*End of second part" long_common_tail.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" long_common_tail.diff) -le 2 +' + +test_expect_success ' context does not include preceding empty lines' ' + test "$(first_context_line <long_common_tail.diff.diff)" != " " +' + +check_diff changed_hello_appended 'changed function plus appended function' + +test_expect_success ' context includes begin' ' + grep "^ .*Begin of hello" changed_hello_appended.diff && + grep "^[+].*Begin of first part" changed_hello_appended.diff +' + +test_expect_success ' context includes end' ' + grep "^ .*End of hello" changed_hello_appended.diff && + grep "^[+].*End of first part" changed_hello_appended.diff +' + +test_expect_success ' context does not include other functions' ' + test $(grep -c "^[ +-].*Begin" changed_hello_appended.diff) -le 2 ' test_done diff --git a/t/t4051/appended1.c b/t/t4051/appended1.c new file mode 100644 index 0000000000..a9f56f11db --- /dev/null +++ b/t/t4051/appended1.c @@ -0,0 +1,15 @@ + +int appended(void) // Begin of first part +{ + int i; + char *s = "a string"; + + printf("%s\n", s); + + for (i = 99; + i >= 0; + i--) { + printf("%d bottles of beer on the wall\n", i); + } + + printf("End of first part\n"); diff --git a/t/t4051/appended2.c b/t/t4051/appended2.c new file mode 100644 index 0000000000..e651f7147b --- /dev/null +++ b/t/t4051/appended2.c @@ -0,0 +1,35 @@ + printf("Begin of second part\n"); + + /* + * Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, + * sed diam nonumy eirmod tempor invidunt ut labore et dolore + * magna aliquyam erat, sed diam voluptua. At vero eos et + * accusam et justo duo dolores et ea rebum. Stet clita kasd + * gubergren, no sea takimata sanctus est Lorem ipsum dolor + * sit amet. + * + * Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, + * sed diam nonumy eirmod tempor invidunt ut labore et dolore + * magna aliquyam erat, sed diam voluptua. At vero eos et + * accusam et justo duo dolores et ea rebum. Stet clita kasd + * gubergren, no sea takimata sanctus est Lorem ipsum dolor + * sit amet. + * + * Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, + * sed diam nonumy eirmod tempor invidunt ut labore et dolore + * magna aliquyam erat, sed diam voluptua. At vero eos et + * accusam et justo duo dolores et ea rebum. Stet clita kasd + * gubergren, no sea takimata sanctus est Lorem ipsum dolor + * sit amet. + * + * Lorem ipsum dolor sit amet, consectetuer sadipscing elitr, + * sed diam nonumy eirmod tempor invidunt ut labore et dolore + * magna aliquyam erat, sed diam voluptua. At vero eos et + * accusam et justo duo dolores et ea rebum. Stet clita kasd + * gubergren, no sea takimata sanctus est Lorem ipsum dolor + * sit amet. + * + */ + + return 0; +} // End of second part diff --git a/t/t4051/dummy.c b/t/t4051/dummy.c new file mode 100644 index 0000000000..a43016e870 --- /dev/null +++ b/t/t4051/dummy.c @@ -0,0 +1,7 @@ + +static int dummy(void) // Begin of dummy +{ + int rc = 0; + + return rc; +} // End of dummy diff --git a/t/t4051/hello.c b/t/t4051/hello.c new file mode 100644 index 0000000000..63b1a1e4ef --- /dev/null +++ b/t/t4051/hello.c @@ -0,0 +1,21 @@ + +static void hello(void) // Begin of hello +{ + /* + * Classic. + */ + putchar('H'); + putchar('e'); + putchar('l'); + putchar('l'); + putchar('o'); + putchar(' '); + /* delete me from hello */ + putchar('w'); + putchar('o'); + putchar('r'); + putchar('l'); + putchar('d'); + putchar('.'); + putchar('\n'); +} // End of hello diff --git a/t/t4051/includes.c b/t/t4051/includes.c new file mode 100644 index 0000000000..efc68f8bf6 --- /dev/null +++ b/t/t4051/includes.c @@ -0,0 +1,20 @@ +#include <Begin.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdarg.h> +/* delete me from includes */ +#include <string.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/time.h> +#include <time.h> +#include <signal.h> +#include <assert.h> +#include <regex.h> +#include <utime.h> +#include <syslog.h> +#include <End.h> diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh index ea5ace99a1..9473c2779e 100755 --- a/t/t4151-am-abort.sh +++ b/t/t4151-am-abort.sh @@ -82,7 +82,7 @@ test_expect_success 'am -3 --abort removes otherfile-4' ' test 4 = "$(cat otherfile-4)" && git am --abort && test_cmp_rev initial HEAD && - test -z $(git ls-files -u) && + test -z "$(git ls-files -u)" && test_path_is_missing otherfile-4 ' diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh index baa9d3c82e..84a809690e 100755 --- a/t/t4204-patch-id.sh +++ b/t/t4204-patch-id.sh @@ -30,11 +30,11 @@ test_expect_success 'patch-id output is well-formed' ' #calculate patch id. Make sure output is not empty. calc_patch_id () { - name="$1" + patch_name="$1" shift git patch-id "$@" | - sed "s/ .*//" >patch-id_"$name" && - test_line_count -gt 0 patch-id_"$name" + sed "s/ .*//" >patch-id_"$patch_name" && + test_line_count -gt 0 patch-id_"$patch_name" } get_top_diff () { diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index d446706e94..3893afd687 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -47,6 +47,12 @@ rev_list_tests() { test_cmp expect actual ' + test_expect_success "counting commits with limit ($state)" ' + git rev-list --count -n 1 HEAD >expect && + git rev-list --use-bitmap-index --count -n 1 HEAD >actual && + test_cmp expect actual + ' + test_expect_success "counting non-linear history ($state)" ' git rev-list --count other...master >expect && git rev-list --use-bitmap-index --count other...master >actual && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 91a69fc33a..82d913a6a8 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -558,7 +558,6 @@ check_prot_path () { } check_prot_host_port_path () { - local diagport case "$2" in *ssh*) pp=ssh diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 739c089d50..3159956fde 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -341,6 +341,22 @@ test_expect_success 'branch.to-rebase.rebase should override pull.rebase' ' test new = "$(git show HEAD:file2)" ' +test_expect_success "pull --rebase warns on --verify-signatures" ' + git reset --hard before-rebase && + git pull --rebase --verify-signatures . copy 2>err && + test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" && + test new = "$(git show HEAD:file2)" && + test_i18ngrep "ignoring --verify-signatures for rebase" err +' + +test_expect_success "pull --rebase does not warn on --no-verify-signatures" ' + git reset --hard before-rebase && + git pull --rebase --no-verify-signatures . copy 2>err && + test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" && + test new = "$(git show HEAD:file2)" && + test_i18ngrep ! "verify-signatures" err +' + # add a feature branch, keep-merge, that is merged into master, so the # test can try preserving the merge commit (or not) with various # --rebase flags/pull.rebase settings. diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index e44fe72c7a..2f375eb94d 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -283,10 +283,20 @@ test_expect_success EXPENSIVE 'http can handle enormous ref negotiation' ' ' test_expect_success 'custom http headers' ' - test_must_fail git fetch "$HTTPD_URL/smart_headers/repo.git" && + test_must_fail git -c http.extraheader="x-magic-two: cadabra" \ + fetch "$HTTPD_URL/smart_headers/repo.git" && git -c http.extraheader="x-magic-one: abra" \ -c http.extraheader="x-magic-two: cadabra" \ - fetch "$HTTPD_URL/smart_headers/repo.git" + fetch "$HTTPD_URL/smart_headers/repo.git" && + git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub && + git config -f .gitmodules submodule.sub.path sub && + git config -f .gitmodules submodule.sub.url \ + "$HTTPD_URL/smart_headers/repo.git" && + git submodule init sub && + test_must_fail git submodule update sub && + git -c http.extraheader="x-magic-one: abra" \ + -c http.extraheader="x-magic-two: cadabra" \ + submodule update sub ' stop_httpd diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 150aeaf713..a433394200 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -466,7 +466,7 @@ test_expect_success 'clone ssh://host.xz:22/~repo' ' #IPv6 for tuah in ::1 [::1] [::1]: user@::1 user@[::1] user@[::1]: [user@::1] [user@::1]: do - ehost=$(echo $tuah | sed -e "s/1]:/1]/ "| tr -d "[]") + ehost=$(echo $tuah | sed -e "s/1]:/1]/" | tr -d "[]") test_expect_success "clone ssh://$tuah/home/user/repo" " test_clone_url ssh://$tuah/home/user/repo $ehost /home/user/repo " diff --git a/t/t5611-clone-config.sh b/t/t5611-clone-config.sh index 27d730c0a7..e4850b778c 100755 --- a/t/t5611-clone-config.sh +++ b/t/t5611-clone-config.sh @@ -37,4 +37,24 @@ test_expect_success 'clone -c config is available during clone' ' test_cmp expect child/file ' +# Tests for the hidden file attribute on windows +is_hidden () { + # Use the output of `attrib`, ignore the absolute path + case "$(attrib "$1")" in *H*?:*) return 0;; esac + return 1 +} + +test_expect_success MINGW 'clone -c core.hideDotFiles' ' + test_commit attributes .gitattributes "" && + rm -rf child && + git clone -c core.hideDotFiles=false . child && + ! is_hidden child/.gitattributes && + rm -rf child && + git clone -c core.hideDotFiles=dotGitOnly . child && + ! is_hidden child/.gitattributes && + rm -rf child && + git clone -c core.hideDotFiles=true . child && + is_hidden child/.gitattributes +' + test_done diff --git a/t/t5614-clone-submodules.sh b/t/t5614-clone-submodules.sh index 62044c5a02..32d83e2694 100755 --- a/t/t5614-clone-submodules.sh +++ b/t/t5614-clone-submodules.sh @@ -82,4 +82,56 @@ test_expect_success 'non shallow clone with shallow submodule' ' ) ' +test_expect_success 'clone follows shallow recommendation' ' + test_when_finished "rm -rf super_clone" && + git config -f .gitmodules submodule.sub.shallow true && + git add .gitmodules && + git commit -m "recommed shallow for sub" && + git clone --recurse-submodules --no-local "file://$pwd/." super_clone && + ( + cd super_clone && + git log --oneline >lines && + test_line_count = 4 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 1 lines + ) +' + +test_expect_success 'get unshallow recommended shallow submodule' ' + test_when_finished "rm -rf super_clone" && + git clone --no-local "file://$pwd/." super_clone && + ( + cd super_clone && + git submodule update --init --no-recommend-shallow && + git log --oneline >lines && + test_line_count = 4 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 3 lines + ) +' + +test_expect_success 'clone follows non shallow recommendation' ' + test_when_finished "rm -rf super_clone" && + git config -f .gitmodules submodule.sub.shallow false && + git add .gitmodules && + git commit -m "recommed non shallow for sub" && + git clone --recurse-submodules --no-local "file://$pwd/." super_clone && + ( + cd super_clone && + git log --oneline >lines && + test_line_count = 5 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 3 lines + ) +' + test_done diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index b77d4c97c1..a1dcdb81d7 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -184,38 +184,38 @@ commit $head1 [1;31;43mfoo[m EOF -test_expect_success '%C(auto) does not enable color by default' ' +test_expect_success '%C(auto,...) does not enable color by default' ' git log --format=$AUTO_COLOR -1 >actual && has_no_color actual ' -test_expect_success '%C(auto) enables colors for color.diff' ' +test_expect_success '%C(auto,...) enables colors for color.diff' ' git -c color.diff=always log --format=$AUTO_COLOR -1 >actual && has_color actual ' -test_expect_success '%C(auto) enables colors for color.ui' ' +test_expect_success '%C(auto,...) enables colors for color.ui' ' git -c color.ui=always log --format=$AUTO_COLOR -1 >actual && has_color actual ' -test_expect_success '%C(auto) respects --color' ' +test_expect_success '%C(auto,...) respects --color' ' git log --format=$AUTO_COLOR -1 --color >actual && has_color actual ' -test_expect_success '%C(auto) respects --no-color' ' +test_expect_success '%C(auto,...) respects --no-color' ' git -c color.ui=always log --format=$AUTO_COLOR -1 --no-color >actual && has_no_color actual ' -test_expect_success TTY '%C(auto) respects --color=auto (stdout is tty)' ' +test_expect_success TTY '%C(auto,...) respects --color=auto (stdout is tty)' ' test_terminal env TERM=vt100 \ git log --format=$AUTO_COLOR -1 --color=auto >actual && has_color actual ' -test_expect_success '%C(auto) respects --color=auto (stdout not tty)' ' +test_expect_success '%C(auto,...) respects --color=auto (stdout not tty)' ' ( TERM=vt100 && export TERM && git log --format=$AUTO_COLOR -1 --color=auto >actual && @@ -223,6 +223,18 @@ test_expect_success '%C(auto) respects --color=auto (stdout not tty)' ' ) ' +test_expect_success '%C(auto) respects --color' ' + git log --color --format="%C(auto)%H" -1 >actual && + printf "\\033[33m%s\\033[m\\n" $(git rev-parse HEAD) >expect && + test_cmp expect actual +' + +test_expect_success '%C(auto) respects --no-color' ' + git log --no-color --format="%C(auto)%H" -1 >actual && + git rev-parse HEAD >expect && + test_cmp expect actual +' + iconv -f utf-8 -t $test_encoding > commit-msg <<EOF Test printing of complex bodies diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh index 755d30ce2a..3f59e58dfb 100755 --- a/t/t6024-recursive-merge.sh +++ b/t/t6024-recursive-merge.sh @@ -76,7 +76,7 @@ test_expect_success "result contains a conflict" "test_cmp expect a1" git ls-files --stage > out cat > expect << EOF -100644 439cc46de773d8a83c77799b7cc9191c128bfcff 1 a1 +100644 ec3fe2a791706733f2d8fa7ad45d9a9672031f5e 1 a1 100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1 100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1 EOF diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index 9d6621c056..18aa88b5c0 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -212,7 +212,8 @@ test_expect_success 'git detects differently handled merges conflict' ' -L "" \ -L "Temporary merge branch 1" \ merged empty merge-me && - test $(git rev-parse :1:new_a) = $(git hash-object merged) + sed -e "s/^\([<=>]\)/\1\1\1/" merged >merged-internal && + test $(git rev-parse :1:new_a) = $(git hash-object merged-internal) ' # @@ -299,89 +300,6 @@ test_expect_success 'git detects conflict merging criss-cross+modify/delete, rev ' # -# criss-cross + modify/modify with very contrived file contents: -# -# B D -# o---o -# / \ / \ -# A o X ? F -# \ / \ / -# o---o -# C E -# -# Commit A: file with contents 'A\n' -# Commit B: file with contents 'B\n' -# Commit C: file with contents 'C\n' -# Commit D: file with contents 'D\n' -# Commit E: file with contents: -# <<<<<<< Temporary merge branch 1 -# C -# ======= -# B -# >>>>>>> Temporary merge branch 2 -# -# Now, when we merge commits D & E, does git detect the conflict? - -test_expect_success 'setup differently handled merges of content conflict' ' - git clean -fdqx && - rm -rf .git && - git init && - - echo A >file && - git add file && - test_tick && - git commit -m A && - - git branch B && - git checkout -b C && - echo C >file && - git add file && - test_tick && - git commit -m C && - - git checkout B && - echo B >file && - git add file && - test_tick && - git commit -m B && - - git checkout B^0 && - test_must_fail git merge C && - echo D >file && - git add file && - test_tick && - git commit -m D && - git tag D && - - git checkout C^0 && - test_must_fail git merge B && - cat <<EOF >file && -<<<<<<< Temporary merge branch 1 -C -======= -B ->>>>>>> Temporary merge branch 2 -EOF - git add file && - test_tick && - git commit -m E && - git tag E -' - -test_expect_failure 'git detects conflict w/ criss-cross+contrived resolution' ' - git checkout D^0 && - - test_must_fail git merge -s recursive E^0 && - - test 3 -eq $(git ls-files -s | wc -l) && - test 3 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && - - test $(git rev-parse :2:file) = $(git rev-parse D:file) && - test $(git rev-parse :3:file) = $(git rev-parse E:file) -' - -# # criss-cross + d/f conflict via add/add: # Commit A: Neither file 'a' nor directory 'a/' exists. # Commit B: Introduce 'a' diff --git a/t/t6044-merge-unrelated-index-changes.sh b/t/t6044-merge-unrelated-index-changes.sh index 20a3ffed69..01023486c5 100755 --- a/t/t6044-merge-unrelated-index-changes.sh +++ b/t/t6044-merge-unrelated-index-changes.sh @@ -20,7 +20,7 @@ test_description="merges with unrelated index changes" # Commit E: renames a->subdir/a, adds subdir/e test_expect_success 'setup trivial merges' ' - seq 1 10 >a && + test_seq 1 10 >a && git add a && test_tick && git commit -m A && @@ -42,7 +42,7 @@ test_expect_success 'setup trivial merges' ' test_tick && git commit -m C && git checkout D && - seq 2 10 >a && + test_seq 2 10 >a && echo d >d && git add a d && test_tick && git commit -m D && diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index 70afb44271..d0ab09f4bd 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -5,15 +5,6 @@ test_description='test for-each-refs usage of ref-filter APIs' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh -test_prepare_expect () { - if test_have_prereq GPG - then - cat - else - sed '/signed/d' - fi -} - test_expect_success 'setup some history and refs' ' test_commit one && test_commit two && @@ -22,11 +13,19 @@ test_expect_success 'setup some history and refs' ' test_commit four && git tag -m "An annotated tag" annotated-tag && git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag && + + # Note that these "signed" tags might not actually be signed. + # Tests which care about the distinction should be marked + # with the GPG prereq. if test_have_prereq GPG then - git tag -s -m "A signed tag" signed-tag && - git tag -s -m "Signed doubly" doubly-signed-tag signed-tag + sign=-s + else + sign= fi && + git tag $sign -m "A signed tag" signed-tag && + git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag && + git checkout master && git update-ref refs/odd/spot master ' @@ -42,7 +41,7 @@ test_expect_success 'filtering with --points-at' ' ' test_expect_success 'check signed tags with --points-at' ' - test_prepare_expect <<-\EOF | sed -e "s/Z$//" >expect && + sed -e "s/Z$//" >expect <<-\EOF && refs/heads/side Z refs/tags/annotated-tag four refs/tags/four Z @@ -65,7 +64,7 @@ test_expect_success 'filtering with --merged' ' ' test_expect_success 'filtering with --no-merged' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && refs/heads/side refs/tags/annotated-tag refs/tags/doubly-annotated-tag @@ -78,7 +77,7 @@ test_expect_success 'filtering with --no-merged' ' ' test_expect_success 'filtering with --contains' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && refs/heads/master refs/heads/side refs/odd/spot @@ -99,7 +98,7 @@ test_expect_success '%(color) must fail' ' ' test_expect_success 'left alignment is default' ' - test_prepare_expect >expect <<-\EOF && + 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 @@ -117,7 +116,7 @@ test_expect_success 'left alignment is default' ' ' test_expect_success 'middle alignment' ' - test_prepare_expect >expect <<-\EOF && + 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 @@ -135,7 +134,7 @@ test_expect_success 'middle alignment' ' ' test_expect_success 'right alignment' ' - test_prepare_expect >expect <<-\EOF && + 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 @@ -152,7 +151,7 @@ test_expect_success 'right alignment' ' test_cmp expect actual ' -test_prepare_expect >expect <<-\EOF +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 @@ -199,7 +198,7 @@ EOF # Individual atoms inside %(align:...) and %(end) must not be quoted. test_expect_success 'alignment with format quote' " - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && |' '\''master| A U Thor'\'' '| |' '\''side| A U Thor'\'' '| |' '\''odd/spot| A U Thor'\'' '| @@ -217,7 +216,7 @@ test_expect_success 'alignment with format quote' " " test_expect_success 'nested alignment with quote formatting' " - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && |' master '| |' side '| |' odd/spot '| @@ -235,7 +234,7 @@ test_expect_success 'nested alignment with quote formatting' " " test_expect_success 'check `%(contents:lines=1)`' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && master |three side |four odd/spot |three @@ -253,7 +252,7 @@ test_expect_success 'check `%(contents:lines=1)`' ' ' test_expect_success 'check `%(contents:lines=0)`' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && master | side | odd/spot | @@ -271,7 +270,7 @@ test_expect_success 'check `%(contents:lines=0)`' ' ' test_expect_success 'check `%(contents:lines=99999)`' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && master |three side |four odd/spot |three diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh index 79bc135bf6..5503ec067f 100755 --- a/t/t7403-submodule-sync.sh +++ b/t/t7403-submodule-sync.sh @@ -62,13 +62,13 @@ test_expect_success 'change submodule' ' ' reset_submodule_urls () { - local root - root=$(pwd) && ( + root=$(pwd) && cd super-clone/submodule && git config remote.origin.url "$root/submodule" ) && ( + root=$(pwd) && cd super-clone/submodule/sub-submodule && git config remote.origin.url "$root/submodule" ) diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index 900f7de05a..d84897a67a 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -607,4 +607,24 @@ test_expect_success '--only works on to-be-born branch' ' test_cmp expected actual ' +test_expect_success '--dry-run with conflicts fixed from a merge' ' + # setup two branches with conflicting information + # in the same file, resolve the conflict, + # call commit with --dry-run + echo "Initial contents, unimportant" >test-file && + git add test-file && + git commit -m "Initial commit" && + echo "commit-1-state" >test-file && + git commit -m "commit 1" -i test-file && + git tag commit-1 && + git checkout -b branch-2 HEAD^1 && + echo "commit-2-state" >test-file && + git commit -m "commit 2" -i test-file && + ! $(git merge --no-commit commit-1) && + echo "commit-2-state" >test-file && + git add test-file && + git commit --dry-run && + git commit -m "conflicts fixed from merge." +' + test_done diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh index 2ddf28c984..ed2653d46f 100755 --- a/t/t7507-commit-verbose.sh +++ b/t/t7507-commit-verbose.sh @@ -3,11 +3,10 @@ test_description='verbose commit template' . ./test-lib.sh -cat >check-for-diff <<EOF -#!$SHELL_PATH -exec grep '^diff --git' "\$1" +write_script "check-for-diff" <<\EOF && +grep '^diff --git' "$1" >out +exit 0 EOF -chmod +x check-for-diff test_set_editor "$PWD/check-for-diff" cat >message <<'EOF' @@ -23,7 +22,8 @@ test_expect_success 'setup' ' ' test_expect_success 'initial commit shows verbose diff' ' - git commit --amend -v + git commit --amend -v && + test_line_count = 1 out ' test_expect_success 'second commit' ' @@ -39,13 +39,15 @@ check_message() { test_expect_success 'verbose diff is stripped out' ' git commit --amend -v && - check_message message + check_message message && + test_line_count = 1 out ' test_expect_success 'verbose diff is stripped out (mnemonicprefix)' ' git config diff.mnemonicprefix true && git commit --amend -v && - check_message message + check_message message && + test_line_count = 1 out ' cat >diff <<'EOF' @@ -96,4 +98,60 @@ test_expect_success 'verbose diff is stripped out with set core.commentChar' ' test_i18ngrep "Aborting commit due to empty commit message." err ' +test_expect_success 'status does not verbose without --verbose' ' + git status >actual && + ! grep "^diff --git" actual +' + +test_expect_success 'setup -v -v' ' + echo dirty >file +' + +for i in true 1 +do + test_expect_success "commit.verbose=$i and --verbose omitted" " + git -c commit.verbose=$i commit --amend && + test_line_count = 1 out + " +done + +for i in false -2 -1 0 +do + test_expect_success "commit.verbose=$i and --verbose omitted" " + git -c commit.verbose=$i commit --amend && + test_line_count = 0 out + " +done + +for i in 2 3 +do + test_expect_success "commit.verbose=$i and --verbose omitted" " + git -c commit.verbose=$i commit --amend && + test_line_count = 2 out + " +done + +for i in true false -2 -1 0 1 2 3 +do + test_expect_success "commit.verbose=$i and --verbose" " + git -c commit.verbose=$i commit --amend --verbose && + test_line_count = 1 out + " + + test_expect_success "commit.verbose=$i and --no-verbose" " + git -c commit.verbose=$i commit --amend --no-verbose && + test_line_count = 0 out + " + + test_expect_success "commit.verbose=$i and -v -v" " + git -c commit.verbose=$i commit --amend -v -v && + test_line_count = 2 out + " +done + +test_expect_success "status ignores commit.verbose=true" ' + git -c commit.verbose=true status >actual && + ! grep "^diff --git actual" +' + test_done diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index ff7a9e968f..7ce4cd753e 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -419,6 +419,29 @@ run_dir_diff_test 'difftool --dir-diff when worktree file is missing' ' grep file2 output ' +run_dir_diff_test 'difftool --dir-diff with unmerged files' ' + test_when_finished git reset --hard && + test_config difftool.echo.cmd "echo ok" && + git checkout -B conflict-a && + git checkout -B conflict-b && + git checkout conflict-a && + echo a >>file && + git add file && + git commit -m conflict-a && + git checkout conflict-b && + echo b >>file && + git add file && + git commit -m conflict-b && + git checkout master && + git merge conflict-a && + test_must_fail git merge conflict-b && + cat >expect <<-EOF && + ok + EOF + git difftool --dir-diff $symlinks -t echo >actual && + test_cmp expect actual +' + write_script .git/CHECK_SYMLINKS <<\EOF for f in file file2 sub/sub do diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 1e72971a16..960425a4ec 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -9,7 +9,9 @@ test_description='git grep various. . ./test-lib.sh cat >hello.c <<EOF +#include <assert.h> #include <stdio.h> + int main(int argc, const char **argv) { printf("Hello world.\n"); @@ -715,6 +717,7 @@ test_expect_success 'grep -p' ' cat >expected <<EOF hello.c-#include <stdio.h> +hello.c- hello.c=int main(int argc, const char **argv) hello.c-{ hello.c- printf("Hello world.\n"); @@ -741,6 +744,16 @@ test_expect_success 'grep -W' ' ' cat >expected <<EOF +hello.c-#include <assert.h> +hello.c:#include <stdio.h> +EOF + +test_expect_success 'grep -W shows no trailing empty lines' ' + git grep -W stdio >actual && + test_cmp expected actual +' + +cat >expected <<EOF hello.c= printf("Hello world.\n"); hello.c: return 0; hello.c- /* char ?? */ @@ -1232,8 +1245,8 @@ test_expect_success 'grep --heading' ' cat >expected <<EOF <BOLD;GREEN>hello.c<RESET> -2:int main(int argc, const <BLACK;BYELLOW>char<RESET> **argv) -6: /* <BLACK;BYELLOW>char<RESET> ?? */ +4:int main(int argc, const <BLACK;BYELLOW>char<RESET> **argv) +8: /* <BLACK;BYELLOW>char<RESET> ?? */ <BOLD;GREEN>hello_world<RESET> 3:Hel<BLACK;BYELLOW>lo_w<RESET>orld @@ -1340,7 +1353,7 @@ test_expect_success 'grep --color -e A --and --not -e B with context' ' ' cat >expected <<EOF -hello.c-#include <stdio.h> +hello.c- hello.c=int main(int argc, const char **argv) hello.c-{ hello.c: pr<RED>int<RESET>f("<RED>Hello<RESET> world.\n"); diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index 22d8367ff3..28082b134f 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -45,13 +45,13 @@ test_expect_success "checkout from svn" 'svn co "$svnrepo" "$SVN_TREE"' name='try a deep --rmdir with a commit' test_expect_success "$name" ' - git checkout -f -b mybranch ${remotes_git_svn} && + git checkout -f -b mybranch remotes/git-svn && mv dir/a/b/c/d/e/file dir/file && cp dir/file file && git update-index --add --remove dir/a/b/c/d/e/file dir/file file && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch && + remotes/git-svn..mybranch && svn_cmd up "$SVN_TREE" && test -d "$SVN_TREE"/dir && test ! -d "$SVN_TREE"/dir/a' @@ -65,14 +65,14 @@ test_expect_success "$name" " git update-index --add dir/file/file && git commit -m '$name' && test_must_fail git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch + remotes/git-svn..mybranch " name='detect node change from directory to file #1' test_expect_success "$name" ' rm -rf dir "$GIT_DIR"/index && - git checkout -f -b mybranch2 ${remotes_git_svn} && + git checkout -f -b mybranch2 remotes/git-svn && mv bar/zzz zzz && rm -rf bar && mv zzz bar && @@ -80,14 +80,14 @@ test_expect_success "$name" ' git update-index --add -- bar && git commit -m "$name" && test_must_fail git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch2 + remotes/git-svn..mybranch2 ' name='detect node change from file to directory #2' test_expect_success "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch3 ${remotes_git_svn} && + git checkout -f -b mybranch3 remotes/git-svn && rm bar/zzz && git update-index --remove bar/zzz && mkdir bar/zzz && @@ -95,7 +95,7 @@ test_expect_success "$name" ' git update-index --add bar/zzz/yyy && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch3 && + remotes/git-svn..mybranch3 && svn_cmd up "$SVN_TREE" && test -d "$SVN_TREE"/bar/zzz && test -e "$SVN_TREE"/bar/zzz/yyy @@ -104,7 +104,7 @@ test_expect_success "$name" ' name='detect node change from directory to file #2' test_expect_success "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch4 ${remotes_git_svn} && + git checkout -f -b mybranch4 remotes/git-svn && rm -rf dir && git update-index --remove -- dir/file && touch dir && @@ -112,19 +112,19 @@ test_expect_success "$name" ' git update-index --add -- dir && git commit -m "$name" && test_must_fail git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch4 + remotes/git-svn..mybranch4 ' name='remove executable bit from a file' test_expect_success POSIXPERM "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch5 ${remotes_git_svn} && + git checkout -f -b mybranch5 remotes/git-svn && chmod -x exec.sh && git update-index exec.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test ! -x "$SVN_TREE"/exec.sh' @@ -135,7 +135,7 @@ test_expect_success POSIXPERM "$name" ' git update-index exec.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test -x "$SVN_TREE"/exec.sh' @@ -147,7 +147,7 @@ test_expect_success SYMLINKS "$name" ' git update-index exec.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test -h "$SVN_TREE"/exec.sh' @@ -159,7 +159,7 @@ test_expect_success POSIXPERM,SYMLINKS "$name" ' git update-index --add file exec-2.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test -x "$SVN_TREE"/file && test -h "$SVN_TREE"/exec-2.sh' @@ -172,7 +172,7 @@ test_expect_success POSIXPERM,SYMLINKS "$name" ' git update-index exec-2.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test -f "$SVN_TREE"/exec-2.sh && test ! -h "$SVN_TREE"/exec-2.sh && @@ -194,7 +194,7 @@ GIT_SVN_ID=alt export GIT_SVN_ID test_expect_success "$name" \ 'git svn init "$svnrepo" && git svn fetch && - git rev-list --pretty=raw ${remotes_git_svn} | grep ^tree | uniq > a && + git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a && git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b && test_cmp a b' @@ -217,17 +217,17 @@ EOF test_expect_success POSIXPERM,SYMLINKS "$name" "test_cmp a expected" -test_expect_success 'exit if remote refs are ambigious' " +test_expect_success 'exit if remote refs are ambigious' ' git config --add svn-remote.svn.fetch \ - bar:refs/${remotes_git_svn} && + bar:refs/remotes/git-svn && test_must_fail git svn migrate -" +' test_expect_success 'exit if init-ing a would clobber a URL' ' svnadmin create "${PWD}/svnrepo2" && svn mkdir -m "mkdir bar" "${svnrepo}2/bar" && git config --unset svn-remote.svn.fetch \ - "^bar:refs/${remotes_git_svn}$" && + "^bar:refs/remotes/git-svn$" && test_must_fail git svn init "${svnrepo}2/bar" ' @@ -237,7 +237,7 @@ test_expect_success \ git config --get svn-remote.svn.fetch \ "^bar:refs/remotes/bar$" && git config --get svn-remote.svn.fetch \ - "^:refs/${remotes_git_svn}$" + "^:refs/remotes/git-svn$" ' test_expect_success 'dcommit $rev does not clobber current branch' ' @@ -259,26 +259,26 @@ test_expect_success 'dcommit $rev does not clobber current branch' ' git branch -D my-bar ' -test_expect_success 'able to dcommit to a subdirectory' " +test_expect_success 'able to dcommit to a subdirectory' ' git svn fetch -i bar && git checkout -b my-bar refs/remotes/bar && echo abc > d && git update-index --add d && - git commit -m '/bar/d should be in the log' && + git commit -m "/bar/d should be in the log" && git svn dcommit -i bar && - test -z \"\$(git diff refs/heads/my-bar refs/remotes/bar)\" && + test -z "$(git diff refs/heads/my-bar refs/remotes/bar)" && mkdir newdir && echo new > newdir/dir && git update-index --add newdir/dir && - git commit -m 'add a new directory' && + git commit -m "add a new directory" && git svn dcommit -i bar && - test -z \"\$(git diff refs/heads/my-bar refs/remotes/bar)\" && + test -z "$(git diff refs/heads/my-bar refs/remotes/bar)" && echo foo >> newdir/dir && git update-index newdir/dir && - git commit -m 'modify a file in new directory' && + git commit -m "modify a file in new directory" && git svn dcommit -i bar && - test -z \"\$(git diff refs/heads/my-bar refs/remotes/bar)\" - " + test -z "$(git diff refs/heads/my-bar refs/remotes/bar)" +' test_expect_success 'dcommit should not fail with a touched file' ' test_commit "commit-new-file-foo2" foo2 && @@ -291,13 +291,13 @@ test_expect_success 'rebase should not fail with a touched file' ' git svn rebase ' -test_expect_success 'able to set-tree to a subdirectory' " +test_expect_success 'able to set-tree to a subdirectory' ' echo cba > d && git update-index d && - git commit -m 'update /bar/d' && + git commit -m "update /bar/d" && git svn set-tree -i bar HEAD && - test -z \"\$(git diff refs/heads/my-bar refs/remotes/bar)\" - " + test -z "$(git diff refs/heads/my-bar refs/remotes/bar)" +' test_expect_success 'git-svn works in a bare repository' ' mkdir bare-repo && diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index e8173d5fef..07bfb63777 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -73,11 +73,11 @@ test_expect_success 'fetch revisions from svn' 'git svn fetch' name='test svn:keywords ignoring' test_expect_success "$name" \ - 'git checkout -b mybranch ${remotes_git_svn} && + 'git checkout -b mybranch remotes/git-svn && echo Hi again >> kw.c && git commit -a -m "test keywords ignoring" && - git svn set-tree ${remotes_git_svn}..mybranch && - git pull . ${remotes_git_svn}' + git svn set-tree remotes/git-svn..mybranch && + git pull . remotes/git-svn' expect='/* $Id$ */' got="$(sed -ne 2p kw.c)" @@ -95,7 +95,7 @@ test_expect_success "propset CR on crlf files" ' test_expect_success 'fetch and pull latest from svn and checkout a new wc' \ 'git svn fetch && - git pull . ${remotes_git_svn} && + git pull . remotes/git-svn && svn_cmd co "$svnrepo" new_wc' for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf @@ -117,7 +117,7 @@ cd test_wc svn_cmd commit -m "propset CRLF on cr files"' cd .. test_expect_success 'fetch and pull latest from svn' \ - 'git svn fetch && git pull . ${remotes_git_svn}' + 'git svn fetch && git pull . remotes/git-svn' b_cr="$(git hash-object cr)" b_ne_cr="$(git hash-object ne_cr)" @@ -168,7 +168,7 @@ cat >create-ignore-index.expect <<\EOF EOF test_expect_success 'test create-ignore' " - git svn fetch && git pull . ${remotes_git_svn} && + git svn fetch && git pull . remotes/git-svn && git svn create-ignore && cmp ./.gitignore create-ignore.expect && cmp ./deeply/.gitignore create-ignore.expect && diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh index eb70f4839c..66cd51102c 100755 --- a/t/t9102-git-svn-deep-rmdir.sh +++ b/t/t9102-git-svn-deep-rmdir.sh @@ -17,7 +17,7 @@ test_expect_success 'initialize repo' ' test_expect_success 'mirror via git svn' ' git svn init "$svnrepo" && git svn fetch && - git checkout -f -b test-rmdir ${remotes_git_svn} + git checkout -f -b test-rmdir remotes/git-svn ' test_expect_success 'Try a commit on rmdir' ' diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh index 3413164cb1..b28271345c 100755 --- a/t/t9103-git-svn-tracked-directory-removed.sh +++ b/t/t9103-git-svn-tracked-directory-removed.sh @@ -23,17 +23,19 @@ test_expect_success 'make history for tracking' ' test_expect_success 'clone repo with git' ' git svn clone -s "$svnrepo" x && - test -f x/FOLLOWME && - test ! -f x/README + test_path_is_file x/FOLLOWME && + test_path_is_missing x/README ' -test_expect_success 'make sure r2 still has old file' " - cd x && - test -n \"\$(git svn find-rev r1)\" && - git reset --hard \$(git svn find-rev r1) && - test -f README && - test ! -f FOLLOWME && - test x\$(git svn find-rev r2) = x -" +test_expect_success 'make sure r2 still has old file' ' + ( + cd x && + test -n "$(git svn find-rev r1)" && + git reset --hard "$(git svn find-rev r1)" && + test_path_is_file README && + test_path_is_missing FOLLOWME && + test -z "$(git svn find-rev r2)" + ) +' test_done diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh index f6d7ac7c5f..dbe8deac0d 100755 --- a/t/t9106-git-svn-commit-diff-clobber.sh +++ b/t/t9106-git-svn-commit-diff-clobber.sh @@ -44,7 +44,7 @@ test_expect_success 'commit complementing change from git' ' test_expect_success 'dcommit fails to commit because of conflict' ' git svn init "$svnrepo" && git svn fetch && - git reset --hard refs/${remotes_git_svn} && + git reset --hard refs/remotes/git-svn && svn_cmd co "$svnrepo" t.svn && ( cd t.svn && @@ -59,7 +59,7 @@ test_expect_success 'dcommit fails to commit because of conflict' ' ' test_expect_success 'dcommit does the svn equivalent of an index merge' " - git reset --hard refs/${remotes_git_svn} && + git reset --hard refs/remotes/git-svn && echo 'index merge' > file2 && git update-index --add file2 && git commit -a -m 'index merge' && @@ -81,7 +81,7 @@ test_expect_success 'commit another change from svn side' ' ' test_expect_success 'multiple dcommit from git svn will not clobber svn' " - git reset --hard refs/${remotes_git_svn} && + git reset --hard refs/remotes/git-svn && echo new file >> new-file && git update-index --add new-file && git commit -a -m 'new file' && diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh index 9060198037..9f3ef8f2ef 100755 --- a/t/t9107-git-svn-migrate.sh +++ b/t/t9107-git-svn-migrate.sh @@ -19,13 +19,14 @@ test_expect_success 'setup old-looking metadata' ' git svn init "$svnrepo" && git svn fetch && rm -rf "$GIT_DIR"/svn && - git update-ref refs/heads/git-svn-HEAD refs/${remotes_git_svn} && - git update-ref refs/heads/svn-HEAD refs/${remotes_git_svn} && - git update-ref -d refs/${remotes_git_svn} refs/${remotes_git_svn} + git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn && + git update-ref refs/heads/svn-HEAD refs/remotes/git-svn && + git update-ref -d refs/remotes/git-svn refs/remotes/git-svn ' -head=$(git rev-parse --verify refs/heads/git-svn-HEAD^0) -test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'" +test_expect_success 'git-svn-HEAD is a real HEAD' ' + git rev-parse --verify refs/heads/git-svn-HEAD^0 +' svnrepo_escaped=$(echo $svnrepo | sed 's/ /%20/') @@ -35,11 +36,11 @@ test_expect_success 'initialize old-style (v0) git svn layout' ' echo "$svnrepo" > "$GIT_DIR"/svn/info/url && git svn migrate && ! test -d "$GIT_DIR"/git-svn && - git rev-parse --verify refs/${remotes_git_svn}^0 && + git rev-parse --verify refs/remotes/git-svn^0 && git rev-parse --verify refs/remotes/svn^0 && test "$(git config --get svn-remote.svn.url)" = "$svnrepo_escaped" && test $(git config --get svn-remote.svn.fetch) = \ - ":refs/${remotes_git_svn}" + ":refs/remotes/git-svn" ' test_expect_success 'initialize a multi-repository repo' ' @@ -56,9 +57,11 @@ test_expect_success 'initialize a multi-repository repo' ' "^tags/\*:refs/remotes/origin/tags/\*$" && git config --add svn-remote.svn.fetch "branches/a:refs/remotes/origin/a" && git config --add svn-remote.svn.fetch "branches/b:refs/remotes/origin/b" && - for i in tags/0.1 tags/0.2 tags/0.3; do + for i in tags/0.1 tags/0.2 tags/0.3 + do git config --add svn-remote.svn.fetch \ - $i:refs/remotes/origin/$i || exit 1; done && + $i:refs/remotes/origin/$i || return 1 + done && git config --get-all svn-remote.svn.fetch > fetch.out && grep "^trunk:refs/remotes/origin/trunk$" fetch.out && grep "^branches/a:refs/remotes/origin/a$" fetch.out && @@ -66,34 +69,42 @@ test_expect_success 'initialize a multi-repository repo' ' grep "^tags/0\.1:refs/remotes/origin/tags/0\.1$" fetch.out && grep "^tags/0\.2:refs/remotes/origin/tags/0\.2$" fetch.out && grep "^tags/0\.3:refs/remotes/origin/tags/0\.3$" fetch.out && - grep "^:refs/${remotes_git_svn}" fetch.out + grep "^:refs/remotes/git-svn" fetch.out ' # refs should all be different, but the trees should all be the same: -test_expect_success 'multi-fetch works on partial urls + paths' " +test_expect_success 'multi-fetch works on partial urls + paths' ' + refs="trunk a b tags/0.1 tags/0.2 tags/0.3" && git svn multi-fetch && - for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do - git rev-parse --verify refs/remotes/origin/\$i^0 >> refs.out || exit 1; - done && - test -z \"\$(sort < refs.out | uniq -d)\" && - for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do - for j in trunk a b tags/0.1 tags/0.2 tags/0.3; do - if test \$j != \$i; then continue; fi - test -z \"\$(git diff refs/remotes/origin/\$i \ - refs/remotes/origin/\$j)\" ||exit 1; done; done - " + for i in $refs + do + git rev-parse --verify refs/remotes/origin/$i^0 || return 1; + done >refs.out && + test -z "$(sort <refs.out | uniq -d)" && + for i in $refs + do + for j in $refs + do + git diff --exit-code refs/remotes/origin/$i \ + refs/remotes/origin/$j || + return 1 + done + done +' test_expect_success 'migrate --minimize on old inited layout' ' git config --unset-all svn-remote.svn.fetch && git config --unset-all svn-remote.svn.url && rm -rf "$GIT_DIR"/svn && - for i in $(cat fetch.out); do + for i in $(cat fetch.out) + do path=$(expr $i : "\([^:]*\):.*$") ref=$(expr $i : "[^:]*:\(refs/remotes/.*\)$") if test -z "$ref"; then continue; fi if test -n "$path"; then path="/$path"; fi - ( mkdir -p "$GIT_DIR"/svn/$ref/info/ && - echo "$svnrepo"$path > "$GIT_DIR"/svn/$ref/info/url ) || exit 1; + mkdir -p "$GIT_DIR"/svn/$ref/info/ && + echo "$svnrepo"$path >"$GIT_DIR"/svn/$ref/info/url || + return 1 done && git svn migrate --minimize && test -z "$(git config -l | grep "^svn-remote\.git-svn\.")" && @@ -104,7 +115,7 @@ test_expect_success 'migrate --minimize on old inited layout' ' grep "^tags/0\.1:refs/remotes/origin/tags/0\.1$" fetch.out && grep "^tags/0\.2:refs/remotes/origin/tags/0\.2$" fetch.out && grep "^tags/0\.3:refs/remotes/origin/tags/0\.3$" fetch.out && - grep "^:refs/${remotes_git_svn}" fetch.out + grep "^:refs/remotes/git-svn" fetch.out ' test_expect_success ".rev_db auto-converted to .rev_map.UUID" ' diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh index 29fbdfdd3f..dde0a3c222 100755 --- a/t/t9110-git-svn-use-svm-props.sh +++ b/t/t9110-git-svn-use-svm-props.sh @@ -22,31 +22,31 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89 bar_url=http://mayonaise/svnrepo/bar test_expect_success 'verify metadata for /bar' " git cat-file commit refs/remotes/bar | \ - grep '^${git_svn_id}: $bar_url@12 $uuid$' && + grep '^git-svn-id: $bar_url@12 $uuid$' && git cat-file commit refs/remotes/bar~1 | \ - grep '^${git_svn_id}: $bar_url@11 $uuid$' && + grep '^git-svn-id: $bar_url@11 $uuid$' && git cat-file commit refs/remotes/bar~2 | \ - grep '^${git_svn_id}: $bar_url@10 $uuid$' && + grep '^git-svn-id: $bar_url@10 $uuid$' && git cat-file commit refs/remotes/bar~3 | \ - grep '^${git_svn_id}: $bar_url@9 $uuid$' && + grep '^git-svn-id: $bar_url@9 $uuid$' && git cat-file commit refs/remotes/bar~4 | \ - grep '^${git_svn_id}: $bar_url@6 $uuid$' && + grep '^git-svn-id: $bar_url@6 $uuid$' && git cat-file commit refs/remotes/bar~5 | \ - grep '^${git_svn_id}: $bar_url@1 $uuid$' + grep '^git-svn-id: $bar_url@1 $uuid$' " e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e test_expect_success 'verify metadata for /dir/a/b/c/d/e' " git cat-file commit refs/remotes/e | \ - grep '^${git_svn_id}: $e_url@1 $uuid$' + grep '^git-svn-id: $e_url@1 $uuid$' " dir_url=http://mayonaise/svnrepo/dir test_expect_success 'verify metadata for /dir' " git cat-file commit refs/remotes/dir | \ - grep '^${git_svn_id}: $dir_url@2 $uuid$' && + grep '^git-svn-id: $dir_url@2 $uuid$' && git cat-file commit refs/remotes/dir~1 | \ - grep '^${git_svn_id}: $dir_url@1 $uuid$' + grep '^git-svn-id: $dir_url@1 $uuid$' " test_expect_success 'find commit based on SVN revision number' " diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh index bd081c2ec3..22b6e5ee7d 100755 --- a/t/t9111-git-svn-use-svnsync-props.sh +++ b/t/t9111-git-svn-use-svnsync-props.sh @@ -21,31 +21,31 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89 bar_url=http://mayonaise/svnrepo/bar test_expect_success 'verify metadata for /bar' " git cat-file commit refs/remotes/bar | \ - grep '^${git_svn_id}: $bar_url@12 $uuid$' && + grep '^git-svn-id: $bar_url@12 $uuid$' && git cat-file commit refs/remotes/bar~1 | \ - grep '^${git_svn_id}: $bar_url@11 $uuid$' && + grep '^git-svn-id: $bar_url@11 $uuid$' && git cat-file commit refs/remotes/bar~2 | \ - grep '^${git_svn_id}: $bar_url@10 $uuid$' && + grep '^git-svn-id: $bar_url@10 $uuid$' && git cat-file commit refs/remotes/bar~3 | \ - grep '^${git_svn_id}: $bar_url@9 $uuid$' && + grep '^git-svn-id: $bar_url@9 $uuid$' && git cat-file commit refs/remotes/bar~4 | \ - grep '^${git_svn_id}: $bar_url@6 $uuid$' && + grep '^git-svn-id: $bar_url@6 $uuid$' && git cat-file commit refs/remotes/bar~5 | \ - grep '^${git_svn_id}: $bar_url@1 $uuid$' + grep '^git-svn-id: $bar_url@1 $uuid$' " e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e test_expect_success 'verify metadata for /dir/a/b/c/d/e' " git cat-file commit refs/remotes/e | \ - grep '^${git_svn_id}: $e_url@1 $uuid$' + grep '^git-svn-id: $e_url@1 $uuid$' " dir_url=http://mayonaise/svnrepo/dir test_expect_success 'verify metadata for /dir' " git cat-file commit refs/remotes/dir | \ - grep '^${git_svn_id}: $dir_url@2 $uuid$' && + grep '^git-svn-id: $dir_url@2 $uuid$' && git cat-file commit refs/remotes/dir~1 | \ - grep '^${git_svn_id}: $dir_url@1 $uuid$' + grep '^git-svn-id: $dir_url@1 $uuid$' " test_done diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh index 1c84ce1023..59465b147e 100755 --- a/t/t9120-git-svn-clone-with-percent-escapes.sh +++ b/t/t9120-git-svn-clone-with-percent-escapes.sh @@ -22,7 +22,7 @@ test_expect_success 'test clone with percent escapes' ' git svn clone "$svnrepo/pr%20ject" clone && ( cd clone && - git rev-parse refs/${remotes_git_svn} + git rev-parse refs/remotes/git-svn ) ' @@ -42,7 +42,7 @@ test_expect_success 'test clone trunk with percent escapes and minimize-url' ' git svn clone --minimize-url "$svnrepo/pr%20ject/trunk" minimize && ( cd minimize && - git rev-parse refs/${remotes_git_svn} + git rev-parse refs/remotes/git-svn ) ' @@ -50,7 +50,7 @@ test_expect_success 'test clone trunk with percent escapes' ' git svn clone "$svnrepo/pr%20ject/trunk" trunk && ( cd trunk && - git rev-parse refs/${remotes_git_svn} + git rev-parse refs/remotes/git-svn ) ' diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh index fd8184787f..ead404589e 100755 --- a/t/t9123-git-svn-rebuild-with-rewriteroot.sh +++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh @@ -17,7 +17,7 @@ rm -rf import test_expect_success 'init, fetch and checkout repository' ' git svn init --rewrite-root=http://invalid.invalid/ "$svnrepo" && git svn fetch && - git checkout -b mybranch ${remotes_git_svn} + git checkout -b mybranch remotes/git-svn ' test_expect_success 'remove rev_map' ' diff --git a/t/t9153-git-svn-rewrite-uuid.sh b/t/t9153-git-svn-rewrite-uuid.sh index 88a2cfa233..372ef15685 100755 --- a/t/t9153-git-svn-rewrite-uuid.sh +++ b/t/t9153-git-svn-rewrite-uuid.sh @@ -17,9 +17,9 @@ test_expect_success 'load svn repo' " test_expect_success 'verify uuid' " git cat-file commit refs/remotes/git-svn~0 | \ - grep '^${git_svn_id}: .*@2 $uuid$' && + grep '^git-svn-id: .*@2 $uuid$' && git cat-file commit refs/remotes/git-svn~1 | \ - grep '^${git_svn_id}: .*@1 $uuid$' + grep '^git-svn-id: .*@1 $uuid$' " test_done diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 25bb60b281..74d740de41 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -52,6 +52,7 @@ echo "$@"' ### test_expect_success 'empty stream succeeds' ' + git config fastimport.unpackLimit 0 && git fast-import </dev/null ' @@ -2650,6 +2651,21 @@ test_expect_success 'R: ignore non-git options' ' git fast-import <input ' +test_expect_success 'R: corrupt lines do not mess marks file' ' + rm -f io.marks && + blob=$(echo hi | git hash-object --stdin) && + cat >expect <<-EOF && + :3 0000000000000000000000000000000000000000 + :1 $blob + :2 $blob + EOF + cp expect io.marks && + test_must_fail git fast-import --import-marks=io.marks --export-marks=io.marks <<-\EOF && + + EOF + test_cmp expect io.marks +' + ## ## R: very large blobs ## @@ -2675,6 +2691,7 @@ test_expect_success 'R: blob bigger than threshold' ' echo >>input && test_create_repo R && + git --git-dir=R/.git config fastimport.unpackLimit 0 && git --git-dir=R/.git fast-import --big-file-threshold=1 <input ' diff --git a/t/t9302-fast-import-unpack-limit.sh b/t/t9302-fast-import-unpack-limit.sh new file mode 100755 index 0000000000..a04de14677 --- /dev/null +++ b/t/t9302-fast-import-unpack-limit.sh @@ -0,0 +1,105 @@ +#!/bin/sh +test_description='test git fast-import unpack limit' +. ./test-lib.sh + +test_expect_success 'create loose objects on import' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/master + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + initial + COMMIT + + done + INPUT_END + + git -c fastimport.unpackLimit=2 fast-import --done <input && + git fsck --no-progress && + test $(find .git/objects/?? -type f | wc -l) -eq 2 && + test $(find .git/objects/pack -type f | wc -l) -eq 0 +' + +test_expect_success 'bigger packs are preserved' ' + test_tick && + cat >input <<-INPUT_END && + commit refs/heads/master + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + incremental should create a pack + COMMIT + from refs/heads/master^0 + + commit refs/heads/branch + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + branch + COMMIT + + done + INPUT_END + + git -c fastimport.unpackLimit=2 fast-import --done <input && + git fsck --no-progress && + test $(find .git/objects/?? -type f | wc -l) -eq 2 && + test $(find .git/objects/pack -type f | wc -l) -eq 2 +' + +test_expect_success 'lookups after checkpoint works' ' + hello_id=$(echo hello | git hash-object --stdin -t blob) && + id="$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" && + before=$(git rev-parse refs/heads/master^0) && + ( + cat <<-INPUT_END && + blob + mark :1 + data 6 + hello + + commit refs/heads/master + mark :2 + committer $id + data <<COMMIT + checkpoint after this + COMMIT + from refs/heads/master^0 + M 100644 :1 hello + + # pre-checkpoint + cat-blob :1 + cat-blob $hello_id + checkpoint + # post-checkpoint + cat-blob :1 + cat-blob $hello_id + INPUT_END + + n=0 && + from=$before && + while test x"$from" = x"$before" + do + if test $n -gt 30 + then + echo >&2 "checkpoint did not update branch" + exit 1 + else + n=$(($n + 1)) + fi && + sleep 1 && + from=$(git rev-parse refs/heads/master^0) + done && + cat <<-INPUT_END && + commit refs/heads/master + committer $id + data <<COMMIT + make sure from "unpacked sha1 reference" works, too + COMMIT + from $from + INPUT_END + echo done + ) | git -c fastimport.unpackLimit=100 fast-import --done && + test $(find .git/objects/?? -type f | wc -l) -eq 6 && + test $(find .git/objects/pack -type f | wc -l) -eq 2 +' + +test_done diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 8d99eb303f..48884d5208 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -718,20 +718,13 @@ test_cmp_rev () { test_cmp expect.rev actual.rev } -# Print a sequence of numbers or letters in increasing order. This is -# similar to GNU seq(1), but the latter might not be available -# everywhere (and does not do letters). It may be used like: -# -# for i in $(test_seq 100) -# do -# for j in $(test_seq 10 20) -# do -# for k in $(test_seq a z) -# do -# echo $i-$j-$k -# done -# done -# done +# Print a sequence of integers in increasing order, either with +# two arguments (start and end): +# +# test_seq 1 5 -- outputs 1 2 3 4 5 one line at a time +# +# or with one argument (end), in which case it starts counting +# from 1. test_seq () { case $# in @@ -739,7 +732,12 @@ test_seq () { 2) ;; *) error "bug in the test script: not 1 or 2 parameters to test_seq" ;; esac - perl -le 'print for $ARGV[0]..$ARGV[1]' -- "$@" + test_seq_counter__=$1 + while test "$test_seq_counter__" -le "$2" + do + echo "$test_seq_counter__" + test_seq_counter__=$(( $test_seq_counter__ + 1 )) + done } # This function can be used to schedule some commands to be run @@ -941,3 +939,25 @@ mingw_read_file_strip_cr_ () { eval "$1=\$$1\$line" done } + +# Like "env FOO=BAR some-program", but run inside a subshell, which means +# it also works for shell functions (though those functions cannot impact +# the environment outside of the test_env invocation). +test_env () { + ( + while test $# -gt 0 + do + case "$1" in + *=*) + eval "${1%%=*}=\${1#*=}" + eval "export ${1%%=*}" + shift + ;; + *) + "$@" + exit + ;; + esac + done + ) +} diff --git a/t/test-lib.sh b/t/test-lib.sh index 286c5f33d1..0055ebba46 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -322,6 +322,19 @@ else exec 4>/dev/null 3>/dev/null fi +# Send any "-x" output directly to stderr to avoid polluting tests +# which capture stderr. We can do this unconditionally since it +# has no effect if tracing isn't turned on. +# +# Note that this sets up the trace fd as soon as we assign the variable, so it +# must come after the creation of descriptor 4 above. Likewise, we must never +# unset this, as it has the side effect of closing descriptor 4, which we +# use to show verbose tests to the user. +# +# Note also that we don't need or want to export it. The tracing is local to +# this shell, and we would not want to influence any shells we exec. +BASH_XTRACEFD=4 + test_failure=0 test_count=0 test_fixed=0 |