diff --git a/Documentation/RelNotes/2.53.0.adoc b/Documentation/RelNotes/2.53.0.adoc index 38cbd2186e8172..41ae2a5a7a4696 100644 --- a/Documentation/RelNotes/2.53.0.adoc +++ b/Documentation/RelNotes/2.53.0.adoc @@ -26,6 +26,11 @@ UI, Workflows & Features * The use of "revision" (a connected set of commits) has been clarified in the "git replay" documentation. + * A help message from "git branch" now mentions "git help" instead of + "man" when suggesting to read some documentation. + + * "git repo struct" learned to take "-z" as a synonym to "--format=nul". + Performance, Internal Implementation, Development Support etc. -------------------------------------------------------------- @@ -51,6 +56,10 @@ Performance, Internal Implementation, Development Support etc. * Code refactoring around object database sources. + * Halve the memory consumed by artificial filepairs created during + "git diff --find-copioes-harder", also making the operation run + faster. + Fixes since v2.52 ----------------- @@ -150,9 +159,18 @@ Fixes since v2.52 * The way patience diff finds LCS has been optimized. (merge c7e3b8085b yc/xdiff-patience-optim later to maint). + * Recent optimization to "last-modified" command introduced use of + uninitialized block of memory, which has been corrected. + (merge fe4e60759b tc/last-modified-active-paths-optimization later to maint). + + * "git last-modified" used to mishandle "--" to mark the beginning of + pathspec, which has been corrected. + (merge 05491b90ce js/last-modified-with-sparse-checkouts later to maint). + * Other code cleanup, docfix, build fix, etc. (merge 46207a54cc qj/doc-http-bad-want-response later to maint). (merge df90eccd93 kh/doc-commit-extra-references later to maint). (merge f18aa68861 rs/xmkstemp-simplify later to maint). (merge fddba8f737 ja/doc-synopsis-style later to maint). (merge 22ce0cb639 en/xdiff-cleanup-2 later to maint). + (merge 8ef7355a8f je/doc-pull later to maint). diff --git a/Documentation/git-pull.adoc b/Documentation/git-pull.adoc index 248f6c3f39ac74..88f4fd3926981e 100644 --- a/Documentation/git-pull.adoc +++ b/Documentation/git-pull.adoc @@ -37,8 +37,8 @@ You can also set the configuration options `pull.rebase`, `pull.squash`, or `pull.ff` with your preferred behaviour. If there's a merge conflict during the merge or rebase that you don't -want to handle, you can safely abort it with `git merge --abort` or `git ---rebase abort`. +want to handle, you can safely abort it with `git merge --abort` or +`git rebase --abort`. OPTIONS ------- diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc index 70f0a6d2e47291..c4a78277df61c0 100644 --- a/Documentation/git-repo.adoc +++ b/Documentation/git-repo.adoc @@ -8,8 +8,8 @@ git-repo - Retrieve information about the repository SYNOPSIS -------- [synopsis] -git repo info [--format=(keyvalue|nul)] [-z] [--all | ...] -git repo structure [--format=(table|keyvalue|nul)] +git repo info [--format=(keyvalue|nul) | -z] [--all | ...] +git repo structure [--format=(table|keyvalue|nul) | -z] DESCRIPTION ----------- @@ -19,7 +19,7 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. COMMANDS -------- -`info [--format=(keyvalue|nul)] [-z] [--all | ...]`:: +`info [--format=(keyvalue|nul) | -z] [--all | ...]`:: Retrieve metadata-related information about the current repository. Only the requested data will be returned based on their keys (see "INFO KEYS" section below). @@ -44,13 +44,12 @@ supported: + `-z` is an alias for `--format=nul`. -`structure [--format=(table|keyvalue|nul)]`:: +`structure [--format=(table|keyvalue|nul) | -z]`:: Retrieve statistics about the current repository structure. The following kinds of information are reported: + * Reference counts categorized by type * Reachable object counts categorized by type - + The output format can be chosen through the flag `--format`. Three formats are supported: @@ -72,6 +71,8 @@ supported: the delimiter between the key and value instead of '='. Unlike the `keyvalue` format, values containing "unusual" characters are never quoted. ++ +`-z` is an alias for `--format=nul`. INFO KEYS --------- diff --git a/Documentation/gitdatamodel.adoc b/Documentation/gitdatamodel.adoc index 3614f5960ea143..dcfdff0346f669 100644 --- a/Documentation/gitdatamodel.adoc +++ b/Documentation/gitdatamodel.adoc @@ -235,8 +235,6 @@ there will no longer be a branch that points at the old commit. The old commit is recorded in the current branch's <>, so it is still "reachable", but when the reflog entry expires it may become unreachable and get deleted. - -the old commit will usually not be reachable, so it may be deleted eventually. Reachable objects will never be deleted. [[index]] diff --git a/branch.c b/branch.c index 26be35834718f2..243db7d0fc0226 100644 --- a/branch.c +++ b/branch.c @@ -375,7 +375,7 @@ int validate_branchname(const char *name, struct strbuf *ref) if (check_branch_ref(ref, name)) { int code = die_message(_("'%s' is not a valid branch name"), name); advise_if_enabled(ADVICE_REF_SYNTAX, - _("See `man git check-ref-format`")); + _("See 'git help check-ref-format'")); exit(code); } diff --git a/builtin/branch.c b/builtin/branch.c index 9fcf04bebb2e72..c577b5d20f2969 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -591,7 +591,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int else { int code = die_message(_("invalid branch name: '%s'"), oldname); advise_if_enabled(ADVICE_REF_SYNTAX, - _("See `man git check-ref-format`")); + _("See 'git help check-ref-format'")); exit(code); } } diff --git a/builtin/last-modified.c b/builtin/last-modified.c index b0ecbdc5400d13..7345665a92d5ff 100644 --- a/builtin/last-modified.c +++ b/builtin/last-modified.c @@ -327,7 +327,7 @@ static void process_parent(struct last_modified *lm, if (!(parent->object.flags & PARENT1)) active_paths_free(lm, parent); - memset(lm->scratch->words, 0x0, lm->scratch->word_alloc); + memset(lm->scratch->words, 0x0, lm->scratch->word_alloc * sizeof(eword_t)); diff_queue_clear(&diff_queued_diff); } @@ -525,7 +525,8 @@ int cmd_last_modified(int argc, const char **argv, const char *prefix, argc = parse_options(argc, argv, prefix, last_modified_options, last_modified_usage, - PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT); + PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT | + PARSE_OPT_KEEP_DASHDASH); repo_config(repo, git_default_config, NULL); diff --git a/builtin/repo.c b/builtin/repo.c index 2a653bd3eacf20..0dd41b17783ed1 100644 --- a/builtin/repo.c +++ b/builtin/repo.c @@ -15,8 +15,8 @@ #include "utf8.h" static const char *const repo_usage[] = { - "git repo info [--format=(keyvalue|nul)] [-z] [--all | ...]", - "git repo structure [--format=(table|keyvalue|nul)]", + "git repo info [--format=(keyvalue|nul) | -z] [--all | ...]", + "git repo structure [--format=(table|keyvalue|nul) | -z]", NULL }; @@ -529,6 +529,10 @@ static int cmd_repo_structure(int argc, const char **argv, const char *prefix, OPT_CALLBACK_F(0, "format", &format, N_("format"), N_("output format"), PARSE_OPT_NONEG, parse_format_cb), + OPT_CALLBACK_F('z', NULL, &format, NULL, + N_("synonym for --format=nul"), + PARSE_OPT_NONEG | PARSE_OPT_NOARG, + parse_format_cb), OPT_BOOL(0, "progress", &show_progress, N_("show progress")), OPT_END() }; diff --git a/diff-lib.c b/diff-lib.c index b8f8f3bc312fbe..8e624f38c6d6f3 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -418,13 +418,12 @@ static int show_modified(struct rev_info *revs, } oldmode = old_entry->ce_mode; - if (mode == oldmode && oideq(oid, &old_entry->oid) && !dirty_submodule && - !revs->diffopt.flags.find_copies_harder) - return 0; - - diff_change(&revs->diffopt, oldmode, mode, - &old_entry->oid, oid, 1, !is_null_oid(oid), - old_entry->name, 0, dirty_submodule); + if (mode != oldmode || !oideq(oid, &old_entry->oid) || dirty_submodule) + diff_change(&revs->diffopt, oldmode, mode, + &old_entry->oid, oid, 1, !is_null_oid(oid), + old_entry->name, 0, dirty_submodule); + else if (revs->diffopt.flags.find_copies_harder) + diff_same(&revs->diffopt, mode, oid, old_entry->name); return 0; } diff --git a/diff.c b/diff.c index f66dd7ff6b9610..436da250eb150d 100644 --- a/diff.c +++ b/diff.c @@ -7399,6 +7399,26 @@ void diff_change(struct diff_options *options, concatpath, old_dirty_submodule, new_dirty_submodule); } +void diff_same(struct diff_options *options, + unsigned mode, + const struct object_id *oid, + const char *concatpath) +{ + struct diff_filespec *one; + + if (S_ISGITLINK(mode) && is_submodule_ignored(concatpath, options)) + return; + + if (options->prefix && + strncmp(concatpath, options->prefix, options->prefix_length)) + return; + + one = alloc_filespec(concatpath); + fill_filespec(one, oid, 1, mode); + one->count++; + diff_queue(&diff_queued_diff, one, one); +} + struct diff_filepair *diff_unmerge(struct diff_options *options, const char *path) { struct diff_filepair *pair; diff --git a/diff.h b/diff.h index b3a4c6335beb7c..7eb84aadf40c41 100644 --- a/diff.h +++ b/diff.h @@ -572,6 +572,11 @@ void diff_change(struct diff_options *, const char *fullpath, unsigned dirty_submodule1, unsigned dirty_submodule2); +void diff_same(struct diff_options *, + unsigned mode, + const struct object_id *oid, + const char *fullpath); + struct diff_filepair *diff_unmerge(struct diff_options *, const char *path); void compute_diffstat(struct diff_options *options, struct diffstat_t *diffstat, diff --git a/meson.build b/meson.build index f1b3615659e56a..00ad8a5c6011e5 100644 --- a/meson.build +++ b/meson.build @@ -1064,7 +1064,7 @@ if iconv.found() } ''' - if compiler.run(iconv_omits_bom_source, + if meson.can_run_host_binaries() and compiler.run(iconv_omits_bom_source, dependencies: iconv, name: 'iconv omits BOM', ).returncode() != 0 @@ -1492,7 +1492,7 @@ if not has_bsd_sysctl endif endif -if not meson.is_cross_build() and compiler.run(''' +if meson.can_run_host_binaries() and compiler.run(''' #include int main(int argc, const char **argv) diff --git a/subprojects/.gitignore b/subprojects/.gitignore index 63ea916ef5f302..2bb68c879432d7 100644 --- a/subprojects/.gitignore +++ b/subprojects/.gitignore @@ -1 +1,2 @@ /*/ +.wraplock diff --git a/t/t1901-repo-structure.sh b/t/t1901-repo-structure.sh index 36a71a144e3f74..df7d4ea52485da 100755 --- a/t/t1901-repo-structure.sh +++ b/t/t1901-repo-structure.sh @@ -101,6 +101,13 @@ test_expect_success 'keyvalue and nul format' ' tr "\n=" "\0\n" expect_nul && git repo structure --format=nul >out 2>err && + test_cmp expect_nul out && + test_line_count = 0 err && + + # "-z", as a synonym to "--format=nul", participates in the + # usual "last one wins" rule. + git repo structure --format=table -z >out 2>err && + test_cmp expect_nul out && test_line_count = 0 err ) diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index f3e720dc10da46..c58e505c43f9b9 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -1707,9 +1707,9 @@ test_expect_success '--track overrides branch.autoSetupMerge' ' ' test_expect_success 'errors if given a bad branch name' ' - cat <<-\EOF >expect && - fatal: '\''foo..bar'\'' is not a valid branch name - hint: See `man git check-ref-format` + cat <<-EOF >expect && + fatal: ${SQ}foo..bar${SQ} is not a valid branch name + hint: See ${SQ}git help check-ref-format${SQ} hint: Disable this message with "git config set advice.refSyntax false" EOF test_must_fail git branch foo..bar >actual 2>&1 && diff --git a/t/t8020-last-modified.sh b/t/t8020-last-modified.sh index a4c1114ee28f7f..50f4312f715f41 100755 --- a/t/t8020-last-modified.sh +++ b/t/t8020-last-modified.sh @@ -78,6 +78,14 @@ test_expect_success 'last-modified subdir' ' EOF ' +test_expect_success 'last-modified in sparse checkout' ' + test_when_finished "git sparse-checkout disable" && + git sparse-checkout set b && + check_last_modified -- a <<-\EOF + 3 a + EOF +' + test_expect_success 'last-modified subdir recursive' ' check_last_modified -r a <<-\EOF 3 a/b/file