]> Kevux Git Server - rit/log
rit
4 months agobuiltin/history: implement "split" subcommand
Patrick Steinhardt [Mon, 2 Mar 2026 12:13:12 +0000 (13:13 +0100)]
builtin/history: implement "split" subcommand

It is quite a common use case that one wants to split up one commit into
multiple commits by moving parts of the changes of the original commit
out into a separate commit. This is quite an involved operation though:

  1. Identify the commit in question that is to be dropped.

  2. Perform an interactive rebase on top of that commit's parent.

  3. Modify the instruction sheet to "edit" the commit that is to be
     split up.

  4. Drop the commit via "git reset HEAD~".

  5. Stage changes that should go into the first commit and commit it.

  6. Stage changes that should go into the second commit and commit it.

  7. Finalize the rebase.

This is quite complex, and overall I would claim that most people who
are not experts in Git would struggle with this flow.

Introduce a new "split" subcommand for git-history(1) to make this way
easier. All the user needs to do is to say `git history split $COMMIT`.
From hereon, Git asks the user which parts of the commit shall be moved
out into a separate commit and, once done, asks the user for the commit
message. Git then creates that split-out commit and applies the original
commit on top of it.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agobuiltin/history: split out extended function to create commits
Patrick Steinhardt [Mon, 2 Mar 2026 12:13:11 +0000 (13:13 +0100)]
builtin/history: split out extended function to create commits

In the next commit we're about to introduce a new command that splits up
a commit into two. Most of the logic will be shared with rewording
commits, except that we also need to have control over the parents and
the old/new trees.

Extract a new function `commit_tree_with_edited_message_ext()` to
prepare for this commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agocache-tree: allow writing in-memory index as tree
Patrick Steinhardt [Mon, 2 Mar 2026 12:13:10 +0000 (13:13 +0100)]
cache-tree: allow writing in-memory index as tree

The function `write_in_core_index_as_tree()` takes a repository and
writes its index into a tree object. What this function cannot do though
is to take an _arbitrary_ in-memory index.

Introduce a new `struct index_state` parameter so that the caller can
pass a different index than the one belonging to the repository. This
will be used in a subsequent commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoadd-patch: allow disabling editing of hunks
Patrick Steinhardt [Mon, 2 Mar 2026 12:13:09 +0000 (13:13 +0100)]
add-patch: allow disabling editing of hunks

The "add-patch" mode allows the user to edit hunks to apply custom
changes. This is incompatible with a new `git history split` command
that we're about to introduce in a subsequent commit, so we need a way
to disable this mode.

Add a new flag to disable editing hunks.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoadd-patch: add support for in-memory index patching
Patrick Steinhardt [Mon, 2 Mar 2026 12:13:08 +0000 (13:13 +0100)]
add-patch: add support for in-memory index patching

With `run_add_p()` callers have the ability to apply changes from a
specific revision to a repository's index. This infra supports several
different modes, like for example applying changes to the index,
working tree or both.

One feature that is missing though is the ability to apply changes to an
in-memory index different from the repository's index. Add a new
function `run_add_p_index()` to plug this gap.

This new function will be used in a subsequent commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoadd-patch: remove dependency on "add-interactive" subsystem
Patrick Steinhardt [Mon, 2 Mar 2026 12:13:07 +0000 (13:13 +0100)]
add-patch: remove dependency on "add-interactive" subsystem

With the preceding commit we have split out interactive configuration
that is used by both "git add -p" and "git add -i". But we still
initialize that configuration in the "add -p" subsystem by calling
`init_add_i_state()`, even though we only do so to initialize the
interactive configuration as well as a repository pointer.

Stop doing so and instead store and initialize the interactive
configuration in `struct add_p_state` directly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoadd-patch: split out `struct interactive_options`
Patrick Steinhardt [Mon, 2 Mar 2026 12:13:06 +0000 (13:13 +0100)]
add-patch: split out `struct interactive_options`

The `struct add_p_opt` is reused both by our infra for "git add -p" and
"git add -i". Users of `run_add_i()` for example are expected to pass
`struct add_p_opt`. This is somewhat confusing and raises the question
of which options apply to what part of the stack.

But things are even more confusing than that: while callers are expected
to pass in `struct add_p_opt`, these options ultimately get used to
initialize a `struct add_i_state` that is used by both subsystems. So we
are basically going full circle here.

Refactor the code and split out a new `struct interactive_options` that
hosts common options used by both. These options are then applied to a
`struct interactive_config` that hosts common configuration.

This refactoring doesn't yet fully detangle the two subsystems from one
another, as we still end up calling `init_add_i_state()` in the "git add
-p" subsystem. This will be fixed in a subsequent commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoadd-patch: split out header from "add-interactive.h"
Patrick Steinhardt [Mon, 2 Mar 2026 12:13:05 +0000 (13:13 +0100)]
add-patch: split out header from "add-interactive.h"

While we have a "add-patch.c" code file, its declarations are part of
"add-interactive.h". This makes it somewhat harder than necessary to
find relevant code and to identify clear boundaries between the two
subsystems.

Split up concerns and move declarations that relate to "add-patch.c"
into a new "add-patch.h" header.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoThe 10th batch
Junio C Hamano [Tue, 3 Mar 2026 19:08:01 +0000 (11:08 -0800)]
The 10th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoMerge branch 'hy/diff-lazy-fetch-with-break-fix'
Junio C Hamano [Tue, 3 Mar 2026 19:08:13 +0000 (11:08 -0800)]
Merge branch 'hy/diff-lazy-fetch-with-break-fix'

A prefetch call can be triggered to access a stale diff_queue entry
after diffcore-break breaks a filepair into two and freed the
original entry that is no longer used, leading to a segfault, which
has been corrected.

* hy/diff-lazy-fetch-with-break-fix:
  diffcore-break: avoid segfault with freed entries

4 months agoMerge branch 'aa/add-p-no-auto-advance'
Junio C Hamano [Tue, 3 Mar 2026 19:08:13 +0000 (11:08 -0800)]
Merge branch 'aa/add-p-no-auto-advance'

"git add -p" learned a new mode that allows the user to revisit a
file that was already dealt with.

* aa/add-p-no-auto-advance:
  add-patch: allow interfile navigation when selecting hunks
  add-patch: allow all-or-none application of patches
  add-patch: modify patch_update_file() signature
  interactive -p: add new `--auto-advance` flag

4 months agoMerge branch 'lg/t2004-test-path-is-helpers'
Junio C Hamano [Tue, 3 Mar 2026 19:08:13 +0000 (11:08 -0800)]
Merge branch 'lg/t2004-test-path-is-helpers'

Test code clean-up.

* lg/t2004-test-path-is-helpers:
  t2004: use test_path_is_file instead of test -f

4 months agoMerge branch 'ps/simplify-normalize-path-copy-len'
Junio C Hamano [Tue, 3 Mar 2026 19:08:12 +0000 (11:08 -0800)]
Merge branch 'ps/simplify-normalize-path-copy-len'

Code clean-up.

* ps/simplify-normalize-path-copy-len:
  path: factor out skip_slashes() in normalize_path_copy_len()

4 months agoMerge branch 'sc/pack-redundant-leakfix'
Junio C Hamano [Tue, 3 Mar 2026 19:08:12 +0000 (11:08 -0800)]
Merge branch 'sc/pack-redundant-leakfix'

Leakfix.

* sc/pack-redundant-leakfix:
  pack-redundant: fix memory leak when open_pack_index() fails

4 months agoMerge branch 'cs/subtree-split-fixes'
Junio C Hamano [Tue, 3 Mar 2026 19:08:12 +0000 (11:08 -0800)]
Merge branch 'cs/subtree-split-fixes'

An earlier attempt to optimize "git subtree" discarded too much
relevant histories, which has been corrected.

* cs/subtree-split-fixes:
  contrib/subtree: process out-of-prefix subtrees
  contrib/subtree: test history depth
  contrib/subtree: capture additional test-cases

4 months agoThe 9th batch
Junio C Hamano [Tue, 3 Mar 2026 00:05:51 +0000 (16:05 -0800)]
The 9th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoMerge branch 'jt/object-file-use-container-of'
Junio C Hamano [Tue, 3 Mar 2026 01:06:53 +0000 (17:06 -0800)]
Merge branch 'jt/object-file-use-container-of'

