diff options
35 files changed, 324 insertions, 74 deletions
diff --git a/Documentation/RelNotes/2.36.1.txt b/Documentation/RelNotes/2.36.1.txt new file mode 100644 index 0000000000..a9617095db --- /dev/null +++ b/Documentation/RelNotes/2.36.1.txt @@ -0,0 +1,33 @@ +Git v2.36.1 Release Notes +========================= + +Fixes since v2.36 +----------------- + + * "git submodule update" without pathspec should silently skip an + uninitialized submodule, but it started to become noisy by mistake. + + * "diff-tree --stdin" has been broken for about a year, but 2.36 + release broke it even worse by breaking running the command with + <pathspec>, which in turn broke "gitk" and got noticed. This has + been corrected by aligning its behaviour to that of "log". + + * Regression fix for 2.36 where "git name-rev" started to sometimes + reference strings after they are freed. + + * "git show <commit1> <commit2>... -- <pathspec>" lost the pathspec + when showing the second and subsequent commits, which has been + corrected. + + * "git fast-export -- <pathspec>" lost the pathspec when showing the + second and subsequent commits, which has been corrected. + + * "git format-patch <args> -- <pathspec>" lost the pathspec when + showing the second and subsequent commits, which has been + corrected. + + * Get rid of a bogus and over-eager coccinelle rule. + + * Correct choices of C compilers used in various CI jobs. + +Also contains minor documentation updates and code clean-ups. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index a6121d1d42..5bd795e5db 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -452,7 +452,10 @@ repositories. - `gitk-git/` comes from Paul Mackerras's gitk project: - git://ozlabs.org/~paulus/gitk + git://git.ozlabs.org/~paulus/gitk + + Those who are interested in improve gitk can volunteer to help Paul + in maintaining it cf. <YntxL/fTplFm8lr6@cleo>. - `po/` comes from the localization coordinator, Jiang Xin: diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index fdcebd2c58..c1e8552d27 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.36.0 +DEF_VER=v2.36.1 LF=' ' @@ -1267,8 +1267,9 @@ PTHREAD_CFLAGS = SPARSE_FLAGS ?= -std=gnu99 SP_EXTRA_FLAGS = -Wno-universal-initializer -# For informing GIT-BUILD-OPTIONS of the SANITIZE=leak target +# For informing GIT-BUILD-OPTIONS of the SANITIZE=leak,address targets SANITIZE_LEAK = +SANITIZE_ADDRESS = # For the 'coccicheck' target; setting SPATCH_BATCH_SIZE higher will # usually result in less CPU usage at the cost of higher peak memory. @@ -1314,6 +1315,7 @@ SANITIZE_LEAK = YesCompiledWithIt endif ifneq ($(filter address,$(SANITIZERS)),) NO_REGEX = NeededForASAN +SANITIZE_ADDRESS = YesCompiledWithIt endif endif @@ -2862,6 +2864,7 @@ GIT-BUILD-OPTIONS: FORCE @echo PAGER_ENV=\''$(subst ','\'',$(subst ','\'',$(PAGER_ENV)))'\' >>$@+ @echo DC_SHA1=\''$(subst ','\'',$(subst ','\'',$(DC_SHA1)))'\' >>$@+ @echo SANITIZE_LEAK=\''$(subst ','\'',$(subst ','\'',$(SANITIZE_LEAK)))'\' >>$@+ + @echo SANITIZE_ADDRESS=\''$(subst ','\'',$(subst ','\'',$(SANITIZE_ADDRESS)))'\' >>$@+ @echo X=\'$(X)\' >>$@+ ifdef FSMONITOR_DAEMON_BACKEND @echo FSMONITOR_DAEMON_BACKEND=\''$(subst ','\'',$(subst ','\'',$(FSMONITOR_DAEMON_BACKEND)))'\' >>$@+ @@ -1 +1 @@ -Documentation/RelNotes/2.36.0.txt
\ No newline at end of file +Documentation/RelNotes/2.36.1.txt
\ No newline at end of file @@ -342,7 +342,7 @@ int write_archive_entries(struct archiver_args *args, else err = write_entry(args, &fake_oid, path_in_archive.buf, path_in_archive.len, - info->stat.st_mode, + canon_mode(info->stat.st_mode), content.buf, content.len); if (err) break; diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 0e0ac1f167..116097a404 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -195,6 +195,7 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) int saved_dcctc = 0; opt->diffopt.rotate_to_strict = 0; + opt->diffopt.no_free = 1; if (opt->diffopt.detect_rename) { if (!the_index.cache) repo_read_index(the_repository); @@ -217,6 +218,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) } opt->diffopt.degraded_cc_to_c = saved_dcctc; opt->diffopt.needed_rename_limit = saved_nrl; + opt->diffopt.no_free = 0; + diff_free(&opt->diffopt); } return diff_result_code(&opt->diffopt, 0); diff --git a/builtin/fast-export.c b/builtin/fast-export.c index a7d72697fb..1355b5a96d 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -1261,6 +1261,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) revs.diffopt.format_callback = show_filemodify; revs.diffopt.format_callback_data = &paths_of_changed_objects; revs.diffopt.flags.recursive = 1; + revs.diffopt.no_free = 1; while ((commit = get_revision(&revs))) handle_commit(commit, &revs, &paths_of_changed_objects); diff --git a/builtin/log.c b/builtin/log.c index c211d66d1d..3ac479bec3 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -417,7 +417,7 @@ static void finish_early_output(struct rev_info *rev) show_early_header(rev, "done", n); } -static int cmd_log_walk(struct rev_info *rev) +static int cmd_log_walk_no_free(struct rev_info *rev) { struct commit *commit; int saved_nrl = 0; @@ -444,7 +444,6 @@ static int cmd_log_walk(struct rev_info *rev) * and HAS_CHANGES being accumulated in rev->diffopt, so be careful to * retain that state information if replacing rev->diffopt in this loop */ - rev->diffopt.no_free = 1; while ((commit = get_revision(rev)) != NULL) { if (!log_tree_commit(rev, commit) && rev->max_count >= 0) /* @@ -469,8 +468,6 @@ static int cmd_log_walk(struct rev_info *rev) } rev->diffopt.degraded_cc_to_c = saved_dcctc; rev->diffopt.needed_rename_limit = saved_nrl; - rev->diffopt.no_free = 0; - diff_free(&rev->diffopt); if (rev->remerge_diff) { tmp_objdir_destroy(rev->remerge_objdir); @@ -484,6 +481,17 @@ static int cmd_log_walk(struct rev_info *rev) return diff_result_code(&rev->diffopt, 0); } +static int cmd_log_walk(struct rev_info *rev) +{ + int retval; + + rev->diffopt.no_free = 1; + retval = cmd_log_walk_no_free(rev); + rev->diffopt.no_free = 0; + diff_free(&rev->diffopt); + return retval; +} + static int git_log_config(const char *var, const char *value, void *cb) { const char *slot_name; @@ -680,6 +688,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) count = rev.pending.nr; objects = rev.pending.objects; + rev.diffopt.no_free = 1; for (i = 0; i < count && !ret; i++) { struct object *o = objects[i].item; const char *name = objects[i].name; @@ -725,12 +734,16 @@ int cmd_show(int argc, const char **argv, const char *prefix) rev.pending.nr = rev.pending.alloc = 0; rev.pending.objects = NULL; add_object_array(o, name, &rev.pending); - ret = cmd_log_walk(&rev); + ret = cmd_log_walk_no_free(&rev); break; default: ret = error(_("unknown type: %d"), o->type); } } + + rev.diffopt.no_free = 0; + diff_free(&rev.diffopt); + free(objects); return ret; } @@ -1883,6 +1896,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.diff = 1; rev.max_parents = 1; rev.diffopt.flags.recursive = 1; + rev.diffopt.no_free = 1; rev.subject_prefix = fmt_patch_subject_prefix; memset(&s_r_opt, 0, sizeof(s_r_opt)); s_r_opt.def = "HEAD"; @@ -2008,13 +2022,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (use_stdout) { setup_pager(); - } else if (rev.diffopt.close_file) { - /* - * The diff code parsed --output; it has already opened the - * file, but we must instruct it not to close after each diff. - */ - rev.diffopt.no_free = 1; - } else { + } else if (!rev.diffopt.close_file) { int saved; if (!output_directory) diff --git a/builtin/name-rev.c b/builtin/name-rev.c index c59b5699fe..02ea9d1633 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -18,7 +18,7 @@ #define CUTOFF_DATE_SLOP 86400 struct rev_name { - char *tip_name; + const char *tip_name; timestamp_t taggerdate; int generation; int distance; @@ -84,7 +84,7 @@ static int commit_is_before_cutoff(struct commit *commit) static int is_valid_rev_name(const struct rev_name *name) { - return name && (name->generation || name->tip_name); + return name && name->tip_name; } static struct rev_name *get_commit_rev_name(const struct commit *commit) @@ -146,20 +146,9 @@ static struct rev_name *create_or_update_name(struct commit *commit, { struct rev_name *name = commit_rev_name_at(&rev_names, commit); - if (is_valid_rev_name(name)) { - if (!is_better_name(name, taggerdate, generation, distance, from_tag)) - return NULL; - - /* - * This string might still be shared with ancestors - * (generation > 0). We can release it here regardless, - * because the new name that has just won will be better - * for them as well, so name_rev() will replace these - * stale pointers when it processes the parents. - */ - if (!name->generation) - free(name->tip_name); - } + if (is_valid_rev_name(name) && + !is_better_name(name, taggerdate, generation, distance, from_tag)) + return NULL; name->taggerdate = taggerdate; name->generation = generation; diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 330b0553b9..64c649c6a2 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -712,6 +712,10 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) "--all/--remotes/--independent/--merge-base"); } + if (with_current_branch && reflog) + die(_("options '%s' and '%s' cannot be used together"), + "--reflog", "--current"); + /* If nothing is specified, show all branches by default */ if (ac <= topics && all_heads + all_remotes == 0) all_heads = 1; diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 2c87ef9364..1a8e5d0621 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -2026,7 +2026,6 @@ struct update_data { .references = STRING_LIST_INIT_DUP, \ .single_branch = -1, \ .max_jobs = 1, \ - .warn_if_uninitialized = 1, \ } static void next_submodule_warn_missing(struct submodule_update_clone *suc, diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index dbcebad2fb..107757a1fe 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -5,7 +5,7 @@ . ${0%/*}/lib.sh -P4WHENCE=http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION +P4WHENCE=https://cdist2.perforce.com/perforce/r$LINUX_P4_VERSION LFSWHENCE=https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION UBUNTU_COMMON_PKGS="make libssl-dev libcurl4-openssl-dev libexpat-dev tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl @@ -37,13 +37,15 @@ macos-latest) test -z "$BREW_INSTALL_PACKAGES" || brew install $BREW_INSTALL_PACKAGES brew link --force gettext - brew install --cask --no-quarantine perforce || { - # Update the definitions and try again - cask_repo="$(brew --repository)"/Library/Taps/homebrew/homebrew-cask && - git -C "$cask_repo" pull --no-stat --ff-only && - brew install --cask --no-quarantine perforce - } || - brew install homebrew/cask/perforce + mkdir -p $HOME/bin + ( + cd $HOME/bin + wget -q "https://cdist2.perforce.com/perforce/r21.2/bin.macosx1015x86_64/helix-core-server.tgz" && + tar -xf helix-core-server.tgz && + sudo xattr -d com.apple.quarantine p4 p4d 2>/dev/null || true + ) + PATH="$PATH:${HOME}/bin" + export PATH if test -n "$CC_PACKAGE" then @@ -78,15 +80,19 @@ linux-gcc-default) ;; esac -if type p4d >/dev/null && type p4 >/dev/null +if type p4d >/dev/null 2>&1 && type p4 >/dev/null 2>&1 then echo "$(tput setaf 6)Perforce Server Version$(tput sgr0)" p4d -V | grep Rev. echo "$(tput setaf 6)Perforce Client Version$(tput sgr0)" p4 -V | grep Rev. +else + echo >&2 "WARNING: perforce wasn't installed, see above for clues why" fi -if type git-lfs >/dev/null +if type git-lfs >/dev/null 2>&1 then echo "$(tput setaf 6)Git-LFS Version$(tput sgr0)" git-lfs version +else + echo >&2 "WARNING: git-lfs wasn't installed, see above for clues why" fi @@ -122,7 +122,7 @@ then test macos != "$CI_OS_NAME" || CI_OS_NAME=osx CI_REPO_SLUG="$GITHUB_REPOSITORY" CI_JOB_ID="$GITHUB_RUN_ID" - CC="${CC:-gcc}" + CC="${CC_PACKAGE:-${CC:-gcc}}" DONT_SKIP_TAGS=t cache_dir="$HOME/none" diff --git a/commit-graph.c b/commit-graph.c index 441b36016b..2b52818731 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -2206,7 +2206,8 @@ static void mark_commit_graphs(struct write_commit_graph_context *ctx) struct stat st; struct utimbuf updated_time; - stat(ctx->commit_graph_filenames_before[i], &st); + if (stat(ctx->commit_graph_filenames_before[i], &st) < 0) + continue; updated_time.actime = st.st_atime; updated_time.modtime = now; @@ -2247,7 +2248,8 @@ static void expire_commit_graphs(struct write_commit_graph_context *ctx) strbuf_setlen(&path, dirnamelen); strbuf_addstr(&path, de->d_name); - stat(path.buf, &st); + if (stat(path.buf, &st) < 0) + continue; if (st.st_mtime > expire_time) continue; diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c index edb438a777..2c0ace7075 100644 --- a/compat/nedmalloc/nedmalloc.c +++ b/compat/nedmalloc/nedmalloc.c @@ -323,7 +323,6 @@ static NOINLINE void RemoveCacheEntries(nedpool *p, threadcache *tc, unsigned in } static void DestroyCaches(nedpool *p) THROWSPEC { - if(p->caches) { threadcache *tc; int n; diff --git a/compat/win32/syslog.c b/compat/win32/syslog.c index 161978d720..1f8d8934cc 100644 --- a/compat/win32/syslog.c +++ b/compat/win32/syslog.c @@ -43,6 +43,7 @@ void syslog(int priority, const char *fmt, ...) va_end(ap); while ((pos = strstr(str, "%1")) != NULL) { + size_t offset = pos - str; char *oldstr = str; str = realloc(str, st_add(++str_len, 1)); if (!str) { @@ -50,6 +51,7 @@ void syslog(int priority, const char *fmt, ...) warning_errno("realloc failed"); return; } + pos = str + offset; memmove(pos + 2, pos + 1, strlen(pos)); pos[1] = ' '; } diff --git a/contrib/coccinelle/xstrdup_or_null.cocci b/contrib/coccinelle/xstrdup_or_null.cocci index 8e05d1ca4b..9c1d2939b6 100644 --- a/contrib/coccinelle/xstrdup_or_null.cocci +++ b/contrib/coccinelle/xstrdup_or_null.cocci @@ -1,13 +1,5 @@ @@ expression E; -expression V; -@@ -- if (E) -- V = xstrdup(E); -+ V = xstrdup_or_null(E); - -@@ -expression E; @@ - xstrdup(absolute_path(E)) + absolute_pathdup(E) diff --git a/detect-compiler b/detect-compiler index 11d60da5b7..50087f5670 100755 --- a/detect-compiler +++ b/detect-compiler @@ -9,7 +9,7 @@ CC="$*" # # FreeBSD clang version 3.4.1 (tags/RELEASE...) get_version_line() { - $CC -v 2>&1 | grep ' version ' + LANG=C LC_ALL=C $CC -v 2>&1 | grep ' version ' } get_family() { @@ -3082,6 +3082,15 @@ char *git_url_basename(const char *repo, int is_bundle, int is_bare) } /* + * It should not be possible to overflow `ptrdiff_t` by passing in an + * insanely long URL, but GCC does not know that and will complain + * without this check. + */ + if (end - start < 0) + die(_("No directory name could be guessed.\n" + "Please specify a directory on the command line")); + + /* * Strip trailing port number if we've got only a * hostname (that is, there is no dir separator but a * colon). This check is required such that we do not @@ -1367,6 +1367,32 @@ void run_active_slot(struct active_request_slot *slot) select(max_fd+1, &readfds, &writefds, &excfds, &select_timeout); } } + + /* + * The value of slot->finished we set before the loop was used + * to set our "finished" variable when our request completed. + * + * 1. The slot may not have been reused for another requst + * yet, in which case it still has &finished. + * + * 2. The slot may already be in-use to serve another request, + * which can further be divided into two cases: + * + * (a) If call run_active_slot() hasn't been called for that + * other request, slot->finished would have been cleared + * by get_active_slot() and has NULL. + * + * (b) If the request did call run_active_slot(), then the + * call would have updated slot->finished at the beginning + * of this function, and with the clearing of the member + * below, we would find that slot->finished is now NULL. + * + * In all cases, slot->finished has no useful information to + * anybody at this point. Some compilers warn us for + * attempting to smuggle a pointer that is about to become + * invalid, i.e. &finished. We clear it here to assure them. + */ + slot->finished = NULL; } static void release_active_slot(struct active_request_slot *slot) diff --git a/log-tree.c b/log-tree.c index 38e5cccc1a..3a03e34c30 100644 --- a/log-tree.c +++ b/log-tree.c @@ -1098,6 +1098,7 @@ int log_tree_commit(struct rev_info *opt, struct commit *commit) opt->loginfo = &log; opt->diffopt.no_free = 1; + /* NEEDSWORK: no restoring of no_free? Why? */ if (opt->line_level_traverse) return line_log_print(opt, commit); diff --git a/object-file.c b/object-file.c index 5ffbf3d4fd..b5d1d12b68 100644 --- a/object-file.c +++ b/object-file.c @@ -2623,8 +2623,12 @@ int read_loose_object(const char *path, goto out; } - if (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr), - NULL) < 0) { + switch (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr), + NULL)) { + case ULHR_OK: + break; + case ULHR_BAD: + case ULHR_TOO_LONG: error(_("unable to unpack header of %s"), path); goto out; } diff --git a/sequencer.c b/sequencer.c index a5f678f452..8c3ed3532a 100644 --- a/sequencer.c +++ b/sequencer.c @@ -1327,7 +1327,6 @@ void print_commit_summary(struct repository *r, get_commit_format(format.buf, &rev); rev.always_show_header = 0; rev.diffopt.detect_rename = DIFF_DETECT_RENAME; - rev.diffopt.break_opt = 0; diff_setup_done(&rev.diffopt); refs = get_main_ref_store(the_repository); diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 2fe6ae6a4e..aa35350b6f 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -542,7 +542,7 @@ test_lazy_prereq CAN_EXEC_IN_PWD ' ./git rev-parse ' -test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' +test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' mkdir -p pretend/bin pretend/libexec/git-core && echo "echo HERE" | write_script pretend/libexec/git-core/git-here && cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && @@ -550,7 +550,7 @@ test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' echo HERE >expect && test_cmp expect actual' -test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' ' +test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' ' mkdir -p pretend/bin && cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && git config yes.path "%(prefix)/yes" && diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index 1b85207694..dadf3b1458 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -681,7 +681,7 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' ' # Setup and create the empty blob and its path empty_path=$(git rev-parse --git-path objects/$(test_oid_to_path "$EMPTY_BLOB")) && - git hash-object -w --stdin </dev/null && + empty_blob=$(git hash-object -w --stdin </dev/null) && # Create another blob and its path echo other >other.blob && @@ -722,7 +722,13 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' ' # content out as-is. Try to make it zlib-invalid. mv -f other.blob "$empty_path" && test_must_fail git fsck 2>err.fsck && - grep "^error: inflate: data stream error (" err.fsck + cat >expect <<-EOF && + error: inflate: data stream error (incorrect header check) + error: unable to unpack header of ./$empty_path + error: $empty_blob: object corrupt or missing: ./$empty_path + EOF + grep "^error: " err.fsck >actual && + test_cmp expect actual ) ' diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index de50c0ea01..ab7f31f1dc 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -774,10 +774,19 @@ test_expect_success 'fsck finds problems in duplicate loose objects' ' # no "-d" here, so we end up with duplicates git repack && # now corrupt the loose copy - file=$(sha1_file "$(git rev-parse HEAD)") && + oid="$(git rev-parse HEAD)" && + file=$(sha1_file "$oid") && rm "$file" && echo broken >"$file" && - test_must_fail git fsck + test_must_fail git fsck 2>err && + + cat >expect <<-EOF && + error: inflate: data stream error (incorrect header check) + error: unable to unpack header of $file + error: $oid: object corrupt or missing: $file + EOF + grep "^error: " err >actual && + test_cmp expect actual ) ' diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh index 7a1be73ce8..f2b9199007 100755 --- a/t/t3202-show-branch.sh +++ b/t/t3202-show-branch.sh @@ -161,4 +161,18 @@ test_expect_success 'show branch --reflog=2' ' test_cmp actual expect ' +# incompatible options +while read combo +do + test_expect_success "show-branch $combo (should fail)" ' + test_must_fail git show-branch $combo 2>error && + grep -e "cannot be used together" -e "usage:" error + ' +done <<\EOF +--all --reflog +--merge-base --reflog +--list --merge-base +--reflog --current +EOF + test_done diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 750aee17ea..056e922164 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -542,6 +542,39 @@ test_expect_success 'diff-tree --stdin with log formatting' ' test_cmp expect actual ' +test_expect_success 'diff-tree --stdin with pathspec' ' + cat >expect <<-EOF && + Third + + dir/sub + Second + + dir/sub + EOF + git rev-list master^ | + git diff-tree -r --stdin --name-only --format=%s dir >actual && + test_cmp expect actual +' + +test_expect_success 'show A B ... -- <pathspec>' ' + # side touches dir/sub, file0, and file3 + # master^ touches dir/sub, and file1 + # master^^ touches dir/sub, file0, and file2 + git show --name-only --format="<%s>" side master^ master^^ -- dir >actual && + cat >expect <<-\EOF && + <Side> + + dir/sub + <Third> + + dir/sub + <Second> + + dir/sub + EOF + test_cmp expect actual +' + test_expect_success 'diff -I<regex>: setup' ' git checkout master && test_seq 50 >file0 && diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 7dc5a5c736..fbec8ad2ef 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -926,11 +926,40 @@ test_expect_success 'format-patch --numstat should produce a patch' ' ' test_expect_success 'format-patch -- <path>' ' - git format-patch main..side -- file 2>error && - ! grep "Use .--" error + rm -f *.patch && + git checkout -b pathspec main && + + echo file_a 1 >file_a && + echo file_b 1 >file_b && + git add file_a file_b && + git commit -m pathspec_initial && + + echo file_a 2 >>file_a && + git add file_a && + git commit -m pathspec_a && + + echo file_b 2 >>file_b && + git add file_b && + git commit -m pathspec_b && + + echo file_a 3 >>file_a && + echo file_b 3 >>file_b && + git add file_a file_b && + git commit -m pathspec_ab && + + cat >expect <<-\EOF && + 0001-pathspec_initial.patch + 0002-pathspec_a.patch + 0003-pathspec_ab.patch + EOF + + git format-patch main..pathspec -- file_a >output && + test_cmp expect output && + ! grep file_b *.patch ' test_expect_success 'format-patch --ignore-if-in-upstream HEAD' ' + git checkout side && git format-patch --ignore-if-in-upstream HEAD ' diff --git a/t/t4202-log.sh b/t/t4202-log.sh index be07407f85..6e66352558 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -1992,10 +1992,13 @@ test_expect_success GPG 'log --show-signature for merged tag with GPG failure' ' git tag -s -m signed_tag_msg signed_tag_fail && git checkout plain-fail && git merge --no-ff -m msg signed_tag_fail && - TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual && - grep "^merged tag" actual && - grep "^No signature" actual && - ! grep "^gpg: Signature made" actual + if ! test_have_prereq VALGRIND + then + TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual && + grep "^merged tag" actual && + grep "^No signature" actual && + ! grep "^gpg: Signature made" actual + fi ' test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' ' diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 000e055811..43f779d751 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -670,6 +670,39 @@ test_expect_success 'submodule update --init skips submodule with update=none' ' ) ' +test_expect_success 'submodule update with pathspec warns against uninitialized ones' ' + test_when_finished "rm -fr selective" && + git clone super selective && + ( + cd selective && + git submodule init submodule && + + git submodule update submodule 2>err && + ! grep "Submodule path .* not initialized" err && + + git submodule update rebasing 2>err && + grep "Submodule path .rebasing. not initialized" err && + + test_path_exists submodule/.git && + test_path_is_missing rebasing/.git + ) + +' + +test_expect_success 'submodule update without pathspec updates only initialized ones' ' + test_when_finished "rm -fr selective" && + git clone super selective && + ( + cd selective && + git submodule init submodule && + git submodule update 2>err && + test_path_exists submodule/.git && + test_path_is_missing rebasing/.git && + ! grep "Submodule path .* not initialized" err + ) + +' + test_expect_success 'submodule update continues after checkout error' ' (cd super && git reset --hard HEAD && diff --git a/t/t7524-commit-summary.sh b/t/t7524-commit-summary.sh new file mode 100755 index 0000000000..47b2f1dc22 --- /dev/null +++ b/t/t7524-commit-summary.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +test_description='git commit summary' +. ./test-lib.sh + +test_expect_success 'setup' ' + test_seq 101 200 >file && + git add file && + git commit -m initial && + git tag initial +' + +test_expect_success 'commit summary ignores rewrites' ' + git reset --hard initial && + test_seq 200 300 >file && + + git diff --stat >diffstat && + git diff --stat --break-rewrites >diffstatrewrite && + + # make sure this scenario is a detectable rewrite + ! test_cmp_bin diffstat diffstatrewrite && + + git add file && + git commit -m second >actual && + + grep "1 file" <actual >actual.total && + grep "1 file" <diffstat >diffstat.total && + test_cmp diffstat.total actual.total +' + +test_done diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 7b7a18dd2c..fc99703fc5 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -500,6 +500,13 @@ test_expect_success 'path limiting with import-marks does not lose unmodified fi grep file0 actual ' +test_expect_success 'path limiting works' ' + git fast-export simple -- file >actual && + sed -ne "s/^M .* //p" <actual | sort -u >actual.files && + echo file >expect && + test_cmp expect actual.files +' + test_expect_success 'avoid corrupt stream with non-existent mark' ' test_create_repo avoid_non_existent_mark && ( diff --git a/t/test-lib.sh b/t/test-lib.sh index 531cef097d..8ba5ca1534 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -535,9 +535,10 @@ case $GIT_TEST_FSYNC in ;; esac -# Add libc MALLOC and MALLOC_PERTURB test -# only if we are not executing the test with valgrind +# Add libc MALLOC and MALLOC_PERTURB test only if we are not executing +# the test with valgrind and have not compiled with SANITIZE=address. if test -n "$valgrind" || + test -n "$SANITIZE_ADDRESS" || test -n "$TEST_NO_MALLOC_CHECK" then setup_malloc_check () { @@ -1666,6 +1667,7 @@ test -n "$USE_LIBPCRE2" && test_set_prereq PCRE test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT test -n "$SANITIZE_LEAK" && test_set_prereq SANITIZE_LEAK +test -n "$GIT_VALGRIND_ENABLED" && test_set_prereq VALGRIND if test -z "$GIT_TEST_CHECK_CACHE_TREE" then |
