]> git.ipfire.org Git - thirdparty/git.git/log
thirdparty/git.git
8 weeks agoMerge branch 'jt/index-fd-wo-repo-regression-fix-maint' into HEAD
Junio C Hamano [Wed, 8 Apr 2026 00:34:30 +0000 (17:34 -0700)] 
Merge branch 'jt/index-fd-wo-repo-regression-fix-maint' into HEAD

* jt/index-fd-wo-repo-regression-fix-maint:
  object-file: avoid ODB transaction when not writing objects

8 weeks agoobject-file: avoid ODB transaction when not writing objects
Justin Tobler [Tue, 7 Apr 2026 20:17:30 +0000 (15:17 -0500)] 
object-file: avoid ODB transaction when not writing objects

In ce1661f9da (odb: add transaction interface, 2025-09-16), existing
ODB transaction logic is adapted to create a transaction interface
at the ODB layer. The intent here is for the ODB transaction
interface to eventually provide an object source agnostic means to
manage transactions.

An unintended consequence of this change though is that
`object-file.c:index_fd()` may enter the ODB transaction path even
when no object write is requested. In non-repository contexts, this
can result in a NULL dereference and segfault. One such case occurs
when running git-diff(1) outside of a repository with
"core.bigFileThreshold" forcing the streaming path in `index_fd()`:

        $ echo foo >foo
        $ echo bar >bar
        $ git -c core.bigFileThreshold=1 diff -- foo bar

In this scenario, the caller only needs to compute the object ID. Object
hashing does not require an ODB, so starting a transaction is both
unnecessary and invalid.

Fix the bug by avoiding the use of ODB transactions in `index_fd()` when
callers are only interested in computing the object hash.

Reported-by: Luca Stefani <luca.stefani.ge1@gmail.com>
Signed-off-by: Justin Tobler <jltobler@gmail.com>
[jc: adjusted to fd13909e (Merge branch 'jt/odb-transaction', 2025-10-02)]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoA handful before -rc1
Junio C Hamano [Mon, 6 Apr 2026 22:42:30 +0000 (15:42 -0700)] 
A handful before -rc1

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'jk/c23-const-preserving-fixes'
Junio C Hamano [Mon, 6 Apr 2026 22:42:51 +0000 (15:42 -0700)] 
Merge branch 'jk/c23-const-preserving-fixes'

Adjust the codebase for C23 that changes functions like strchr()
that discarded constness when they return a pointer into a const
string to preserve constness.

* jk/c23-const-preserving-fixes:
  config: store allocated string in non-const pointer
  rev-parse: avoid writing to const string for parent marks
  revision: avoid writing to const string for parent marks
  rev-parse: simplify dotdot parsing
  revision: make handle_dotdot() interface less confusing

2 months agoMerge branch 'aa/reap-transport-child-processes'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'aa/reap-transport-child-processes'

A few code paths that spawned child processes for network
connection weren't wait(2)ing for their children and letting "init"
reap them instead; they have been tightened.

* aa/reap-transport-child-processes:
  transport-helper, connect: use clean_on_exit to reap children on abnormal exit

2 months agoMerge branch 'qb/doc-git-stash-push-optionality'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'qb/doc-git-stash-push-optionality'

Doc update.

* qb/doc-git-stash-push-optionality:
  docs: fix "git stash [push]" documentation

2 months agoMerge branch 'sp/doc-gitignore-oowt'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'sp/doc-gitignore-oowt'

Doc update.

* sp/doc-gitignore-oowt:
  doc: gitignore: clarify pattern base for info/exclude and core.excludesFile

2 months agoMerge branch 'th/t6101-unhide-git-failures'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'th/t6101-unhide-git-failures'

Test cleanup.

* th/t6101-unhide-git-failures:
  t6101: avoid suppressing git's exit code

2 months agoMerge branch 'za/t2000-modernise'
Junio C Hamano [Mon, 6 Apr 2026 22:42:50 +0000 (15:42 -0700)] 
Merge branch 'za/t2000-modernise'

Test cleanup.

* za/t2000-modernise:
  t2000: modernise overall structure

2 months agoMerge branch 'tc/replay-down-to-root'
Junio C Hamano [Mon, 6 Apr 2026 22:42:49 +0000 (15:42 -0700)] 
Merge branch 'tc/replay-down-to-root'

git replay now supports replaying down to the root commit.

* tc/replay-down-to-root:
  replay: support replaying down from root commit

2 months agoMerge branch 'tb/stdin-packs-excluded-but-open'
Junio C Hamano [Mon, 6 Apr 2026 22:42:49 +0000 (15:42 -0700)] 
Merge branch 'tb/stdin-packs-excluded-but-open'

pack-objects's --stdin-packs=follow mode learns to handle
excluded-but-open packs.

* tb/stdin-packs-excluded-but-open:
  repack: mark non-MIDX packs above the split as excluded-open
  pack-objects: support excluded-open packs with --stdin-packs
  t7704: demonstrate failure with once-cruft objects above the geometric split
  pack-objects: refactor `read_packs_list_from_stdin()` to use `strmap`
  pack-objects: plug leak in `read_stdin_packs()`

2 months agoMerge branch 'ps/odb-generic-object-name-handling'
Junio C Hamano [Mon, 6 Apr 2026 22:42:48 +0000 (15:42 -0700)] 
Merge branch 'ps/odb-generic-object-name-handling'

Object name handling (disambiguation and abbreviation) has been
refactored to be backend-generic, moving logic into the respective
object database backends.

* ps/odb-generic-object-name-handling:
  odb: introduce generic `odb_find_abbrev_len()`
  object-file: move logic to compute packed abbreviation length
  object-name: move logic to compute loose abbreviation length
  object-name: simplify computing common prefixes
  object-name: abbreviate loose object names without `disambiguate_state`
  object-name: merge `update_candidates()` and `match_prefix()`
  object-name: backend-generic `get_short_oid()`
  object-name: backend-generic `repo_collect_ambiguous()`
  object-name: extract function to parse object ID prefixes
  object-name: move logic to iterate through packed prefixed objects
  object-name: move logic to iterate through loose prefixed objects
  odb: introduce `struct odb_for_each_object_options`
  oidtree: extend iteration to allow for arbitrary return codes
  oidtree: modernize the code a bit
  object-file: fix sparse 'plain integer as NULL pointer' error

2 months agocompat/winansi: drop pre-Vista workaround
Matthias Aßhauer [Mon, 6 Apr 2026 05:45:30 +0000 (05:45 +0000)] 
compat/winansi: drop pre-Vista workaround

1edeb9a (Win32: warn if the console font doesn't support Unicode,
2014-06-10) introduced both code to detect the current console font on
Windows Vista and newer and a fallback for older systems to detect the
default console font and issue a warning if that font doesn't support
unicode.

Since we haven't supported any Windows older than Vista in almost a
decade, we don't need to keep the workaround.

Signed-off-by: Matthias Aßhauer <mha1993@live.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agounify and bump _WIN32_WINNT definition to Windows 8.1
Matthias Aßhauer [Mon, 6 Apr 2026 05:45:29 +0000 (05:45 +0000)] 
unify and bump _WIN32_WINNT definition to Windows 8.1

Git for Windows doesn't support anything prior to Windows 8.1 since 2.47.0
and Git followed along with commits like ce6ccba (mingw: drop Windows
7-specific work-around, 2025-08-04).

There is no need to pretend to the compiler that we still support Windows
Vista, just to lock us out of easy access to newer APIs. There is also no
need to have conflicting and unused definitions claiming we support some
versions of Windows XP or even Windows NT 4.0.

Bump all definitions of _WIN32_WINNT to a realistic value of Windows 8.1.
This will also simplify code for a followup commit that will improve cpu
core detection on multi-socket systems.

Signed-off-by: Matthias Aßhauer <mha1993@live.de>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoA couple more on top of -rc0
Junio C Hamano [Fri, 3 Apr 2026 22:26:34 +0000 (15:26 -0700)] 
A couple more on top of -rc0

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'ps/dash-buggy-0.5.13-workaround'
Junio C Hamano [Fri, 3 Apr 2026 22:24:45 +0000 (15:24 -0700)] 
Merge branch 'ps/dash-buggy-0.5.13-workaround'