Code clean-up.

* jt/object-file-use-container-of:
  object-file.c: avoid container_of() of a NULL container
  object-file: use `container_of()` to convert from base types

4 months agoMerge branch 'ps/receive-pack-shallow-optim'
Junio C Hamano [Tue, 3 Mar 2026 01:06:53 +0000 (17:06 -0800)]
Merge branch 'ps/receive-pack-shallow-optim'

The code to accept shallow "git push" has been optimized.

* ps/receive-pack-shallow-optim:
  commit: use commit graph in `lookup_commit_reference_gently()`
  commit: make `repo_parse_commit_no_graph()` more robust
  commit: avoid parsing non-commits in `lookup_commit_reference_gently()`

4 months agoMerge branch 'kh/doc-patch-id-4'
Junio C Hamano [Tue, 3 Mar 2026 01:06:53 +0000 (17:06 -0800)]
Merge branch 'kh/doc-patch-id-4'

Doc update.

* kh/doc-patch-id-4:
  doc: patch-id: see also git-cherry(1)
  doc: patch-id: add script example
  doc: patch-id: emphasize multi-patch processing

4 months agoMerge branch 'ps/meson-gitk-git-gui'
Junio C Hamano [Tue, 3 Mar 2026 01:06:52 +0000 (17:06 -0800)]
Merge branch 'ps/meson-gitk-git-gui'

Plumb gitk/git-gui build and install procedure in meson based
builds.

* ps/meson-gitk-git-gui:
  meson: wire up gitk and git-gui

4 months agoMerge branch 'pw/meson-doc-mergetool'
Junio C Hamano [Tue, 3 Mar 2026 01:06:52 +0000 (17:06 -0800)]
Merge branch 'pw/meson-doc-mergetool'

Update build precedure for mergetool documentation in meson-based builds.

* pw/meson-doc-mergetool:
  meson: fix building mergetool docs

4 months agoMerge branch 'kh/doc-am-xref'
Junio C Hamano [Tue, 3 Mar 2026 01:06:52 +0000 (17:06 -0800)]
Merge branch 'kh/doc-am-xref'

Doc update.

* kh/doc-am-xref:
  doc: am: fill out hook discussion
  doc: am: add missing config am.messageId
  doc: am: say that --message-id adds a trailer
  doc: am: normalize git(1) command links

4 months agoMerge branch 'ps/object-info-bits-cleanup'
Junio C Hamano [Tue, 3 Mar 2026 01:06:52 +0000 (17:06 -0800)]
Merge branch 'ps/object-info-bits-cleanup'

A couple of bugs in use of flag bits around odb API has been
corrected, and the flag bits reordered.

* ps/object-info-bits-cleanup:
  odb: convert `odb_has_object()` flags into an enum
  odb: convert object info flags into an enum
  odb: drop gaps in object info flag values
  builtin/fsck: fix flags passed to `odb_has_object()`
  builtin/backfill: fix flags passed to `odb_has_object()`

4 months agoMerge branch 'ag/http-netrc-tests'
Junio C Hamano [Tue, 3 Mar 2026 01:06:51 +0000 (17:06 -0800)]
Merge branch 'ag/http-netrc-tests'

Additional tests were introduced to see the interaction with netrc
auth with auth failure on the http transport.

* ag/http-netrc-tests:
  t5550: add netrc tests for http 401/403

4 months agoMerge branch 'ty/symlinks-use-unsigned-for-bitset'
Junio C Hamano [Tue, 3 Mar 2026 01:06:51 +0000 (17:06 -0800)]
Merge branch 'ty/symlinks-use-unsigned-for-bitset'

Code clean-up.

* ty/symlinks-use-unsigned-for-bitset:
  symlinks: use unsigned int for flags

4 months agoMerge branch 'ps/validate-prefix-in-subtree-split'
Junio C Hamano [Tue, 3 Mar 2026 01:06:51 +0000 (17:06 -0800)]
Merge branch 'ps/validate-prefix-in-subtree-split'

"git subtree split --prefix=P <commit>" now checks the prefix P
against the tree of the (potentially quite different from the
current working tree) given commit.

* ps/validate-prefix-in-subtree-split:
  subtree: validate --prefix against commit in split

4 months agoMerge branch 'uk/signature-is-good-after-key-expires'
Junio C Hamano [Tue, 3 Mar 2026 01:06:50 +0000 (17:06 -0800)]
Merge branch 'uk/signature-is-good-after-key-expires'

A signature on a commit that was GPG signed long time ago ought to
be still valid after the key that was used to sign it has expired,
but we showed them in alarming red.

* uk/signature-is-good-after-key-expires:
  gpg-interface: signatures by expired keys are fine

4 months agoMerge branch 'ps/odb-for-each-object'
Junio C Hamano [Tue, 3 Mar 2026 01:06:50 +0000 (17:06 -0800)]
Merge branch 'ps/odb-for-each-object'

Revamp object enumeration API around odb.

* ps/odb-for-each-object:
  odb: drop unused `for_each_{loose,packed}_object()` functions
  reachable: convert to use `odb_for_each_object()`
  builtin/pack-objects: use `packfile_store_for_each_object()`
  odb: introduce mtime fields for object info requests
  treewide: drop uses of `for_each_{loose,packed}_object()`
  treewide: enumerate promisor objects via `odb_for_each_object()`
  builtin/fsck: refactor to use `odb_for_each_object()`
  odb: introduce `odb_for_each_object()`
  packfile: introduce function to iterate through objects
  packfile: extract function to iterate through objects of a store
  object-file: introduce function to iterate through objects
  object-file: extract function to read object info from path
  odb: fix flags parameter to be unsigned
  odb: rename `FOR_EACH_OBJECT_*` flags

4 months agoThe 8th batch
Junio C Hamano [Fri, 27 Feb 2026 22:19:13 +0000 (14:19 -0800)]
The 8th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoMerge branch 'ap/use-test-seq-f-more'
Junio C Hamano [Fri, 27 Feb 2026 23:11:55 +0000 (15:11 -0800)]
Merge branch 'ap/use-test-seq-f-more'

Test clean-up.

* ap/use-test-seq-f-more:
  t: use test_seq -f and pipes in a few more places

4 months agoMerge branch 'db/doc-fetch-jobs-auto'
Junio C Hamano [Fri, 27 Feb 2026 23:11:54 +0000 (15:11 -0800)]
Merge branch 'db/doc-fetch-jobs-auto'

Doc update.

* db/doc-fetch-jobs-auto:
  doc: fetch: document `--jobs=0` behavior

4 months agoMerge branch 'mf/format-patch-honor-from-for-cover-letter'
Junio C Hamano [Fri, 27 Feb 2026 23:11:53 +0000 (15:11 -0800)]
Merge branch 'mf/format-patch-honor-from-for-cover-letter'

"git format-patch --from=<me>" did not honor the command line
option when writing out the cover letter, which has been corrected.

* mf/format-patch-honor-from-for-cover-letter:
  format-patch: fix From header in cover letter

4 months agoMerge branch 'jh/alias-i18n'
Junio C Hamano [Fri, 27 Feb 2026 23:11:53 +0000 (15:11 -0800)]
Merge branch 'jh/alias-i18n'

Extend the alias configuration syntax to allow aliases using
characters outside ASCII alphanumeric (plus '-').

* jh/alias-i18n:
  completion: fix zsh alias listing for subsection aliases
  alias: support non-alphanumeric names via subsection syntax
  alias: prepare for subsection aliases
  help: use list_aliases() for alias listing

4 months agoMerge branch 'ps/tests-wo-iconv-fixes'
Junio C Hamano [Fri, 27 Feb 2026 23:11:52 +0000 (15:11 -0800)]
Merge branch 'ps/tests-wo-iconv-fixes'

Some tests assumed "iconv" is available without honoring ICONV
prerequisite, which has been corrected.

* ps/tests-wo-iconv-fixes:
  t6006: don't use iconv(1) without ICONV prereq
  t5550: add ICONV prereq to tests that use "$HTTPD_URL/error"
  t4205: improve handling of ICONV prerequisite
  t40xx: don't use iconv(1) without ICONV prereq
  t: don't set ICONV prereq when iconv(1) is missing

