]> git.99rst.org Git - git.git/log
git.git
5 weeks agorefs: protect against chicken-and-egg recursion
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:09 +0000 (11:20 +0200)]
refs: protect against chicken-and-egg recursion

In the preceding commits we have fixed recursion when creating the
reference backends due to a chicken-and-egg situation with "onbranch"
conditions. Unfortunately, this issue has existed for a while, and we
didn't really have a good mechanism to detect this recursion.

Improve the status quo by detecting the recursion when creating the main
reference store.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agorefs/reftable: lazy-load configuration to fix chicken-and-egg
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:08 +0000 (11:20 +0200)]
refs/reftable: lazy-load configuration to fix chicken-and-egg

Same as with the "files" backend, the "reftable" backend also has a
chicken-and-egg problem with "onbranch" conditions. Fix this issue the
same as we did with the "files" backend by lazy-loading configuration.

Now that both the "files" and the "reftable" backend handle this
properly, add a generic test to t1400 that verifies that the user can
configure "core.logAllRefUpdates" via an "onbranch" condition. This is
mostly a nonsensical thing to do in the first place, but it serves as a
good sanity check.

Note that we had to move `should_write_log()` around so that it can
access the new `reftable_be_write_options()` function.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agoreftable: split up write options
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:07 +0000 (11:20 +0200)]
reftable: split up write options

When initializing the reftable stack the caller may optionally pass some
write options. These write options mix up two different concerns though:

  - Of course, they allow the caller to configure how new reftables are
    being written.

  - But they also allow the caller to configure the stack itself, like
    its hash ID and the `on_reload` callback.

This is somewhat awkward, as it doesn't easily give the caller the
flexibility to for example write multiple reftables with different
options. Furthermore, this requires us to eagerly parse relevant
configuration when initializing the reftable backend.

Refactor the code by splitting out those options that configure the
stack itself. Creating a new stack will thus only require this limited
set of options, whereas the caller is expected to pass write options to
all functions that end up writing tables.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agorefs/files: lazy-load configuration to fix chicken-and-egg
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:06 +0000 (11:20 +0200)]
refs/files: lazy-load configuration to fix chicken-and-egg

When initializing the "files" reference backend we read the repository's
config to parse "core.preferSymlinkRefs" and "core.logAllRefUpdates".
This results in a chicken-and-egg problem though, because parsing the
configuration may require us to have access to the reference store
already when an "onbranch" condition exists.

Luckily, all the configuration that we honor only relates to writing
references. Consequently, we don't strictly need that configuration to
be readily available at initialization time, and we can easiliy defer
parsing it to a later point in time.

Implement this fix and add tests that verify that we can indeed properly
parse these config knobs via an "onbranch" condition.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agorefs: move parsing of "core.logAllRefUpdates" back into ref stores
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:05 +0000 (11:20 +0200)]
refs: move parsing of "core.logAllRefUpdates" back into ref stores

In cc42c88945 (refs: extract out reflog config to generic layer,
2026-05-04) we have refactored how we parse "core.logAllRefUpdates" so
that it happens in the generic layer. Unfortunately, this has worsened a
preexisting issue where we may recurse when creating the reference store
because of a chicken-and-egg problem between parsing the configuration
and evaluating "onbranch" conditions.

Prepare for a fix by essentially reverting that change so that we handle
this setting in the respective backends again. The backends are already
parsing other configuration anyway, so by moving the logic back in there
we can ensure that all backend configuration is parsed the same way.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agorepository: free main reference database
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:04 +0000 (11:20 +0200)]
repository: free main reference database

While we release worktree and submodule reference databases when
clearing a repository, we don't ever release the main reference
database. This memory leak went unnoticed because its pointer is
kept alive by the "chdir_notify" subsystem.

Fix the memory leak.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agochdir-notify: drop unused `chdir_notify_reparent()`
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:03 +0000 (11:20 +0200)]
chdir-notify: drop unused `chdir_notify_reparent()`

With the preceding commit we've removed all callers of
`chdir_notify_reparent()`, so the function is unused now. Drop it.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agorefs: unregister reference stores from "chdir_notify"
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:02 +0000 (11:20 +0200)]
refs: unregister reference stores from "chdir_notify"

When creating reference stores we register them with the "chdir_notify"
subsystem. This is required because some of the paths we track may be
relative paths, so we have to reparent them in case the current working
directory changes.

But while we register the reference stores, we never unregister them.
This can have multiple outcomes:

  - For a repository's main reference database we essentially keep the
    pointer alive. We never free that database, either, and our leak
    checker doesn't notice because it's still registered.

  - For submodule and worktree reference databases we do eventually free
    them in `repo_clear()`, so we may keep pointers to free'd memory
    registered. We never notice though as we don't tend to chdir around
    in the middle of the process.

We never noticed either of these symptoms, but they are obviously bad.

Partially fix those issues by unregistering the reference stores when
releasing them. The leak of the main reference database will be fixed in
a subsequent commit.

Note that this requires us to use `chdir_notify_register()` instead of
`chdir_notify_reparent()`, as there is no infrastructure to unregister the
latter.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agosetup: don't apply "GIT_REFERENCE_BACKEND" without a repository
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:01 +0000 (11:20 +0200)]
setup: don't apply "GIT_REFERENCE_BACKEND" without a repository

When discovering a repository we eventually also apply the
"GIT_REFERENCE_BACKEND" environment variable to the repository. There's
two problems with that:

  - We do this unconditionally, which is rather pointless: we really
    only have to configure the repository when we have found one.

  - We have already applied the repository format at that point in time,
    so we need to manually reapply it.

Move the logic around so that we only apply the environment variable
when a repository was discovered. This also allows us to drop the
explcit call to `repo_set_ref_storage_format()` because we now adjust
the format before we apply it via `apply_repository_format()`.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agosetup: stop applying repository format twice
Patrick Steinhardt [Thu, 25 Jun 2026 09:20:00 +0000 (11:20 +0200)]
setup: stop applying repository format twice

When discovering the repository in "setup.c" we apply the final
repository format multiple times:

  - Once via `repository_format_configure()`, where we apply the hash
    algorithm and ref storage format to both `struct repository_format`
    and `struct repository`.

  - And once via `apply_repository_format()`, where we apply these two
    settings from `struct repository_format` to `struct repository`.

With the current flow both of these are in fact necessary. But this is
only because we call `repository_format_configure()` after we have
called `apply_repository_format()`. Consequently, if we only changed the
repository format in `repository_format_configure()` it would never
propagate to the repository.

Refactor the code so that we first configure the repository format
before applying it to the repository so that we can stop setting the
hash and reference storage format multiple times.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agosetup: inline `check_and_apply_repository_format()`
Patrick Steinhardt [Thu, 25 Jun 2026 09:19:59 +0000 (11:19 +0200)]
setup: inline `check_and_apply_repository_format()`

We have two callsites of `check_and_apply_repository_format()`. In a
subsequent commit we'll want to adapt one of those callsites to change
the order in which we read and apply the repository format, at which
point the helper function will not really be a good fit for us anymore.

Inline the function to both of the callsites.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
5 weeks agoMerge branch 'ps/setup-centralize-odb-creation' into ps/refs-onbranch-fixes
Junio C Hamano [Thu, 11 Jun 2026 12:09:19 +0000 (05:09 -0700)]
Merge branch 'ps/setup-centralize-odb-creation' into ps/refs-onbranch-fixes

* ps/setup-centralize-odb-creation:
  setup: construct object database in `apply_repository_format()`
  repository: stop reading loose object map twice on repo init
  setup: stop initializing object database without repository
  setup: stop creating the object database in `setup_git_env()`
  repository: stop initializing the object database in `repo_set_gitdir()`
  setup: deduplicate logic to apply repository format
  setup: drop `setup_git_env()`
  t0001: plug test gaps for git-init(1) with GIT_OBJECT_DIRECTORY

8 weeks agoThe 13th batch
Junio C Hamano [Tue, 9 Jun 2026 01:04:31 +0000 (10:04 +0900)]
The 13th batch

Signed-off-by: Junio C Hamano <redacted>
8 weeks agoMerge branch 'jc/doc-monitor-ghci'
Junio C Hamano [Tue, 9 Jun 2026 01:04:51 +0000 (10:04 +0900)]
Merge branch 'jc/doc-monitor-ghci'

Encourage original authors to monitor the CI status.

* jc/doc-monitor-ghci:
  SubmittingPatches: proactively monitor GHCI pages

8 weeks agoMerge branch 'ib/doc-push-default-simple'
Junio C Hamano [Tue, 9 Jun 2026 01:04:51 +0000 (10:04 +0900)]
Merge branch 'ib/doc-push-default-simple'

The documentation for `push.default = simple` has been clarified to
better explain its behavior, making it clear that it pushes the
current branch to a same-named branch on the remote, and detailing
the upstream requirements for centralized workflows.

* ib/doc-push-default-simple:
  doc: clarify push.default=simple behavior

8 weeks agoMerge branch 'gh/jump-auto-mode'
Junio C Hamano [Tue, 9 Jun 2026 01:04:50 +0000 (10:04 +0900)]
Merge branch 'gh/jump-auto-mode'