The way dash 0.5.13 handles non-ASCII contents in here-doc
is buggy and breaks our existing tests, which unfortunately
have been rewritten to avoid triggering the bug.

* ps/dash-buggy-0.5.13-workaround:
  t9300: work around partial read bug in Dash v0.5.13
  t: work around multibyte bug in quoted heredocs with Dash v0.5.13

2 months agoMerge branch 'js/cmake-needs-writev-compat-too'
Junio C Hamano [Fri, 3 Apr 2026 22:24:45 +0000 (15:24 -0700)] 
Merge branch 'js/cmake-needs-writev-compat-too'

Build instruction for recently added writev() compatibility wrapper
has been also added to cmake.

* js/cmake-needs-writev-compat-too:
  cmake: use writev(3p) wrapper as needed

2 months agoMerge branch 'js/mingw-use-strftime-directly-in-ucrt-build'
Junio C Hamano [Fri, 3 Apr 2026 22:24:44 +0000 (15:24 -0700)] 
Merge branch 'js/mingw-use-strftime-directly-in-ucrt-build'

MinGW build updates.

* js/mingw-use-strftime-directly-in-ucrt-build:
  mingw: use strftime() directly in UCRT builds

2 months agoA bit more on top of 2.54-rc0
Junio C Hamano [Fri, 3 Apr 2026 20:00:49 +0000 (13:00 -0700)] 
A bit more on top of 2.54-rc0

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'th/t8003-unhide-git-failures'
Junio C Hamano [Fri, 3 Apr 2026 20:01:09 +0000 (13:01 -0700)] 
Merge branch 'th/t8003-unhide-git-failures'

Test clean-up.

* th/t8003-unhide-git-failures:
  t8003: modernise style
  t8003: avoid suppressing git's exit code

2 months agoMerge branch 'sa/replay-revert'
Junio C Hamano [Fri, 3 Apr 2026 20:01:09 +0000 (13:01 -0700)] 
Merge branch 'sa/replay-revert'

"git replay" (experimental) learns, in addition to "pick" and
"replay", a new operating mode "revert".

* sa/replay-revert:
  replay: add --revert mode to reverse commit changes
  sequencer: extract revert message formatting into shared function

2 months agoMerge branch 'pw/worktree-reduce-the-repository'
Junio C Hamano [Fri, 3 Apr 2026 20:01:09 +0000 (13:01 -0700)] 
Merge branch 'pw/worktree-reduce-the-repository'

Reduce the reference to the_repository in the worktree subsystem.

* pw/worktree-reduce-the-repository:
  worktree: reject NULL worktree in get_worktree_git_dir()
  worktree add: stop reading ".git/HEAD"
  worktree: remove "the_repository" from is_current_worktree()

2 months agoMerge branch 'ar/config-hook-cleanups'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'ar/config-hook-cleanups'

Code clean-up around the recent "hooks defined in config" topic.

* ar/config-hook-cleanups:
  hook: reject unknown hook names in git-hook(1)
  hook: show disabled hooks in "git hook list"
  hook: show config scope in git hook list
  hook: introduce hook_config_cache_entry for per-hook data
  t1800: add test to verify hook execution ordering
  hook: make consistent use of friendly-name in docs
  hook: replace hook_list_clear() -> string_list_clear_func()
  hook: detect & emit two more bugs
  hook: rename cb_data_free/alloc -> hook_data_free/alloc
  hook: fix minor style issues
  builtin/receive-pack: properly init receive_hook strbuf
  hook: move unsorted_string_list_remove() to string-list.[ch]

2 months agoMerge branch 'ds/backfill-revs'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'ds/backfill-revs'

`git backfill` learned to accept revision and pathspec arguments.

* ds/backfill-revs:
  t5620: test backfill's unknown argument handling
  path-walk: support wildcard pathspecs for blob filtering
  backfill: work with prefix pathspecs
  backfill: accept revision arguments
  t5620: prepare branched repo for revision tests
  revision: include object-name.h

2 months agoMerge branch 'mf/format-patch-commit-list-format-doc'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'mf/format-patch-commit-list-format-doc'

Doc updates.

* mf/format-patch-commit-list-format-doc:
  format-patch: removing unconditional wrapping
  docs: fix --commit-list-format related entries

2 months agoMerge branch 'mf/format-patch-commit-list-format'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'mf/format-patch-commit-list-format'

Improve the recently introduced `git format-patch
--commit-list-format` (formerly `--cover-letter-format`) option,
including a new "modern" preset and better CLI ergonomics.

* mf/format-patch-commit-list-format:
  format-patch: --commit-list-format without prefix
  format-patch: add preset for --commit-list-format
  format-patch: wrap generate_commit_list_cover()
  format.commitListFormat: strip meaning from empty
  docs/pretty-formats: add %(count) and %(total)
  format-patch: rename --cover-letter-format option
  format-patch: refactor generate_commit_list_cover
  pretty.c: better die message %(count) and %(total)

2 months agoMerge branch 'mf/format-patch-cover-letter-format'
Junio C Hamano [Fri, 3 Apr 2026 20:01:08 +0000 (13:01 -0700)] 
Merge branch 'mf/format-patch-cover-letter-format'

"git format-patch --cover-letter" learns to use a simpler format
instead of the traditional shortlog format to list its commits with
a new --cover-letter-format option and format.commitListFormat
configuration variable.

* mf/format-patch-cover-letter-format:
  docs: add usage for the cover-letter fmt feature
  format-patch: add commitListFormat config
  format-patch: add ability to use alt cover format
  format-patch: move cover letter summary generation
  pretty.c: add %(count) and %(total) placeholders

2 months agomingw: use strftime() directly in UCRT builds
Johannes Schindelin [Fri, 3 Apr 2026 09:56:23 +0000 (09:56 +0000)] 
mingw: use strftime() directly in UCRT builds

The `mingw_strftime()` wrapper exists to work around msvcrt.dll's
incomplete `strftime()` implementation by dynamically loading the
version from ucrtbase.dll at runtime via `LoadLibrary()` +
`GetProcAddress()`. When the binary is already linked against UCRT
(i.e. when building in the UCRT64 environment), the linked-in
`strftime()` is the ucrtbase.dll version, making the dynamic loading
needless churn: It's calling the very same code.

Simply guard both the declaration and implementation so that the
unnecessary work-around is skipped in UCRT builds.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agocmake: use writev(3p) wrapper as needed
Johannes Schindelin [Fri, 3 Apr 2026 08:55:02 +0000 (08:55 +0000)] 
cmake: use writev(3p) wrapper as needed

This is a companion patch of 3b9b2c2a29a (compat/posix: introduce
writev(3p) wrapper, 2026-03-13) where support for using the `writev()`
wrapper was introduced in the `Makefile` and the Meson-based build, but
the CMake build still needs that treatment, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot9300: work around partial read bug in Dash v0.5.13
Patrick Steinhardt [Thu, 2 Apr 2026 06:51:19 +0000 (08:51 +0200)] 
t9300: work around partial read bug in Dash v0.5.13

When executing t9300 with Dash v0.5.13.1 we can see that the test hangs
completely with the following (condensed) trace:

  git fast-import
  + error=1
  + read output
  + cat input
  + echo checkpoint
  + echo progress checkpoint
  + test rogress checkpoint = progress checkpoint
  + test rogress checkpoint = UNEXPECTED
  + echo cruft: rogress checkpoint
  cruft: rogress checkpoint
  + read output
  + test  = progress checkpoint
  + test  = UNEXPECTED
  + echo cruft:
  cruft:
  + read output

Basically, what's happening here is that we spawn git-fast-import(1) and
wait for it to output a certain string, "progress checkpoint". Curiously
though, what we end up reading is "rogress checkpoint" -- so the first
byte of the expected string is missing.

Same as in the preceding commit, this seems to be a bug in Dash itself
that bisects to c5bf970 (expand: Add multi-byte support to pmatch,
2024-06-02). But other than in the preceding commit, this bug has
already been fixed upstream in 079059a (input: Fix heap-buffer-overflow
in preadbuffer on long lines, 2026-02-11), which is part of v0.5.13.2.