4 months agoMerge branch 'ps/ci-gitlab-msvc-updates'
Junio C Hamano [Fri, 27 Feb 2026 23:11:52 +0000 (15:11 -0800)]
Merge branch 'ps/ci-gitlab-msvc-updates'

CI update.

* ps/ci-gitlab-msvc-updates:
  gitlab-ci: handle failed tests on MSVC+Meson job
  gitlab-ci: use "run-test-slice-meson.sh"
  ci: make test slicing consistent across Meson/Make
  github: fix Meson tests not executing at all
  meson: fix MERGE_TOOL_DIR with "--no-bin-wrappers"
  ci: don't skip smallest test slice in GitLab
  ci: handle failures of test-slice helper

4 months agoMerge branch 'jc/whitespace-incomplete-line'
Junio C Hamano [Fri, 27 Feb 2026 23:11:52 +0000 (15:11 -0800)]
Merge branch 'jc/whitespace-incomplete-line'

It does not make much sense to apply the "incomplete-line"
whitespace rule to symbolic links, whose contents almost always
lack the final newline.  "git apply" and "git diff" are now taught
to exclude them for a change to symbolic links.

* jc/whitespace-incomplete-line:
  whitespace: symbolic links usually lack LF at the end

4 months agoMerge branch 'jc/checkout-switch-restore'
Junio C Hamano [Fri, 27 Feb 2026 23:11:51 +0000 (15:11 -0800)]
Merge branch 'jc/checkout-switch-restore'

"git switch <name>", in an attempt to create a local branch <name>
after a remote tracking branch of the same name gave an advise
message to disambiguate using "git checkout", which has been
updated to use "git switch".

* jc/checkout-switch-restore:
  checkout: tell "parse_remote_branch" which command is calling it
  checkout: pass program-readable token to unified "main"

4 months agoMerge branch 'jk/ref-filter-lrstrip-optim'
Junio C Hamano [Fri, 27 Feb 2026 23:11:50 +0000 (15:11 -0800)]
Merge branch 'jk/ref-filter-lrstrip-optim'

Code clean-up.

* jk/ref-filter-lrstrip-optim:
  ref-filter: clarify lstrip/rstrip component counting
  ref-filter: avoid strrchr() in rstrip_ref_components()
  ref-filter: simplify rstrip_ref_components() memory handling
  ref-filter: simplify lstrip_ref_components() memory handling
  ref-filter: factor out refname component counting

4 months agoMerge branch 'ps/history-ergonomics-updates'
Junio C Hamano [Fri, 27 Feb 2026 23:11:50 +0000 (15:11 -0800)]
Merge branch 'ps/history-ergonomics-updates'

UI improvements for "git history reword".

* ps/history-ergonomics-updates:
  Documentation/git-history: document default for "--update-refs="
  builtin/history: rename "--ref-action=" to "--update-refs="
  builtin/history: replace "--ref-action=print" with "--dry-run"
  builtin/history: check for merges before asking for user input
  builtin/history: perform revwalk checks before asking for user input

4 months agoMerge branch 'ps/for-each-ref-in-fixes'
Junio C Hamano [Fri, 27 Feb 2026 23:11:50 +0000 (15:11 -0800)]
Merge branch 'ps/for-each-ref-in-fixes'

A handful of places used refs_for_each_ref_in() API incorrectly,
which has been corrected.

* ps/for-each-ref-in-fixes:
  bisect: simplify string_list memory handling
  bisect: fix misuse of `refs_for_each_ref_in()`
  pack-bitmap: fix bug with exact ref match in "pack.preferBitmapTips"
  pack-bitmap: deduplicate logic to iterate over preferred bitmap tips

4 months agoMerge branch 'lo/repo-info-keys'
Junio C Hamano [Fri, 27 Feb 2026 23:11:49 +0000 (15:11 -0800)]
Merge branch 'lo/repo-info-keys'

"git repo info" learns "--keys" action to list known keys.

* lo/repo-info-keys:
  repo: add new flag --keys to git-repo-info
  repo: rename the output format "keyvalue" to "lines"

4 months agoThe 7th batch
Junio C Hamano [Wed, 25 Feb 2026 18:49:04 +0000 (10:49 -0800)]
The 7th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoMerge branch 'ac/string-list-sort-u-and-tests'
Junio C Hamano [Wed, 25 Feb 2026 19:54:18 +0000 (11:54 -0800)]
Merge branch 'ac/string-list-sort-u-and-tests'

Code clean-up using a new helper function introduced lately.

* ac/string-list-sort-u-and-tests:
  sparse-checkout: use string_list_sort_u

4 months agoMerge branch 'mc/tr2-process-ancestry-cleanup'
Junio C Hamano [Wed, 25 Feb 2026 19:54:18 +0000 (11:54 -0800)]
Merge branch 'mc/tr2-process-ancestry-cleanup'

Add process ancestry data to trace2 on macOS to match what we
already do on Linux and Windows.  Also adjust the way Windows
implementation reports this information to match the other two.

* mc/tr2-process-ancestry-cleanup:
  t0213: add trace2 cmd_ancestry tests
  test-tool: extend trace2 helper with 400ancestry
  trace2: emit cmd_ancestry data for Windows
  trace2: refactor Windows process ancestry trace2 event
  build: include procinfo.c impl for macOS
  trace2: add macOS process ancestry tracing

4 months agoMerge branch 'ps/pack-concat-wo-backfill'
Junio C Hamano [Wed, 25 Feb 2026 19:54:17 +0000 (11:54 -0800)]
Merge branch 'ps/pack-concat-wo-backfill'

"git pack-objects --stdin-packs" with "--exclude-promisor-objects"
fetched objects that are promised, which was not wanted.  This has
been fixed.

* ps/pack-concat-wo-backfill:
  builtin/pack-objects: don't fetch objects when merging packs

4 months agoMerge branch 'dk/complete-stash-import-export'
Junio C Hamano [Wed, 25 Feb 2026 19:54:17 +0000 (11:54 -0800)]
Merge branch 'dk/complete-stash-import-export'

Command line completion (in contrib/) update.

* dk/complete-stash-import-export:
  completion: add stash import, export

4 months agoMerge branch 'jc/doc-cg-needswork'
Junio C Hamano [Wed, 25 Feb 2026 19:54:17 +0000 (11:54 -0800)]
Merge branch 'jc/doc-cg-needswork'

A CodingGuidelines update.

* jc/doc-cg-needswork:
  CodingGuidelines: document NEEDSWORK comments

4 months agoMerge branch 'ds/revision-maximal-only'
Junio C Hamano [Wed, 25 Feb 2026 19:54:17 +0000 (11:54 -0800)]
Merge branch 'ds/revision-maximal-only'

"git rev-list" and friends learn "--maximal-only" to show only the
commits that are not reachable by other commits.

* ds/revision-maximal-only:
  revision: add --maximal-only option

4 months agoMerge branch 'cc/lop-filter-auto'
Junio C Hamano [Wed, 25 Feb 2026 19:54:16 +0000 (11:54 -0800)]
Merge branch 'cc/lop-filter-auto'

"auto filter" logic for large-object promisor remote.

* cc/lop-filter-auto:
  fetch-pack: wire up and enable auto filter logic
  promisor-remote: change promisor_remote_reply()'s signature
  promisor-remote: keep advertised filters in memory
  list-objects-filter-options: support 'auto' mode for --filter
  doc: fetch: document `--filter=<filter-spec>` option
  fetch: make filter_options local to cmd_fetch()
  clone: make filter_options local to cmd_clone()
  promisor-remote: allow a client to store fields
  promisor-remote: refactor initialising field lists

4 months agoMerge branch 'pw/commit-msg-sample-hook'
Junio C Hamano [Wed, 25 Feb 2026 19:54:16 +0000 (11:54 -0800)]
Merge branch 'pw/commit-msg-sample-hook'

Update sample commit-msg hook to complain when a log message has
material mailinfo considers the end of log message in the middle.

* pw/commit-msg-sample-hook:
  templates: detect commit messages containing diffs
  templates: add .gitattributes entry for sample hooks

4 months agoMerge branch 'kh/doc-am-format-sendmail'
Junio C Hamano [Wed, 25 Feb 2026 19:54:16 +0000 (11:54 -0800)]
Merge branch 'kh/doc-am-format-sendmail'

Doc update.

* kh/doc-am-format-sendmail:
  doc: add caveat about round-tripping format-patch