The 'git-jump' command (in contrib/) has been taught to automatically
pick a mode (merge, diff, or ws) when invoked without arguments.

* gh/jump-auto-mode:
  git-jump: pick a mode automatically when invoked without arguments

8 weeks agoMerge branch 'rs/strbuf-add-oid-hex'
Junio C Hamano [Tue, 9 Jun 2026 01:04:50 +0000 (10:04 +0900)]
Merge branch 'rs/strbuf-add-oid-hex'

Formatting object name in full hexadecimal form has been optimized
by using a new strbuf_add_oid_hex() helper function.

* rs/strbuf-add-oid-hex:
  hex: add and use strbuf_add_oid_hex()

8 weeks agoMerge branch 'rs/strbuf-add-uint'
Junio C Hamano [Tue, 9 Jun 2026 01:04:50 +0000 (10:04 +0900)]
Merge branch 'rs/strbuf-add-uint'

Adding a decimal integer with strbuf_addf("%u") appears commonly;
they have been optimized by using a custom formatter.

* rs/strbuf-add-uint:
  ls-tree: use strbuf_add_uint()
  ls-files: use strbuf_add_uint()
  cat-file: use strbuf_add_uint()
  strbuf: add strbuf_add_uint()

8 weeks agoMerge branch 'ua/push-remote-group'
Junio C Hamano [Tue, 9 Jun 2026 01:04:50 +0000 (10:04 +0900)]
Merge branch 'ua/push-remote-group'

"git push" learned to take a "remote group" name to push to, which
causes pushes to multiple places, just like "git fetch" would do.

* ua/push-remote-group:
  push: support pushing to a remote group
  remote: move remote group resolution to remote.c
  remote: fix sign-compare warnings in push_cas_option

8 weeks agoMerge branch 'th/promisor-quiet-per-repo'
Junio C Hamano [Tue, 9 Jun 2026 01:04:49 +0000 (10:04 +0900)]
Merge branch 'th/promisor-quiet-per-repo'

The "promisor.quiet" configuration variable was not used from
relevant submodules when commands like "grep --recurse-submodules"
triggered a lazy fetch, which has been corrected.

* th/promisor-quiet-per-repo:
  promisor-remote: fix promisor.quiet to use the correct repository

8 weeks agoMerge branch 'tb/bitmap-build-performance'
Junio C Hamano [Tue, 9 Jun 2026 01:04:49 +0000 (10:04 +0900)]
Merge branch 'tb/bitmap-build-performance'

Reachability bitmap generation has been significantly optimized. By
reordering tree traversal, caching object positions, and refining how
pseudo-merge bitmaps are constructed, the performance of "git repack
--write-midx-bitmaps" is improved, especially for large repositories
and when using pseudo-merges.

* tb/bitmap-build-performance:
  pack-bitmap: build pseudo-merge bitmaps after regular bitmaps
  pack-bitmap: remember pseudo-merge parents
  pack-bitmap: sort bitmaps before XORing
  pack-bitmap: cache object positions during fill
  pack-bitmap: consolidate `find_object_pos()` success path
  pack-bitmap: reuse stored selected bitmaps
  pack-bitmap: check subtree bits before recursing
  pack-bitmap: pass object position to `fill_bitmap_tree()`

8 weeks agoThe 12th batch
Junio C Hamano [Sun, 7 Jun 2026 14:58:12 +0000 (23:58 +0900)]
The 12th batch

Signed-off-by: Junio C Hamano <redacted>
8 weeks agoMerge branch 'ja/doc-synopsis-style-again'
Junio C Hamano [Sun, 7 Jun 2026 14:58:25 +0000 (23:58 +0900)]
Merge branch 'ja/doc-synopsis-style-again'

A batch of documentation pages has been updated to use the modern
synopsis style.

* ja/doc-synopsis-style-again:
  doc: convert git-imap-send synopsis and options to new style
  doc: convert git-apply synopsis and options to new style
  doc: convert git-am synopsis and options to new style
  doc: convert git-grep synopsis and options to new style
  doc: git bisect: clarify the usage of the synopsis vs actual command
  doc: convert git-bisect to synopsis style

8 weeks agoMerge branch 'kk/commit-reach-optim'
Junio C Hamano [Sun, 7 Jun 2026 14:58:25 +0000 (23:58 +0900)]
Merge branch 'kk/commit-reach-optim'

The check for non-stale commits in the priority queue used by
`paint_down_to_common` and `ahead_behind` has been optimized by
replacing an O(N) scan with an O(1) counter, yielding performance
improvements in repositories with wide histories.

* kk/commit-reach-optim:
  commit-reach: replace queue_has_nonstale() scan with O(1) tracking
  commit-reach: deduplicate queue entries in paint_down_to_common
  object.h: fix stale entries in object flag allocation table

8 weeks agoMerge branch 'aj/stash-patch-optimize-temporary-index'
Junio C Hamano [Sun, 7 Jun 2026 14:58:24 +0000 (23:58 +0900)]
Merge branch 'aj/stash-patch-optimize-temporary-index'

"git stash -p" has been optimized by reusing cached index
entries in its temporary index, avoiding unnecessary lstat()
calls on unchanged files.

* aj/stash-patch-optimize-temporary-index:
  stash: reuse cached index entries in --patch temporary index

8 weeks agoMerge branch 'kh/free-commit-list'
Junio C Hamano [Sun, 7 Jun 2026 14:58:24 +0000 (23:58 +0900)]
Merge branch 'kh/free-commit-list'

Code clean-up.

* kh/free-commit-list:
  commit: remove deprecated functions
  *: replace deprecated free_commit_list

8 weeks agoMerge branch 'ds/restore-sparse-index'
Junio C Hamano [Sun, 7 Jun 2026 14:58:24 +0000 (23:58 +0900)]
Merge branch 'ds/restore-sparse-index'

'git restore --staged' has been optimized to avoid unnecessarily expanding
the sparse index when operating on paths within the sparse checkout
definition, by handling sparse directory entries at the tree level.

* ds/restore-sparse-index:
  restore: avoid sparse index expansion
  t1092: test 'git restore' with sparse index

8 weeks agoMerge branch 'ar/receive-pack-worktree-env'
Junio C Hamano [Sun, 7 Jun 2026 14:58:24 +0000 (23:58 +0900)]
Merge branch 'ar/receive-pack-worktree-env'

The GIT_WORK_TREE variable prepared to invoke the push-to-checkout
hook was leaking into the environment even when there was no hook
used and broke the default push-to-deploy (i.e., let "git checkout"
update the working tree only when the working tree is clean).

* ar/receive-pack-worktree-env:
  receive-pack: fix updateInstead with core.worktree

8 weeks agosetup: construct object database in `apply_repository_format()`
Patrick Steinhardt [Thu, 4 Jun 2026 07:46:32 +0000 (09:46 +0200)]
setup: construct object database in `apply_repository_format()`

With the preceding changes we now always construct the repository's
object database before applying the repository format. Remove this
duplication by constructing it in `apply_repository_format()` instead.

Note that we create the object database _after_ having set up the
repository's hash algorithm, but _before_ setting the compat hash
algorithm. This is intentional:

  - Constructing the object database may require knowledge of its
    intended object format.

  - Setting up the compatibility hash requires the object database to be
    initialized already, because we immediately read the loose object
    map.

The first point is sensible, the second maybe a little less so. Ideally,
it should be the responsibility of the object database itself to
initialize any data structures required for the compatibility hash. But
this would require further changes, so this is kept as-is for now.

Further note that this requires us to move handling of the environment
variables GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES into
the repository format, as well. This allows the caller more flexibility
around whether or not those environment variables are being honored, as
we want to respect them in "setup.c", but not in "repository.c".

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
8 weeks agorepository: stop reading loose object map twice on repo init
Patrick Steinhardt [Thu, 4 Jun 2026 07:46:31 +0000 (09:46 +0200)]
repository: stop reading loose object map twice on repo init

When initializing a repository via `repo_init()` we end up reading the
loose object map twice:

  - `apply_repository_format()` calls `repo_set_compat_hash_algo()`,
    which in turn calls `repo_read_loose_object_map()` if we have a
    compatibility hash configured.

  - `repo_init()` calls `repo_read_loose_object_map()` directly a second
    time.

Drop the second read of the loose object map in `repo_init()`.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
8 weeks agosetup: stop initializing object database without repository
Patrick Steinhardt [Thu, 4 Jun 2026 07:46:30 +0000 (09:46 +0200)]
setup: stop initializing object database without repository

The function `setup_git_directory_gently()` is responsible for
discovering and setting up a Git repository based on various environment
variables and the current working directory. The result is thus a fully
usable Git repository.

One oddity of this function is that we may set up the object database
even in the case where we don't have a repository, namely in the case
where the `GIT_DIR_EXPLICIT` environment variable is set but points to a
non-existent repository. If so, we call `setup_git_env_internal()` with
the value of the environment variable so that the repository's Git
directory is configured, even if it points to a non-existent directory.

Historically though, this function didn't only configure the repository,
but also initialized the object database. We retained this behaviour
from a preceding commit, even though it really doesn't make much sense
in the first place -- there is no repository, so we don't have an object
database either. There seemingly isn't much of a reason to construct the
object database, as we typically won't try to read objects when we don't
have an object database.