For now though, work around the bug by waiting for the expected output
in a different way. There is no good reason why one version should work
better than the other, but at least the new version doesn't exhibit the
bug. And, if you ask me, it's also slightly easier to read.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot: work around multibyte bug in quoted heredocs with Dash v0.5.13
Patrick Steinhardt [Thu, 2 Apr 2026 06:51:18 +0000 (08:51 +0200)] 
t: work around multibyte bug in quoted heredocs with Dash v0.5.13

When executing our test suite with Dash v0.5.13.2 one can observe
several test failures that all have the same symptoms: we have a quoted
heredoc that contains multibyte characters, but the final data does not
match what we actually wanted to write. One such example is in t0300,
where we see the diffs like the following:

  --- expect-stdout 2026-04-01 07:25:45.249919440 +0000
  +++ stdout 2026-04-01 07:25:45.254919509 +0000
  @@ -1,5 +1,5 @@
   protocol=https
   host=example.com
  -path=perú.git
  +path=perú.git
   username=foo
   password=bar

While seemingly the same, the data that we've written via the heredoc
contains some invisible bytes. The expected hex representation of the
string is:

  7065 72c3 ba2e 6769 74                 per...git

But what we actually get instead is this string:

  7065 7285 02c3 ba02 852e 6769 74       per.......git

What's important to note here is that the multibyte character exists in
both versions. But in the broken version we see that the bytes are
wrapped in a sequence of "85 02" and "02 85". This is the CTLMBCHAR byte
sequence of Dash, which it uses internally to quote multibyte sequences.

As it turns out, this bug was introduced in c5bf970 (expand: Add
multi-byte support to pmatch, 2024-06-02), which adds multibyte support
to more contexts of Dash. One of these contexts seems to be in heredocs,
and Dash _does_ correctly unquote these multibyte sequences when using
an unquoted heredoc. But the bug seems to be that this unquoting does
not happen in quoted heredocs, and the bug still exists on the latest
"master" branch.

For now, work around the bug by using unquoted heredocs instead.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoGit 2.54-rc0 v2.54.0-rc0
Junio C Hamano [Thu, 2 Apr 2026 04:31:08 +0000 (21:31 -0700)] 
Git 2.54-rc0

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoRelNotes: minor typo fixes in 2.54.0 draft
Todd Zullinger [Wed, 1 Apr 2026 21:14:36 +0000 (17:14 -0400)] 
RelNotes: minor typo fixes in 2.54.0 draft

Signed-off-by: Todd Zullinger <tmz@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoThe 24th batch
Junio C Hamano [Wed, 1 Apr 2026 17:28:07 +0000 (10:28 -0700)] 
The 24th batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'kj/refspec-parsing-outside-repository'
Junio C Hamano [Wed, 1 Apr 2026 17:28:19 +0000 (10:28 -0700)] 
Merge branch 'kj/refspec-parsing-outside-repository'

"git ls-remote '+refs/tags/*:refs/tags/*' https://..." run outside a
repository would dereference a NULL while trying to see if the given
refspec is a single-object refspec, which has been corrected.

* kj/refspec-parsing-outside-repository:
  refspec: fix typo in comment
  remote-curl: fall back to default hash outside repo

2 months agoMerge branch 'jk/t0061-bat-test-update'
Junio C Hamano [Wed, 1 Apr 2026 17:28:19 +0000 (10:28 -0700)] 
Merge branch 'jk/t0061-bat-test-update'

A test to run a .bat file with whitespaces in the name with arguments
with whitespaces in them was flaky in that sometimes it got killed
before it produced expected side effects, which has been rewritten to
make it more robust.

* jk/t0061-bat-test-update:
  t0061: simplify .bat test

2 months agoMerge branch 'mk/repo-help-strings'
Junio C Hamano [Wed, 1 Apr 2026 17:28:19 +0000 (10:28 -0700)] 
Merge branch 'mk/repo-help-strings'

"git repo info -h" and "git repo structure -h" limit their help output
to the part that is specific to the subcommand.

* mk/repo-help-strings:
  repo: show subcommand-specific help text
  repo: factor repo usage strings into shared macros

2 months agoMerge branch 'jc/macos-homebrew-wo-reg-enhanced'
Junio C Hamano [Wed, 1 Apr 2026 17:28:19 +0000 (10:28 -0700)] 
Merge branch 'jc/macos-homebrew-wo-reg-enhanced'

In case homebrew breaks REG_ENHANCED again, leave a in-code comment
to suggest use of our replacement regex as a workaround.

* jc/macos-homebrew-wo-reg-enhanced:
  regexp: leave a pointer to resurrect workaround for Homebrew

2 months agoMerge branch 'rs/use-strvec-pushv'
Junio C Hamano [Wed, 1 Apr 2026 17:28:18 +0000 (10:28 -0700)] 
Merge branch 'rs/use-strvec-pushv'

Code paths that loop over another array to push each element into a
strvec have been rewritten to use strvec_pushv() instead.

* rs/use-strvec-pushv:
  use strvec_pushv() to add another strvec

2 months agoMerge branch 'bk/t5315-test-path-is-helpers'
Junio C Hamano [Wed, 1 Apr 2026 17:28:18 +0000 (10:28 -0700)] 
Merge branch 'bk/t5315-test-path-is-helpers'

Test clean-up.

* bk/t5315-test-path-is-helpers:
  t5315: use test_path_is_file for loose-object check

2 months agoMerge branch 'jk/diff-highlight-more'
Junio C Hamano [Wed, 1 Apr 2026 17:28:18 +0000 (10:28 -0700)] 
Merge branch 'jk/diff-highlight-more'

Various updates to contrib/diff-highlight, including documentation
updates, test improvements, and color configuration handling.

* jk/diff-highlight-more:
  diff-highlight: fetch all config with one process
  diff-highlight: allow module callers to pass in color config
  diff-highlight: test color config
  diff-highlight: use test_decode_color in tests
  t: add matching negative attributes to test_decode_color
  diff-highlight: check diff-highlight exit status in tests
  diff-highlight: drop perl version dependency back to 5.8
  diff-highlight: mention build instructions

2 months agoMerge branch 'vp/http-rate-limit-retries'
Junio C Hamano [Wed, 1 Apr 2026 17:28:18 +0000 (10:28 -0700)] 
Merge branch 'vp/http-rate-limit-retries'

The HTTP transport learned to react to "429 Too Many Requests".

* vp/http-rate-limit-retries:
  http: add support for HTTP 429 rate limit retries
  strbuf_attach: fix call sites to pass correct alloc
  strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()

2 months agoThe 23rd batch
Junio C Hamano [Mon, 30 Mar 2026 20:56:44 +0000 (13:56 -0700)] 
The 23rd batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'ai/t2107-test-path-is-helpers'
Junio C Hamano [Mon, 30 Mar 2026 20:57:03 +0000 (13:57 -0700)] 
Merge branch 'ai/t2107-test-path-is-helpers'

Test cleanup.

* ai/t2107-test-path-is-helpers:
  t2107: modernize path existence check

2 months agoMerge branch 'jw/object-name-bitset-to-enum'
Junio C Hamano [Mon, 30 Mar 2026 20:57:02 +0000 (13:57 -0700)] 
Merge branch 'jw/object-name-bitset-to-enum'

The unsigned integer that is used as an bitset to specify the kind
of branches interpret_branch_name() function has been changed to
use a dedicated enum type.

* jw/object-name-bitset-to-enum:
  object-name: turn INTERPRET_BRANCH_* constants into enum values

2 months agoMerge branch 'jw/t2203-status-pipe-fix'
Junio C Hamano [Mon, 30 Mar 2026 20:57:01 +0000 (13:57 -0700)] 
Merge branch 'jw/t2203-status-pipe-fix'

Test clean-up.

* jw/t2203-status-pipe-fix:
  t2203: avoid suppressing git status exit code

2 months agoMerge branch 'jw/apply-corrupt-location'
Junio C Hamano [Mon, 30 Mar 2026 20:57:00 +0000 (13:57 -0700)] 
Merge branch 'jw/apply-corrupt-location'

"git apply" now reports the name of the input file along with the
line number when it encounters a corrupt patch, and correctly
resets the line counter when processing multiple patch files.

* jw/apply-corrupt-location:
  apply: report input location in binary and garbage patch errors
  apply: report input location in header parsing errors
  apply: report the location of corrupt patches