4 months agodiffcore-break: avoid segfault with freed entries
Han Young [Tue, 24 Feb 2026 06:13:29 +0000 (14:13 +0800)]
diffcore-break: avoid segfault with freed entries

After we have freed the file pair, we should set the queue reference to null.
When computing a diff in a partial clone, there is a chance that we
could trigger a prefetch of missing objects when there are freed entries in
the global diff queue due to break-rewrites detection. The segfault only occurs
if an entry has been freed by break-rewrites and there is an entry
to be prefetched.

There is a new test in t4067 that trigger the segmentation fault that results
in this case. The test explicitly fetch the necessary blobs to trigger the
break rewrites, some blobs are left to be prefetched.

The fix is to set the queue pointer to NULL after it is freed, the prefetch
will skip NULL entries.

Signed-off-by: Han Young <hanyang.tony@bytedance.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoobject-file.c: avoid container_of() of a NULL container
Junio C Hamano [Sun, 22 Feb 2026 20:16:19 +0000 (12:16 -0800)]
object-file.c: avoid container_of() of a NULL container

Even though the "struct odb_transaction" member is at the beginning
of the containing "struct odb_transaction_files", i.e., at offset 0,
using container_of() to add offset 0 to a NULL pointer gets flagged
as a bad behaviour under SANITIZE=undefined.

Use container_of_or_null() to work around this issue.

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agopack-redundant: fix memory leak when open_pack_index() fails
Sahitya Chandra [Sat, 21 Feb 2026 10:38:59 +0000 (16:08 +0530)]
pack-redundant: fix memory leak when open_pack_index() fails

In add_pack(), we allocate l.remaining_objects with llist_init() before
calling open_pack_index(). If open_pack_index() fails we return NULL
without freeing the allocated list, leaking the memory.

Fix by calling llist_free(l.remaining_objects) on the error path before
returning.

Signed-off-by: Sahitya Chandra <sahityajb@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agopath: factor out skip_slashes() in normalize_path_copy_len()
Pushkar Singh [Sat, 21 Feb 2026 11:05:12 +0000 (11:05 +0000)]
path: factor out skip_slashes() in normalize_path_copy_len()

Extract skip_slashes() to avoid repeating the same is_dir_sep()
loop in multiple places inside normalize_path_copy_len().

Keep the dot-component handling inline to preserve the original
control flow and readability, as suggested in review.

No functional changes. Behavior verified with t0060-path-utils.sh.

Signed-off-by: Pushkar Singh <pushkarkumarsingh1970@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agot2004: use test_path_is_file instead of test -f
Lambert Duclos-de Guise [Sat, 21 Feb 2026 17:28:13 +0000 (17:28 +0000)]
t2004: use test_path_is_file instead of test -f

Replace 'test -f' with the helper function 'test_path_is_file'
to provide better error messages upon failure.

Signed-off-by: Lambert Duclos-de Guise <lambertddg@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agosymlinks: use unsigned int for flags
Tian Yuchen [Mon, 16 Feb 2026 17:20:28 +0000 (01:20 +0800)]
symlinks: use unsigned int for flags

The 'flags' and 'track_flags' fields in symlinks.c are used
strictly as a collection of bits (using bitwise operators including
&, |, ~). Using a signed integer for bitmasks may lead to undefined
behavior with shift operations and logic errors if the MSB is touched.

Change these fields from 'int' to 'unsigned int' to match our usage
patterns.

Signed-off-by: Tian Yuchen <a3205153416@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoThe 6th batch
Junio C Hamano [Fri, 20 Feb 2026 18:28:05 +0000 (10:28 -0800)]
The 6th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoMerge branch 'ak/t9812-test-path-is-helpers'
Junio C Hamano [Fri, 20 Feb 2026 19:36:18 +0000 (11:36 -0800)]
Merge branch 'ak/t9812-test-path-is-helpers'

Test update.

* ak/t9812-test-path-is-helpers:
  t9812: modernize test path helpers

4 months agoMerge branch 'pw/diff-anchored-optim'
Junio C Hamano [Fri, 20 Feb 2026 19:36:18 +0000 (11:36 -0800)]
Merge branch 'pw/diff-anchored-optim'

"git diff --anchored=<text>" has been optimized.

* pw/diff-anchored-optim:
  diff --anchored: avoid checking unmatched lines

4 months agoMerge branch 'jc/doc-cg-c-comment'
Junio C Hamano [Fri, 20 Feb 2026 19:36:18 +0000 (11:36 -0800)]
Merge branch 'jc/doc-cg-c-comment'

A CodingGuidelines update.

* jc/doc-cg-c-comment:
  CodingGuidelines: document // comments

4 months agoMerge branch 'pw/xdiff-cleanups'
Junio C Hamano [Fri, 20 Feb 2026 19:36:17 +0000 (11:36 -0800)]
Merge branch 'pw/xdiff-cleanups'

Small clean-up of xdiff library to remove unnecessary data
duplication.

* pw/xdiff-cleanups:
  xdiff: remove unused data from xdlclass_t
  xdiff: remove "line_hash" field from xrecord_t

4 months agocontrib/subtree: process out-of-prefix subtrees
Colin Stagner [Wed, 18 Feb 2026 02:31:32 +0000 (20:31 -0600)]
contrib/subtree: process out-of-prefix subtrees

`should_ignore_subtree_split_commit` detects subtrees which are
outside of the current path --prefix and ignores them. This can
speed up splits of repositories that have many subtrees.

Since its inception [1], every iteration of this logic [2], [3]
incorrectly excludes commits. This alters the split history. The
split history and its commit hashes are API contract, so this is
not permissible.

While a commit from a different subtree may look like it doesn't
contribute anything to a split, sometimes it does. Merge commits
are a particular hot spot. For these, the pruning logic in
`copy_or_skip` performs:

1. a check for "treesame" parents
2. two different common ancestry checks

These checks operate on the **split history**, not the input
history. The split history omits commits that do not affect the
--prefix. This can significantly alter the ancestry of a merge.
In order to determine if `copy_or_skip` will skip a merge, it
is likely necessary to compute all the split history... which
is what `should_ignore_subtree_split_commit` tries to avoid.

To make this logic API-preserving, we could gate it behind a
new CLI argument. The present implementation is actually a
speed penalty in many cases, however, so this is not done here.

Remove the `should_ignore_subtree_split_commit` logic. This
fixes the regression reported in [4].

[1]: 98ba49ccc2 (subtree: fix split processing with multiple subtrees present, 2023-12-01)

[2]: 83f9dad7d6 (contrib/subtree: fix split with squashed subtrees, 2025-09-09)

[3]: 28a7e27cff (contrib/subtree: detect rewritten subtree commits, 2026-01-09)

[4]: <20251230170719.845029-1-george@mail.dietrich.pub>

Reported-by: George <george@mail.dietrich.pub>
Reported-by: Christian Heusel <christian@heusel.eu>
Signed-off-by: Colin Stagner <ask+git@howdoi.land>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agocontrib/subtree: test history depth
Colin Stagner [Wed, 18 Feb 2026 02:31:31 +0000 (20:31 -0600)]
contrib/subtree: test history depth

Add history depth checks to some of the subtree unit tests.

These checks were previously introduced as part of 28a7e27cff
(contrib/subtree: detect rewritten subtree commits, 2026-01-09),
which has since been reverted.

Signed-off-by: Colin Stagner <ask+git@howdoi.land>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agocontrib/subtree: capture additional test-cases
Colin Stagner [Wed, 18 Feb 2026 02:31:30 +0000 (20:31 -0600)]
contrib/subtree: capture additional test-cases

Patch series e7b07376e5 (Merge branch 'rs/subtree-fixes',
2018-10-26) corrects several defects in `git subtree split`.
The defects affect `split --rejoin` and merge commit processing.

There is no test coverage for this, and e7b07376e5 did not
introduce any.

Convert the minimum working example [1] from the original patch
submission [2] into test cases.

[1]: https://gist.github.com/FoxFireX/1b794384612b7fd5e7cd157cff96269e

[2]: <20180928183540.48968-1-roger.strain@swri.org>

Signed-off-by: Colin Stagner <ask+git@howdoi.land>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoref-filter: clarify lstrip/rstrip component counting
Jeff King [Fri, 20 Feb 2026 06:00:03 +0000 (01:00 -0500)]
ref-filter: clarify lstrip/rstrip component counting