There's one exception though: git-index-pack(1) may run outside of a
repository, which can be used to perform consistency checks for a
packfile. The code path is _almost_ working: we already know to call
`parse_object_buffer()`, which can read objects without an object
database being available. And that works for all object types except for
commits, because `parse_commit_buffer()` calls `parse_commit_graph()`,
and that function doesn't handle the case where we don't have an object
database.

Fix this instance to check for the object database instead of checking
for the Git directory having been initialized. With this fixed, we can
now stop constructing an object database completely.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
8 weeks agosetup: stop creating the object database in `setup_git_env()`
Patrick Steinhardt [Thu, 4 Jun 2026 07:46:29 +0000 (09:46 +0200)]
setup: stop creating the object database in `setup_git_env()`

In the preceding commit we have stopped creating the object database in
`repo_set_gitdir()`. But the logic is still somewhat confusing as we
still end up creating it conditionally in `setup_git_dir()`, which is
called multiple times.

Drop the conditional logic and instead create the object database in all
places where we have discovered and configured a repository.

This leads to even more duplication than we already had in the preceding
commit, but an alert reader may notice that we now (almost) always call
`odb_new()` directly before having called `apply_repository_format()`.
The only exception to this is `setup_git_directory_gently()`, where we
also call the function when _not_ applying the repository format. This
will be fixed in the next commit, and once that's done we can then unify
creation of the object database into `apply_repository_format()`.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
8 weeks agorepository: stop initializing the object database in `repo_set_gitdir()`
Patrick Steinhardt [Thu, 4 Jun 2026 07:46:28 +0000 (09:46 +0200)]
repository: stop initializing the object database in `repo_set_gitdir()`

The function `repo_set_gitdir()` obviously sets the Git directory for a
given repository. Less obviously though, the function also configures a
couple of auxiliary settings.

One such thing is that we create the object database in this function.
This logic only happens conditionally though, as `set_git_dir()` may be
called multiple times during repository setup, and we don't want to
create the object database multiple times. This is somewhat tangled and
hard to follow.

Remove the logic from `repo_set_gitdir()` and instead initialize the
object database outside of it. This leads to some duplication right now,
but that duplication will be removed in a subsequent step where we will
start initializing the object database as part of applying the repo's
format.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
8 weeks agosetup: deduplicate logic to apply repository format
Patrick Steinhardt [Thu, 4 Jun 2026 07:46:27 +0000 (09:46 +0200)]
setup: deduplicate logic to apply repository format

After having discovered the repository format we then apply it to the
repository so that it knows to use the proper repository extensions. The
logic to apply the format is duplicated across three callsites, which
makes it rather painfull to add new extensions.

Introduce a new function `apply_repository_format()` that takes a repo
and applies a given format to it and adapt all callsites to use it.
This function is also the new caller of `verify_repository_format()` so
that we can ensure that we never apply an invalid repository format.
The verification we have in `read_and_verify_repository_format()` is
thus redundant now and dropped.

Rename `read_and_verify_repository_format()` accordingly. While at it,
also rename `check_repository_format()` to clarify that it doesn't only
_check_ the format, but that it also applies it.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
8 weeks agosetup: drop `setup_git_env()`
Patrick Steinhardt [Thu, 4 Jun 2026 07:46:26 +0000 (09:46 +0200)]
setup: drop `setup_git_env()`

The `setup_git_env()` function is a trivial wrapper around
`setup_git_env_internal()` and has a single call site only. Drop the
function.

While at it, drop stale documentation in "environment.h" that points to
this function, even though it hasn't been exposed to callers outside of
"setup.c" since 43ad1047a9 (setup: stop using `the_repository` in
`setup_git_env()`, 2026-03-27) anymore.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
8 weeks agot0001: plug test gaps for git-init(1) with GIT_OBJECT_DIRECTORY
Patrick Steinhardt [Thu, 4 Jun 2026 07:46:25 +0000 (09:46 +0200)]
t0001: plug test gaps for git-init(1) with GIT_OBJECT_DIRECTORY

In subsequent commits we'll rework how we set up the repository. This is
a somewhat intricate and thus fragile sequence; there's many things that
can go subtly wrong, and there are lots of interesting interactions that
one can discover.

One such discovered edge case was the interaction between git-init(1)
and the "GIT_OBJECT_DIRECTORY" environment variable. When set, the
behaviour is that the object directory should be created at the path
that the variable points to. This behaviour is documented as such in
its man page:

  If the object storage directory is specified via the
  GIT_OBJECT_DIRECTORY environment variable then the sha1 directories
  are created underneath; otherwise, the default $GIT_DIR/objects
  directory is used.

Curiously enough though we don't seem to have any tests that exercise
this directly, and thus a subsequent commit inadvertently would have
broken this expectation.

Plug this test gap.

Signed-off-by: Patrick Steinhardt <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agoThe 11th batch
Junio C Hamano [Tue, 2 Jun 2026 03:48:59 +0000 (12:48 +0900)]
The 11th batch

Signed-off-by: Junio C Hamano <redacted>
2 months agoMerge branch 'kh/doc-hook'
Junio C Hamano [Tue, 2 Jun 2026 07:15:29 +0000 (16:15 +0900)]
Merge branch 'kh/doc-hook'

Doc updates.

* kh/doc-hook:
  doc: hook: don’t self-link via config include
  doc: config: include existing git-hook(1) section
  doc: hook: consistently capitalize Git
  doc: hook: remove stray backtick

2 months agoMerge branch 'ds/path-walk-filters'
Junio C Hamano [Tue, 2 Jun 2026 07:15:29 +0000 (16:15 +0900)]
Merge branch 'ds/path-walk-filters'

The "git pack-objects --path-walk" traversal has been integrated
with several object filters, including blobless and sparse filters.

* ds/path-walk-filters:
  path-walk: support `combine` filter
  path-walk: support `object:type` filter
  path-walk: support `tree:0` filter
  t6601: tag otherwise-unreachable trees
  pack-objects: support sparse:oid filter with path-walk
  path-walk: add pl_sparse_trees to control tree pruning
  path-walk: support blob size limit filter
  backfill: die on incompatible filter options
  path-walk: support blobless filter
  path-walk: always emit directly-requested objects
  t/perf: add pack-objects filter and path-walk benchmark
  pack-objects: pass --objects with --path-walk
  t5620: make test work with path-walk var

2 months agoMerge branch 'ta/approxidate-noon-fix'
Junio C Hamano [Tue, 2 Jun 2026 07:15:29 +0000 (16:15 +0900)]
Merge branch 'ta/approxidate-noon-fix'

"Friday noon" asked in the morning on Sunday was parsed to be one
day before the specified time, which has been corrected.

* ta/approxidate-noon-fix:
  approxidate: use deferred mday adjustments for "specials"
  approxidate: make "specials" respect fixed day-of-month
  t0006: add support for approxidate test date adjustment
  approxidate: make "today" wrap to midnight

2 months agoMerge branch 'jk/connect-service-enum'
Junio C Hamano [Tue, 2 Jun 2026 07:15:28 +0000 (16:15 +0900)]
Merge branch 'jk/connect-service-enum'

The "name" argument in git_connect() and related functions has been
converted to a "service" enum to improve type safety and clarify its
purpose.

* jk/connect-service-enum:
  transport-helper: fix typo in BUG() message
  connect: use "service" enum for "name" argument

2 months agoThe 10th batch
Junio C Hamano [Sun, 31 May 2026 01:00:11 +0000 (10:00 +0900)]
The 10th batch

Signed-off-by: Junio C Hamano <redacted>
2 months agoMerge branch 'sp/doc-range-diff-takes-notes'
Junio C Hamano [Sun, 31 May 2026 01:00:39 +0000 (10:00 +0900)]
Merge branch 'sp/doc-range-diff-takes-notes'

Docfix.

* sp/doc-range-diff-takes-notes:
  Documentation/git-range-diff: add missing notes options in synopsis

2 months agoMerge branch 'ps/gitlab-ci-macOS-improvements'
Junio C Hamano [Sun, 31 May 2026 01:00:38 +0000 (10:00 +0900)]
Merge branch 'ps/gitlab-ci-macOS-improvements'

Update GitLab CI jobs that exercise macOS.

* ps/gitlab-ci-macOS-improvements:
  gitlab-ci: update macOS image
  gitlab-ci: upgrade macOS runners

2 months agoMerge branch 'sa/cat-file-batch-mailmap-switch'
Junio C Hamano [Sun, 31 May 2026 01:00:38 +0000 (10:00 +0900)]
Merge branch 'sa/cat-file-batch-mailmap-switch'

"git cat-file --batch" learns an in-line command "mailmap"
that lets the user toggle use of mailmap.

* sa/cat-file-batch-mailmap-switch:
  cat-file: add mailmap subcommand to --batch-command

2 months agoMerge branch 'jk/commit-graph-lazy-load-fallback'
Junio C Hamano [Sun, 31 May 2026 01:00:38 +0000 (10:00 +0900)]
Merge branch 'jk/commit-graph-lazy-load-fallback'