2 months agoMerge branch 'rs/split-index-the-repo-fix'
Junio C Hamano [Mon, 30 Mar 2026 20:56:59 +0000 (13:56 -0700)] 
Merge branch 'rs/split-index-the-repo-fix'

split-index.c has been updated to not use the global the_repository
and the_hash_algo variables.

* rs/split-index-the-repo-fix:
  split-index: stop using the_repository and the_hash_algo

2 months agoMerge branch 'rs/ahead-behind-cleanup-optimization'
Junio C Hamano [Mon, 30 Mar 2026 20:56:58 +0000 (13:56 -0700)] 
Merge branch 'rs/ahead-behind-cleanup-optimization'

The cleanup of remaining bitmaps in "ahead_behind()" has been
simplified.

* rs/ahead-behind-cleanup-optimization:
  commit-reach: simplify cleanup of remaining bitmaps in ahead_behind ()

2 months agodocs: fix "git stash [push]" documentation
Quentin Bernet [Mon, 30 Mar 2026 13:24:35 +0000 (13:24 +0000)] 
docs: fix "git stash [push]" documentation

Both the synopsis and explanation are incorrect and contradict each
other.
The synopsis claims "push" can only be omitted when you do not give any
options and arguments.
The explanation correctly claims that non-option arguments are not
allowed, except pathspec elements preceded by double hyphens.
But it also adds "-p" to the list of exceptions, even though it is an
option argument.

Signed-off-by: Quentin Bernet <quentin.bernet@bluewin.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodoc: gitignore: clarify pattern base for info/exclude and core.excludesFile
Shreyansh Paliwal [Sat, 28 Mar 2026 15:21:58 +0000 (20:51 +0530)] 
doc: gitignore: clarify pattern base for info/exclude and core.excludesFile

The pattern format section describes how patterns are interpreted
relative to the location of a .gitignore file, but does not mention
the behavior for exclude sources outside the working tree.

Clarify that patterns from $GIT_DIR/info/exclude and core.excludesFile
are treated as if they are specified at the root of the working tree,
so a leading '/' anchors matches at the repository root.

Reported-by: Dan Drake <dan@dandrake.org>
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot6101: avoid suppressing git's exit code
Trieu Huynh [Sat, 28 Mar 2026 13:59:35 +0000 (22:59 +0900)] 
t6101: avoid suppressing git's exit code

Update t6101-rev-parse-parents.sh to redirect git-rev-parse
output to a temporary file instead of piping it directly to
not hide the exit code of git commands behind pipes, as a
crash in git might go unnoticed.

Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot8003: modernise style
Trieu Huynh [Sat, 28 Mar 2026 13:29:55 +0000 (22:29 +0900)] 
t8003: modernise style

Remove the blank lines at both ends of each test_expect_success body
to match the modern style used elsewhere in the test suite.

Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot8003: avoid suppressing git's exit code
Trieu Huynh [Sat, 28 Mar 2026 13:29:54 +0000 (22:29 +0900)] 
t8003: avoid suppressing git's exit code

Update t8003-blame-corner-cases.sh to redirect git-blame output
to a temporary file instead of piping it directly to not hide
the exit code of git commands behind pipes, as a crash in git
might go unnoticed.

Signed-off-by: Trieu Huynh <vikingtc4@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot2000: modernise overall structure
Zakariyah Ali [Fri, 27 Mar 2026 23:40:19 +0000 (00:40 +0100)] 
t2000: modernise overall structure

This test script that dates back to 2005 certainly shows its age and
both its style and the way the tests are laid out do not match the
modern standard.

 * Executables that prepare the data used to test the command should
   be inside the test_expect_success block in modern tests.

 * In modern tests, running a command that is being tested, making
   sure it succeeds, and inspecting other side effects that are
   expected, are all done in a single test_expect_success block.

 * A test_expect_success block in modern tests are laid out as

        test_expect_success 'title of the test' '
                body of the test &&
                ...
                body of the test
        '

   not as

        test_expect_success \
                'title of the test' \
                'body of the test &&
                ...
                body of the test'

   which is in a prehistoric style.

 * In modern tests, each &&-chained statement in the body of the
   test_expect_success block are indented with a horizontal tab,
   unlike prehistoric style that used 4-space indent.

Signed-off-by: Zakariyah Ali <zakariyahali100@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorepack: mark non-MIDX packs above the split as excluded-open
Taylor Blau [Fri, 27 Mar 2026 20:06:54 +0000 (16:06 -0400)] 
repack: mark non-MIDX packs above the split as excluded-open

In 5ee86c273bf (repack: exclude cruft pack(s) from the MIDX where
possible, 2025-06-23), geometric repacking learned to exclude cruft
packs from the MIDX when 'repack.midxMustContainCruft' is set to
'false'.

This works because packs generated with '--stdin-packs=follow' rescue
any once-unreachable objects that later become reachable, making the
resulting packs closed under reachability without needing the cruft pack
in the MIDX.

However, packs above the geometric split that were not part of the
previous MIDX may not have full object closure.  When such packs are
marked as excluded-closed ('^'), pack-objects treats them as a
reachability boundary and does not traverse through them during the
follow pass, potentially leaving the resulting pack without full
closure.

Fix this by marking packs above the geometric split that were not in the
previous MIDX as excluded-open ('!') instead of excluded-closed ('^').
This causes pack-objects to walk through their commits during the follow
pass, rescuing any reachable objects not present in the closed-excluded
packs.

Note that MIDXs which were generated prior to this change and are
unlucky enough to not be closed under reachability may still exhibit
this bug, as we treat all MIDX'd packs as closed. That is true in an
overwhelming number of cases, since in order to have a non-closed MIDX
you would have to:

 - Generate a pack via an earlier geometric repack that is not closed
   under reachability.

 - Store that pack in the MIDX.

 - Avoid picking any commits to receive reachability bitmaps which
   happen to reach objects from which the missing objects are reachable.

In the extremely rare chance that all of the above should happen, an
all-into-one repack will resolve the issue.

Unfortunately, there is no perfect way to determine whether a MIDX'd
pack is closed outside of ensuring that there is a '1' bit in at least
one bitmap for every bit position corresponding to objects in that pack.
While this is possible to do, this approach would treat MIDX'd packs as
open in cases where there is at least one object that is not reachable
from the subset of commits selected for bitmapping.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopack-objects: support excluded-open packs with --stdin-packs
Taylor Blau [Fri, 27 Mar 2026 20:06:51 +0000 (16:06 -0400)] 
pack-objects: support excluded-open packs with --stdin-packs

In cd846bacc7d (pack-objects: introduce '--stdin-packs=follow',
2025-06-23), pack-objects learned to traverse through commits in
included packs when using '--stdin-packs=follow', rescuing reachable
objects from unlisted packs into the output.

When we encounter a commit in an excluded pack during this rescuing
phase we will traverse through its parents. But because we set
`revs.no_kept_objects = 1`, commit simplification will prevent us from
showing it via `get_revision()`. (In practice, `--stdin-packs=follow`
walks commits down to the roots, but only opens up trees for ones that
do not appear in an excluded pack.)

But there are certain cases where we *do* need to see the parents of an
object in an excluded pack. Namely, if an object is rescue-able, but
only reachable from object(s) which appear in excluded packs, then
commit simplification will exclude those commits from the object
traversal, and we will never see a copy of that object, and thus not
rescue it.

This is what causes the failure in the previous commit during repacking.
When performing a geometric repack, packs above the geometric split that
weren't part of the previous MIDX (e.g., packs pushed directly into
`$GIT_DIR/objects/pack`) may not have full object closure.  When those
packs are listed as excluded via the '^' marker, the reachability
traversal encounters the sequence described above, and may miss objects
which we expect to rescue with `--stdin-packs=follow`.

Introduce a new "excluded-open" pack prefix, '!'. Like '^'-prefixed
packs, objects from '!'-prefixed packs are excluded from the resulting
pack. But unlike '^', commits in '!'-prefixed packs *are* used as
starting points for the follow traversal, and the traversal does not
treat them as a closure boundary.

In order to distinguish excluded-closed from excluded-open packs during
the traversal, introduce a new `pack_keep_in_core_open` bit on
`struct packed_git`, along with a corresponding `KEPT_PACK_IN_CORE_OPEN`
flag for the kept-pack cache.