When a strip option to the %(refname) placeholder is asked to leave N
path components, we first count up the path components to know how many
to remove. That happens with a loop like this:

/* Find total no of '/' separated path-components */
for (i = 0; p[i]; p[i] == '/' ? i++ : *p++)
;

which is a little hard to understand for two reasons.

First, the dereference in "*p++" is seemingly useless, since nobody
looks at the result. And static analyzers like Coverity will complain
about that. But removing the "*" will cause gcc to complain with
-Wint-conversion, since the two sides of the ternary do not match (one
is a pointer and the other an int).

Second, it is not clear what the meaning of "p" is at each iteration of
the loop, as its position with respect to our walk over the string
depends on how many slashes we've seen. The answer is that by itself, it
doesn't really mean anything: "p + i" represents the current state of
our walk, with "i" counting up slashes, and "p" by itself essentially
meaningless.

None of this behaves incorrectly, but ultimately the loop is just
counting the slashes in the refname. We can do that much more simply
with a for-loop iterating over the string and a separate slash counter.

We can also drop the comment, which is somewhat misleading. We are
counting slashes, not components (and a comment later in the function
makes it clear that we must add one to compensate). In the new code it
is obvious that we are counting slashes here.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agot6006: don't use iconv(1) without ICONV prereq
Patrick Steinhardt [Fri, 20 Feb 2026 08:26:03 +0000 (09:26 +0100)]
t6006: don't use iconv(1) without ICONV prereq

Two tests in t6006 depend on the iconv(1) prerequisite to reencode a
commit message. This executable may not even exist though in case the
prereq is not set, which will cause the tests to fail.

Fix this by using UTF-8 instead when the prereq is not set.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agot5550: add ICONV prereq to tests that use "$HTTPD_URL/error"
Patrick Steinhardt [Fri, 20 Feb 2026 08:26:02 +0000 (09:26 +0100)]
t5550: add ICONV prereq to tests that use "$HTTPD_URL/error"

We've got a bunch of tests in t5550 that connect to "$HTTPD_URL/error"
to ensure that error messages are properly forwarded. This URL executes
the "t/lib-httpd/error.sh" script, which in turn depends on the iconv(1)
executable to reencode the message.

This executable may not exist on platforms, which will make the tests
fail. Guard them with the ICONV prereq to fix such failures.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agot4205: improve handling of ICONV prerequisite
Patrick Steinhardt [Fri, 20 Feb 2026 08:26:01 +0000 (09:26 +0100)]
t4205: improve handling of ICONV prerequisite

In t4205 we have a bunch of tests that depend on the iconv prereq. This
is for most of the part because we format commit messages that have been
encoded in an encoding different than UTF-8.

Those tests fall into two classes though:

  - One class of tests outputs the data as-is without reencoding.

  - One class of tests outputs the data with "i18n.logOutputEncoding" to
    reencode it.

Curiously enough, both of these classes are marked with the ICONV
prereq, even though one might expect that the first class wouldn't need
the prereq. This is because we unconditionally use ISO-8859-1 encoding
for the initial commit message, and thus we depend on converting to
UTF-8 indeed.

This creates another problem though: when the iconv(1) executable does
not exist the test setup fails, even in the case where the ICONV prereq
has not been set.

Fix these issues by making the test encoding conditional on ICONV: if
it's available we use ISO-8859-1, otherwise we use UTF-8. This fixes the
test setup on platforms without iconv(1), and it allows us to drop the
ICONV prereq from a bunch of tests.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agot40xx: don't use iconv(1) without ICONV prereq
Patrick Steinhardt [Fri, 20 Feb 2026 08:26:00 +0000 (09:26 +0100)]
t40xx: don't use iconv(1) without ICONV prereq

We've got a couple of tests related to diffs in t40xx that use the
iconv(1) executable to convert the encoding of a commit message. All of
these tests are prepared to handle a missing ICONV prereq, in which case
they will simply use UTF-8 encoding.

But even if the ICONV prerequisite has failed we try to use the iconv(1)
executable, even though it's not safe to assume that the executable
exists in that case. And besides that, it's also unnecessary to use
iconv(1) in the first place, as we would only use it to convert from
UTF-8 to UTF-8, which should be equivalent to a no-op.

Fix the issue and skip the call to iconv(1) in case the prerequisite is
not set. This makes tests work on systems that don't have iconv at all.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agot: don't set ICONV prereq when iconv(1) is missing
Patrick Steinhardt [Fri, 20 Feb 2026 08:25:59 +0000 (09:25 +0100)]
t: don't set ICONV prereq when iconv(1) is missing

We've got a couple of tests that exercise Git with different encodings,
typically around commit messages. All of these tests depend on the ICONV
prerequisite, which is set when Git was built with support for iconv.

Many of those tests also end up using the iconv(1) executable to
reencode text. But while tests can rely on the fact that Git does have
support for iconv, they cannot assume that the iconv(1) executable
exists. The consequence is thus that tests will break in case Git is
built with iconv, but the executable doesn't exist. In fact, some of the
tests even use the iconv(1) executable unconditionally, regardless of
whether or not the ICONV prerequisite is set.

Git for Windows has recently (unintentionally) shipped a change where
the iconv(1) binary is not getting installed anymore [1]. And as we use
Git for Windows directly in MSVC+Meson jobs in GitLab CI this has caused
such tests to break. The missing iconv(1) binary is considered a bug
that will be fixed in Git for Windows. But regardless of that it makes
sense to not assume the binary to always exist so that our test suite
passes on platforms that don't have iconv at all.

Extend the ICONV prerequisite so that we know to skip tests in case the
iconv(1) binary doesn't exist. We'll adapt tests that are currently
broken in subsequent commits.

[1]: https://github.com/git-for-windows/git/issues/6083

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agobisect: simplify string_list memory handling
Jeff King [Thu, 19 Feb 2026 07:57:52 +0000 (08:57 +0100)]
bisect: simplify string_list memory handling

We declare the refs_for_removal string_list as NODUP, forcing us to
manually allocate strings we insert. And then when it comes time to
clean up, we set strdup_strings so that string_list_clear() will free
them for us.

This is a confusing pattern, and can be done much more simply by just
declaring the list with the DUP initializer in the first place.

It was written this way originally because one of the callsites
generated the item using xstrfmt(). But that spot switched to a plain
xstrdup() in the preceding commit. That means we can now just let the
string_list code handle allocation itself.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agobisect: fix misuse of `refs_for_each_ref_in()`
Patrick Steinhardt [Thu, 19 Feb 2026 07:57:51 +0000 (08:57 +0100)]
bisect: fix misuse of `refs_for_each_ref_in()`

All callers of `refs_for_each_ref_in()` pass in a string that is
terminated with a trailing slash to indicate that they only want to see
refs in that specific ref hierarchy. This is in fact a requirement if
one wants to use this function, as the function trims the prefix from
each yielded ref. So if there was a reference that was called
"refs/bisect" as in our example, the result after trimming would be the
empty string, and that's something we disallow.

Fix this by adding the trailing slash.

Furthermore, taking a closer look, we strip the prefix only to re-add it
in `mark_for_removal()`. This is somewhat roundabout, as we can instead
call `refs_for_each_fullref_in()` to not do any stripping at all. Do so
to simplify the code a bit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agopack-bitmap: fix bug with exact ref match in "pack.preferBitmapTips"
Patrick Steinhardt [Thu, 19 Feb 2026 07:57:50 +0000 (08:57 +0100)]
pack-bitmap: fix bug with exact ref match in "pack.preferBitmapTips"

The "pack.preferBitmapTips" configuration allows the user to specify
which references should be preferred when generating bitmaps. This
option is typically expected to be set to a reference prefix, like for
example "refs/heads/".

It's not unreasonable though for a user to configure one specific
reference as preferred. But if they do, they'll hit a `BUG()`:

    $ git -c pack.preferBitmapTips=refs/heads/main repack -adb
    BUG: ../refs/iterator.c:366: attempt to trim too many characters
    error: pack-objects died of signal 6

The root cause for this bug is how we enumerate these references. We
call `refs_for_each_ref_in()`, which will:

  - Yield all references that have a user-specified prefix.

  - Trim each of these references so that the prefix is removed.