The logic to lazy-load trees from the commit-graph has been made
more robust by falling back to reading the commit object when
the commit-graph is no longer available.

* jk/commit-graph-lazy-load-fallback:
  commit: fall back to full read when maybe_tree is NULL

2 months agoMerge branch 'pt/fsmonitor-linux'
Junio C Hamano [Sun, 31 May 2026 01:00:38 +0000 (10:00 +0900)]
Merge branch 'pt/fsmonitor-linux'

The fsmonitor daemon has been implemented for Linux.

* pt/fsmonitor-linux:
  fsmonitor: convert shown khash to strset in do_handle_client
  fsmonitor: add tests for Linux
  fsmonitor: add timeout to daemon stop command
  fsmonitor: close inherited file descriptors and detach in daemon
  run-command: add close_fd_above_stderr option
  fsmonitor: implement filesystem change listener for Linux
  fsmonitor: rename fsm-settings-darwin.c to fsm-settings-unix.c
  fsmonitor: rename fsm-ipc-darwin.c to fsm-ipc-unix.c
  fsmonitor: use pthread_cond_timedwait for cookie wait
  compat/win32: add pthread_cond_timedwait
  fsmonitor: fix hashmap memory leak in fsmonitor_run_daemon
  fsmonitor: fix khash memory leak in do_handle_client
  t9210, t9211: disable GIT_TEST_SPLIT_INDEX for scalar clone tests

2 months agoMerge branch 'ps/graph-lane-limit'
Junio C Hamano [Sun, 31 May 2026 01:00:37 +0000 (10:00 +0900)]
Merge branch 'ps/graph-lane-limit'

The graph output from commands like "git log --graph" can now be
limited to a specified number of lanes, preventing overly wide output
in repositories with many branches.

* ps/graph-lane-limit:
  graph: add truncation mark to capped lanes
  graph: add --graph-lane-limit option
  graph: limit the graph width to a hard-coded max

2 months agoMerge branch 'jr/bisect-custom-terms-in-output'
Junio C Hamano [Sun, 31 May 2026 01:00:37 +0000 (10:00 +0900)]
Merge branch 'jr/bisect-custom-terms-in-output'

"git bisect" now uses the selected terms (e.g., old/new) more
consistently in its output.

* jr/bisect-custom-terms-in-output:
  rev-parse: use selected alternate terms to look up refs
  bisect: print bisect terms in single quotes
  bisect: use selected alternate terms in status output

2 months agoMerge branch 'tc/generate-configlist-fix-for-older-ninja'
Junio C Hamano [Sun, 31 May 2026 01:00:37 +0000 (10:00 +0900)]
Merge branch 'tc/generate-configlist-fix-for-older-ninja'

Build update.

* tc/generate-configlist-fix-for-older-ninja:
  generate-configlist: collapse depfile for older Ninja

2 months agoMerge branch 'kk/tips-reachable-from-bases-optim'
Junio C Hamano [Sun, 31 May 2026 01:00:37 +0000 (10:00 +0900)]
Merge branch 'kk/tips-reachable-from-bases-optim'

Revision traversal optimization.

* kk/tips-reachable-from-bases-optim:
  t6600: add tests for duplicate tips in tips_reachable_from_bases()
  commit-reach: use object flags for tips_reachable_from_bases()

2 months agoMerge branch 'ed/check-connected-close-err-fd'
Junio C Hamano [Sun, 31 May 2026 01:00:36 +0000 (10:00 +0900)]
Merge branch 'ed/check-connected-close-err-fd'

File descriptor leak fix.

* ed/check-connected-close-err-fd:

2 months agoMerge branch 'ed/check-connected-close-err-fd-2.53'
Junio C Hamano [Sun, 31 May 2026 01:00:36 +0000 (10:00 +0900)]
Merge branch 'ed/check-connected-close-err-fd-2.53'

File descriptor leak fix (for 2.54 maintenance track).

* ed/check-connected-close-err-fd-2.53:
  connected: close err_fd in promisor fast-path

2 months agocommit: remove deprecated functions
Kristoffer Haugsbakk [Thu, 28 May 2026 07:00:11 +0000 (09:00 +0200)]
commit: remove deprecated functions

These functions were deprecated in a series of commits merged in
52882024 (Merge branch 'ps/commit-list-functions-renamed', 2026-02-13).

The compatibility was for in-flight topics at the time.

Acked-by: Patrick Steinhardt <redacted>
Signed-off-by: Kristoffer Haugsbakk <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months ago*: replace deprecated free_commit_list
Kristoffer Haugsbakk [Thu, 28 May 2026 07:00:10 +0000 (09:00 +0200)]
*: replace deprecated free_commit_list

Replace `free_commit_list` with `commit_list_free`. The former was
deprecated in 9f18d089 (commit: rename `free_commit_list()` to conform
to coding guidelines, 2026-01-15).

This allows us to remove all the deprecated functions in the
next commit:

• `copy_commit_list`
• `reverse_commit_list`
• `free_commit_list`

Acked-by: Patrick Steinhardt <redacted>
Signed-off-by: Kristoffer Haugsbakk <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agopack-bitmap: build pseudo-merge bitmaps after regular bitmaps
Taylor Blau [Wed, 27 May 2026 19:56:11 +0000 (15:56 -0400)]
pack-bitmap: build pseudo-merge bitmaps after regular bitmaps

When generating bitmaps, `bitmap_builder_init()` starts with an initial
selection of commits to receive bitmap coverage, and then determines a
set of "maximal" commits based on its input.

Commit 089f751360f (pack-bitmap-write: build fewer intermediate bitmaps,
2020-12-08) has extensive details, but the gist is as follows:

Each selected commit starts with one commit_mask bit in its "commit
mask" bitmap. Then, we walk the first-parent history in topological
order and OR each commit's mask into its (first) parent. Whenever that
OR results in the parent having more bits set, the child is deemed to be
non-maximal, and the frontier is pushed further back along the first
parent history.

That approach works extremely well for ordinary selected commits, whose
first-parent histories often describe real sharing between the bitmaps
we are going to write.

It struggles, however, to efficiently generate pseudo-merge bitmaps.
Unlike ordinary commits for which the above algorithm is designed,
pseudo-merges don't represent any "real" commit in history, just a
grouping of non-bitmapped reference tips. In that sense, their first
parent is just a part of a larger set, and treating them like ordinary
selected commits imposes a significant slow-down when generating bitmaps
with pseudo-merges enabled.

Consider partitioning all non-bitmapped reference tips into eight
individual pseudo-merges via the following configuration:

    [bitmapPseudoMerge "all"]
        pattern=refs/
        threshold=now
        stableSize=10000000
        maxMerges=8

, the cost of generating a bitmap from scratch rises significantly:

    +------------------+-----------------+---------------+---------------------+
    |                  | no pseudo-merge | pseudo-merges | Delta               |
    |                  |                 | (HEAD^)       |                     |
    +------------------+-----------------+---------------+---------------------+
    | elapsed          |   294.1 s       |   575.0 s     |   +280.9 s (+95.5%) |
    | cycles           | 1,365.5 B       | 2,686.9 B     | +1,321.4 B (+96.8%) |
    | instructions     | 1,389.8 B       | 2,546.6 B     | +1,156.8 B (+83.2%) |
    | CPI              |     0.983       |     1.055     |   +0.073    (+7.4%) |
    +------------------+-----------------+---------------+---------------------+

This is a particularly poor trade-off, because the time saved by these
pseudo-merges during, e.g.,

    $ git rev-list --count --all --objects --use-bitmap-index

is only:

    $ hyperfine -L v true,false -n 'pseudo-merges: {v}' '
        GIT_TEST_USE_PSEUDO_MERGES={v} git.compile rev-list --count \
          --objects --all --use-bitmap-index
      '

    Benchmark 1: pseudo-merges: true
      Time (mean ± σ):      2.613 s ±  0.012 s    [User: 2.308 s, System: 0.305 s]
      Range (min … max):    2.594 s …  2.633 s    10 runs

    Benchmark 2: pseudo-merges: false
      Time (mean ± σ):     52.205 s ±  0.170 s    [User: 51.500 s, System: 0.697 s]
      Range (min … max):   51.956 s … 52.458 s    10 runs

    Summary
      pseudo-merges: true ran
       19.98 ± 0.11 times faster than pseudo-merges: false

In other words, we pay a nearly ~5 minute penalty to generate
pseudo-merge bitmaps, but only save ~50 seconds during traversal.

The problem stems from injecting pseudo-merges into the bitmap builder
as if they were normal commits. The maximal commit selection algorithm
was simply not designed for that case, and performs predictably poorly.

