diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 82d45f4f42c351..be34a81b4ec9ab 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -342,8 +342,8 @@ jobs: image: alpine distro: alpine-latest - jobname: linux32 - image: daald/ubuntu32:xenial - distro: ubuntu32-16.04 + image: i386/ubuntu:focal + distro: ubuntu32-20.04 - jobname: pedantic image: fedora distro: fedora-latest @@ -353,17 +353,17 @@ jobs: runs-on: ubuntu-latest container: ${{matrix.vector.image}} steps: - - uses: actions/checkout@v4 - if: matrix.vector.jobname != 'linux32' - - uses: actions/checkout@v1 # cannot be upgraded because Node.js Actions aren't supported in this container + - name: prepare libc6 for actions if: matrix.vector.jobname == 'linux32' + run: apt -q update && apt -q -y install libc6-amd64 lib64stdc++6 + - uses: actions/checkout@v4 - run: ci/install-dependencies.sh - run: ci/run-build-and-tests.sh - name: print test failures if: failure() && env.FAILED_TEST_ARTIFACTS != '' run: ci/print-test-failures.sh - name: Upload failed tests' directories - if: failure() && env.FAILED_TEST_ARTIFACTS != '' && matrix.vector.jobname != 'linux32' + if: failure() && env.FAILED_TEST_ARTIFACTS != '' uses: actions/upload-artifact@v4 with: name: failed-tests-${{matrix.vector.jobname}} diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 37b991e08079fc..c4c45dad2f956f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,6 +25,9 @@ test:linux: fi parallel: matrix: + - jobname: linux-old + image: ubuntu:16.04 + CC: gcc - jobname: linux-sha256 image: ubuntu:latest CC: clang diff --git a/Documentation/RelNotes/2.46.2.txt b/Documentation/RelNotes/2.46.2.txt new file mode 100644 index 00000000000000..613386878d44c9 --- /dev/null +++ b/Documentation/RelNotes/2.46.2.txt @@ -0,0 +1,23 @@ +Git 2.46.2 Release Notes +======================== + +This release is primarily to merge changes to unbreak the 32-bit +GitHub actions jobs we use for CI testing, so that we can release +real fixes for the 2.46.x track after they pass CI. + +It also reverts the "git patch-id" change that went into 2.46.1, +as it seems to have got a regression reported (I haven't verified, +but it is better to keep a known breakage than adding an unintended +regression). + +Other than that, a handful of minor bugfixes are included. + + * In a few corner cases "git diff --exit-code" failed to report + "changes" (e.g., renamed without any content change), which has + been corrected. + + * Cygwin does have /dev/tty support that is needed by things like + single-key input mode. + + * The interpret-trailers command failed to recognise the end of the + message when the commit log ends in an incomplete line. diff --git a/Documentation/config/remote.txt b/Documentation/config/remote.txt index 8efc53e836d20b..36e771556c67aa 100644 --- a/Documentation/config/remote.txt +++ b/Documentation/config/remote.txt @@ -42,14 +42,15 @@ remote..mirror:: as if the `--mirror` option was given on the command line. remote..skipDefaultUpdate:: - If true, this remote will be skipped by default when updating - using linkgit:git-fetch[1] or the `update` subcommand of - linkgit:git-remote[1]. + A deprecated synonym to `remote..skipFetchAll` (if + both are set in the configuration files with different + values, the value of the last occurrence will be used). remote..skipFetchAll:: - If true, this remote will be skipped by default when updating - using linkgit:git-fetch[1] or the `update` subcommand of - linkgit:git-remote[1]. + If true, this remote will be skipped when updating + using linkgit:git-fetch[1], the `update` subcommand of + linkgit:git-remote[1], and ignored by the prefetch task + of `git maitenance`. remote..receivepack:: The default program to execute on the remote side when pushing. See diff --git a/Documentation/fetch-options.txt b/Documentation/fetch-options.txt index e22b217fba9e2c..80838fe37ef30e 100644 --- a/Documentation/fetch-options.txt +++ b/Documentation/fetch-options.txt @@ -1,6 +1,7 @@ --[no-]all:: - Fetch all remotes. This overrides the configuration variable - `fetch.all`. + Fetch all remotes, except for the ones that has the + `remote..skipFetchAll` configuration variable set. + This overrides the configuration variable fetch.all`. -a:: --append:: diff --git a/Documentation/git-maintenance.txt b/Documentation/git-maintenance.txt index 51d0f7e94b6a01..9d968191331080 100644 --- a/Documentation/git-maintenance.txt +++ b/Documentation/git-maintenance.txt @@ -107,6 +107,9 @@ with the prefetch task, the objects necessary to complete a later real fetch would already be obtained, making the real fetch faster. In the ideal case, it will just become an update to a bunch of remote-tracking branches without any object transfer. ++ +The `remote..skipFetchAll` configuration can be used to +exclude a particular remote from getting prefetched. gc:: Clean up unnecessary files and optimize the local repository. "GC" diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 55850912d13034..05fa12fec794eb 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.46.1 +DEF_VER=v2.46.2 LF=' ' diff --git a/RelNotes b/RelNotes index 89b65f22b19959..0dfe046c8855e5 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.46.1.txt \ No newline at end of file +Documentation/RelNotes/2.46.2.txt \ No newline at end of file diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 1d969494cf5471..e6f22459f15334 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -132,6 +132,7 @@ static void read_input_file(struct strbuf *sb, const char *file) if (strbuf_read(sb, fileno(stdin), 0) < 0) die_errno(_("could not read from stdin")); } + strbuf_complete_line(sb); } static void interpret_trailers(const struct process_trailer_options *opts, diff --git a/builtin/patch-id.c b/builtin/patch-id.c index 35c1179f7e94ba..d790ae6354b415 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -7,9 +7,10 @@ #include "parse-options.h" #include "setup.h" -static void flush_current_id(struct object_id *id, struct object_id *result) +static void flush_current_id(int patchlen, struct object_id *id, struct object_id *result) { - printf("%s %s\n", oid_to_hex(result), oid_to_hex(id)); + if (patchlen) + printf("%s %s\n", oid_to_hex(result), oid_to_hex(id)); } static int remove_space(char *line) @@ -59,27 +60,9 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after) return 1; } -/* - * flag bits to control get_one_patchid()'s behaviour. - * - * STABLE/VERBATIM are given from the command line option as - * --stable/--verbatim. FIND_HEADER conveys the internal state - * maintained by the caller to allow the function to avoid mistaking - * lines of log message before seeing the "diff" part as the beginning - * of the next patch. - */ -enum { - GOPID_STABLE = (1<<0), /* --stable */ - GOPID_VERBATIM = (1<<1), /* --verbatim */ - GOPID_FIND_HEADER = (1<<2), /* stop at the beginning of patch message */ -}; - static int get_one_patchid(struct object_id *next_oid, struct object_id *result, - struct strbuf *line_buf, unsigned flags) + struct strbuf *line_buf, int stable, int verbatim) { - int stable = flags & GOPID_STABLE; - int verbatim = flags & GOPID_VERBATIM; - int find_header = flags & GOPID_FIND_HEADER; int patchlen = 0, found_next = 0; int before = -1, after = -1; int diff_is_binary = 0; @@ -94,40 +77,24 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, const char *p = line; int len; - /* - * The caller hasn't seen us find a patch header and - * return to it, or we have started processing patch - * and may encounter the beginning of the next patch. - */ - if (find_header) { - /* - * If we see a line that begins with "", - * "commit " or "From ", it is - * the beginning of a patch. Return to the caller, as - * we are done with the one we have been processing. - */ - if (skip_prefix(line, "commit ", &p)) - ; - else if (skip_prefix(line, "From ", &p)) - ; - if (!get_oid_hex(p, next_oid)) { - if (verbatim) - the_hash_algo->update_fn(&ctx, line, strlen(line)); - found_next = 1; - break; - } + /* Possibly skip over the prefix added by "log" or "format-patch" */ + if (!skip_prefix(line, "commit ", &p) && + !skip_prefix(line, "From ", &p) && + starts_with(line, "\\ ") && 12 < strlen(line)) { + if (verbatim) + the_hash_algo->update_fn(&ctx, line, strlen(line)); + continue; + } + + if (!get_oid_hex(p, next_oid)) { + found_next = 1; + break; } /* Ignore commit comments */ if (!patchlen && !starts_with(line, "diff ")) continue; - /* - * We are past the commit log message. Prepare to - * stop at the beginning of the next patch header. - */ - find_header = 1; - /* Parsing diff header? */ if (before == -1) { if (starts_with(line, "GIT binary patch") || @@ -160,16 +127,6 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, break; } - /* - * A hunk about an incomplete line may have this - * marker at the end, which should just be ignored. - */ - if (starts_with(line, "\\ ") && 12 < strlen(line)) { - if (verbatim) - the_hash_algo->update_fn(&ctx, line, strlen(line)); - continue; - } - if (diff_is_binary) { if (starts_with(line, "diff ")) { diff_is_binary = 0; @@ -216,20 +173,17 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result, return patchlen; } -static void generate_id_list(unsigned flags) +static void generate_id_list(int stable, int verbatim) { struct object_id oid, n, result; int patchlen; struct strbuf line_buf = STRBUF_INIT; oidclr(&oid, the_repository->hash_algo); - flags |= GOPID_FIND_HEADER; while (!feof(stdin)) { - patchlen = get_one_patchid(&n, &result, &line_buf, flags); - if (patchlen) - flush_current_id(&oid, &result); + patchlen = get_one_patchid(&n, &result, &line_buf, stable, verbatim); + flush_current_id(patchlen, &oid, &result); oidcpy(&oid, &n); - flags &= ~GOPID_FIND_HEADER; } strbuf_release(&line_buf); } @@ -265,7 +219,6 @@ int cmd_patch_id(int argc, const char **argv, const char *prefix) /* if nothing is set, default to unstable */ struct patch_id_opts config = {0, 0}; int opts = 0; - unsigned flags = 0; struct option builtin_patch_id_options[] = { OPT_CMDMODE(0, "unstable", &opts, N_("use the unstable patch-id algorithm"), 1), @@ -297,11 +250,7 @@ int cmd_patch_id(int argc, const char **argv, const char *prefix) if (!the_hash_algo) repo_set_hash_algo(the_repository, GIT_HASH_SHA1); - if (opts ? opts > 1 : config.stable) - flags |= GOPID_STABLE; - if (opts ? opts == 3 : config.verbatim) - flags |= GOPID_VERBATIM; - generate_id_list(flags); - + generate_id_list(opts ? opts > 1 : config.stable, + opts ? opts == 3 : config.verbatim); return 0; } diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index b59fd7c1fd6af1..e2c6ef0f662b9e 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -33,37 +33,49 @@ fedora-*) dnf -yq update >/dev/null && dnf -yq install make gcc findutils diffutils perl python3 gettext zlib-devel expat-devel openssl-devel curl-devel pcre2-devel >/dev/null ;; -ubuntu-*) +ubuntu-*|ubuntu32-*) # Required so that apt doesn't wait for user input on certain packages. export DEBIAN_FRONTEND=noninteractive + case "$distro" in + ubuntu-*) + SVN='libsvn-perl subversion' + ;; + *) + SVN= + ;; + esac + sudo apt-get -q update sudo apt-get -q -y install \ - language-pack-is libsvn-perl apache2 cvs cvsps git gnupg subversion \ + language-pack-is apache2 cvs cvsps git gnupg $SVN \ make libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \ tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \ libemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \ ${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE - mkdir --parents "$CUSTOM_PATH" - wget --quiet --directory-prefix="$CUSTOM_PATH" \ - "$P4WHENCE/bin.linux26x86_64/p4d" "$P4WHENCE/bin.linux26x86_64/p4" - chmod a+x "$CUSTOM_PATH/p4d" "$CUSTOM_PATH/p4" - - wget --quiet "$LFSWHENCE/git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" - tar -xzf "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" \ - -C "$CUSTOM_PATH" --strip-components=1 "git-lfs-$LINUX_GIT_LFS_VERSION/git-lfs" - rm "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" - - wget --quiet "$JGITWHENCE" --output-document="$CUSTOM_PATH/jgit" - chmod a+x "$CUSTOM_PATH/jgit" - ;; -ubuntu32-*) - sudo linux32 --32bit i386 sh -c ' - apt update >/dev/null && - apt install -y build-essential libcurl4-openssl-dev \ - libssl-dev libexpat-dev gettext python >/dev/null - ' + case "$distro" in + ubuntu-16.04) + # Does not support JGit, but we also don't really care about + # the others. We rather care whether Git still compiles and + # runs fine overall. + ;; + ubuntu-*) + mkdir --parents "$CUSTOM_PATH" + + wget --quiet --directory-prefix="$CUSTOM_PATH" \ + "$P4WHENCE/bin.linux26x86_64/p4d" "$P4WHENCE/bin.linux26x86_64/p4" + chmod a+x "$CUSTOM_PATH/p4d" "$CUSTOM_PATH/p4" + + wget --quiet "$LFSWHENCE/git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" + tar -xzf "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" \ + -C "$CUSTOM_PATH" --strip-components=1 "git-lfs-$LINUX_GIT_LFS_VERSION/git-lfs" + rm "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" + + wget --quiet "$JGITWHENCE" --output-document="$CUSTOM_PATH/jgit" + chmod a+x "$CUSTOM_PATH/jgit" + ;; + esac ;; macos-*) export HOMEBREW_NO_AUTO_UPDATE=1 HOMEBREW_NO_INSTALL_CLEANUP=1 diff --git a/ci/lib.sh b/ci/lib.sh index e75108a72f9fbc..d1d40991c4ba42 100755 --- a/ci/lib.sh +++ b/ci/lib.sh @@ -342,7 +342,14 @@ ubuntu-*) fi MAKEFLAGS="$MAKEFLAGS PYTHON_PATH=/usr/bin/$PYTHON_PACKAGE" - export GIT_TEST_HTTPD=true + case "$distro" in + ubuntu-16.04) + # Apache is too old for HTTP/2. + ;; + *) + export GIT_TEST_HTTPD=true + ;; + esac # The Linux build installs the defined dependency versions below. # The OS X build installs much more recent versions, whichever diff --git a/ci/run-docker-build.sh b/ci/run-docker-build.sh deleted file mode 100755 index 6cd832efb9cb59..00000000000000 --- a/ci/run-docker-build.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -# -# Build and test Git inside container -# -# Usage: -# run-docker-build.sh -# - -set -ex - -if test $# -ne 1 || test -z "$1" -then - echo >&2 "usage: run-docker-build.sh " - exit 1 -fi - -case "$jobname" in -linux32) - switch_cmd="linux32 --32bit i386" - ;; -linux-musl) - switch_cmd= - useradd () { adduser -D "$@"; } - ;; -*) - exit 1 - ;; -esac - -"${0%/*}/install-docker-dependencies.sh" - -# If this script runs inside a docker container, then all commands are -# usually executed as root. Consequently, the host user might not be -# able to access the test output files. -# If a non 0 host user id is given, then create a user "ci" with that -# user id to make everything accessible to the host user. -HOST_UID=$1 -if test $HOST_UID -eq 0 -then - # Just in case someone does want to run the test suite as root. - CI_USER=root -else - CI_USER=ci - if test "$(id -u $CI_USER 2>/dev/null)" = $HOST_UID - then - echo "user '$CI_USER' already exists with the requested ID $HOST_UID" - else - useradd -u $HOST_UID $CI_USER - fi -fi - -# Build and test -command $switch_cmd su -m -l $CI_USER -c " - set -ex - export DEVELOPER='$DEVELOPER' - export DEFAULT_TEST_TARGET='$DEFAULT_TEST_TARGET' - export GIT_PROVE_OPTS='$GIT_PROVE_OPTS' - export GIT_TEST_OPTS='$GIT_TEST_OPTS' - export GIT_TEST_CLONE_2GB='$GIT_TEST_CLONE_2GB' - export MAKEFLAGS='$MAKEFLAGS' - export cache_dir='$cache_dir' - cd /usr/src/git - test -n '$cache_dir' && ln -s '$cache_dir/.prove' t/.prove - make - make test -" diff --git a/ci/run-docker.sh b/ci/run-docker.sh deleted file mode 100755 index af89d1624a41cb..00000000000000 --- a/ci/run-docker.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/sh -# -# Download and run Docker image to build and test Git -# - -. ${0%/*}/lib.sh - -case "$jobname" in -linux32) - CI_CONTAINER="daald/ubuntu32:xenial" - ;; -linux-musl) - CI_CONTAINER=alpine - ;; -*) - exit 1 - ;; -esac - -docker pull "$CI_CONTAINER" - -# Use the following command to debug the docker build locally: -# must be 0 if podman is used as drop-in replacement for docker -# $ docker run -itv "${PWD}:/usr/src/git" --entrypoint /bin/sh "$CI_CONTAINER" -# root@container:/# export jobname= -# root@container:/# /usr/src/git/ci/run-docker-build.sh - -container_cache_dir=/tmp/container-cache - -docker run \ - --interactive \ - --env DEVELOPER \ - --env DEFAULT_TEST_TARGET \ - --env GIT_PROVE_OPTS \ - --env GIT_TEST_OPTS \ - --env GIT_TEST_CLONE_2GB \ - --env MAKEFLAGS \ - --env jobname \ - --env cache_dir="$container_cache_dir" \ - --volume "${PWD}:/usr/src/git" \ - --volume "$cache_dir:$container_cache_dir" \ - "$CI_CONTAINER" \ - /usr/src/git/ci/run-docker-build.sh $(id -u $USER) - -check_unignored_build_artifacts - -save_good_tree diff --git a/config.mak.uname b/config.mak.uname index 2a491021a78a5d..d500245d814efd 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -249,6 +249,7 @@ ifeq ($(uname_O),Cygwin) else NO_REGEX = UnfortunatelyYes endif + HAVE_DEV_TTY = YesPlease HAVE_ALLOCA_H = YesPlease NEEDS_LIBICONV = YesPlease NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes diff --git a/diff.c b/diff.c index ebb7538e040a71..a83409944b0243 100644 --- a/diff.c +++ b/diff.c @@ -3565,6 +3565,7 @@ static void builtin_diff(const char *name_a, show_submodule_diff_summary(o, one->path ? one->path : two->path, &one->oid, &two->oid, two->dirty_submodule); + o->found_changes = 1; return; } else if (o->submodule_format == DIFF_SUBMODULE_INLINE_DIFF && (!one->mode || S_ISGITLINK(one->mode)) && @@ -3573,6 +3574,7 @@ static void builtin_diff(const char *name_a, show_submodule_inline_diff(o, one->path ? one->path : two->path, &one->oid, &two->oid, two->dirty_submodule); + o->found_changes = 1; return; } @@ -4587,6 +4589,9 @@ static void run_diff_cmd(const struct external_diff *pgm, builtin_diff(name, other ? other : name, one, two, xfrm_msg, must_show_header, o, complete_rewrite); + if (p->status == DIFF_STATUS_COPIED || + p->status == DIFF_STATUS_RENAMED) + o->found_changes = 1; } else { fprintf(o->file, "* Unmerged path %s\n", name); o->found_changes = 1; diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh index 070fe7a5da7c24..dddc130560ba61 100755 --- a/t/t0211-trace2-perf.sh +++ b/t/t0211-trace2-perf.sh @@ -337,7 +337,8 @@ test_expect_success 'expect def_params for query command' ' # remote-curl.c rather than git.c. Confirm that we get def_param # events from both layers. # -test_expect_success 'expect def_params for remote-curl and _run_dashed_' ' +test_expect_success LIBCURL \ + 'expect def_params for remote-curl and _run_dashed_' ' test_when_finished "rm prop.perf actual" && test_config_global "trace2.configParams" "cfg.prop.*" && @@ -366,7 +367,8 @@ test_expect_success 'expect def_params for remote-curl and _run_dashed_' ' # an executable built from http-fetch.c. Confirm that we get # def_param events from both layers. # -test_expect_success 'expect def_params for http-fetch and _run_dashed_' ' +test_expect_success LIBCURL \ + 'expect def_params for http-fetch and _run_dashed_' ' test_when_finished "rm prop.perf actual" && test_config_global "trace2.configParams" "cfg.prop.*" && diff --git a/t/t1517-outside-repo.sh b/t/t1517-outside-repo.sh index 990a03658214a4..342defbb617628 100755 --- a/t/t1517-outside-repo.sh +++ b/t/t1517-outside-repo.sh @@ -98,7 +98,7 @@ test_expect_success 'stripspace outside repository' ' nongit git stripspace -s actual && test_grep "^error: remote-curl" actual && ( diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh index f439f469bd2bfd..d644310e22a5d1 100755 --- a/t/t4017-diff-retval.sh +++ b/t/t4017-diff-retval.sh @@ -143,4 +143,41 @@ test_expect_success 'option errors are not confused by --exit-code' ' grep '^usage:' err ' +for option in --exit-code --quiet +do + test_expect_success "git diff $option returns 1 for copied file" " + git reset --hard && + cp a copy && + git add copy && + test_expect_code 1 git diff $option --cached --find-copies-harder + " + + test_expect_success "git diff $option returns 1 for renamed file" " + git reset --hard && + git mv a renamed && + test_expect_code 1 git diff $option --cached + " +done + +test_expect_success 'setup dirty subrepo' ' + git reset --hard && + test_create_repo subrepo && + test_commit -C subrepo subrepo-file && + test_tick && + git add subrepo && + git commit -m subrepo && + test_commit -C subrepo another-subrepo-file +' + +for option in --exit-code --quiet +do + for submodule_format in diff log short + do + opts="$option --submodule=$submodule_format" && + test_expect_success "git diff $opts returns 1 for dirty subrepo" " + test_expect_code 1 git diff $opts + " + done +done + test_done diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh index dc8ddb10affcea..605faea0c7baae 100755 --- a/t/t4204-patch-id.sh +++ b/t/t4204-patch-id.sh @@ -114,46 +114,6 @@ test_expect_success 'patch-id supports git-format-patch output' ' test "$2" = $(git rev-parse HEAD) ' -test_expect_success 'patch-id computes the same for various formats' ' - # This test happens to consider "git log -p -1" output - # the canonical input format, so use it as the norm. - git log -1 -p same >log-p.output && - git patch-id expect && - - # format-patch begins with "From " - git format-patch -1 --stdout same >format-patch.output && - git patch-id actual && - test_cmp actual expect && - - # "diff-tree --stdin -p" begins with "" - same=$(git rev-parse same) && - echo $same | git diff-tree --stdin -p >diff-tree.output && - git patch-id actual && - test_cmp actual expect && - - # "diff-tree --stdin -v -p" begins with "commit " - echo $same | git diff-tree --stdin -p -v >diff-tree-v.output && - git patch-id actual && - test_cmp actual expect -' - -hash=$(git rev-parse same:) -for cruft in "$hash" "commit $hash is bad" "From $hash status" -do - test_expect_success "patch-id with <$cruft> in log message" ' - git format-patch -1 --stdout same >patch-0 && - git patch-id expect && - - { - sed -e "/^$/q" patch-0 && - printf "random message\n%s\n\n" "$cruft" && - sed -e "1,/^$/d" patch-0 - } >patch-cruft && - git patch-id actual && - test_cmp actual expect - ' -done - test_expect_success 'whitespace is irrelevant in footer' ' get_patch_id main && git checkout same && diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh index 3d3e13ccf87215..0f7d8938d984d9 100755 --- a/t/t7513-interpret-trailers.sh +++ b/t/t7513-interpret-trailers.sh @@ -175,6 +175,46 @@ test_expect_success 'with only a title in the message' ' test_cmp expected actual ' +test_expect_success 'with a bodiless message that lacks a trailing newline after the subject' ' + cat >expected <<-\EOF && + area: change + + Reviewed-by: Peff + Acked-by: Johan + EOF + printf "area: change" | + git interpret-trailers --trailer "Reviewed-by: Peff" \ + --trailer "Acked-by: Johan" >actual && + test_cmp expected actual +' + +test_expect_success 'with a bodied message that lacks a trailing newline after the body' ' + cat >expected <<-\EOF && + area: change + + details about the change. + + Reviewed-by: Peff + Acked-by: Johan + EOF + printf "area: change\n\ndetails about the change." | + git interpret-trailers --trailer "Reviewed-by: Peff" \ + --trailer "Acked-by: Johan" >actual && + test_cmp expected actual +' + +test_expect_success 'with a message that lacks a trailing newline after the trailers' ' + cat >expected <<-\EOF && + area: change + + Reviewed-by: Peff + Acked-by: Johan + EOF + printf "area: change\n\nReviewed-by: Peff" | + git interpret-trailers --trailer "Acked-by: Johan" >actual && + test_cmp expected actual +' + test_expect_success 'with multiline title in the message' ' cat >expected <<-\EOF && place of