Typically, this function is called with a trailing slash, like
"refs/heads/", and in that case things work alright. But if the function
is called with the name of an existing reference then we'll try to trim
the full reference name, which would leave us with an empty name. And as
this would not really leave us with anything sensible, we call `BUG()`
instead of yielding this reference.

One could argue that this is a bug in `refs_for_each_ref_in()`. But the
question then becomes what the correct behaviour would be:

  - Do we want to skip exact matches? In our case we certainly don't
    want that, as the user has asked us to generate a bitmap for it.

  - Do we want to yield the reference with the empty refname? That would
    lead to a somewhat weird result.

Neither of these feel like viable options, so calling `BUG()` feels like
a sensible way out. The root cause ultimately is that we even try to
trim the whole refname in the first place. There are two possible ways
to fix this issue:

  - We can fix the bug by using `refs_for_each_fullref_in()` instead,
    which does not strip the prefix at all. Consequently, we would now
    start to accept all references that start with the configured
    prefix, including exact matches. So if we had "refs/heads/main", we
    would both match "refs/heads/main" and "refs/heads/main-branch".

  - Or we can fix the bug by appending a slash to the prefix if it
    doesn't already have one. This would mean that we only match
    ref hierarchies that start with this prefix.

While the first fix leaves the user with strictly _more_ configuration
options, we have already fixed a similar case in 10e8a9352b (refs.c:
stop matching non-directory prefixes in exclude patterns, 2025-03-06) by
using the second option. So for the sake of consistency, let's apply the
same fix here.

Clarify the documentation accordingly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agopack-bitmap: deduplicate logic to iterate over preferred bitmap tips
Patrick Steinhardt [Thu, 19 Feb 2026 07:57:49 +0000 (08:57 +0100)]
pack-bitmap: deduplicate logic to iterate over preferred bitmap tips

We have two locations that iterate over the preferred bitmap tips as
configured by the user via "pack.preferBitmapTips". Both of these
callsites are subtly wrong: when the preferred bitmap tips contain an
exact refname match, then we will hit a `BUG()`.

Prepare for the fix by unifying the two callsites into a new
`for_each_preferred_bitmap_tip()` function.

This removes the last callsite of `bitmap_preferred_tips()` outside of
"pack-bitmap.c". As such, convert the function to be local to that file
only. Note that the function is still used by a second caller, so we
cannot just inline it.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agogitlab-ci: handle failed tests on MSVC+Meson job
Patrick Steinhardt [Thu, 19 Feb 2026 06:25:33 +0000 (07:25 +0100)]
gitlab-ci: handle failed tests on MSVC+Meson job

The MSVC+Meson job does not currently have any logic to print failing
tests, nor does it upload the failed test artifacts. Backfill this logic
to make help debugging efforts in case any of its jobs has failed.

GitHub already knows to do this, so we don't need an equivalent change
over there.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agogitlab-ci: use "run-test-slice-meson.sh"
Patrick Steinhardt [Thu, 19 Feb 2026 06:25:32 +0000 (07:25 +0100)]
gitlab-ci: use "run-test-slice-meson.sh"

While our GitHub workflow already uses "ci/run-test-slice-meson.sh",
GitLab CI open-codes the parameters. Adapt the latter to also use the
same script so that we always use the same Meson options across both CI
systems.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoci: make test slicing consistent across Meson/Make
Patrick Steinhardt [Thu, 19 Feb 2026 06:25:31 +0000 (07:25 +0100)]
ci: make test slicing consistent across Meson/Make

In the preceding commit we have adjusted test slicing to be one-based
when using the "ci/run-test-slice.sh" script. But we also have an
equivalent script for Meson that is still zero-based, which is of course
inconsistent.

Adapt the script to be one-based, as well, and adapt the GitHub workflow
accordingly. Note that GitLab doesn't yet use the script, so it does not
need to be adapted. This will change in the next commit though.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agogithub: fix Meson tests not executing at all
Patrick Steinhardt [Thu, 19 Feb 2026 06:25:30 +0000 (07:25 +0100)]
github: fix Meson tests not executing at all

While the win+Meson test jobs run in GitHub workflows, the shell script
that is supposed to run the jobs is seemingly not running at all. All
that the CI job prints is the following:

  Run ci/run-test-slice-meson.sh build 1 10
    ci/run-test-slice-meson.sh build 1 10
    shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'"
    env:
      DEVELOPER: 1

The step is currently defined to use PowerShell, and of course it
doesn't know how to execute POSIX shell scripts. What's surprising
though is that this step doesn't even lead to a CI failure.

Fix the issue by using Bash instead of PowerShell, as we do in other
steps that execute shell scripts.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agomeson: fix MERGE_TOOL_DIR with "--no-bin-wrappers"
Patrick Steinhardt [Thu, 19 Feb 2026 06:25:29 +0000 (07:25 +0100)]
meson: fix MERGE_TOOL_DIR with "--no-bin-wrappers"

On Windows, we execute tests with "--no-bin-wrappers". This has been
introduced via a87e427e35 (ci: speed up Windows phase, 2019-01-29) to
save some time: spawning processes is expensive on Windows, and shell
scripts tend to spawn a bunch of them. So overall, the bin-wrappers led
to a performance overhead of ~10-30%.

This causes test failures when using Meson on Windows:

  failure: t7610.28 mergetool --tool-help shows recognized tools
    ++ git mergetool --tool-help
    /d/a/git/git/build/git-mergetool--lib: line 45: cd: D:/a/git/git/build/mergetools: No such file or directory

The root cause here is that our bin-wrappers are usually responsible for
setting up the `MERGE_TOOL_DIR` environment variable so that we can
locate these scripts. But as we don't use the bin-wrappers, we'll
instead use the default location for merge tools, which is derived from
`GIT_EXEC_PATH`. And as `GIT_EXEC_PATH` points to our build directory,
which won't ever contain any of the merge tools, we will fail to locate
any of the merge tools.

This issue has went unnoticed for a long time given that we only skip
bin-wrappers on Windows, and because the CI jobs on Windows didn't
execute due to a bug.

Fix the issue by always setting the `MERGE_TOOL_DIR` environment
variable to the correct directory.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoci: don't skip smallest test slice in GitLab
Patrick Steinhardt [Thu, 19 Feb 2026 06:25:28 +0000 (07:25 +0100)]
ci: don't skip smallest test slice in GitLab

The "ci/run-test-slice.sh" script can be used to slice up all of our
tests into N pieces and then run each of them on a separate CI job.
This is used by both GitLab and GitHub CI to speed up Windows tests,
which would otherwise be painfully slow.

The infra itself is fueled by `test-tool path-utils slice-tests`. This
tool receives as input an "offset" and a "stride" that can be combined
to slice up tests. This framing can be misleading though: you are
expected to pass a zero-based index as "offset", and the complete number
of slices to the "stride". The latter makes sense, but it is somewhat
surprising that the offset needs to be zero-based. And this is in fact
biting us: while GitHub passes zero-based indices, GitLab passes
`$CI_NODE_INDEX`, which is a one-based indice.

Ideally, we should have verification that the parameters make sense.
And naturally, one would for example expect that it's an error to call
the binary with an offset larger than the stride. But with the current
framing as "offset" it's not even wrong to do so, as it is of course
well-defined to start at a larger offset than the stride.

This means that we get this wrong on GitLab's CI, as we pass a one based
index there, and this causes us to skip one of the tests. Interestingly,
it's not the lexicographically first test that we skip. Instead, as we
sort tests by size before slicing them, we skip the _smallest_ test.

Reframe the problem to instead talk about "slice number" and "total
number of slices". For all of our use cases this is semantically
equivalent, but it allows us to perform some verifications:

  - The total number of slices must be greater than 1.

  - The selected slice must be between 1 <= nr <= slices_total.

As the indices are now one-based it means that GitLab's CI is fixed.
The GitHub workflow is updated accordingly.

Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoci: handle failures of test-slice helper
Patrick Steinhardt [Thu, 19 Feb 2026 06:25:27 +0000 (07:25 +0100)]
ci: handle failures of test-slice helper

The "run-test-slice.sh" script executes the test helper to slice up
tests passed to it. As the execution is part of a pipe though, we end up
ignoring any potential error code returned by the helper.