In `add_object_entry_from_pack()`, move the `want_object_in_pack()`
check to *after* `add_pending_oid()`. This is necessary so that commits
from excluded-open packs are added as traversal tips even though their
objects won't appear in the output. As a consequence, the caller
`for_each_object_in_pack()` will always provide a non-NULL 'p', hence we
are able to drop the "if (p)" conditional.

The `include_check` and `include_check_obj` callbacks on `rev_info` are
used to halt the walk at closed-excluded packs, since objects behind a
'^' boundary are guaranteed to have closure and need not be rescued.

The following commit will make use of this new functionality within the
repack layer to resolve the test failure demonstrated in the previous
commit.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot7704: demonstrate failure with once-cruft objects above the geometric split
Taylor Blau [Fri, 27 Mar 2026 20:06:49 +0000 (16:06 -0400)] 
t7704: demonstrate failure with once-cruft objects above the geometric split

Add a test demonstrating a case where geometric repacking fails to
produce a pack with full object closure, thus making it impossible to
write a reachability bitmap.

Mark the test with 'test_expect_failure' for now. The subsequent commit
will explain the precise failure mode, and implement a fix.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopack-objects: refactor `read_packs_list_from_stdin()` to use `strmap`
Taylor Blau [Fri, 27 Mar 2026 20:06:46 +0000 (16:06 -0400)] 
pack-objects: refactor `read_packs_list_from_stdin()` to use `strmap`

The '--stdin-packs' mode of pack-objects maintains two separate
string_lists: one for included packs, and one for excluded packs. Each
list stores the pack basename as a string and the corresponding
`packed_git` pointer in its `->util` field.

This works, but makes it awkward to extend the set of pack "kinds" that
pack-objects can accept via stdin, since each new kind would need its
own string_list and duplicated handling. A future commit will want to do
just this, so prepare for that change by handling the various "kinds" of
packs specified over stdin in a more generic fashion.

Namely, replace the two `string_list`s with a single `strmap` keyed on
the pack basename, with values pointing to a new `struct
stdin_pack_info`. This struct tracks both the `packed_git` pointer and a
`kind` bitfield indicating whether the pack was specified as included or
excluded.

Extract the logic for sorting packs by mtime and adding their objects
into a separate `stdin_packs_add_pack_entries()` helper.

While we could have used a `string_list`, we must handle the case where
the same pack is specified more than once. With a `string_list` only, we
would have to pay a quadratic cost to either (a) insert elements into
their sorted positions, or (b) a repeated linear search, which is
accidentally quadratic. For that reason, use a strmap instead.

This patch does not include any functional changes.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopack-objects: plug leak in `read_stdin_packs()`
Taylor Blau [Fri, 27 Mar 2026 20:06:43 +0000 (16:06 -0400)] 
pack-objects: plug leak in `read_stdin_packs()`

The `read_stdin_packs()` function added originally via 339bce27f4f
(builtin/pack-objects.c: add '--stdin-packs' option, 2021-02-22)
declares a `rev_info` struct but neglects to call `release_revisions()`
on it before returning, creating the potential for a leak.

The related change in 97ec43247c0 (pack-objects: declare 'rev_info' for
'--stdin-packs' earlier, 2025-06-23) carried forward this oversight and
did not address it.

Ensure that we call `release_revisions()` appropriately to prevent a
potential leak from this function. Note that in practice our `rev_info`
here does not have a present leak, hence t5331 passes cleanly before
this commit, even when built with SANITIZE=leak.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoformat-patch: removing unconditional wrapping
Mirko Faina [Fri, 27 Mar 2026 19:48:10 +0000 (20:48 +0100)] 
format-patch: removing unconditional wrapping

Using format-patch with --commit-list-format different than shortlog,
causes the commit entry lines to wrap if they get longer than
MAIL_DEFAULT_WRAP (72 characters).

While this might be sensible for many when sending changes through
email, it forces this decision of wrapping on the user, reducing the
control granularity of --commit-list-format.

Teach generate_commit_list_cover() to respect commit entry line lengths
and place this wrapping rule on the "modern" preset format instead.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agodocs: fix --commit-list-format related entries
Mirko Faina [Fri, 27 Mar 2026 19:48:09 +0000 (20:48 +0100)] 
docs: fix --commit-list-format related entries

Documentation specifies that "git format-patch" would default to
format.commitListFormat if --commit-list-format is not given, but
doesn't specify the default if the format.commitListFormat is not set.
The text for --cover-letter is also obsolete as the commit list can now
be something other than a shortlog.

Document to reflect changes.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoThe 22nd batch
Junio C Hamano [Fri, 27 Mar 2026 17:59:34 +0000 (10:59 -0700)] 
The 22nd batch

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoMerge branch 'jc/rerere-modern-strbuf-handling'
Junio C Hamano [Fri, 27 Mar 2026 18:00:03 +0000 (11:00 -0700)] 
Merge branch 'jc/rerere-modern-strbuf-handling'

Code clean-up overdue by 19 years.

* jc/rerere-modern-strbuf-handling:
  cocci: strbuf.buf is never NULL
  rerere: update to modern representation of empty strbufs

2 months agoMerge branch 'kh/doc-interpret-trailers-1'
Junio C Hamano [Fri, 27 Mar 2026 18:00:02 +0000 (11:00 -0700)] 
Merge branch 'kh/doc-interpret-trailers-1'

Doc updates.

* kh/doc-interpret-trailers-1:
  interpret-trailers: use placeholder instead of *
  doc: config: convert trailers section to synopsis style
  doc: interpret-trailers: normalize and fill out options
  doc: interpret-trailers: convert to synopsis style

2 months agoMerge branch 'ej/ref-transaction-hook-preparing'
Junio C Hamano [Fri, 27 Mar 2026 18:00:02 +0000 (11:00 -0700)] 
Merge branch 'ej/ref-transaction-hook-preparing'

The reference-transaction hook was taught to be triggered before
taking locks on references in the "preparing" phase.

* ej/ref-transaction-hook-preparing:
  refs: add 'preparing' phase to the reference-transaction hook

2 months agoMerge branch 'mf/apply-p-no-atoi'
Junio C Hamano [Fri, 27 Mar 2026 18:00:02 +0000 (11:00 -0700)] 
Merge branch 'mf/apply-p-no-atoi'

"git apply -p<n>" parses <n> more carefully now.

* mf/apply-p-no-atoi:
  apply.c: fix -p argument parsing

2 months agoMerge branch 'gi/doc-boolean-config-typofix'
Junio C Hamano [Fri, 27 Mar 2026 18:00:02 +0000 (11:00 -0700)] 
Merge branch 'gi/doc-boolean-config-typofix'

Doc typofix.

* gi/doc-boolean-config-typofix:
  doc: add missing space on git-config page

2 months agoMerge branch 'mr/merge-file-object-id-worktree-fix'
Junio C Hamano [Fri, 27 Mar 2026 18:00:01 +0000 (11:00 -0700)] 
Merge branch 'mr/merge-file-object-id-worktree-fix'

merge-file --object-id used to trigger a BUG when run in a linked
worktree, which has been fixed.

* mr/merge-file-object-id-worktree-fix:
  merge-file: fix BUG when --object-id is used in a worktree

2 months agoMerge branch 'rs/prio-queue-to-commit-stack'
Junio C Hamano [Fri, 27 Mar 2026 18:00:01 +0000 (11:00 -0700)] 
Merge branch 'rs/prio-queue-to-commit-stack'

Uses of prio_queue as a LIFO stack of commits have been written
with commit_stack.

* rs/prio-queue-to-commit-stack:
  use commit_stack instead of prio_queue in LIFO mode

2 months agoMerge branch 'ps/build-tweaks'
Junio C Hamano [Fri, 27 Mar 2026 18:00:01 +0000 (11:00 -0700)] 
Merge branch 'ps/build-tweaks'

Tweak the build infrastructure by moving tools around.

* ps/build-tweaks:
  meson: precompile "git-compat-util.h"
  meson: compile compatibility sources separately
  git-compat-util.h: move warning infra to prepare for PCHs
  builds: move build scripts into "tools/"
  contrib: move "update-unicode.sh" script into "tools/"
  contrib: move "coverage-diff.sh" script into "tools/"
  contrib: move "coccinelle/" directory into "tools/"
  Introduce new "tools/" directory