The only reason we reused the maximal commit selection routine for
pseudo-merges alongside regular non-pseudo-merge commits is because we
represent them both as commit objects (where the pseudo-merge commits
just represent a made-up commit as opposed to one that actually exists
in a repository's object store).

Instead, build the regular selected commit bitmaps first, considering
only non-pseudo-merge commits in `bitmap_builder_init()`. Once those
bitmaps have been stored, build each pseudo-merge bitmap separately and
attach its parent and object bitmaps to the corresponding pseudo-merge
entry before writing the extension.

This keeps the regular bitmap build shaped like the no-pseudo-merge
case. The later pseudo-merge fill can still stop at stored selected
ancestor bitmaps, so it does not have to rewalk each pseudo-merge
closure from scratch.

When an existing bitmap has the same pseudo-merge parent set, reuse and
remap that whole pseudo-merge bitmap before falling back to
fill_bitmap_commit(). This preserves the benefit of stable pseudo-merges
while keeping the on-disk format and reader behavior unchanged.

As a result, the overhead cost for generating pseudo-merges in the above
configuration is much smaller:

    +------------------+-----------------+---------------+-------------------+
    |                  | no pseudo-merge | pseudo-merges | Delta             |
    |                  |                 | (HEAD)        |                   |
    +------------------+-----------------+---------------+-------------------+
    | elapsed          |   294.1 s       |   328.4 s     |  +34.3 s (+11.7%) |
    | cycles           | 1,365.5 B       | 1,529.3 B     | +163.7 B (+12.0%) |
    | instructions     | 1,389.8 B       | 1,552.8 B     | +163.0 B (+11.7%) |
    | CPI              |     0.983       |     0.985     |  +0.002   (+0.2%) |
    +------------------+-----------------+---------------+-------------------+

Recall that at the start of this series, generating reachability bitmaps
took 612.5 seconds *without* pseudo-merges. With this commit, it is
still ~46.38% *faster* to generate reachability bitmaps *with*
pseudo-merges than it was to generate bitmaps wihtout them at the
beginning of this series.

The changes to implement this are mostly straightforward. We exclude
pseudo-merge commits from the existing bitmap generation, and walk over
them in a separate pass, by either reusing an existing on-disk
pseudo-merge, or passing the pseudo-merge commit itself back to the
existing routine in `fill_bitmap_commit()`.

(Note that the routine to build pseudo-merge bitmaps is the same both
before and after this change, the difference is only that we do not let
psuedo-merges participate in determining the set of maximal commits.)

The only wrinkle is that `fill_bitmap_commit()` must be taught to not
expect that all tree objects have been parsed, which is the case for any
portion of history reachable by one or more pseudo-merge(s), but not by
any non-pseudo-merge commit selected for bitmapping.

Signed-off-by: Taylor Blau <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agopack-bitmap: remember pseudo-merge parents
Taylor Blau [Wed, 27 May 2026 19:56:08 +0000 (15:56 -0400)]
pack-bitmap: remember pseudo-merge parents

write_pseudo_merges() currently builds an array of temporary bitmaps for
the parent set of each pseudo-merge, then serializes those bitmaps later
while writing the extension.

Move those parent bitmaps onto the corresponding bitmapped_commit
entries instead. This keeps the on-disk output unchanged, but gives the
parent bitmap the same lifetime and access pattern that later changes
will use when pseudo-merge object bitmaps are built before the write
step.

Signed-off-by: Taylor Blau <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agopack-bitmap: sort bitmaps before XORing
Taylor Blau [Wed, 27 May 2026 19:56:05 +0000 (15:56 -0400)]
pack-bitmap: sort bitmaps before XORing

Reachability bitmaps may be stored as XORs against nearby bitmaps, up to
10 away. However, when callers provide selected commits in an arbitrary
order, the writer may miss good ancestor/descendant pairs and produce
much larger bitmap files without changing query coverage.

Sort the selected bitmaps in date order (from oldest to newest) before
computing XOR offsets, leaving pseudo-merge bitmaps alone (which we will
deal with separately in following commits).

On our same testing repository from previous commits, this change shrunk
our selection of 1,261 bitmaps from ~635.46 MiB to 176.4 MiB for a
~72.24% reduction in the on-disk size of our *.bitmap file. The time to
generate the smaller bitmap file decreased by ~3.69 seconds, though this
is likely mostly noise.

Signed-off-by: Taylor Blau <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agopack-bitmap: cache object positions during fill
Taylor Blau [Wed, 27 May 2026 19:56:02 +0000 (15:56 -0400)]
pack-bitmap: cache object positions during fill

The previous commits removed some redundant work from bitmap generation
by avoiding unnecessary tree recursion and by reusing selected bitmaps
that have already been computed.

Even with those changes in place, there is still an extremely hot path
from `fill_bitmap_commit()` and `fill_bitmap_tree()` to translate object
IDs into their corresponding bit positions in order to generate their
bitmaps.

In a small repository, this overhead is not significant. However, in a
very large repository (e.g., the one that we have been using as a
benchmark over the past several commits with ~57M total objects), the
overhead of locating object bit positions (often repeatedly) adds up
significantly.

Combat this by adding a small, direct-mapped cache to the bitmap writer
which maps object IDs to their corresponding bit positions. Size the
cache according to the number of objects being written, with fixed lower
and upper bounds so small repositories do not pay for a large table and
large repositories can avoid most repeated packlist and MIDX lookups.

On my machine with (a somewhat outdated) GCC 15.2.0, each entry in the
cache is 40 bytes wide:

    $ pahole -C bitmap_pos_cache_entry pack-bitmap-write.o
    struct bitmap_pos_cache_entry {
            struct object_id           oid;                  /*     0    36 */
            uint32_t                   pos;                  /*    36     4 */

            /* size: 40, cachelines: 1, members: 2 */
            /* last cacheline: 40 bytes */
    };

, and we will allocate up to 2^21 entries for a maximum total of 80 MiB
of cache overhead.

In our example repository from above and in earlier commits, this
results in a ~9.4% reduction in runtime relative to the previous commit:

    +------------------+-------------+-------------+---------------------+
    |                  | HEAD^       | HEAD        | Delta               |
    +------------------+-------------+-------------+---------------------+
    | elapsed          |   324.8 s   |   294.1 s   |    -30.7 s  (-9.4%) |
    | cycles           | 1,508.6 B   | 1,365.5 B   |   -143.0 B  (-9.5%) |
    | instructions     | 1,436.6 B   | 1,389.8 B   |    -46.9 B  (-3.3%) |
    | CPI              |     1.050   |     0.983   |   -0.068    (-6.4%) |
    +------------------+-------------+-------------+---------------------+

When generating bitmaps on this repository (to produce the above
timings), the cache grew to its maximum size of 80 MiB, and resulted in
1.024B cache hits and 59.957M cache misses.

Signed-off-by: Taylor Blau <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agopack-bitmap: consolidate `find_object_pos()` success path
Taylor Blau [Wed, 27 May 2026 19:55:59 +0000 (15:55 -0400)]
pack-bitmap: consolidate `find_object_pos()` success path

Both sides of `find_object_pos()` report success in the same way by
setting the optional `found` out-parameter and return the resolved
bitmap position.

Prepare for adding more bookkeeping around object-position lookups by
storing the result in a local `pos` variable and sharing the success
return path between the packlist and MIDX cases.

Signed-off-by: Taylor Blau <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agopack-bitmap: reuse stored selected bitmaps
Taylor Blau [Wed, 27 May 2026 19:55:56 +0000 (15:55 -0400)]
pack-bitmap: reuse stored selected bitmaps

When `fill_bitmap_commit()` reaches an ancestor that was selected for
its own bitmap and processed earlier, its object closure is already
stored in `writer->bitmaps` as an EWAH bitmap. As a result, walking
through that commit's tree and parents again is redundant.

Teach `fill_bitmap_commit()` to notice that case. For non-root commits in
the walk, look for a stored selected bitmap and OR it into the bitmap
being built. If one exists, skip the commit, its tree, and its parents.

Building bitmaps from scratch on the same test repository from the
previous commits yields a significant speed-up:

    +------------------+-------------+-------------+---------------------+
    |                  | HEAD^       | HEAD        | Delta               |
    +------------------+-------------+-------------+---------------------+
    | elapsed          |   562.8 s   |   324.8 s   |   -237.9 s (-42.3%) |
    | cycles           | 2,621.3 B   | 1,508.6 B   | -1,112.7 B (-42.4%) |
    | instructions     | 2,348.9 B   | 1,436.6 B   |   -912.3 B (-38.8%) |
    | CPI              |     1.116   |     1.050   |   -0.066    (-5.9%) |
    +------------------+-------------+-------------+---------------------+

In our testing repository, there are 1,261 commits selected for bitmap
coverage, and 1,382 maximal commits induced as a result of that. Of the
1,382 calls made to `fill_bitmap_commit()` (one per maximal commit), 131
of them can be short-circuited at some point during their traversal as a
consequence of this change.

In large repositories where the cost of filling the bitmap for any
individual commit is large, being able to short-circuit even ~9.5% of
the calls to `fill_bitmap_commit()` results in a significant savings.

Signed-off-by: Taylor Blau <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agopack-bitmap: check subtree bits before recursing
Taylor Blau [Wed, 27 May 2026 19:55:53 +0000 (15:55 -0400)]
pack-bitmap: check subtree bits before recursing

In the previous commit, we adjusted the callers of `fill_bitmap_tree()`
to pass in the bit position of the tree they wish to fill.

This commit makes use of that information at the call site to avoid
setting up a stack frame for fill_bitmap_tree() entirely whenever a
tree's bit position is already set.

Since this is such a hot path, the avoided cost of setting up and
tearing down stack frames for each noop'd call to `fill_bitmap_tree()`
is significant:

    +--------------+-------------+-------------+-------------------+
    |              | HEAD^       | HEAD        | Delta             |
    +--------------+-------------+-------------+-------------------+
    | elapsed      |   582.4 s   |   562.8 s   |  -19.6 s  (-3.4%) |
    | cycles       | 2,713.3 B   | 2,621.3 B   |  -92.0 B  (-3.4%) |
    | instructions | 2,415.5 B   | 2,348.9 B   |  -66.6 B  (-2.8%) |
    | CPI          |     1.123   |     1.116   |  -0.007   (-0.7%) |
    +--------------+-------------+-------------+-------------------+

In the same repository as in the previous commit, our timings dropped
from ~582.4 seconds down to ~562.77 seconds.

While the cycles-per-instruction ratio is basically unchanged, we
execute significantly fewer instructions, and correspondingly fewer
cycles.

Signed-off-by: Taylor Blau <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agopack-bitmap: pass object position to `fill_bitmap_tree()`
Taylor Blau [Wed, 27 May 2026 19:55:50 +0000 (15:55 -0400)]
pack-bitmap: pass object position to `fill_bitmap_tree()`

In the following commit, callers of `fill_bitmap_tree()` will be
required to check the bit corresponding to their tree before calling
that function. That change will reduce the overhead of setting up and
tearing down stack frames for trees whose bits are already set.

To prepare for that change, have callers pass in the tree's bit position
in `fill_bitmap_tree()`, which will make the next commit easier to read.

In the meantime, this change has a surprising and measurable benefit
during bitmap generation, particularly on very large repositories.

When processing sub-trees within `fill_bitmap_tree()`, the preimage of
this patch did the following:

    while (tree_entry(&desc, entry)) {
        switch (object_type(entry.mode)) {
        case OBJ_TREE:
            if (fill_bitmap_tree(writer, bitmap,
                                 lookup_tree(writer->repo,
                                             &entry.oid)) < 0) {
                /* ... */
            }
            /* ... */
        }
    }

, first performing the object lookup via `lookup_tree()`, and then
locating its bit position within the recursive call. This patch
effectively reorders those two calls so that we first discover the
sub-tree's bit position, *then* load its tree.

By reordering these two operations, we spend fewer CPU cycles per
instruction, likely due to improved CPU dependency/cache/pipeline
behavior. Comparing the results of: running `perf stat` before and after
this commit, we have:

    +--------------+-------------+-------------+-------------------+
    |              | HEAD^       | HEAD        | Delta             |
    +--------------+-------------+-------------+-------------------+
    | elapsed      |   612.5 s   |   582.4 s   |  -30.1 s  (-4.9%) |
    | cycles       | 2,857.3 B   | 2,713.3 B   | -144.0 B  (-5.0%) |
    | instructions | 2,413.2 B   | 2,415.5 B   |   +2.3 B  (+0.1%) |
    | CPI          |     1.184   |     1.123   |  -0.061   (-5.1%) |
    +--------------+-------------+-------------+-------------------+

In a large repository with ~4.8M commit, and ~37.1M tree objects this
change improves timing from ~612.5 seconds down to ~582.4 seconds, or a
~4.9% improvement. More importantly, the number of CPU cycles spent
dropped off significantly as a result of this commit, lowering our
cycles-per-instruction ratio by about ~5.1%.

Signed-off-by: Taylor Blau <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agoThe 9th batch
Junio C Hamano [Wed, 27 May 2026 05:15:25 +0000 (14:15 +0900)]
The 9th batch

Signed-off-by: Junio C Hamano <redacted>
2 months agoMerge branch 'ps/setup-wo-the-repository'
Junio C Hamano [Wed, 27 May 2026 05:15:46 +0000 (14:15 +0900)]
Merge branch 'ps/setup-wo-the-repository'

Many uses of the_repository has been updated to use a more
appropriate struct repository instance in setup.c codepath.

* ps/setup-wo-the-repository:
  setup: stop using `the_repository` in `init_db()`
  setup: stop using `the_repository` in `create_reference_database()`
  setup: stop using `the_repository` in `initialize_repository_version()`
  setup: stop using `the_repository` in `check_repository_format()`
  setup: stop using `the_repository` in `upgrade_repository_format()`
  setup: stop using `the_repository` in `setup_git_directory()`
  setup: stop using `the_repository` in `setup_git_directory_gently()`
  setup: stop using `the_repository` in `setup_git_env()`
  setup: stop using `the_repository` in `set_git_work_tree()`
  setup: stop using `the_repository` in `setup_work_tree()`
  setup: stop using `the_repository` in `enter_repo()`
  setup: stop using `the_repository` in `verify_non_filename()`
  setup: stop using `the_repository` in `verify_filename()`
  setup: stop using `the_repository` in `path_inside_repo()`
  setup: stop using `the_repository` in `prefix_path()`
  setup: stop using `the_repository` in `is_inside_work_tree()`
  setup: stop using `the_repository` in `is_inside_git_dir()`
  setup: replace use of `the_repository` in static functions

2 months agoMerge branch 'ps/odb-in-memory'
Junio C Hamano [Wed, 27 May 2026 05:15:46 +0000 (14:15 +0900)]
Merge branch 'ps/odb-in-memory'

Add a new odb "in-memory" source that is meant to only hold
tentative objects (like the virtual blob object that represents the
working tree file used by "git blame").

* ps/odb-in-memory:
  t/unit-tests: add tests for the in-memory object source
  odb: generic in-memory source
  odb/source-inmemory: stub out remaining functions
  odb/source-inmemory: implement `freshen_object()` callback
  odb/source-inmemory: implement `count_objects()` callback
  odb/source-inmemory: implement `find_abbrev_len()` callback
  odb/source-inmemory: implement `for_each_object()` callback
  odb/source-inmemory: convert to use oidtree
  oidtree: add ability to store data
  cbtree: allow using arbitrary wrapper structures for nodes
  odb/source-inmemory: implement `write_object_stream()` callback
  odb/source-inmemory: implement `write_object()` callback
  odb/source-inmemory: implement `read_object_stream()` callback
  odb/source-inmemory: implement `read_object_info()` callback
  odb: fix unnecessary call to `find_cached_object()`
  odb/source-inmemory: implement `free()` callback
  odb: introduce "in-memory" source

2 months agoMerge branch 'jt/odb-transaction-write'
Junio C Hamano [Wed, 27 May 2026 05:15:45 +0000 (14:15 +0900)]
Merge branch 'jt/odb-transaction-write'

ODB transaction interface is being reworked to explicitly handle
object writes.

* jt/odb-transaction-write:
  odb/transaction: make `write_object_stream()` pluggable
  object-file: generalize packfile writes to use odb_write_stream
  object-file: avoid fd seekback by checking object size upfront
  object-file: remove flags from transaction packfile writes
  odb: update `struct odb_write_stream` read() callback
  odb/transaction: use pluggable `begin_transaction()`
  odb: split `struct odb_transaction` into separate header

2 months agoMerge branch 'tb/incremental-midx-part-3.3'
Junio C Hamano [Wed, 27 May 2026 05:15:45 +0000 (14:15 +0900)]
Merge branch 'tb/incremental-midx-part-3.3'

The repacking code has been refactored and compaction of MIDX layers
have been implemented, and incremental strategy that does not require
all-into-one repacking has been introduced.

* tb/incremental-midx-part-3.3:
  repack: allow `--write-midx=incremental` without `--geometric`
  repack: introduce `--write-midx=incremental`
  repack: implement incremental MIDX repacking
  packfile: ensure `close_pack_revindex()` frees in-memory revindex
  builtin/repack.c: convert `--write-midx` to an `OPT_CALLBACK`
  repack-geometry: prepare for incremental MIDX repacking
  repack-midx: extract `repack_fill_midx_stdin_packs()`
  repack-midx: factor out `repack_prepare_midx_command()`
  midx: expose `midx_layer_contains_pack()`
  repack: track the ODB source via existing_packs
  midx: support custom `--base` for incremental MIDX writes
  midx: introduce `--no-write-chain-file` for incremental MIDX writes
  midx: use `strvec` for `keep_hashes`
  midx: build `keep_hashes` array in order
  midx: use `strset` for retained MIDX files
  midx-write: handle noop writes when converting incremental chains

2 months agoMerge branch 'ds/fetch-negotiation-options'
Junio C Hamano [Wed, 27 May 2026 05:15:45 +0000 (14:15 +0900)]
Merge branch 'ds/fetch-negotiation-options'

The negotiation tip options in "git fetch" have been reworked to
allow requiring certain refs to be sent as "have" lines, and to
restrict negotiation to a specific set of refs.

* ds/fetch-negotiation-options:
  send-pack: pass negotiation config in push
  remote: add remote.*.negotiationInclude config
  fetch: add --negotiation-include option for negotiation
  negotiator: add have_sent() interface
  remote: add remote.*.negotiationRestrict config
  transport: rename negotiation_tips
  fetch: add --negotiation-restrict option
  t5516: fix test order flakiness

2 months agoMerge branch 'rs/use-builtin-add-overflow-explicitly-on-clang'
Junio C Hamano [Wed, 27 May 2026 05:15:44 +0000 (14:15 +0900)]
Merge branch 'rs/use-builtin-add-overflow-explicitly-on-clang'

Micro optimization of codepaths that compute allocation sizes carefully.

* rs/use-builtin-add-overflow-explicitly-on-clang:
  use __builtin_add_overflow() in st_add() with Clang
  strbuf: use st_add3() in strbuf_grow()

2 months agoMerge branch 'jk/sq-dequote-cleanup'
Junio C Hamano [Wed, 27 May 2026 05:15:44 +0000 (14:15 +0900)]
Merge branch 'jk/sq-dequote-cleanup'

Code simplification.

* jk/sq-dequote-cleanup:
  quote: simplify internals of dequoting
  quote: drop sq_dequote_to_argv()
  quote.h: bump strvec forward declaration to the top

2 months agoMerge branch 'kn/refs-fsck-skip-lock-files'
Junio C Hamano [Wed, 27 May 2026 05:15:44 +0000 (14:15 +0900)]
Merge branch 'kn/refs-fsck-skip-lock-files'

The consistency checks for the files reference backend have been updated
to skip lock files earlier, avoiding unnecessary parsing of
intermediate files.

* kn/refs-fsck-skip-lock-files:
  refs/files: skip lock files during consistency checks

2 months agoMerge branch 'ps/t3903-cover-stash-include-untracked'
Junio C Hamano [Wed, 27 May 2026 05:15:44 +0000 (14:15 +0900)]
Merge branch 'ps/t3903-cover-stash-include-untracked'

Test coverage has been added to "git stash --include-untracked".

* ps/t3903-cover-stash-include-untracked:
  stash: add coverage for show --include-untracked

2 months agoMerge branch 'kk/merge-octopus-optim'
Junio C Hamano [Wed, 27 May 2026 05:15:44 +0000 (14:15 +0900)]
Merge branch 'kk/merge-octopus-optim'

The logic to determine that branches in an octopus merge are
independent has been optimized.

* kk/merge-octopus-optim:
  merge: use repo_in_merge_bases for octopus up-to-date check

2 months agoMerge branch 'en/batch-prefetch'
Junio C Hamano [Wed, 27 May 2026 05:15:43 +0000 (14:15 +0900)]
Merge branch 'en/batch-prefetch'

In a lazy clone, "git cherry" and "git grep" often fetch necessary
blob objects one by one from promisor remotes.  It has been corrected
to collect necessary object names and fetch them in bulk to gain
reasonable performance.

* en/batch-prefetch:
  grep: prefetch necessary blobs
  builtin/log: prefetch necessary blobs for `git cherry`
  patch-ids.h: add missing trailing parenthesis in documentation comment
  promisor-remote: document caller filtering contract

2 months agoMerge branch 'rs/trailer-fold-optim'
Junio C Hamano [Wed, 27 May 2026 05:15:43 +0000 (14:15 +0900)]
Merge branch 'rs/trailer-fold-optim'

Code simplification.

* rs/trailer-fold-optim:
  trailer: change strbuf in-place in unfold_value()

2 months agoMerge branch 'pb/doc-diff-format-updates'
Junio C Hamano [Wed, 27 May 2026 05:15:43 +0000 (14:15 +0900)]
Merge branch 'pb/doc-diff-format-updates'

Doc updates.

* pb/doc-diff-format-updates:
  diff-format.adoc: mode and hash are 0* for unmerged paths from index only
  diff-format.adoc: 'git diff-files' prints two lines for unmerged files
  diff-format.adoc: remove mention of diff-tree specific output

2 months agoMerge branch 'kk/limit-list-optim'
Junio C Hamano [Wed, 27 May 2026 05:15:43 +0000 (14:15 +0900)]
Merge branch 'kk/limit-list-optim'

The limit_list() function that is one of the core part of the
revision traversal infrastructure has been optimized by replacing
its use of linear list with priority queue.

* kk/limit-list-optim:
  revision: use priority queue in limit_list()

2 months agoMerge branch 'tb/pseudo-merge-bugfixes'
Junio C Hamano [Wed, 27 May 2026 05:15:43 +0000 (14:15 +0900)]
Merge branch 'tb/pseudo-merge-bugfixes'

Fixes many bugs in pseudo-merge code.

* tb/pseudo-merge-bugfixes:
  pack-bitmap: prevent pattern leak on pseudo-merge re-assignment
  Documentation: fix broken `sampleRate` in gitpacking(7)
  pack-bitmap: reject pseudo-merge "sampleRate" of 0
  pack-bitmap: parse commits in `find_pseudo_merge_group_for_ref()`
  pack-bitmap: fix pseudo-merge lookup for shared commits
  pack-bitmap: fix inverted binary search in `pseudo_merge_at()`
  pack-bitmap-write: sort pseudo-merge commit lookup table in pack order
  t5333: demonstrate various pseudo-merge bugs
  t/helper: add 'test-tool bitmap write' subcommand

2 months agorestore: avoid sparse index expansion
Derrick Stolee [Tue, 26 May 2026 20:26:34 +0000 (20:26 +0000)]
restore: avoid sparse index expansion

Teach update_some() to handle sparse directory entries at the tree
level rather than expanding the entire sparse index. When iterating a
source tree during checkout/restore operations:

 - If a directory matches a sparse directory entry with the same OID,
   skip it entirely (no change needed).

 - If the OID differs and we are in non-overlay mode (e.g., restore
   --staged), update the sparse directory entry's OID in place. This
   is semantically correct because non-overlay mode removes paths not
   in the source tree anyway.

 - In overlay mode (e.g., checkout <tree> -- .), fall through to
   recursive descent so individual file entries are preserved
   correctly.

Also switch from index_name_pos() to index_name_pos_sparse() for
individual file lookups to avoid triggering ensure_full_index() when
the file is already individually tracked in the index.

Update the test expectation in t1092 to assert that 'restore --staged'
no longer expands the sparse index.

Signed-off-by: Derrick Stolee <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agot1092: test 'git restore' with sparse index
Derrick Stolee [Tue, 26 May 2026 20:26:33 +0000 (20:26 +0000)]
t1092: test 'git restore' with sparse index

A user reported that 'git restore --staged .' causes the sparse index to
expand. This is somewhat natural because the '.' pathspec means 'check
every path'. However, the restore will not update paths marked with the
SKIP_WORKTREE bit, so we shouldn't need to process such entries.

For now, establish the current behavior, including the sparse index
expansion, in the t1092 test case as a baseline.

Signed-off-by: Derrick Stolee <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agodoc: clarify push.default=simple behavior
Ivan Baluta [Tue, 26 May 2026 03:58:07 +0000 (03:58 +0000)]
doc: clarify push.default=simple behavior

The documentation for the 'simple' push mode currently singles out
the centralized workflow, which can cause confusion about its
behavior in other scenarios, such as triangular workflows.

Clarify that 'simple' always pushes the current branch to a branch
of the same name, but only enforces the strict upstream tracking
requirement when pushing back to the same remote being pulled from.

Suggested-by: Junio C Hamano <redacted>
Signed-off-by: Ivan Baluta <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agoreceive-pack: fix updateInstead with core.worktree
Alyssa Ross [Mon, 25 May 2026 16:23:12 +0000 (18:23 +0200)]
receive-pack: fix updateInstead with core.worktree

Before a8cc594333 (hooks: fix an obscure TOCTOU "did we just run a
hook?" race, 2022-03-07), when receive.denyCurrentBranch is set to
updateInstead, only one of push_to_checkout() or push_to_deploy()
was called.  That commit changed to always call push_to_checkout(),
and then to call push_to_deploy() if push_to_checkout() didn't run
anything.

This change didn't take into account that push_to_checkout() had a
side effect of modifying env, and that modified env broke updating
the worktree in push_to_deploy() if core.worktree was configured.
To fix this, only mutate the environment used inside
push_to_commit(), rather than the environment that might later be
passed to push_to_deploy().

Signed-off-by: Alyssa Ross <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agocommit-reach: replace queue_has_nonstale() scan with O(1) tracking
Kristofer Karlsson [Mon, 25 May 2026 14:28:05 +0000 (14:28 +0000)]
commit-reach: replace queue_has_nonstale() scan with O(1) tracking

paint_down_to_common() and ahead_behind() call queue_has_nonstale()
on every iteration to decide whether to continue the walk.
queue_has_nonstale() performs a linear scan of the priority queue,
making the overall walk O(n*m) where n is the number of commits
walked and m is the queue size.

Introduce 'struct nonstale_queue', a thin wrapper around prio_queue
that maintains a 'max_nonstale' pointer — the lowest-priority
(oldest) non-stale commit seen so far. When this commit is popped,
every remaining queue entry is known to be stale, so the walk can
stop. This reduces the per-iteration termination check from O(m)
to O(1).

Uses <= 0 (not < 0) when comparing priorities so that among distinct
commits with equal priority (same generation and timestamp) the
last-enqueued one is tracked. Since prio_queue breaks ties by
insertion order, this ensures max_nonstale is always the last in its
priority class to be popped, making pointer equality on pop
sufficient for correctness.

The previous commit's ENQUEUED deduplication guarantees each commit
appears at most once in the queue, which is required for the pointer
equality check to be unambiguous.

On a large monorepo (3.7M commits), this yields ~2x end-to-end
speedup for merge-base calculations on deep import branches.
Profiling shows paint_down_to_common() drops from 50% to 4% of
total runtime (~27x faster), with the remaining time in commit
graph lookups and heap operations:

  Before: 8536ms / 5757ms / 4743ms  (three test cases)
  After:  3956ms / 4383ms / 1927ms

Suggested-by: Jeff King <redacted>
Signed-off-by: Kristofer Karlsson <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agocommit-reach: deduplicate queue entries in paint_down_to_common
Kristofer Karlsson [Mon, 25 May 2026 14:28:04 +0000 (14:28 +0000)]
commit-reach: deduplicate queue entries in paint_down_to_common

paint_down_to_common() can enqueue the same commit multiple times
when it is reached through different parents with different flag
combinations. Add an ENQUEUED flag to track whether a commit is
currently in the priority queue, and skip it if already present.

Introduce prio_queue_put_dedup() and prio_queue_get_dedup()
wrappers that manage the ENQUEUED flag on enqueue and dequeue.

This change is performance-neutral on its own: the O(n)
queue_has_nonstale() scan still dominates the per-iteration cost.
However, the deduplication guarantee (each commit appears in the
queue at most once) is a prerequisite for the next commit, which
replaces that scan with O(1) tracking.

Signed-off-by: Kristofer Karlsson <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agoobject.h: fix stale entries in object flag allocation table
Kristofer Karlsson [Mon, 25 May 2026 14:28:03 +0000 (14:28 +0000)]
object.h: fix stale entries in object flag allocation table

Update three stale entries found during an audit of the flag
allocation table:

 - sha1-name.c was renamed to object-name.c
 - builtin/show-branch.c uses bits 0 and 2-28, not 0-26
   (REV_SHIFT=2, MAX_REVS=FLAG_BITS-REV_SHIFT=27)
 - negotiator/skipping.c uses bits 2-5 like negotiator/default.c
   (ADVERTISED on bit 3 instead of COMMON_REF)

Signed-off-by: Kristofer Karlsson <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agodoc: convert git-imap-send synopsis and options to new style
Jean-Noël Avila [Mon, 25 May 2026 10:28:27 +0000 (10:28 +0000)]
doc: convert git-imap-send synopsis and options to new style

Convert git-imap-send from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms
- Backtick-quote all config keys in config/imap.adoc
- Backtick-quote bare config key references in prose

Signed-off-by: Jean-Noël Avila <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agodoc: convert git-apply synopsis and options to new style
Jean-Noël Avila [Mon, 25 May 2026 10:28:26 +0000 (10:28 +0000)]
doc: convert git-apply synopsis and options to new style

Convert git-apply from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms and config keys in config/apply.adoc
- Convert single-quoted inline commands ('git apply', 'diff', etc.)
- Wrap standalone placeholders in underscores (<n>, <root>, <action>)
- Backtick-quote `*.rej` and GNU `patch` tool references

Signed-off-by: Jean-Noël Avila <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agodoc: convert git-am synopsis and options to new style
Jean-Noël Avila [Mon, 25 May 2026 10:28:25 +0000 (10:28 +0000)]
doc: convert git-am synopsis and options to new style

Convert git-am from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms
- Convert inline man page refs
- Convert inline command refs
- Convert prose placeholders:

Signed-off-by: Jean-Noël Avila <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agodoc: convert git-grep synopsis and options to new style
Jean-Noël Avila [Mon, 25 May 2026 10:28:24 +0000 (10:28 +0000)]
doc: convert git-grep synopsis and options to new style

Convert git-grep.adoc from [verse]/single-quote style to the modern
synopsis-block style:

- Replace [verse] with [synopsis] in SYNOPSIS block
- Change 'git grep' to git grep (no single quotes)
- Backtick-quote all OPTIONS terms
- Convert inline man page refs: grep(1) -> `grep`(1)
- Convert inline command refs: 'git diff' -> `git diff`
- Convert prose placeholders: <file> -> _<file>_

Signed-off-by: Jean-Noël Avila <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agodoc: git bisect: clarify the usage of the synopsis vs actual command
Jean-Noël Avila [Mon, 25 May 2026 10:28:23 +0000 (10:28 +0000)]
doc: git bisect: clarify the usage of the synopsis vs actual command

The difference between a synopsis and an actual command is that the synopsis
is a more abstract representation of the command, which may include
placeholders for arguments and options. The actual command is the specific
instance of the command with all the arguments and options filled in.

The formatting of an actual command is a code block, with the command
prefixed by a dollar sign ($) to indicate that it is a command to be run in
the terminal. It can also include comments with a hash sign (#) to explain
the command or provide additional information, just like in a regular
terminal session.

Signed-off-by: Jean-Noël Avila <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agodoc: convert git-bisect to synopsis style
Jean-Noël Avila [Mon, 25 May 2026 10:28:22 +0000 (10:28 +0000)]
doc: convert git-bisect to synopsis style

Convert Documentation/git-bisect.adoc to the modern synopsis style.

- Replace [verse] with [synopsis] in the SYNOPSIS block
- Remove single quotes around command names in the synopsis
- Use backticks for inline commands, options, refs, and special values
- Apply [synopsis] attribute to in-body command-form code blocks
- Format OPTIONS entries with backtick-quoted terms and direct
- Add synopsis-style formatting to listing blocks
- Format man page references as `command`(N)

Signed-off-by: Jean-Noël Avila <redacted>
Signed-off-by: Junio C Hamano <redacted>
2 months agoSubmittingPatches: proactively monitor GHCI pages
Junio C Hamano [Mon, 25 May 2026 02:58:48 +0000 (11:58 +0900)]
SubmittingPatches: proactively monitor GHCI pages

Even those contributors who do not come from GGG and do not first
push their changes to their repositories on GitHub with CI enabled,
can still monitor the CI runs triggered by integration of their
topic to 'seen' and other branches to notice a breakage their topic
caused to the system.

Encourage them to help the project by keeping an eye on these CI
runs.

Signed-off-by: Junio C Hamano <redacted>
2 months agoThe 8th batch
Junio C Hamano [Mon, 25 May 2026 00:39:50 +0000 (09:39 +0900)]
The 8th batch

Signed-off-by: Junio C Hamano <redacted>
2 months agoMerge branch 'jk/dumb-http-alternate-fix'
Junio C Hamano [Mon, 25 May 2026 00:40:08 +0000 (09:40 +0900)]
Merge branch 'jk/dumb-http-alternate-fix'

The HTTP walker misinterpreted the alternates file that gives an
absolute path when the server URL does not have the final slash
(i.e., "https://example.com" not "https://example.com/").

* jk/dumb-http-alternate-fix:
  http: handle absolute-path alternates from server root

2 months agoMerge branch 'jk/pretty-no-strbuf-presizing'
Junio C Hamano [Mon, 25 May 2026 00:40:08 +0000 (09:40 +0900)]
Merge branch 'jk/pretty-no-strbuf-presizing'

Remove ineffective strbuf presizing that would have computed an
allocation that would not have fit in the available memory anyway,
or too small due to integer wraparound to cause immediate automatic
growing.

* jk/pretty-no-strbuf-presizing:
  pretty: drop strbuf pre-sizing from add_rfc2047()

2 months agoMerge branch 'ag/sequencer-remove-unused-struct-member'
Junio C Hamano [Mon, 25 May 2026 00:40:07 +0000 (09:40 +0900)]
Merge branch 'ag/sequencer-remove-unused-struct-member'

Code clean-up.

* ag/sequencer-remove-unused-struct-member:
  sequencer: remove todo_add_branch_context.commit

2 months agoMerge branch 'mm/diff-U-takes-no-negative-values'
Junio C Hamano [Mon, 25 May 2026 00:40:07 +0000 (09:40 +0900)]
Merge branch 'mm/diff-U-takes-no-negative-values'

The command line parser for "git diff" learned a few options take
only non-negative integers.

* mm/diff-U-takes-no-negative-values:
  parse-options: clarify what "negated" means for PARSE_OPT_NONEG
  xdiff: guard against negative context lengths
  diff: reject negative values for -U/--unified
  diff: reject negative values for --inter-hunk-context

2 months agoMerge branch 'dk/doc-exclude-is-shared-per-repo'
Junio C Hamano [Mon, 25 May 2026 00:40:07 +0000 (09:40 +0900)]
Merge branch 'dk/doc-exclude-is-shared-per-repo'

Document the fact that .git/info/exclude is shared across worktrees
linked to the same repository.

* dk/doc-exclude-is-shared-per-repo:
  ignore: note info/exclude lives in GIT_COMMON_DIR, not GIT_DIR

2 months agoMerge branch 'kk/paint-down-to-common-optim'
Junio C Hamano [Mon, 25 May 2026 00:40:07 +0000 (09:40 +0900)]
Merge branch 'kk/paint-down-to-common-optim'

"git merge-base" optimization.

* kk/paint-down-to-common-optim:
  commit-reach: early exit paint_down_to_common for single merge-base
  commit-reach: introduce merge_base_flags enum

git clone https://git.99rst.org/PROJECT