Make the code more robust by storing the tests in a variable first so
that we can split up the pipeline.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agocompletion: fix zsh alias listing for subsection aliases
Jonatan Holmgren [Wed, 18 Feb 2026 21:57:37 +0000 (22:57 +0100)]
completion: fix zsh alias listing for subsection aliases

The zsh completion function __git_zsh_cmd_alias() uses 'git config
--get-regexp' to enumerate aliases and then strips the "alias." prefix
from each key. For subsection-style aliases (alias.name.command), this
leaves "name.command" as the completion candidate instead of just
"name".

The bash completion does not have this problem because it goes through
'git --list-cmds=alias', which calls list_aliases() in C and already
handles both alias syntaxes correctly. However, zsh needs both the
alias name and its value for descriptive completion, which
--list-cmds=alias does not provide.

Add a hidden --aliases-for-completion option to 'git help', following
the existing --config-for-completion pattern. It outputs NUL-separated
"name\nvalue" pairs using list_aliases(), which correctly resolves both
the traditional (alias.name) and subsection (alias.name.command)
formats. Update __git_zsh_cmd_alias() to use it.

Signed-off-by: Jonatan Holmgren <jonatan@jontes.page>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoalias: support non-alphanumeric names via subsection syntax
Jonatan Holmgren [Wed, 18 Feb 2026 21:57:36 +0000 (22:57 +0100)]
alias: support non-alphanumeric names via subsection syntax

Git alias names are limited to ASCII alphanumeric characters and
dashes because aliases are implemented as config variable names.
This prevents aliases being created in languages using characters outside that range.

Add support for arbitrary alias names by using config subsections:

    [alias "förgrena"]
        command = branch

The subsection name is matched as-is (case-sensitive byte comparison),
while the existing definition without a subsection (e.g.,
"[alias] co = checkout") remains case-insensitive for backward
compatibility. This uses existing config infrastructure since
subsections already support arbitrary bytes, and avoids introducing
Unicode normalization.

Also teach the help subsystem about the new syntax so that "git help
-a" properly lists subsection aliases and the autocorrect feature can
suggest them. Use utf8_strwidth() instead of strlen() for column
alignment so that non-ASCII alias names display correctly.

Suggested-by: Jeff King <peff@peff.net>
Signed-off-by: Jonatan Holmgren <jonatan@jontes.page>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoalias: prepare for subsection aliases
Jonatan Holmgren [Wed, 18 Feb 2026 21:57:35 +0000 (22:57 +0100)]
alias: prepare for subsection aliases

Switch git_unknown_cmd_config() from skip_prefix() to
parse_config_key() for alias parsing. This properly handles the
three-level config key structure and prepares for the new
alias.*.command subsection syntax in the next commit.

This is a compatibility break: the alias configuration parser used
to be overly permissive and accepted "alias.<subsection>.<key>" as
defining an alias "<subsection>.<key>". With this change,
alias.<subsection>.<key> entries are silently ignored (unless <key>
is "command", which will be given meaning in the next commit).

This behavior was arguably a bug, since config subsections were never
intended to work this way for aliases, and aliases with dots in their
names have never been documented or intentionally supported.

Signed-off-by: Jonatan Holmgren <jonatan@jontes.page>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agohelp: use list_aliases() for alias listing
Jonatan Holmgren [Wed, 18 Feb 2026 21:57:34 +0000 (22:57 +0100)]
help: use list_aliases() for alias listing

help.c has its own get_alias() config callback that duplicates the
parsing logic in alias.c. Consolidate by teaching list_aliases() to
also store the alias values (via the string_list util field), then
use it in list_all_cmds_help_aliases() instead of the private
callback.

This preserves the existing error checking for value-less alias
definitions by checking in alias.c rather than help.c.

No functional change intended.

Signed-off-by: Jonatan Holmgren <jonatan@jontes.page>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoobject-file: use `container_of()` to convert from base types
Justin Tobler [Wed, 18 Feb 2026 21:01:20 +0000 (15:01 -0600)]
object-file: use `container_of()` to convert from base types

To improve code hygiene, replace direct casts from `struct
odb_transaction` and `struct odb_read_stream` to their concrete
implementations with `container_of()`.

Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agodoc: fetch: document `--jobs=0` behavior
Daniel D. Beck [Wed, 18 Feb 2026 19:32:39 +0000 (19:32 +0000)]
doc: fetch: document `--jobs=0` behavior

In c39952b92 (fetch: choose a sensible default with --jobs=0 again,
2023-02-20), the `--jobs=0` behavior was (re)introduced, but it went
undocumented. Since this is the same behavior as `git -c fetch.parallel=0
fetch`, which is documented, this change creates symmetry between the two
documentation sections.

Signed-off-by: Daniel D. Beck <daniel@ddbeck.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agocommit: use commit graph in `lookup_commit_reference_gently()`
Patrick Steinhardt [Mon, 16 Feb 2026 15:38:03 +0000 (16:38 +0100)]
commit: use commit graph in `lookup_commit_reference_gently()`

In the preceding commit we refactored `lookup_commit_reference_gently()`
so that it doesn't parse non-commit objects anymore. This has led to a
speedup when git-receive-pack(1) accepts a shallow push into a repo
with lots of refs that point to blobs or trees.

But while this case is now faster, we still have the issue that
accepting pushes with lots of "normal" refs that point to commits are
still slow. This is mostly because we look up the commits via the object
database, and that is rather costly.

Adapt the code to use `repo_parse_commit_gently()` instead of
`parse_object()` to parse the resulting commit object. This function
knows to use the commit-graph to fill in the object, which is way more
cost efficient.

This leads to another significant speedup when accepting shallow pushes.
The following benchmark pushes a single objects from a shallow clone
into a repository with 600,000 references that all point to commits:

  Benchmark 1: git-receive-pack (rev = HEAD~)
    Time (mean ± σ):      9.179 s ±  0.031 s    [User: 8.858 s, System: 0.528 s]
    Range (min … max):    9.154 s …  9.213 s    3 runs

  Benchmark 2: git-receive-pack (rev = HEAD)
    Time (mean ± σ):      2.337 s ±  0.032 s    [User: 2.331 s, System: 0.234 s]
    Range (min … max):    2.308 s …  2.371 s    3 runs

  Summary
    git-receive-pack . </tmp/input (rev = HEAD) ran
      3.93 ± 0.05 times faster than git-receive-pack (rev = HEAD~)

Also, this again leads to a significant reduction in memory allocations.
Before this change:

  HEAP SUMMARY:
      in use at exit: 17,524,978 bytes in 22,393 blocks
    total heap usage: 33,313 allocs, 10,920 frees, 407,774,251 bytes allocated

And after this change:

  HEAP SUMMARY:
      in use at exit: 11,534,036 bytes in 12,406 blocks
    total heap usage: 13,284 allocs, 878 frees, 15,521,451 bytes allocated

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agocommit: make `repo_parse_commit_no_graph()` more robust
Patrick Steinhardt [Mon, 16 Feb 2026 15:38:02 +0000 (16:38 +0100)]
commit: make `repo_parse_commit_no_graph()` more robust

In the next commit we will start to parse more commits via the
commit-graph. This change will lead to a segfault though because we try
to access the tree of a commit via `repo_get_commit_tree()`, but:

  - The commit has been parsed via the commit-graph, and thus its
    `maybe_tree` field is not yet populated.

  - We cannot use the commit-graph to populate the commit's tree because
    we're in the process of writing the commit-graph.

The consequence is that we'll get a `NULL` pointer for the tree in
`write_graph_chunk_data()`.

In theory we are already mindful of this situation, as we explicitly use
`repo_parse_commit_no_graph()` to parse the commit without the help of
the commit-graph. But that doesn't do the trick as the commit is already
marked as parsed, so the function will not re-populate it. And as the
commit-graph has been closed, neither will `get_commit_tree_oid()` be
able to load the tree for us.

It seems like this issue can only be hit under artificial circumstances:
the error was hit via `git_test_write_commit_graph_or_die()`, which is
run by git-commit(1) and git-merge(1) in case `GIT_TEST_COMMIT_GRAPH=1`:

  $ GIT_TEST_COMMIT_GRAPH=1 meson test t7507-commit-verbose \
      --test-args=-ix -i
  ...
  ++ git -c commit.verbose=true commit --amend
  hint: Waiting for your editor to close the file...
  ./test-lib.sh: line 1012: 55895 Segmentation fault         (core dumped) git -c commit.verbose=true commit --amend