2 months agoMerge branch 'jk/diff-highlight-identical-pairs'
Junio C Hamano [Fri, 27 Mar 2026 18:00:00 +0000 (11:00 -0700)] 
Merge branch 'jk/diff-highlight-identical-pairs'

The handling of the incomplete lines at the end by "git
diff-highlight" has been fixed.

* jk/diff-highlight-identical-pairs:
  contrib/diff-highlight: do not highlight identical pairs

2 months agoMerge branch 'mf/format-patch-commit-list-format' into mf/format-patch-commit-list...
Junio C Hamano [Thu, 26 Mar 2026 21:03:57 +0000 (14:03 -0700)] 
Merge branch 'mf/format-patch-commit-list-format' into mf/format-patch-commit-list-format-doc

* mf/format-patch-commit-list-format:
  format-patch: --commit-list-format without prefix
  format-patch: add preset for --commit-list-format
  format-patch: wrap generate_commit_list_cover()
  format.commitListFormat: strip meaning from empty
  docs/pretty-formats: add %(count) and %(total)
  format-patch: rename --cover-letter-format option
  format-patch: refactor generate_commit_list_cover
  pretty.c: better die message %(count) and %(total)
  docs: add usage for the cover-letter fmt feature
  format-patch: add commitListFormat config
  format-patch: add ability to use alt cover format
  format-patch: move cover letter summary generation
  pretty.c: add %(count) and %(total) placeholders

2 months agoconfig: store allocated string in non-const pointer
Jeff King [Thu, 26 Mar 2026 19:23:20 +0000 (15:23 -0400)] 
config: store allocated string in non-const pointer

When git-config matches a url, we copy the variable section name and
store it in the "section" member of a urlmatch_config struct. That
member is const, since the url-matcher will not touch it (and other
callers really will have a const string).

But that means that we have only a const pointer to our allocated
string. We have to cast away the constness when we free it, and likewise
when we assign NUL to tie off the "." separating the subsection and key.
This latter happens implicitly via a strchr() call, but recent versions
of glibc have added annotations that let the compiler detect that and
complain.

Let's keep our own "section" pointer for the non-const string, and then
just point config.section at it. That avoids all of the casting, both
explicit and implicit.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorev-parse: avoid writing to const string for parent marks
Jeff King [Thu, 26 Mar 2026 19:14:24 +0000 (15:14 -0400)] 
rev-parse: avoid writing to const string for parent marks

The previous commit cleared up some const confusion in handling parent
marks in revision.c, but we have roughly the same code duplicated in
rev-parse. This one is much easier to fix, because the handling of the
shortened string is all done in one place, after detecting any marks
(but without shortening the string between marks).

  As a side note, I suspect this means that it behaves differently than
  the revision.c parser for weird stuff like "foo^!^@^-", but that is
  outside the scope of this patch.

While we are here, let's also rename the variable "dotdot", which is
totally misleading (and which we already fixed in revision.c long ago
via f632dedd8d (handle_revision_arg: stop using "dotdot" as a generic
pointer, 2017-05-19)).

Doing that here makes the diff a little messier, but it also lets the
compiler help us make sure we did not miss any stray mentions of the
variable while we are changing its semantics.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorevision: avoid writing to const string for parent marks
Jeff King [Thu, 26 Mar 2026 19:13:18 +0000 (15:13 -0400)] 
revision: avoid writing to const string for parent marks

We take in a "const char *", but may write a NUL into it when parsing
parent marks like "foo^-", since we want to isolate "foo" as a string
for further parsing. This is usually OK, as our "const" strings are
often actually argv strings which are technically writeable, but we'd
segfault with a string literal like:

  handle_revision_arg("HEAD^-", &revs, 0, 0);

Similar to how we handled dotdot in a previous commit, we can avoid this
by making a temporary copy of the left-hand side of the string. The cost
should negligible compared to the rest of the parsing (like actually
parsing commits to create their parent linked-lists).

There is one slightly tricky thing, though. We parse some of the marks
progressively, so that if we see "foo^!" for example, we'll strip that
down to "foo" not just for calling add_parents_only(), but also for the
rest of the function. That makes sense since we eventually want to pass
"foo" to get_oid_with_context(). But it also means that we'll keep
looking for other marks. In particular, "foo^-^!" is valid, though oddly
"foo^!^-" would ignore the "^-". I'm not sure if this is a weird
historical artifact of the implementation, or if there are important
corner cases.

So I've left the behavior unchanged. Each mark we find allocates a
string with the mark stripped, which means we could allocate multiple
times (and carry a free-able pointer for each to the end). But in
practice we won't, because of the three marks, "^@" jumps immediately to
the end without further parsing, and "^-^!" is nonsense that nobody
would pass. So you'd get one allocation in general, and never more than
two.

Another obvious option would be to just copy "arg" up front and be OK
with munging it. But that means we pay the cost even when we find no
marks. We could make a single copy upon finding a mark and then munge,
but that adds extra code to each site (checking whether somebody else
allocated, and if not, adjusting our "mark" pointer to be relative to
the copied string).

I aimed for something that was clear and obvious, if a bit verbose.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorev-parse: simplify dotdot parsing
Jeff King [Thu, 26 Mar 2026 19:05:25 +0000 (15:05 -0400)] 
rev-parse: simplify dotdot parsing

The previous commit simplified the way that revision.c parses ".." and
"..." range operators. But there's roughly similar code in rev-parse.
This is less likely to trigger a segfault, as there is no library
function which we'd pass a string literal to, but it still causes the
compiler to complain about laundering away constness via strstr().

Let's give it the same treatment, copying the left-hand side of the
range operator into its own string.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorevision: make handle_dotdot() interface less confusing
Jeff King [Thu, 26 Mar 2026 19:04:44 +0000 (15:04 -0400)] 
revision: make handle_dotdot() interface less confusing

There are two very subtle bits to the way we parse ".." (and "...")
range operators:

 1. In handle_dotdot_1(), we assume that the incoming arguments "dotdot"
    and "arg" are part of the same string, with the first digit of the
    range-operator blanked to a NUL. Then when we want the full name
    (e.g., to report an error), we replace the NUL with a dot to restore
    the original string.

 2. In handle_dotdot(), we take in a const string, but then we modify it
    by overwriting the range operator with a NUL. This has worked OK in
    practice since we tend to pass in buffers that are actually
    writeable (including argv), but segfaults with something like:

      handle_revision_arg("..HEAD", &revs, 0, 0);

    On top of that, building with recent versions of glibc causes the
    compiler to complain, because it notices when we use strchr() or
    strstr() to launder away constness (basically detecting the
    possibility of the segfault above via the type system).

Instead of munging the buffer, let's instead make a temporary copy of
the left-hand side of the range operator. That avoids any const
violations, and lets us pass around the parsed elements independently:
the left-hand side, the right-hand side, the number of dots (via the
"symmetric" flag), and the original full string for error messages.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot5620: test backfill's unknown argument handling
Derrick Stolee [Thu, 26 Mar 2026 15:14:54 +0000 (15:14 +0000)] 
t5620: test backfill's unknown argument handling

Before the recent changes to parse rev-list arguments inside of 'git
backfill', the builtin would take arbitrary arguments without complaint (and
ignore them). This was noticed and a patch was sent [1] which motivates
this change.

[1] https://lore.kernel.org/git/20260321031643.5185-1-r.siddharth.shrimali@gmail.com/

Note that the revision machinery can output an "ambiguous argument"
warning if a value not starting with '--' is found and doesn't make
sense as a reference or a pathspec. For unrecognized arguments starting
with '--' we need to add logic into builtin/backfill.c to catch leftover
arguments.

Reported-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agopath-walk: support wildcard pathspecs for blob filtering
Derrick Stolee [Thu, 26 Mar 2026 15:14:53 +0000 (15:14 +0000)] 
path-walk: support wildcard pathspecs for blob filtering

Previously, walk_objects_by_path() silently ignored pathspecs containing
wildcards or magic by clearing them. This caused all blobs to be
downloaded regardless of the given pathspec. Wildcard pathspecs like
"d/file.*.txt" are useful for narrowing which blobs to process (e.g.,
during 'git backfill').

