diff --git a/Documentation/RelNotes/2.21.0.txt b/Documentation/RelNotes/2.21.0.txt index 8a9a8dd496..7a49deddf3 100644 --- a/Documentation/RelNotes/2.21.0.txt +++ b/Documentation/RelNotes/2.21.0.txt @@ -26,7 +26,7 @@ UI, Workflows & Features the fast-export side has been made. * "git push $there $src:$dst" rejects when $dst is not a fully - qualified refname and not clear what the end user meant. The + qualified refname and it is not clear what the end user meant. The codepath has been taught to give a clearer error message, and also guess where the push should go by taking the type of the pushed object into account (e.g. a tag object would want to go under @@ -77,9 +77,9 @@ UI, Workflows & Features * A new date format "--date=human" that morphs its output depending on how far the time is from the current time has been introduced. - "--date=auto" can be used to use this new format when the output is - going to the pager or to the terminal and otherwise the default - format. + "--date=auto:human" can be used to use this new format (or any + existing format) when the output is going to the pager or to the + terminal, and otherwise the default format. Performance, Internal Implementation, Development Support etc. @@ -88,7 +88,7 @@ Performance, Internal Implementation, Development Support etc. (non-)existence of loose objects. * More codepaths have become aware of working with in-core repository - instance other than the default "the_repository". + instances other than the default "the_repository". * The "strncat()" function is now among the banned functions. @@ -125,13 +125,13 @@ Performance, Internal Implementation, Development Support etc. * The in-core repository instances are passed through more codepaths. * Update the protocol message specification to allow only the limited - use of scaled quantities. This is ensure potential compatibility - issues will not go out of hand. + use of scaled quantities. This is to ensure potential compatibility + issues will not get out of hand. * Micro-optimize the code that prepares commit objects to be walked by "git rev-list" when the commit-graph is available. - * "git fetch" and "git upload-pack" learned to send all exchange over + * "git fetch" and "git upload-pack" learned to send all exchanges over the sideband channel while talking the v2 protocol. * The codepath to write out commit-graph has been optimized by @@ -180,6 +180,13 @@ Performance, Internal Implementation, Development Support etc. * A flakey "p4" test has been removed. + * The code and tests assume that the system supplied iconv() would + always use BOM in its output when asked to encode to UTF-16 (or + UTF-32), but apparently some implementations output big-endian + without BOM. A compile-time knob has been added to help such + systems (e.g. NonStop) to add BOM to the output to increase + portability. + Fixes since v2.20 ----------------- @@ -439,3 +446,6 @@ Fixes since v2.20 (merge 2e285e7803 tz/gpg-test-fix later to maint). (merge 5427de960b kl/pretty-doc-markup-fix later to maint). (merge 3815f64b0d js/mingw-host-cpu later to maint). + (merge 5fe81438b5 rj/sequencer-sign-off-header-static later to maint). + (merge 18a4f6be6b nd/fileno-may-be-macro later to maint). + (merge 99e9ab54ab kd/t0028-octal-del-is-377-not-777 later to maint). diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index daa16403ec..5629ba4c5d 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -529,7 +529,6 @@ are incompatible with the following options: * --interactive * --exec * --keep-empty - * --autosquash * --edit-todo * --root when used in combination with --onto @@ -554,8 +553,6 @@ commit started empty (had no changes relative to its parent to start with) or ended empty (all changes were already applied upstream in other commits). -The merge backend does the same. - The interactive backend drops commits by default that started empty and halts if it hits a commit that ended up empty. The `--keep-empty` option exists for the interactive backend to allow diff --git a/Makefile b/Makefile index 0e13a5b469..f0b2299172 100644 --- a/Makefile +++ b/Makefile @@ -259,6 +259,10 @@ all:: # Define OLD_ICONV if your library has an old iconv(), where the second # (input buffer pointer) parameter is declared with type (const char **). # +# Define ICONV_OMITS_BOM if your iconv implementation does not write a +# byte-order mark (BOM) when writing UTF-16 or UTF-32 and always writes in +# big-endian format. +# # Define NO_DEFLATE_BOUND if your zlib does not have deflateBound. # # Define NO_R_TO_GCC_LINKER if your gcc does not like "-R/path/lib" @@ -433,6 +437,8 @@ all:: # # Define HAVE_GETDELIM if your system has the getdelim() function. # +# Define FILENO_IS_A_MACRO if fileno() is a macro, not a real function. +# # Define PAGER_ENV to a SP separated VAR=VAL pairs to define # default environment variables to be passed when a pager is spawned, e.g. # @@ -1415,6 +1421,9 @@ ifndef NO_ICONV EXTLIBS += $(ICONV_LINK) -liconv endif endif +ifdef ICONV_OMITS_BOM + BASIC_CFLAGS += -DICONV_OMITS_BOM +endif ifdef NEEDS_LIBGEN EXTLIBS += -lgen endif @@ -1800,6 +1809,11 @@ ifdef HAVE_WPGMPTR BASIC_CFLAGS += -DHAVE_WPGMPTR endif +ifdef FILENO_IS_A_MACRO + COMPAT_CFLAGS += -DFILENO_IS_A_MACRO + COMPAT_OBJS += compat/fileno.o +endif + ifeq ($(TCLTK_PATH),) NO_TCLTK = NoThanks endif diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index c1cff32661..e7325fe37f 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -173,7 +173,7 @@ static int bisect_reset(const char *commit) argv_array_clear(&argv); return error(_("could not check out original" " HEAD '%s'. Try 'git bisect" - "reset '."), branch.buf); + " reset '."), branch.buf); } argv_array_clear(&argv); } @@ -646,7 +646,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "no-checkout", &no_checkout, N_("update BISECT_HEAD instead of checking out the current commit")), OPT_BOOL(0, "no-log", &nolog, - N_("no log for BISECT_WRITE ")), + N_("no log for BISECT_WRITE")), OPT_END() }; struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL }; diff --git a/builtin/fetch.c b/builtin/fetch.c index 5a09fe24cd..b620fd54b4 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1480,7 +1480,7 @@ static inline void fetch_one_setup_partial(struct remote *remote) if (strcmp(remote->name, repository_format_partial_clone)) { if (filter_options.choice) die(_("--filter can only be used with the remote " - "configured in extensions.partialclone")); + "configured in extensions.partialClone")); return; } diff --git a/builtin/rebase.c b/builtin/rebase.c index 96efd40901..7c7bc13e91 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1434,7 +1434,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) } if (options.reschedule_failed_exec && !is_interactive(&options)) - die(_("--reschedule-failed-exec requires an interactive rebase")); + die(_("%s requires an interactive rebase"), "--reschedule-failed-exec"); if (options.git_am_opts.argc) { /* all am options except -q are compatible only with --am */ diff --git a/compat/fileno.c b/compat/fileno.c new file mode 100644 index 0000000000..7b105f4cd7 --- /dev/null +++ b/compat/fileno.c @@ -0,0 +1,7 @@ +#define COMPAT_CODE +#include "../git-compat-util.h" + +int git_fileno(FILE *stream) +{ + return fileno(stream); +} diff --git a/compat/mingw.h b/compat/mingw.h index 98407744f2..30d9fb3e36 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -6,25 +6,6 @@ typedef _sigset_t sigset_t; #include #include -#ifdef __MINGW64_VERSION_MAJOR -/* - * In Git for Windows, we cannot rely on `uname -m` to report the correct - * architecture: /usr/bin/uname.exe will report the architecture with which the - * current MSYS2 runtime was built, not the architecture for which we are - * currently compiling (both 32-bit and 64-bit `git.exe` is built in the 64-bit - * Git for Windows SDK). - */ -#undef GIT_HOST_CPU -/* This was figured out by looking at `cpp -dM auth_method, "CRAM-MD5")) { if (!CAP(AUTH_CRAM_MD5)) { - fprintf(stderr, "You specified" + fprintf(stderr, "You specified " "CRAM-MD5 as authentication method, " "but %s doesn't support it.\n", srvc->host); goto bail; diff --git a/sequencer.c b/sequencer.c index 972402e8c0..0db410d590 100644 --- a/sequencer.c +++ b/sequencer.c @@ -35,7 +35,7 @@ #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION" -const char sign_off_header[] = "Signed-off-by: "; +static const char sign_off_header[] = "Signed-off-by: "; static const char cherry_picked_prefix[] = "(cherry picked from commit "; GIT_PATH_FUNC(git_path_commit_editmsg, "COMMIT_EDITMSG") diff --git a/sequencer.h b/sequencer.h index 93e891309b..4d505b3590 100644 --- a/sequencer.h +++ b/sequencer.h @@ -107,8 +107,6 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla unsigned autosquash); int rearrange_squash(struct repository *r); -extern const char sign_off_header[]; - /* * Append a signoff to the commit message in "msgbuf". The ignore_footer * parameter specifies the number of bytes at the end of msgbuf that should diff --git a/sha1-name.c b/sha1-name.c index d1cc77c124..6dda2c16df 100644 --- a/sha1-name.c +++ b/sha1-name.c @@ -1820,9 +1820,11 @@ void maybe_die_on_misspelt_object_name(const char *name, const char *prefix) prefix, &oid, &oc); } -int get_oid_with_context(struct repository *repo, const char *str, - unsigned flags, struct object_id *oid, - struct object_context *oc) +enum get_oid_result get_oid_with_context(struct repository *repo, + const char *str, + unsigned flags, + struct object_id *oid, + struct object_context *oc) { if (flags & GET_OID_FOLLOW_SYMLINKS && flags & GET_OID_ONLY_TO_DIE) BUG("incompatible flags for get_sha1_with_context"); diff --git a/t/README b/t/README index 1326fd7505..886bbec5bc 100644 --- a/t/README +++ b/t/README @@ -211,6 +211,11 @@ appropriately before running "make". '.stress-' suffix, and the trash directory of the failed test job is renamed to end with a '.stress-failed' suffix. +--stress-limit=:: + When combined with --stress run the test script repeatedly + this many times in each of the parallel jobs or until one of + them fails, whichever comes first. + You can also set the GIT_TEST_INSTALLED environment variable to the bindir of an existing git installation to test that installation. You still need to have built this git sandbox, from which various diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 216281eabc..0dfb48c2f6 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -91,6 +91,7 @@ HTTPD_DOCUMENT_ROOT_PATH=$HTTPD_ROOT_PATH/www # hack to suppress apache PassEnv warnings GIT_VALGRIND=$GIT_VALGRIND; export GIT_VALGRIND GIT_VALGRIND_OPTIONS=$GIT_VALGRIND_OPTIONS; export GIT_VALGRIND_OPTIONS +GIT_TEST_SIDEBAND_ALL=$GIT_TEST_SIDEBAND_ALL; export GIT_TEST_SIDEBAND_ALL GIT_TRACE=$GIT_TRACE; export GIT_TRACE if ! test -x "$LIB_HTTPD_PATH" diff --git a/t/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh index e58ecbfc44..1090e650ed 100755 --- a/t/t0028-working-tree-encoding.sh +++ b/t/t0028-working-tree-encoding.sh @@ -6,6 +6,30 @@ test_description='working-tree-encoding conversion via gitattributes' GIT_TRACE_WORKING_TREE_ENCODING=1 && export GIT_TRACE_WORKING_TREE_ENCODING +test_lazy_prereq NO_UTF16_BOM ' + test $(printf abc | iconv -f UTF-8 -t UTF-16 | wc -c) = 6 +' + +test_lazy_prereq NO_UTF32_BOM ' + test $(printf abc | iconv -f UTF-8 -t UTF-32 | wc -c) = 12 +' + +write_utf16 () { + if test_have_prereq NO_UTF16_BOM + then + printf '\xfe\xff' + fi && + iconv -f UTF-8 -t UTF-16 +} + +write_utf32 () { + if test_have_prereq NO_UTF32_BOM + then + printf '\x00\x00\xfe\xff' + fi && + iconv -f UTF-8 -t UTF-32 +} + test_expect_success 'setup test files' ' git config core.eol lf && @@ -13,8 +37,8 @@ test_expect_success 'setup test files' ' echo "*.utf16 text working-tree-encoding=utf-16" >.gitattributes && echo "*.utf16lebom text working-tree-encoding=UTF-16LE-BOM" >>.gitattributes && printf "$text" >test.utf8.raw && - printf "$text" | iconv -f UTF-8 -t UTF-16 >test.utf16.raw && - printf "$text" | iconv -f UTF-8 -t UTF-32 >test.utf32.raw && + printf "$text" | write_utf16 >test.utf16.raw && + printf "$text" | write_utf32 >test.utf32.raw && printf "\377\376" >test.utf16lebom.raw && printf "$text" | iconv -f UTF-8 -t UTF-32LE >>test.utf16lebom.raw && @@ -25,12 +49,12 @@ test_expect_success 'setup test files' ' # BOM tests printf "\0a\0b\0c" >nobom.utf16be.raw && printf "a\0b\0c\0" >nobom.utf16le.raw && - printf "\376\777\0a\0b\0c" >bebom.utf16be.raw && - printf "\777\376a\0b\0c\0" >lebom.utf16le.raw && + printf "\376\377\0a\0b\0c" >bebom.utf16be.raw && + printf "\377\376a\0b\0c\0" >lebom.utf16le.raw && printf "\0\0\0a\0\0\0b\0\0\0c" >nobom.utf32be.raw && printf "a\0\0\0b\0\0\0c\0\0\0" >nobom.utf32le.raw && - printf "\0\0\376\777\0\0\0a\0\0\0b\0\0\0c" >bebom.utf32be.raw && - printf "\777\376\0\0a\0\0\0b\0\0\0c\0\0\0" >lebom.utf32le.raw && + printf "\0\0\376\377\0\0\0a\0\0\0b\0\0\0c" >bebom.utf32be.raw && + printf "\377\376\0\0a\0\0\0b\0\0\0c\0\0\0" >lebom.utf32le.raw && # Add only UTF-16 file, we will add the UTF-32 file later cp test.utf16.raw test.utf16 && @@ -124,8 +148,8 @@ do test_when_finished "rm -f crlf.utf${i}.raw lf.utf${i}.raw" && test_when_finished "git reset --hard HEAD^" && - cat lf.utf8.raw | iconv -f UTF-8 -t UTF-${i} >lf.utf${i}.raw && - cat crlf.utf8.raw | iconv -f UTF-8 -t UTF-${i} >crlf.utf${i}.raw && + cat lf.utf8.raw | write_utf${i} >lf.utf${i}.raw && + cat crlf.utf8.raw | write_utf${i} >crlf.utf${i}.raw && cp crlf.utf${i}.raw eol.utf${i} && cat >expectIndexLF <<-EOF && @@ -223,7 +247,7 @@ test_expect_success ICONV_SHIFT_JIS 'check roundtrip encoding' ' text="hallo there!\nroundtrip test here!" && printf "$text" | iconv -f UTF-8 -t SHIFT-JIS >roundtrip.shift && - printf "$text" | iconv -f UTF-8 -t UTF-16 >roundtrip.utf16 && + printf "$text" | write_utf16 >roundtrip.utf16 && echo "*.shift text working-tree-encoding=SHIFT-JIS" >>.gitattributes && # SHIFT-JIS encoded files are round-trip checked by default... diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh index 51a4f4c0ac..6b6a8e2292 100755 --- a/t/t1404-update-ref-errors.sh +++ b/t/t1404-update-ref-errors.sh @@ -614,7 +614,7 @@ test_expect_success 'delete fails cleanly if packed-refs file is locked' ' test_when_finished "rm -f .git/packed-refs.lock" && test_must_fail git update-ref -d $prefix/foo >out 2>err && git for-each-ref $prefix >actual && - test_i18ngrep "Unable to create $Q.*packed-refs.lock$Q: File exists" err && + test_i18ngrep "Unable to create $Q.*packed-refs.lock$Q: " err && test_cmp unchanged actual ' diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 52fa41c707..b60b11f9f2 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -149,10 +149,12 @@ test_expect_success 'rebase -i with the exec command checks tree cleanness' ' test_expect_success 'rebase -x with empty command fails' ' test_when_finished "git rebase --abort ||:" && - test_must_fail git rebase -x "" @ 2>actual && + test_must_fail env GIT_TEST_REBASE_USE_BUILTIN=true \ + git rebase -x "" @ 2>actual && test_write_lines "error: empty exec command" >expected && test_i18ncmp expected actual && - test_must_fail git rebase -x " " @ 2>actual && + test_must_fail env GIT_TEST_REBASE_USE_BUILTIN=true \ + git rebase -x " " @ 2>actual && test_i18ncmp expected actual ' @@ -160,7 +162,8 @@ LF=' ' test_expect_success 'rebase -x with newline in command fails' ' test_when_finished "git rebase --abort ||:" && - test_must_fail git rebase -x "a${LF}b" @ 2>actual && + test_must_fail env GIT_TEST_REBASE_USE_BUILTIN=true \ + git rebase -x "a${LF}b" @ 2>actual && test_write_lines "error: exec commands cannot contain newlines" \ >expected && test_i18ncmp expected actual diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 16d10ebce8..d4bd1522fe 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -383,7 +383,7 @@ corrupt_graph_and_verify() { cp $objdir/info/commit-graph commit-graph-backup && printf "$data" | dd of="$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc && dd of="$objdir/info/commit-graph" bs=1 seek="$zero_pos" count=0 && - dd if=/dev/zero of="$objdir/info/commit-graph" bs=1 seek="$zero_pos" count=$(($orig_size - $zero_pos)) && + generate_zero_bytes $(($orig_size - $zero_pos)) >>"$objdir/info/commit-graph" && test_must_fail git commit-graph verify 2>test_err && grep -v "^+" test_err >err && test_i18ngrep "$grepstr" err diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh index 90d890d02f..bbadde2c6e 100755 --- a/t/t5562-http-backend-content-length.sh +++ b/t/t5562-http-backend-content-length.sh @@ -143,14 +143,14 @@ test_expect_success GZIP 'push gzipped empty' ' test_expect_success 'CONTENT_LENGTH overflow ssite_t' ' NOT_FIT_IN_SSIZE=$(ssize_b100dots) && - env \ + generate_zero_bytes infinity | env \ CONTENT_TYPE=application/x-git-upload-pack-request \ QUERY_STRING=/repo.git/git-upload-pack \ PATH_TRANSLATED="$PWD"/.git/git-upload-pack \ GIT_HTTP_EXPORT_ALL=TRUE \ REQUEST_METHOD=POST \ CONTENT_LENGTH="$NOT_FIT_IN_SSIZE" \ - git http-backend /dev/null 2>err && + git http-backend >/dev/null 2>err && grep "fatal:.*CONTENT_LENGTH" err ' diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 92cf8f812c..094c07748a 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -116,6 +116,19 @@ remove_cr () { tr '\015' Q | sed -e 's/Q$//' } +# Generate an output of $1 bytes of all zeroes (NULs, not ASCII zeroes). +# If $1 is 'infinity', output forever or until the receiving pipe stops reading, +# whichever comes first. +generate_zero_bytes () { + perl -e 'if ($ARGV[0] == "infinity") { + while (-1) { + print "\0" + } + } else { + print "\0" x $ARGV[0] + }' "$@" +} + # In some bourne shell implementations, the "unset" builtin returns # nonzero status when a variable to be unset was not set in the first # place. @@ -1289,7 +1302,7 @@ test_set_port () { port=$(($port + 10000)) fi ;; - *[^0-9]*|0*) + *[!0-9]*|0*) error >&7 "invalid port number: $port" ;; *) diff --git a/t/test-lib.sh b/t/test-lib.sh index 42b1a0aa7f..8665b0a9b6 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -149,7 +149,7 @@ do --stress=*) stress=${opt#--*=} case "$stress" in - *[^0-9]*|0*|"") + *[!0-9]*|0*|"") echo "error: --stress= requires the number of jobs to run" >&2 exit 1 ;; @@ -157,6 +157,17 @@ do ;; esac ;; + --stress-limit=*) + stress_limit=${opt#--*=} + case "$stress_limit" in + *[!0-9]*|0*|"") + echo "error: --stress-limit= requires the number of repetitions" >&2 + exit 1 + ;; + *) # Good. + ;; + esac + ;; *) echo "error: unknown test option '$opt'" >&2; exit 1 ;; esac @@ -242,8 +253,10 @@ then exit 1 ' TERM INT - cnt=0 - while ! test -e "$stressfail" + cnt=1 + while ! test -e "$stressfail" && + { test -z "$stress_limit" || + test $cnt -le $stress_limit ; } do $TEST_SHELL_PATH "$0" "$@" >"$TEST_RESULTS_BASE.stress-$job_nr.out" 2>&1 & test_pid=$! @@ -266,6 +279,7 @@ then if test -f "$stressfail" then + stress_exit=1 echo "Log(s) of failed test run(s):" for failed_job_nr in $(sort -n "$stressfail") do diff --git a/utf8.c b/utf8.c index 83824dc2f4..3b42fadffd 100644 --- a/utf8.c +++ b/utf8.c @@ -559,6 +559,10 @@ char *reencode_string_len(const char *in, size_t insz, /* * For writing, UTF-16 iconv typically creates "UTF-16BE-BOM" * Some users under Windows want the little endian version + * + * We handle UTF-16 and UTF-32 ourselves only if the platform does not + * provide a BOM (which we require), since we want to match the behavior + * of the system tools and libc as much as possible. */ if (same_utf_encoding("UTF-16LE-BOM", out_encoding)) { bom_str = utf16_le_bom; @@ -568,6 +572,16 @@ char *reencode_string_len(const char *in, size_t insz, bom_str = utf16_be_bom; bom_len = sizeof(utf16_be_bom); out_encoding = "UTF-16BE"; +#ifdef ICONV_OMITS_BOM + } else if (same_utf_encoding("UTF-16", out_encoding)) { + bom_str = utf16_be_bom; + bom_len = sizeof(utf16_be_bom); + out_encoding = "UTF-16BE"; + } else if (same_utf_encoding("UTF-32", out_encoding)) { + bom_str = utf32_be_bom; + bom_len = sizeof(utf32_be_bom); + out_encoding = "UTF-32BE"; +#endif } conv = iconv_open(out_encoding, in_encoding);