To the best of my knowledge, this is the only case where we end up
writing a commit-graph in the same process that might have already
consulted the commit-graph to look up arbitrary objects. But regardless
of that, this feels like a bigger accident that is just waiting to
happen.

Make the code more robust by extending `repo_parse_commit_no_graph()` to
unparse a commit first in case we detect it's coming from a graph. This
ensures that we will re-read the object without it, and thus we will
populate `maybe_tree` properly.

This fix shouldn't have any performance consequences: the function is
only ever called in the "commit-graph.c" code, and we'll only re-parse
the commit at most once.

Add an exclusion to our Coccinelle rules so that it doesn't complain
about us accessing `maybe_tree` directly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agocommit: avoid parsing non-commits in `lookup_commit_reference_gently()`
Patrick Steinhardt [Mon, 16 Feb 2026 15:38:01 +0000 (16:38 +0100)]
commit: avoid parsing non-commits in `lookup_commit_reference_gently()`

The function `lookup_commit_reference_gently()` can be used to look up a
committish by object ID. As such, the function knows to peel for example
tag objects so that we eventually end up with the commit.

The function is used quite a lot throughout our tree. One such user is
"shallow.c" via `assign_shallow_commits_to_refs()`. The intent of this
function is to figure out whether a shallow push is missing any objects
that are required to satisfy the ref updates, and if so, which of the
ref updates is missing objects.

This is done by painting the tree with `UNINTERESTING`. We start
painting by calling `refs_for_each_ref()` so that we can mark all
existing referenced objects as the boundary of objects that we already
have, and which are supposed to be fully connected. The reference tips
are then parsed via `lookup_commit_reference_gently()`, and the commit
is then marked as uninteresting.

But references may not necessarily point to a committish, and if a lot
of them aren't then this step takes a lot of time. This is mostly due to
the way that `lookup_commit_reference_gently()` is implemented: before
we learn about the type of the object we already call `parse_object()`
on the object ID. This has two consequences:

  - We parse all objects, including trees and blobs, even though we
    don't even need the contents of them.

  - More importantly though, `parse_object()` will cause us to check
    whether the object ID matches its contents.

Combined this means that we deflate and hash every non-committish
object, and that of course ends up being both CPU- and memory-intensive.

Improve the logic so that we first use `peel_object()`. This function
won't parse the object for us, and thus it allows us to learn about the
object's type before we parse and return it.

The following benchmark pushes a single object from a shallow clone into
a repository that has 100,000 refs. These refs were created by listing
all objects via `git rev-list(1) --objects --all` and creating refs for
a subset of them, so lots of those refs will cover non-commit objects.

  Benchmark 1: git-receive-pack (rev = HEAD~)
    Time (mean ± σ):     62.571 s ±  0.413 s    [User: 58.331 s, System: 4.053 s]
    Range (min … max):   62.191 s … 63.010 s    3 runs

  Benchmark 2: git-receive-pack (rev = HEAD)
    Time (mean ± σ):     38.339 s ±  0.192 s    [User: 36.220 s, System: 1.992 s]
    Range (min … max):   38.176 s … 38.551 s    3 runs

  Summary
    git-receive-pack . </tmp/input (rev = HEAD) ran
      1.63 ± 0.01 times faster than git-receive-pack . </tmp/input (rev = HEAD~)

This leads to a sizeable speedup as we now skip reading and parsing
non-commit objects. Before this change we spent around 40% of the time
in `assign_shallow_commits_to_refs()`, after the change we only spend
around 1.2% of the time in there. Almost the entire remainder of the
time is spent in git-rev-list(1) to perform the connectivity checks.

Despite the speedup though, this also leads to a massive reduction in
allocations. Before:

  HEAP SUMMARY:
      in use at exit: 352,480,441 bytes in 97,185 blocks
    total heap usage: 2,793,820 allocs, 2,696,635 frees, 67,271,456,983 bytes allocated

And after:

  HEAP SUMMARY:
      in use at exit: 17,524,978 bytes in 22,393 blocks
    total heap usage: 33,313 allocs, 10,920 frees, 407,774,251 bytes allocated

Note that when all references refer to commits performance stays roughly
the same, as expected. The following benchmark was executed with 600k
commits:

  Benchmark 1: git-receive-pack (rev = HEAD~)
    Time (mean ± σ):      9.101 s ±  0.006 s    [User: 8.800 s, System: 0.520 s]
    Range (min … max):    9.095 s …  9.106 s    3 runs

  Benchmark 2: git-receive-pack (rev = HEAD)
    Time (mean ± σ):      9.128 s ±  0.094 s    [User: 8.820 s, System: 0.522 s]
    Range (min … max):    9.019 s …  9.188 s    3 runs

  Summary
    git-receive-pack (rev = HEAD~) ran
      1.00 ± 0.01 times faster than git-receive-pack (rev = HEAD)

This will be improved in the next commit.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agot: use test_seq -f and pipes in a few more places
Aaron Plattner [Wed, 18 Feb 2026 18:10:19 +0000 (10:10 -0800)]
t: use test_seq -f and pipes in a few more places

Several tests use a pattern that writes to a temporary file like this:

  printf "do something with %d\n" $(test_seq <count>) >tmpfile &&
  git do-something --stdin <tmpfile

Other tests use test_seq's -f parameter, but still write to a temporary file:

  test_seq -f "do something with %d" <count> >input &&
  git do-something --stdin <input

Simplify both of these patterns to

  test_seq -f "do something with %d" <count> |
  git do-something --stdin

Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoformat-patch: fix From header in cover letter
Mirko Faina [Tue, 17 Feb 2026 23:25:18 +0000 (00:25 +0100)]
format-patch: fix From header in cover letter

"git format-patch" takes "--from=<user ident>" command line option
and uses the given ident for patch e-mails, but this is not applied
to the cover letter, the option is ignored and the committer ident
of the current user is used. This has been the case ever since
"--from" was introduced in a9080475 (teach format-patch to place
other authors into in-body "From", 2013-07-03).

Teach the make_cover_letter() function to honor the option, instead of
always using the current committer identity. Change variable name from
"committer" to "from" to better reflect the purpose of the variable.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoThe 5th batch
Junio C Hamano [Tue, 17 Feb 2026 21:29:49 +0000 (13:29 -0800)]
The 5th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
4 months agoMerge branch 'jc/doc-rerere-update'
Junio C Hamano [Tue, 17 Feb 2026 21:30:43 +0000 (13:30 -0800)]
Merge branch 'jc/doc-rerere-update'

Doc update.

* jc/doc-rerere-update:
  rerere: minor documantation update

4 months agoMerge branch 'sd/t7003-test-path-is-helpers'
Junio C Hamano [Tue, 17 Feb 2026 21:30:43 +0000 (13:30 -0800)]
Merge branch 'sd/t7003-test-path-is-helpers'

Test updates.

* sd/t7003-test-path-is-helpers:
  t7003: modernize path existence checks using test helpers

4 months agoMerge branch 'kh/doc-rerere-options-xref'
Junio C Hamano [Tue, 17 Feb 2026 21:30:43 +0000 (13:30 -0800)]
Merge branch 'kh/doc-rerere-options-xref'

Doc update.

* kh/doc-rerere-options-xref:
  doc: rerere-options.adoc: link to git-rerere(1)

4 months agoMerge branch 'bk/t2003-modernise'
Junio C Hamano [Tue, 17 Feb 2026 21:30:42 +0000 (13:30 -0800)]
Merge branch 'bk/t2003-modernise'

Test update.

* bk/t2003-modernise:
  t2003: modernize path existence checks using test helpers

4 months agoMerge branch 'rs/commit-commit-stack'
Junio C Hamano [Tue, 17 Feb 2026 21:30:42 +0000 (13:30 -0800)]
Merge branch 'rs/commit-commit-stack'

Code clean-up to use the commit_stack API.

* rs/commit-commit-stack:
  commit: use commit_stack

4 months agoMerge branch 'rs/clean-includes'
Junio C Hamano [Tue, 17 Feb 2026 21:30:42 +0000 (13:30 -0800)]
Merge branch 'rs/clean-includes'

Clean up redundant includes of header files.

* rs/clean-includes:
  remove duplicate includes