Support wildcard pathspecs by making two changes:

 1. Add an 'exact_pathspecs' flag to path_walk_context. When the
    pathspec has no wildcards or magic, set this flag and use the
    existing fast-path prefix matching in add_tree_entries(). When
    wildcards are present, skip that block since prefix matching
    cannot handle glob patterns.

 2. Add a match_pathspec() check in walk_path() to filter out blobs
    whose full path does not match the pathspec. This provides the
    actual blob-level filtering for wildcard pathspecs.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agobackfill: work with prefix pathspecs
Derrick Stolee [Thu, 26 Mar 2026 15:14:52 +0000 (15:14 +0000)] 
backfill: work with prefix pathspecs

The previous change allowed specifying revision arguments over the 'git
backfill' command-line. This created the opportunity for restricting the
initial commit set by filtering the revision walk through a pathspec. Other
than filtering the commit set (and thereby the root trees), this did not
restrict the path-walk implementation of 'git backfill' and did not restrict
the blobs that were downloaded to only those matching the pathspec.

Update the path-walk API to accept certain kinds of pathspecs and to
silently ignore anything too complex, for now. We will update this in the
next change to properly restrict to even complex pathspecs.

The current behavior focuses on pathspecs that match paths exactly. This
includes exact filenames, including directory names as prefixes. Pathspecs
containing wildcards or magic are cleared so the path walk downloads all
blobs, as before.

The reason for this restriction is to allow for a faster execution by
pruning the path walk to only trees that could contribute towards one of
those paths as a parent directory.

The test directory 'd/f/' (next to 'd/file*.txt') was prepared in a
previous commit to exercise the subtlety in prefix matching.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agobackfill: accept revision arguments
Derrick Stolee [Thu, 26 Mar 2026 15:14:51 +0000 (15:14 +0000)] 
backfill: accept revision arguments

The existing implementation of 'git backfill' only includes downloading
missing blobs reachable from HEAD. Advanced uses may desire more general
commit limiting options, such as '--all' for all references, specifying a
commit range via negative references, or specifying a recency of use such as
with '--since=<date>'.

All of these options are available if we use setup_revisions() to parse the
unknown arguments with the revision machinery. This opens up a large number
of possibilities, only a small set of which are tested here.

For documentation, we avoid duplicating the option documentation and instead
link to the documentation of 'git rev-list'.

Note that these arguments currently allow specifying a pathspec, which
modifies the commit history checks but does not limit the paths used in the
backfill logic. This will be updated in a future change.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot5620: prepare branched repo for revision tests
Derrick Stolee [Thu, 26 Mar 2026 15:14:50 +0000 (15:14 +0000)] 
t5620: prepare branched repo for revision tests

Prepare the test infrastructure for upcoming changes that teach 'git
backfill' to accept revision arguments and pathspecs.

Add test_tick before each commit in the setup loop so that commit dates
are deterministic. This enables reliable testing with '--since'.

Rename the 'd/e/' directory to 'd/f/' so that the prefix 'd/f' is
ambiguous with the files 'd/file.*.txt'. This exercises the subtlety
in prefix pathspec matching that will be added in a later commit.

Create a branched version of the test repository (src-revs) with:
 - A 'side' branch merged into main, adding s/file.{1,2}.txt with
   two versions (4 new blobs, 52 total from main HEAD).
 - An unmerged 'other' branch adding o/file.{1,2}.txt (2 more blobs,
   54 total reachable from --all).

This structure makes --all, --first-parent, and --since produce
meaningfully different results when used with 'git backfill'.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agorevision: include object-name.h
Derrick Stolee [Thu, 26 Mar 2026 15:14:49 +0000 (15:14 +0000)] 
revision: include object-name.h

The REV_INFO_INIT macro includes a use of the DEFAULT_ABBREV macro, which is
defined in object-name.h. Include it in revision.h so consumers of
REV_INFO_INIT do not need to include this hidden dependency.

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoworktree: reject NULL worktree in get_worktree_git_dir()
Phillip Wood [Thu, 26 Mar 2026 14:16:59 +0000 (14:16 +0000)] 
worktree: reject NULL worktree in get_worktree_git_dir()

This removes the final dependence on "the_repository" in
get_worktree_git_dir(). The last commit removed only caller that
passed a NULL worktree.

get_worktree_git_dir() has the following callers:

 - branch.c:prepare_checked_out_branches() which loops over all
   worktrees.

 - builtin/fsck.c:cmd_fsck() which loops over all worktrees.

 - builtin/receive-pack.c:update_worktree() which is called from
   update() only when "worktree" is non-NULL.

 - builtin/worktree.c:validate_no_submodules() which is called from
   check_clean_worktree() and move_worktree(), both of which supply
   a non-NULL worktree.

 - reachable.c:add_rebase_files() which loops over all worktrees.

 - revision.c:add_index_objects_to_pending() which loops over all
   worktrees.

 - worktree.c:is_current_worktree() which expects a non-NULL worktree.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoworktree add: stop reading ".git/HEAD"
Phillip Wood [Thu, 26 Mar 2026 14:16:58 +0000 (14:16 +0000)] 
worktree add: stop reading ".git/HEAD"

The function can_use_local_refs() prints a warning if there are no local
branches and HEAD is invalid or points to an unborn branch. As part of
the warning it prints the contents of ".git/HEAD". In a repository using
the reftable backend HEAD is not stored in the filesystem so reading
that file is pointless. In a repository using the files backend it is
unclear how useful printing it is - it would be better to diagnose the
problem for the user. For now, simplify the warning by not printing
the file contents and adjust the relevant test case accordingly. Also
fixup the test case to use test_grep so that anyone trying to debug a
test failure in the future is not met by a wall of silence.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoworktree: remove "the_repository" from is_current_worktree()
Phillip Wood [Thu, 26 Mar 2026 14:16:57 +0000 (14:16 +0000)] 
worktree: remove "the_repository" from is_current_worktree()

The "is_current" member of struct worktree was added in 750e8a60d69
(worktree.c: mark current worktree, 2016-04-22) and was used in
8d9fdd7087d (worktree.c: check whether branch is rebased in another
worktree, 2016-04-22) to optionally skip the current worktree when
seeing if a branch is already checked out in die_if_checked_out().

To determine if a worktree is "current" is_current_worktree() compares
the gitdir of the worktree to the gitdir of "the_repository"
and returns true when they match. To get the gitdir of the
worktree it calls get_workree_git_dir() which also depends on
"the_repository". This means that even if "wt->path" matches
"wt->repo->worktree" is_current_worktree(wt) will return false when
"wt->repo" is not "the_repository". Consequently die_if_checked_out()
will fail to skip such a worktree when checking if a branch is already
checked out and may die errounously. Fix this by using the worktree's
repository instance instead of "the_repository" when comparing gitdirs.

The use of "the_repository" in is_current_wortree() comes from
replacing get_git_dir() with repo_get_git_dir() in 246deeac951
(environment: make `get_git_dir()` accept a repository, 2024-09-12). In
get_worktree_git_dir() it comes from replacing git_common_path() with
repo_common_path() in 07242c2a5af (path: drop `git_common_path()`
in favor of `repo_common_path()`, 2025-02-07). In both cases the
replacements appear to have been mechanical.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoregexp: leave a pointer to resurrect workaround for Homebrew
Junio C Hamano [Mon, 23 Mar 2026 16:54:42 +0000 (09:54 -0700)] 
regexp: leave a pointer to resurrect workaround for Homebrew

Recently some GitHub CI jobs were broken by update on the platform
side, which was eventually resolved by image rollback, but in the
meantime Dscho invented a workaround patch to sidestep the broken
part of the platform.  Their future image update may contain the
same bug, in which case the workaround may again become needed.

As we do not want to be building with workaround that avoids system
regexp library altogether unless the system is known to be broken,
so short of an automated "detect broken system and apply workaround"
mechanism, let's use the folks who are compiling the code to detect
breakage on their system and cope with the breakage ;-)

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agoreplay: add --revert mode to reverse commit changes
Siddharth Asthana [Wed, 25 Mar 2026 20:23:52 +0000 (01:53 +0530)] 
replay: add --revert mode to reverse commit changes

Add a `--revert <branch>` mode to git replay that undoes the changes
introduced by the specified commits. Like --onto and --advance, --revert
is a standalone mode: it takes a branch argument and updates that branch
with the newly created revert commits.

At GitLab, we need this in Gitaly for reverting commits directly on bare
repositories without requiring a working tree checkout.

The approach is the same as sequencer.c's do_pick_commit() -- cherry-pick
and revert are just the same three-way merge with swapped arguments:

  - Cherry-pick: merge(ancestor=parent, ours=current, theirs=commit)
  - Revert: merge(ancestor=commit, ours=current, theirs=parent)

We swap the base and pickme trees passed to merge_incore_nonrecursive()
to reverse the diff direction.

Reverts are processed newest-first (matching git revert behavior) to
reduce conflicts by peeling off changes from the top. Each revert
builds on the result of the previous one via the last_commit fallback
in the main replay loop, rather than relying on the parent-mapping
used for cherry-pick.

Revert commit messages follow the usual git revert conventions: prefixed
with "Revert" (or "Reapply" when reverting a revert), and including
"This reverts commit <hash>.". The author is set to the current user
rather than preserving the original author, matching git revert behavior.

Helped-by: Christian Couder <christian.couder@gmail.com>
Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Elijah Newren <newren@gmail.com>
Helped-by: Phillip Wood <phillip.wood123@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agosequencer: extract revert message formatting into shared function
Siddharth Asthana [Wed, 25 Mar 2026 20:23:51 +0000 (01:53 +0530)] 
sequencer: extract revert message formatting into shared function

The logic for formatting revert commit messages (handling "Revert" and
"Reapply" cases, appending "This reverts commit <ref>.", and handling
merge-parent references) currently lives inline in do_pick_commit().
The upcoming replay --revert mode needs to reuse this logic.

Extract all of this into a new sequencer_format_revert_message()
function. The function takes a repository, the subject line, commit,
parent, a use_commit_reference flag, and the output strbuf. It handles
both regular reverts ("Revert "<subject>"") and revert-of-revert cases
("Reapply "<subject>""), and uses refer_to_commit() internally to
format the commit reference.

Update refer_to_commit() to take a struct repository parameter instead
of relying on the_repository, and a bool instead of reading from
replay_opts directly. This makes it usable from the new shared function
without pulling in sequencer-specific state.

Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: reject unknown hook names in git-hook(1)
Adrian Ratiu [Wed, 25 Mar 2026 19:55:03 +0000 (21:55 +0200)] 
hook: reject unknown hook names in git-hook(1)

Teach "git hook run" and "git hook list" to reject hook event names
that are not recognized by Git. This helps catch typos such as
"prereceive" when "pre-receive" was intended, since in 99% of the
cases users want known (already-existing) hook names.

The list of known hooks is derived from the generated hook-list.h
(built from Documentation/githooks.adoc). This is why the Makefile
is updated, so builtin/hook.c depends on hook-list.h. In meson the
header is already a dependency for all builtins, no change required.

The "--allow-unknown-hook-name" flag can be used to bypass this check.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: show disabled hooks in "git hook list"
Adrian Ratiu [Wed, 25 Mar 2026 19:55:02 +0000 (21:55 +0200)] 
hook: show disabled hooks in "git hook list"

Disabled hooks were filtered out of the cache entirely, making them
invisible to "git hook list". Keep them in the cache with a new
"disabled" flag which is propagated to the respective struct hook.

"git hook list" now shows disabled hooks as tab-separated columns,
with the status as a prefix before the name (like scope with
--show-scope). With --show-scope it looks like:

$ git hook list --show-scope pre-commit
global linter
local disabled no-leaks
hook from hookdir

A disabled hook without a command issues a warning instead of the
fatal "hook.X.command must be configured" error. We could also throw
an error, however it seemd a bit excessive to me in this case.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: show config scope in git hook list
Adrian Ratiu [Wed, 25 Mar 2026 19:55:01 +0000 (21:55 +0200)] 
hook: show config scope in git hook list

Users running "git hook list" can see which hooks are configured but
have no way to tell at which config scope (local, global, system...)
each hook was defined.

Store the scope from ctx->kvi->scope in the single-pass config callback,
then carry it through the cache to the hook structs, so we can expose it
to users via the "git hook list --show-scope" flag, which mirrors the
existing git config --show-scope convention.

Without the flag the output is unchanged.

The scope is printed as a tab-separated prefix (like "git config --show-scope"),
making it unambiguously machine-parseable even when the friendly name
contains spaces.

Example usage:
$ git hook list --show-scope pre-commit
global linter
local no-leaks
hook from hookdir

Traditional hooks from the hookdir are unaffected by --show-scope since
the config scope concept does not apply to them.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: introduce hook_config_cache_entry for per-hook data
Adrian Ratiu [Wed, 25 Mar 2026 19:55:00 +0000 (21:55 +0200)] 
hook: introduce hook_config_cache_entry for per-hook data

Replace the bare `char *command` util pointer stored in each string_list
item with a heap-allocated `struct hook_config_cache_entry` that carries
that command string.

This is just a refactoring with no behavior changes, to give the cache
entry room to grow, so it can carry the additional hook metadata we'll
be adding in the following commits.

Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agot1800: add test to verify hook execution ordering
Adrian Ratiu [Wed, 25 Mar 2026 19:54:59 +0000 (21:54 +0200)] 
t1800: add test to verify hook execution ordering

There is a documented expectation that configured hooks are
run before the hook from the hookdir. Add a test for it.

While at it, I noticed that `git hook list -h` runs twice
in the `git hook usage` test, so remove one invocation.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: make consistent use of friendly-name in docs
Adrian Ratiu [Wed, 25 Mar 2026 19:54:58 +0000 (21:54 +0200)] 
hook: make consistent use of friendly-name in docs

Both `name` and `friendly-name` is being used. Standardize on
`friendly-name` for consistency since name is rather generic,
even when used in the hooks namespace.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: replace hook_list_clear() -> string_list_clear_func()
Adrian Ratiu [Wed, 25 Mar 2026 19:54:57 +0000 (21:54 +0200)] 
hook: replace hook_list_clear() -> string_list_clear_func()

Replace the custom function with string_list_clear_func() which
is a more common pattern for clearing a string_list.

To be able to do this, rework hook_clear() into hook_free(), so
it can be passed to string_list_clear_func().

A slight complication is the need to keep a copy of the internal
cb data free() pointer, however I think it's worth it since the
API becomes cleaner, e.g. no more calls with NULL function args
like hook_list_clear(hooks, NULL).

In other words, the callers don't need to keep track of hook
internal state to determine when cleanup is necessary or not
(pass NULL) because each `struct hook` now owns its data_free
callback.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: detect & emit two more bugs
Adrian Ratiu [Wed, 25 Mar 2026 19:54:56 +0000 (21:54 +0200)] 
hook: detect & emit two more bugs

Trigger a bug when an unknown hook type is encountered while
setting up hook execution.

Also issue a bug if a configured hook is enabled without a cmd.

Mostly useful for defensive coding.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: rename cb_data_free/alloc -> hook_data_free/alloc
Adrian Ratiu [Wed, 25 Mar 2026 19:54:55 +0000 (21:54 +0200)] 
hook: rename cb_data_free/alloc -> hook_data_free/alloc

Rename the hook callback function types to use the hook prefix.

This is a style fix with no logic changes.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2 months agohook: fix minor style issues
Adrian Ratiu [Wed, 25 Mar 2026 19:54:54 +0000 (21:54 +0200)] 
hook: fix minor style issues

Fix some minor style nits pointed out by Patrick, Junio and Eric:
  * Use CALLOC_ARRAY instead of xcalloc.
  * Init struct members during declaration.
  * Simplify if condition boolean logic.
  * Missing curly braces in if/else stmts.
  * Unnecessary header includes.
  * Capitalization and full-stop in error/warn messages.
  * Curly brace on separate line when defining struct.
  * Comment spelling: free'd -> freed.
  * Sort the included headers.
  * Blank line fixes to improve readability.

These contain no logic changes, the code behaves the same as before.

Suggested-by: Eric Sunshine <sunshine@sunshineco.com>
Suggested-by: Junio C Hamano <gitster@pobox.com>
Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>