* Re: [PATCH 0/2] commit-reach: fix !FIND_ALL early exit with v1 commit graph
From: Junio C Hamano @ 2026-06-29 17:50 UTC (permalink / raw)
To: Kristofer Karlsson via GitGitGadget
Cc: git, Derrick Stolee, Kristofer Karlsson
In-Reply-To: <pull.2162.git.1782739162.gitgitgadget@gmail.com>
"Kristofer Karlsson via GitGitGadget" <gitgitgadget@gmail.com>
writes:
> Fixes a bug introduced by 93e5b1680e (commit-reach: early exit
> paint_down_to_common for single merge-base, 2025-04-10) where git merge-base
> can return the wrong result.
>
> The bug requires all of the following to trigger:
>
> 1. A v1 commit graph (topological levels only, no corrected commit dates).
> Generation v2 with corrected commit dates has been the default since
> 2021, so only repos that have not rewritten their commit graph in over
> four years would be affected.
> 2. git merge-base without --all (the common case, but --all is unaffected
> because it disables the early exit).
> 3. A topology with clock skew: the correct merge base has a lower committer
> date than one of its ancestors that is also a common ancestor. With date
> ordering, the deeper ancestor pops first and the early exit fires before
> the correct result is found.
>
> This two-patch series:
>
> 1. Adds a test demonstrating the bug (clock-skew topology where the correct
> merge base has a lower date than its ancestor)
> 2. Fixes it by tracking whether the queue is generation-ordered and gating
> the early exit on that flag
Where should this new "gen_ordered" flag go in the world with
kk/merge-base-exhaustion topic merged in? Does it also belong
to the paint_state struct or can it be on-stack independent variable
to the function?
^ permalink raw reply
* What's cooking in git.git (Jun 2026, #11)
From: Junio C Hamano @ 2026-06-29 17:50 UTC (permalink / raw)
To: git
Here are the topics that have been cooking in my tree. Commits
prefixed with '+' are in 'next' (being in 'next' is a sign that a
topic is stable enough to be used and is a candidate to be in a
future release). Commits prefixed with '-' are only in 'seen', and
aren't considered "accepted" at all and may be annotated with a URL
to a message that raises issues but they are by no means exhaustive.
A topic without enough support may be discarded after a long period
of no activity (of course they can be resubmitted when new interests
arise).
Git 2.55 (final) has been tagged, with a few last-minute fixes.
Copies of the source code to Git live in many repositories, and the
following is a list of the ones I push into or their mirrors. Some
repositories have only a subset of branches.
With maint, master, next, seen, todo:
git://git.kernel.org/pub/scm/git/git.git/
git://repo.or.cz/alt-git.git/
https://kernel.googlesource.com/pub/scm/git/git/
https://github.com/git/git/
https://gitlab.com/git-scm/git/
With all the integration branches and topics broken out:
https://github.com/gitster/git/
Even though the preformatted documentation in HTML and man format
are not sources, they are published in these repositories for
convenience (replace "htmldocs" with "manpages" for the manual
pages):
git://git.kernel.org/pub/scm/git/git-htmldocs.git/
https://github.com/gitster/git-htmldocs.git/
Release tarballs are available at:
https://www.kernel.org/pub/software/scm/git/
--------------------------------------------------
[New Topics]
* tb/repack-geometric-cruft (2026-06-28) 11 commits
- SQUASH??? bare grep !???
- repack: support combining '--geometric' with '--cruft'
- pack-objects: support '--refs-snapshot' with 'follow-reachable'
- pack-objects: introduce '--stdin-packs=follow-reachable'
- pack-objects: extract `stdin_packs_add_all_pack_entries()`
- repack-geometry: drop unused redundant-pack removal
- repack: delete geometric packs via existing_packs
- repack: teach MIDX retention about geometric rollups
- repack: mark geometric progression of packs as retained
- repack: extract `locate_existing_pack()` helper
- repack: unconditionally exclude non-kept packs
Teach `git repack` to accept `--geometric` and `--cruft`
together. When both are given, the geometric repack rolls up non-cruft
packs as usual, while a separate cruft pack is written to collect
unreachable objects.
Needs review.
cf. <xmqqpl1d56dd.fsf@gitster.g>
source: <cover.1782500507.git.me@ttaylorr.com>
* jk/reftable-leakfix (2026-06-28) 1 commit
- reftable: fix unlikely leak on API error
Leakfix.
Will merge to 'next'?
cf. <akIPBJLtPqDjQt-A@pks.im>
source: <20260628090314.GA661068@coredump.intra.peff.net>
* sg/t3420-do-not-grep-in-missing-file (2021-10-10) 1 commit
(merged to 'next' on 2026-06-29 at 2bf33c6a40)
+ t3420-rebase-autostash: don't try to grep non-existing files
Test fix.
Will merge to 'master'.
source: <20211010172809.1472914-1-szeder.dev@gmail.com>
--------------------------------------------------
[Graduated to 'master']
* jk/t5551-expensive-test-timeouts-fix (2026-06-28) 2 commits
- t5551: put many-tags case into its own repo
- t/lib-httpd: bump apache timeout
The Apache timeout in HTTP tests has been increased to prevent test
failures on heavily loaded CI runners. The tests creating an
enormous number of refs have been isolated to their own
repositories to avoid slowing down subsequent tests.
cf. <akIPBJLtPqDjQt-A@pks.im>
source: <20260628075716.GA3525066@coredump.intra.peff.net>
* js/http-https-proxy-fix (2026-06-27) 1 commit
(merged to 'next' on 2026-06-28 at a7fdf2ec97)
+ http: accept https:// proxies again
We lost ability to use https:// proxies during this cycle; this is
a hotfix for the regression.
source: <pull.2161.git.1782580676734.gitgitgadget@gmail.com>
* ps/t4216-tap-fix (2026-06-19) 1 commit
(merged to 'next' on 2026-06-25 at 42296fc12e)
+ t4216: fix no-op test that breaks TAP output
TAP output breakage fix.
cf. <xmqq8q82fk8r.fsf@gitster.g>
source: <20260619-pks-t4216-drop-unused-prereq-v1-1-2ce0d7bea088@pks.im>
--------------------------------------------------
[Stalled]
* jt/config-lock-timeout (2026-05-17) 1 commit
- config: retry acquiring config.lock, configurable via core.configLockTimeout
Configuration file locking now retries for a short period, avoiding
failures when multiple processes attempt to update the configuration
simultaneously.
Waiting for response(s) to review comment(s) for too long, stalled.
cf. <agrIrGwSMFlKTx9x@pks.im>
source: <20260517132111.1014901-1-joerg@thalheim.io>
* js/parseopt-subcommand-autocorrection (2026-04-27) 11 commits
- SQUASH???
- doc: document autocorrect API
- parseopt: add tests for subcommand autocorrection
- parseopt: enable subcommand autocorrection for git-remote and git-notes
- parseopt: autocorrect mistyped subcommands
- autocorrect: provide config resolution API
- autocorrect: rename AUTOCORRECT_SHOW to AUTOCORRECT_HINT
- autocorrect: use mode and delay instead of magic numbers
- help: move tty check for autocorrection to autocorrect.c
- help: make autocorrect handling reusable
- parseopt: extract subcommand handling from parse_options_step()
The parse-options library learned to auto-correct misspelled
subcommand names.
Waiting for response(s) to review comment(s) for too long, stalled.
cf. <xmqq33yzd9yf.fsf@gitster.g>
cf. <SY0P300MB0801E50FCB7EB2F45CD15208CE042@SY0P300MB0801.AUSP300.PROD.OUTLOOK.COM>
source: <SY0P300MB0801677A2A1E0FD38D06A841CE2A2@SY0P300MB0801.AUSP300.PROD.OUTLOOK.COM>
* cl/conditional-config-on-worktree-path (2026-05-24) 2 commits
- config: add "worktree" and "worktree/i" includeIf conditions
- config: refactor include_by_gitdir() into include_by_path()
The [includeIf "condition"] conditional inclusion facility for
configuration files has learned to use the location of worktree
in its condition.
Waiting for response(s) to review comment(s) for too long, stalled.
cf. <xmqq8q97et9b.fsf@gitster.g>
source: <20260525-includeif-worktree-v5-0-1efe525d025a@black-desk.cn>
--------------------------------------------------
[Cooking]
* ad/gpg-strip-cr-before-lf (2026-06-24) 1 commit
- gpg-interface: fix strip_cr_before_lf to only remove CR before LF
The GPG and SSH signature parsing code has been corrected to strip
carriage return characters only when they immediately precede line
feeds, instead of unconditionally stripping all carriage returns.
Needs review.
source: <20260624093618.17456-1-antonio.destefani08@gmail.com>
* jt/receive-pack-use-odb-transactions (2026-06-23) 6 commits
- builtin/receive-pack: stage incoming objects via ODB transactions
- odb/transaction: add transaction env interface
- odb/transaction: propagate commit errors
- odb/transaction: propagate begin errors
- object-file: propagate files transaction errors
- object-file: rename files transaction prepare function
git-receive-pack has been refactored to use ODB transaction
interfaces instead of directly managing tmp_objdir for staging
incoming objects, bringing it closer to being ODB backend agnostic.
Waiting for response(s) to review comment(s).
cf. <aju_AmlKVi5UZaiQ@pks.im>
source: <20260624041920.2601961-1-jltobler@gmail.com>
* ps/odb-drop-whence (2026-06-24) 7 commits
- odb: document object info fields
- odb: drop `whence` field from object info
- treewide: convert users of `whence` to the new source field
- odb: add `source` field to struct object_info_source
- odb: make backend-specific fields optional
- packfile: thread odb_source_packed through packed_object_info()
- Merge branch 'ps/odb-source-packed' into ps/odb-drop-whence
(this branch uses ps/odb-source-packed.)
The whence field in struct object_info has been removed,
refactoring backend-specific object information retrieval into an
opt-in struct object_info_source structure.
Needs review.
source: <20260624-b4-pks-odb-drop-whence-v1-0-8d1877b790ac@pks.im>
* ps/reftable-hardening (2026-06-29) 12 commits
- reftable/table: fix OOB read on truncated table
- reftable/table: fix NULL pointer access when seeking to bogus offsets
- reftable/block: fix OOB read with bogus restart offset
- reftable/block: fix use of uninitialized memory when binsearch fails
- reftable/block: fix OOB read with bogus restart count
- reftable/block: fix OOB read with bogus block size
- reftable/block: fix OOB write with bogus inflated log size
- t/unit-tests: introduce test helper to write reftable blocks
- reftable/record: don't abort when decoding invalid ref value type
- reftable/basics: fix OOB read on binary search of empty range
- oss-fuzz: add fuzzer for parsing reftables
- meson: support building fuzzers with libFuzzer
The reftable code has been hardened against corrupted tables by
fixing out-of-bounds writes, out-of-bounds reads, and abort calls
during parsing.
Needs review.
source: <20260629-pks-reftable-hardening-v2-0-b0228e7d908d@pks.im>
* hn/branch-push-slip-advice (2026-06-27) 2 commits
- push: suggest <remote> <branch> for a slash slip
- branch: suggest <remote>/<branch> on upstream slip
"git push origin/main" and "git branch origin main" could both be
an obvious typo, in which case offer the obvious typofix.
Will merge to 'next'?
cf. <xmqqfr272lq7.fsf@gitster.g>
source: <pull.2331.v3.git.git.1782583345.gitgitgadget@gmail.com>
* jc/history-message-prep-fix (2026-06-29) 1 commit
- history: streamline message preparation and plug file stream leak
Code clean-up with leakfix for a write file stream.
Needs review.
source: <xmqqmrwdxrat.fsf@gitster.g>
* ty/migrate-excludes-file (2026-06-27) 1 commit
- environment: move excludes_file into repo_config_values
Move excludes_file global variable into per-repository structure.
Waiting for response(s) to review comment(s).
cf. <xmqqbjcv2h3j.fsf@gitster.g>
cf. <CAP8UFD3Z0M_1NEXGcAxNZKpRUQiSkHZLTEvNNYushKA_PoPgjA@mail.gmail.com>
source: <20260627160813.1074201-2-cat@malon.dev>
* kk/merge-base-exhaustion (2026-06-28) 8 commits
- commit-reach: move min_generation check into paint_queue_get()
- commit-reach: terminate merge-base walk when one paint side is exhausted
- commit-reach: remove unused nonstale_queue dedup wrappers
- commit-reach: introduce struct paint_state with per-side counters
- commit-reach: add trace2 instrumentation to paint_down_to_common()
- t6099, t6600: add side-exhaustion regression tests
- t6600: add test cases for side-exhaustion edge cases
- Documentation/technical: add paint-down-to-common doc
The merge-base computation has been optimized by stopping the walk
early when one side's exclusive commits in the queue are exhausted,
yielding significant speedups for queries with one-sided histories.
Expecting a reroll.
cf. <48bfdb11-2624-4aa6-8fbd-d3f894c33bcc@gmail.com>
cf. <CAL71e4N92t8170UBW3rMA6B-rEUeOm-R_HSioB957mUKOpwRyQ@mail.gmail.com>
source: <pull.2149.v4.git.1782649547.gitgitgadget@gmail.com>
* dk/meson-enable-use-nsec-build (2026-06-20) 1 commit
- meson: wire up USE_NSEC build knob
The USE_NSEC build knob, which enables support for sub-second file
timestamp resolution, has been wired up to the Meson build system.
Waiting for response(s) to review comment(s).
cf. <ajjuoS5Qc3K0nCRl@pks.im>
cf. <akIL6oJgUv8J8SB2@pks.im>
source: <c4c5ade901ff95b0f95939ea818870e4f3d59da1.1781971201.git.ben.knoble+github@gmail.com>
* ps/connected-generic-promisor-checks (2026-06-25) 5 commits
(merged to 'next' on 2026-06-29 at 10eef65b98)
+ connected: search promisor objects generically
+ connected: split out promisor-based connectivity check
+ odb/source-packed: support flags when iterating an object prefix
+ odb/source-packed: extract logic to skip certain packs
+ Merge branch 'ps/odb-source-packed' into ps/connected-generic-promisor-checks
(this branch uses ps/odb-source-packed.)
The connectivity check has been refactored to search for promisor
objects in a generic way using the object database interface,
rather than iterating packfiles directly. This allows connectivity
checks to work properly in repositories that do not use packfiles.
Will merge to 'master'.
cf. <CAP8UFD07AzNtP3rRj4btYfFfakX0kkLXKpO9T=a3Mds3YWEsXw@mail.gmail.com>
source: <20260625-pks-connected-generic-promisor-checks-v3-0-7308f3b9dc44@pks.im>
* ps/libgit-in-subdir (2026-06-26) 4 commits
- fixup??? Move libgit.a sources into separate "lib/" directory
- Move libgit.a sources into separate "lib/" directory
- t/helper: prepare "test-example-tap.c" for introduction of "lib/"
- Merge branch 'ps/odb-source-packed' into ps/libgit-in-subdir
(this branch uses ps/odb-source-packed.)
The source files for libgit.a have been moved into a new "lib/"
directory to clean up the top-level directory and clearly separate
library code.
Waiting for response(s) to review comment(s).
cf. <32bb1cf6-1e37-dc0c-dfb2-e78a30763342@gmx.de>
cf. <xmqqwlvl6sr5.fsf@gitster.g>
cf. <aj9wcFEb6oCRnfn2@szeder.dev>
source: <20260622-pks-libgit-in-subdir-v2-0-cb946c51ee7b@pks.im>
* ps/odb-generalize-prepare (2026-06-22) 3 commits
- odb: introduce `odb_prepare()`
- odb/source: generalize `reprepare()` callback
- Merge branch 'ps/odb-source-packed' into ps/odb-generalize-prepare
(this branch uses ps/odb-source-packed.)
The `reprepare()` callback for object database sources has been
generalized into a `prepare()` callback with an optional flush cache
flag, and a new `odb_prepare()` wrapper has been introduced to
allow pre-opening object database sources.
Waiting for response(s) to review comment(s).
cf. <87ldc14i4n.fsf@emacs.iotcl.com>
source: <20260622-b4-pks-odb-generalize-prepare-v1-0-d2a5c5d13144@pks.im>
* jc/submittingpatches-design-critiques (2026-06-20) 1 commit
(merged to 'next' on 2026-06-22 at 7495b5f9d6)
+ SubmittingPatches: address design critiques
The documentation in SubmittingPatches has been updated to clarify how
patch contributors should respond to design and viability critiques,
and how the resolution of such critiques should be recorded in the
final commit messages.
Will cook in 'next'.
cf. <ajjwYGWZ6hQWr600@pks.im>
source: <xmqqeci0g4mz.fsf@gitster.g>
* wy/doc-clarify-review-replies (2026-06-21) 2 commits
(merged to 'next' on 2026-06-29 at 21ae0599dc)
+ doc: advise batching patch rerolls
+ doc: encourage review replies before rerolling
Documentation on community contribution guidelines has been updated to
encourage replying to review comments before rerolling, and to advise
a default limit of at most one reroll per day to give reviewers across
different time zones enough time to participate.
Will merge to 'master'.
cf. <ajvDuUiDsmyf5LnX@pks.im>
source: <cover.1782028813.git.wy@wyuan.org>
* ty/migrate-ignorecase (2026-06-19) 2 commits
- config: use repo_ignore_case() to access core.ignorecase
- environment: move ignore_case into repo_config_values
The global configuration variable ignore_case (representing the
core.ignorecase configuration) has been migrated into struct
repo_config_values to tie it to a specific repository instance.
Waiting for comments from Johannes.
cf. <xmqqzf0mzc7j.fsf@gitster.g>
source: <20260619155152.642760-1-cat@malon.dev>
* mm/line-log-limited-ops (2026-06-27) 7 commits
- diffcore-pickaxe: scope -G to the -L tracked range
- diff: support --check with -L line ranges
- line-log: support diff stat formats with -L
- diff: extract a line-range diff helper for reuse
- diff: emit -L hunk headers via xdiff's formatter
- diff: simplify the line-range filter by classifying removals immediately
- diff: rename and group the line-range filter for clarity
"git log -L<range>:<path>" learned to limit various "diff" operations
like --stat, --check, -G, to the specified range:path.
Needs review.
source: <pull.2152.v2.git.1782581342.gitgitgadget@gmail.com>
* hn/history-squash (2026-06-28) 4 commits
- history: re-edit a squash with every message
- history: add squash subcommand to fold a range
- history: give commit_tree_ext a message template
- history: extract helper for a commit's parent tree
The experimental "git history" command has been taught a new
"squash" subcommand to fold a range of commits into a single commit,
replaying any descendants on top.
Waiting for response(s) to review comment(s).
cf. <xmqqse65zyhw.fsf@gitster.g>
cf. <akIQLM6xZTHBudWT@pks.im>
source: <pull.2337.v6.git.git.1782635349.gitgitgadget@gmail.com>
* mh/fetch-follow-remote-head-config (2026-06-19) 8 commits
(merged to 'next' on 2026-06-22 at 423079e1c8)
+ fetch: fixup a misaligned comment
+ fetch: add configuration variable fetch.followRemoteHEAD
+ fetch: refactor do_fetch handling of followRemoteHEAD
+ fetch: return 0 on known git_fetch_config
+ fetch: rename function report_set_head
+ t5510: cleanup remote in followRemoteHEAD dangling ref test
+ doc: explain fetchRemoteHEADWarn advice
+ fetch: fixup set_head advice for warn-if-not-branch
The `fetch.followRemoteHEAD` configuration variable has been added to
provide a default for the per-remote `remote.<name>.followRemoteHEAD`
setting.
Will cook in 'next'.
cf. <xmqqcxxp1j2t.fsf@gitster.g>
source: <20260619094751.2996804-1-m@lfurio.us>
* ps/refs-writing-subcommands (2026-06-17) 5 commits
- builtin/refs: add "rename" subcommand
- builtin/refs: add "create" subcommand
- builtin/refs: add "update" subcommand
- builtin/refs: add "delete" subcommand
- builtin/refs: drop `the_repository`
The "git refs" toolbox has been extended with new "create", "delete",
"update", and "rename" subcommands to create, delete, update, and
rename references, respectively.
Needs review.
source: <20260617-pks-refs-writing-subcommands-v2-0-07f3d18336f9@pks.im>
* po/hash-object-size-t (2026-06-16) 6 commits
(merged to 'next' on 2026-06-21 at b780a276b9)
+ hash-object: add a >4GB/LLP64 test case using filtered input
+ hash-object: add another >4GB/LLP64 test case
+ hash-object --stdin: verify that it works with >4GB/LLP64
+ hash algorithms: use size_t for section lengths
+ object-file.c: use size_t for header lengths
+ hash-object: demonstrate a >4GB/LLP64 problem
Support for hashing loose or packed objects larger than 4GB on Windows
and other LLP64 platforms has been improved by converting object header
buffers and data-handling functions from 'unsigned long' to 'size_t'.
Will cook in 'next'.
cf. <ajOQthRjhD3hRM9w@pks.im>
source: <pull.2138.v2.git.1781621398.gitgitgadget@gmail.com>
* kh/submittingpatches-trailers (2026-06-18) 5 commits
(merged to 'next' on 2026-06-22 at 2cd4a152c9)
+ SubmittingPatches: note that trailer order matters
+ SubmittingPatches: be consistent with trailer markup
+ SubmittingPatches: document Based-on-patch-by trailer
+ SubmittingPatches: discourage common Linux trailers
+ SubmittingPatches: encourage trailer use for substantial help
The trailer sections in SubmittingPatches have been updated to
encourage use of standard trailers.
Will cook in 'next'.
cf. <xmqq4ij0vo8f.fsf@gitster.g>
source: <V3_CV_SubPatches_trailers.9ec@msgid.xyz>
* mv/log-follow-mergy (2026-06-21) 1 commit
(merged to 'next' on 2026-06-22 at f7e984a003)
+ log: improve --follow following renames for non-linear history
"git log --follow" has been updated to handle non-linear history, in
which the path being tracked gets renamed differently in multiple
history lines, better.
Will cook in 'next'.
source: <ajjU4w2B0NlZffw1@collabora.com>
* wy/doc-myfirstcontribution-trim-quotes (2026-06-11) 1 commit
- MyFirstContribution: mention trimming quoted text in replies
The contributor guide has been updated to advise new contributors to
trim irrelevant quoted text when replying to review comments, matching
the existing advice given to reviewers.
Comments?
cf. <xmqqcxxwljue.fsf@gitster.g>
source: <080402ff0ac8127b654dccea59a1bf643df62a5c.1781186476.git.wy@wyuan.org>
* tb/midx-incremental-custom-base (2026-06-12) 3 commits
- midx-write: include packs above custom incremental base
- midx: pass custom '--base' through incremental writes
- t5334: expose shared `nth_line()` helper
The `git multi-pack-index write --incremental` command has been
corrected to properly honor the `--base` option. Previously, the
custom base was ignored by the normal write path, and the pack
exclusion logic incorrectly skipped packs from layers above the
selected base, breaking reachability closure for bitmaps.
Needs review.
source: <cover.1781294771.git.me@ttaylorr.com>
* mm/test-grep-lint (2026-06-12) 6 commits
- t: add greplint to detect bare grep assertions
- t: convert grep assertions to test_grep
- t: fix Lexer line count for $() inside double-quoted strings
- t: extract chainlint's parser into shared module
- t: fix grep assertions missing file arguments
- t/README: document test_grep helper
Waiting for response(s) to review comment(s).
cf. <aj93BE8MYatQAjoy@szeder.dev>
source: <pull.2135.v2.git.1781323575.gitgitgadget@gmail.com>
* rs/cat-file-default-format-optim (2026-06-14) 1 commit
(merged to 'next' on 2026-06-17 at 43ed8b3969)
+ cat-file: speed up default format
Will cook in 'next'.
cf. <20260615165326.GA91269@coredump.intra.peff.net>
source: <5a7ed929-6fe0-496c-83bd-65dee57c2241@web.de>
* kk/prio-queue-get-put-fusion (2026-06-08) 2 commits
- prio-queue: fold lazy_queue into prio_queue for automatic get+put fusion
- prio-queue: rename .nr to .nr_ and add accessor helpers
The lazy priority queue optimization pattern (deferring actual removal
in prio_queue_get() to allow get+put fusion) has been folded directly
into prio_queue itself, speeding up commit traversal workflows and
simplifying callers.
On hold, waiting for kk/prio-queue-get-put-fusion to land first.
cf. <CAL71e4MYNiScZjTwkApjDAjRh2LM0_SP59h5HCTywV-Pua03tw@mail.gmail.com>
source: <pull.2140.v4.git.1780945851.gitgitgadget@gmail.com>
* td/ref-filter-memoize-contains (2026-06-12) 3 commits
- commit-reach: die on contains walk errors
- ref-filter: memoize --contains with generations
- commit-reach: reject cycles in contains walk
'git branch --contains' and 'git for-each-ref --contains' have
been optimized to use the memoized commit traversal previously
used only by 'git tag --contains', significantly speeding up
connectivity checks across many candidate refs with shared
history.
Needs review.
source: <20260612-ref-filter-memoized-contains-v4-0-5ed39fd001dd@gmail.com>
* tc/replay-linearize (2026-06-25) 3 commits
- replay: offer an option to linearize the commit topology
- replay: better explain how pick_regular_commit() picks a base
- replay: add helper to put entry into mapped_commits
git replay learns --linearize option to drop merge commits and
linearize the replayed history, mimicking git rebase
--no-rebase-merges.
Waiting for response(s) to review comment(s).
cf. <xmqq5x358byf.fsf@gitster.g>
cf. <b5d70a0b-ef32-49c9-84ba-8a64b7809574@gmail.com>
cf. <f8b520d1-edeb-9e45-c503-025c8b5833c3@gmx.de>
source: <20260626-toon-git-replay-drop-merges-v5-0-5e120738b9d0@iotcl.com>
* ps/setup-drop-global-state (2026-06-10) 8 commits
(merged to 'next' on 2026-06-15 at d9a8b88d47)
+ treewide: drop USE_THE_REPOSITORY_VARIABLE
+ environment: stop using `the_repository` in `is_bare_repository()`
+ environment: split up concerns of `is_bare_repository_cfg`
+ builtin/init: stop modifying `is_bare_repository_cfg`
+ setup: remove global `git_work_tree_cfg` variable
+ builtin/init: simplify logic to configure worktree
+ builtin/init: stop modifying global `git_work_tree_cfg` variable
+ Merge branch 'ps/setup-centralize-odb-creation' into ps/setup-drop-global-state
Continuation of "setup.c" refactoring to drop remaining global state
(`git_work_tree_cfg`, `is_bare_repository_cfg`). The most notable
outcome is that `is_bare_repository()` has been updated to no longer
implicitly rely on `the_repository`.
Will cook in 'next'.
cf. <airVOrTboNDDGBak@denethor>
cf. <87ldckyygk.fsf@emacs.iotcl.com>
source: <20260611-b4-pks-setup-drop-global-state-v2-0-a6f7269c841d@pks.im>
* ps/refs-onbranch-fixes (2026-06-25) 12 commits
(merged to 'next' on 2026-06-29 at 7b4929e311)
+ refs: protect against chicken-and-egg recursion
+ refs/reftable: lazy-load configuration to fix chicken-and-egg
+ reftable: split up write options
+ refs/files: lazy-load configuration to fix chicken-and-egg
+ refs: move parsing of "core.logAllRefUpdates" back into ref stores
+ repository: free main reference database
+ chdir-notify: drop unused `chdir_notify_reparent()`
+ refs: unregister reference stores from "chdir_notify"
+ setup: don't apply "GIT_REFERENCE_BACKEND" without a repository
+ setup: stop applying repository format twice
+ setup: inline `check_and_apply_repository_format()`
+ Merge branch 'ps/setup-centralize-odb-creation' into ps/refs-onbranch-fixes
Reference backend configuration is now loaded lazily to avoid
recursive calls during repository initialization when "onbranch"
configuration conditions are evaluated. This also fixes a memory
leak and allows dropping the unused `chdir_notify_reparent()`
machinery.
Will merge to 'master'.
cf. <xmqqse6ae45i.fsf@gitster.g>
source: <20260625-b4-pks-refs-avoid-chdir-notify-reparent-v6-0-41fbca3cf5e3@pks.im>
* ps/odb-source-packed (2026-06-16) 18 commits
(merged to 'next' on 2026-06-19 at dcf0c084e4)
+ odb/source-packed: drop pointer to "files" parent source
+ midx: refactor interfaces to work on "packed" source
+ odb/source-packed: stub out remaining functions
+ odb/source-packed: wire up `freshen_object()` callback
+ odb/source-packed: wire up `find_abbrev_len()` callback
+ odb/source-packed: wire up `count_objects()` callback
+ odb/source-packed: wire up `for_each_object()` callback
+ odb/source-packed: wire up `read_object_stream()` callback
+ odb/source-packed: wire up `read_object_info()` callback
+ packfile: use higher-level interface to implement `has_object_pack()`
+ odb/source-packed: wire up `reprepare()` callback
+ odb/source-packed: wire up `close()` callback
+ odb/source-packed: start converting to a proper `struct odb_source`
+ odb/source-packed: store pointer to "files" instead of generic source
+ packfile: move packed source into "odb/" subsystem
+ packfile: split out packfile list logic
+ packfile: rename `struct packfile_store` to `odb_source_packed`
+ Merge branch 'ps/odb-source-loose' into ps/odb-source-packed
(this branch is used by ps/connected-generic-promisor-checks, ps/libgit-in-subdir, ps/odb-drop-whence and ps/odb-generalize-prepare.)
The packed object source has been refactored into a proper struct
odb_source.
Will cook in 'next'.
cf. <ajK2QKdW-TdflfR0@denethor>
source: <20260617-pks-odb-source-packed-v3-0-b5c7583cd795@pks.im>
* td/ref-filter-restore-prefix-iteration (2026-06-12) 1 commit
(merged to 'next' on 2026-06-19 at a19dbb4193)
+ ref-filter: restore prefix-scoped iteration
Commands that list branches and tags (like git branch and git tag)
have been optimized to pass the namespace prefix when initializing
their ref iterator, avoiding a loose-ref scaling regression in
repositories with many unrelated loose references.
Will cook in 'next'.
cf. <xmqqik7fsv2m.fsf@gitster.g>
source: <20260612-fix-git-branch-regression-v4-1-f150038c02f4@gmail.com>
* ty/move-protect-hfs-ntfs (2026-06-20) 2 commits
(merged to 'next' on 2026-06-20 at d8ca0d5180)
+ environment: use 'repo->initialized' for repo_protect_hfs() and repo_protect_ntfs()
(merged to 'next' on 2026-06-15 at c2a30ca954)
+ environment: move 'protect_hfs' and 'protect_ntfs' into 'repo_config_values'
The global configuration variables protect_hfs and protect_ntfs have
been migrated into struct repo_config_values to tie them to
per-repository configuration state.
Will cook in 'next'.
cf. <CAP8UFD35Tiy1_fqpjq8P-z=ZhzR3MTiThqfCs977652umRoSEQ@mail.gmail.com>
cf. <xmqqse6uwdnz.fsf@gitster.g>
source: <20260610124353.149874-2-cat@malon.dev>
source: <20260620140957.667820-1-cat@malon.dev>
* ps/cat-file-remote-object-info (2026-06-25) 13 commits
- cat-file: make remote-object-info allow-list dynamic
- cat-file: validate remote atoms with allow_list
- cat-file: add remote-object-info to batch-command
- transport: add client support for object-info
- serve: advertise object-info feature
- fetch-pack: move fetch initialization
- connect: refactor packet writing
- fetch-pack: move function to connect.c
- fetch-pack: prepare function to be moved
- t1006: split test utility functions into new "lib-cat-file.sh"
- cat-file: declare loop counter inside for()
- git-compat-util: add strtoul_szt() with error handling
- transport-helper: fix memory leak of helper on disconnect
The `remote-object-info` command has been added to `git cat-file
--batch-command`, allowing clients to request object metadata
(currently size) from a remote server via protocol v2 without
downloading the entire object.
The client dynamically filters format placeholders based on
server-advertised capabilities and safely returns empty strings for
inapplicable or unsupported fields.
Waiting for response(s) to review comment(s).
cf. <CAOLa=ZScS3Gmm5BAgJF69phpaDXGnP_j9jx+bMhn_tfF65RXEg@mail.gmail.com>
source: <20260625-ps-eric-work-rebase-v14-0-09f7ffe21a53@gmail.com>
* ap/http-redirect-wwwauth-fix (2026-06-02) 1 commit
- http: preserve wwwauth_headers across redirects
When cURL follows a redirect, the WWW-Authenticate headers from the
redirect target were lost because credential_from_url() cleared the
credential state. This has been fixed by preserving the collected
headers across the redirect update.
Expecting a reroll.
cf. <5144a29d-a53f-4446-beff-e1f549345bf9@nvidia.com>
source: <20260602161150.1527493-1-aplattner@nvidia.com>
* ps/doc-recommend-b4 (2026-06-15) 3 commits
(merged to 'next' on 2026-06-17 at dd9a463369)
+ b4: introduce configuration for the Git project
+ MyFirstContribution: recommend the use of b4
+ MyFirstContribution: recommend shallow threading of cover letters
Project-specific configuration for b4 has been introduced, and the
documentation has been updated to recommend using it as a
streamlined method for submitting patches.
Will cook in 'next'.
cf. <87eci7yomp.fsf@emacs.iotcl.com>
source: <20260615-pks-b4-v4-0-22cfca8f19c5@pks.im>
* sn/rebase-update-refs-symrefs (2026-06-03) 1 commit
- rebase: skip branch symref aliases
"git rebase --update-refs" has been taught to resolve local branch
symrefs to their referents before queuing updates. This correctly
skips aliases of the current branch and avoids duplicate updates for
underlying real branches, fixing failures when branch aliases (like a
default branch rename) are present.
Waiting for response(s) to review comment(s).
cf. <f982c386-e329-4ab0-b695-e540bcb9de3d@gmail.com>
source: <pull.2126.v2.git.1780482436865.gitgitgadget@gmail.com>
* mm/diff-process-hunks (2026-06-14) 6 commits
- blame: consult diff process for no-hunk detection
- diff: bypass diff process with --no-ext-diff and in format-patch
- diff: add long-running diff process via diff.<driver>.process
- sub-process: separate process lifecycle from hashmap management
- userdiff: add diff.<driver>.process config
- xdiff: support external hunks via xpparam_t
A new `diff.<driver>.process` configuration has been introduced to
allow a long-running external process to act as a hunk provider to
allows external tools to control which lines Git considers changed
while leaving all output formatting (word diff, color, blame, etc.) to
Git's standard pipeline.
Expecting a reroll.
cf. <CAC2Qwm+P=fZOtpfMPeMiSXf3Afk6OLYpTP8Br78_PRA8WNL1Wg@mail.gmail.com>
source: <pull.2120.v4.git.1781463564.gitgitgadget@gmail.com>
* tb/pack-path-walk-bitmap-delta-islands (2026-06-21) 5 commits
(merged to 'next' on 2026-06-22 at 59cf1663e7)
+ pack-objects: support `--delta-islands` with `--path-walk`
+ pack-objects: extract `record_tree_depth()` helper
+ pack-objects: support reachability bitmaps with `--path-walk`
+ t/perf: drop p5311's lookup-table permutation
+ Merge branch 'ds/path-walk-filters' into tb/pack-path-walk-bitmap-delta-islands
The pack-objects command now supports using reachability bitmaps and
delta-islands concurrently with the `--path-walk` option, allowing
faster packaging by falling back to path-walk when bitmaps cannot
fully satisfy the request.
Will cook in 'next'.
cf. <xmqqwlvq1qyy.fsf@gitster.g>
source: <cover.1782082975.git.me@ttaylorr.com>
* ty/migrate-trust-executable-bit (2026-06-19) 3 commits
- environment: move trust_executable_bit into repo_config_values
- read-cache: move 'ce_mode_from_stat()' to 'read-cache.c'
- read-cache: remove redundant extern declarations
The 'trust_executable_bit' (coming from 'core.filemode'
configuration) has been migrated into 'repo_config_values' to tie it
to a specific repository instance.
Needs review.
source: <20260619162105.648495-1-cat@malon.dev>
* kk/prio-queue-cascade-sift (2026-06-01) 1 commit
- prio-queue: use cascade-down for faster extract-min
prio_queue_get() has been optimized by using a cascade-down approach
(promoting the smaller child at each level and sifting up the last
element from the leaf vacancy), which halves the number of comparisons
per extract-min operation in the common case.
On hold, waiting for kk/prio-queue-get-put-fusion to land first.
cf. <CAL71e4MYNiScZjTwkApjDAjRh2LM0_SP59h5HCTywV-Pua03tw@mail.gmail.com>
source: <pull.2132.v2.git.1780301856444.gitgitgadget@gmail.com>
* jk/repo-info-path-keys (2026-06-23) 3 commits
(merged to 'next' on 2026-06-29 at fbf9652169)
+ repo: add path.gitdir with absolute and relative suffix formatting
+ repo: add path.commondir with absolute and relative suffix formatting
+ path: extract format_path() and use in rev-parse
The "git repo info" command has been taught new keys to output both
absolute and relative paths for "gitdir" and "commondir", supported by
a new path-formatting helper extracted from "git rev-parse".
Will merge to 'master'.
cf. <xmqqy0g3iz38.fsf@gitster.g>
source: <20260624033748.108281-1-jayatheerthkulkarni2005@gmail.com>
* ps/history-drop (2026-06-29) 11 commits
- builtin/history: implement "drop" subcommand
- builtin/history: split handling of ref updates into two phases
- replay: expose `replay_result_queue_update()`
- reset: stop assuming that the caller passes in a clean index
- reset: allow the caller to specify the current HEAD object
- reset: introduce ability to skip updating HEAD
- reset: introduce dry-run mode
- reset: modernize flags passed to `reset_working_tree()`
- reset: rename `reset_head()`
- reset: drop `USE_THE_REPOSITORY_VARIABLE`
- read-cache: split out function to drop unmerged entries to stage 0
The experimental "git history" command has been taught a new "drop"
subcommand to remove a commit and replay its descendants onto its
parent.
Needs review.
source: <20260629-b4-pks-history-drop-v7-0-6e9392a957d8@pks.im>
* jk/setup-gitfile-diag-fix (2026-06-16) 1 commit
(merged to 'next' on 2026-06-18 at b63b3d1f25)
+ read_gitfile(): simplify NOT_A_REPO error message
A regression in the error diagnosis code for invalid .git files has
been fixed, avoiding a potential NULL-pointer crash when reporting
that a .git file does not point to a valid repository.
Will cook in 'next'.
cf. <xmqqjyry4hax.fsf@gitster.g>
source: <20260616123516.GA2301231@coredump.intra.peff.net>
* kh/doc-trailers (2026-06-10) 10 commits
- doc: interpret-trailers: document comment line treatment
- doc: interpret-trailers: commit to “trailer block” term
- doc: interpret-trailers: join new-trailers again
- doc: interpret-trailers: add key format example
- doc: interpret-trailers: explain key format
- doc: interpret-trailers: explain the format after the intro
- doc: interpret-trailers: not just for commit messages
- doc: interpret-trailers: use “metadata” in Name as well
- doc: interpret-trailers: replace “lines” with “metadata”
- doc: interpret-trailers: stop fixating on RFC 822
Documentation updates.
Expecting a reroll.
cf. <729baf6b-53ea-4e8d-95ab-5935667e66c2@app.fastmail.com>
source: <V3_CV_doc_int-tr_key_format.8a3@msgid.xyz>
* za/completion-hide-dotfiles (2026-06-20) 2 commits
- completion: hide dotfiles by default for path completion
- completion: hide dotfiles for selected path completion
The path completion for commands like `git rm` and `git mv`, is being
updated to hide dotfiles by default, unless the user explicitly starts
the path with a dot, matching standard shell-completion behavior.
Waiting for response(s) to review comment(s).
cf. <xmqq1pe0g08t.fsf@gitster.g>
cf. <xmqqbjd37i4y.fsf@gitster.g>
source: <pull.2311.v3.git.git.1781978156.gitgitgadget@gmail.com>
* ec/commit-fixup-options (2026-05-26) 2 commits
- commit: allow -c/-C for all kinds of --fixup
- commit: allow -m/-F for all kinds of --fixup
The -m/-F/-c/-C options to supply commit log message from outside the
editor are now supported for all "git commit --fixup" variations.
Needs review.
source: <cover.1779792311.git.erik@cervined.in>
* kh/doc-replay-config (2026-06-05) 4 commits
- doc: replay: move “default” to the right-hand side
- doc: replay: use a nested description list
- doc: replay: improve config description
- doc: link to config for git-replay(1)
Doc update for "git replay" to actually refer to its configuration
variables.
Needs review.
source: <V3_CV_doc_replay_config.780@msgid.xyz>
* hn/status-pull-advice-qualified (2026-05-21) 1 commit
(merged to 'next' on 2026-06-15 at 898a4df940)
+ remote: qualify "git pull" advice for non-upstream compareBranches
Advice shown by "git status" when the local branch is behind or has
diverged from its push branch has been updated to suggest "git pull
<remote> <branch>".
Will cook in 'next'.
cf. <xmqq7bo6xuok.fsf@gitster.g>
source: <pull.2301.v4.git.git.1779372367317.gitgitgadget@gmail.com>
* hn/branch-delete-merged (2026-06-24) 7 commits
- branch: add --dry-run for --delete-merged
- branch: add branch.<name>.deleteMerged opt-out
- branch: add --delete-merged <branch>
- branch: prepare delete_branches for a bulk caller
- branch: let delete_branches skip unmerged branches on bulk refusal
- branch: convert delete_branches() to a flags argument
- branch: add --forked filter for --list mode
"git branch" command learned "--delete-merged" option to remove
local branches that have already been merged to the remote-tracking
branches they track.
Needs review.
source: <pull.2285.v18.git.git.1782338106.gitgitgadget@gmail.com>
* cc/promisor-auto-config-url-more (2026-05-27) 8 commits
(merged to 'next' on 2026-06-15 at d1c99e75cc)
+ doc: promisor: improve acceptFromServer entry
+ promisor-remote: auto-configure unknown remotes
+ promisor-remote: trust known remotes matching acceptFromServerUrl
+ promisor-remote: introduce promisor.acceptFromServerUrl
+ promisor-remote: add 'local_name' to 'struct promisor_info'
+ urlmatch: add url_normalize_pattern() helper
+ urlmatch: change 'allow_globs' arg to bool
+ t5710: simplify 'mkdir X' followed by 'git -C X init'
The handling of promisor-remote protocol capability has been
loosened to allow the other side to add to the list of promisor
remotes via the promisor.acceptFromServerURL configuration
variable.
Will cook in 'next'.
cf. <877bo7294j.fsf@emacs.iotcl.com>
cf. <xmqqh5naxwfc.fsf@gitster.g>
source: <20260527140820.1438165-1-christian.couder@gmail.com>
* hn/checkout-track-fetch (2026-06-24) 2 commits
- checkout: extend --track with a "fetch" mode to refresh start-point
- branch: expose helpers for finding the remote owning a tracking ref
"git checkout --track=..." learned to optionally fetch the branch
from the remote the new branch will work with.
Waiting for response(s) to review comment(s).
cf. <12998c3a-ff69-4a98-9ed6-18aa0224e75e@gmail.com>
cf. <CAL71e4MiijEiM26TKJcOYT7L4pfQeMM_F2oT3U3igP-wOZm2Ag@mail.gmail.com>
source: <pull.2281.v15.git.git.1782338098.gitgitgadget@gmail.com>
* en/ort-harden-against-corrupt-trees (2026-06-13) 5 commits
(merged to 'next' on 2026-06-18 at e51bee59ca)
+ cache-tree: fix verify_cache() to catch non-adjacent D/F conflicts
+ merge-ort: abort merge when trees have duplicate entries
+ merge-ort: free diff pairs queue in clear_or_reinit_internal_opts()
+ merge-ort: drop unnecessary show_all_errors from collect_merge_info()
+ merge-ort: propagate callback errors from traverse_trees_wrapper()
"ort" merge backend handles merging corrupt trees better by
aborting when it should.
Will cook in 'next'.
cf. <xmqq5x3ldu4h.fsf@gitster.g>
source: <pull.2096.v2.git.1781419047.gitgitgadget@gmail.com>
* pw/status-rebase-todo (2026-06-23) 2 commits
(merged to 'next' on 2026-06-23 at a0fcde09dc)
+ status: improve rebase todo list parsing
+ sequencer: factor out parsing of todo commands
The display of the rebase todo list in "git status" has been
improved to correctly abbreviate object IDs for more commands and
avoid misinterpreting refs as object IDs.
Will cook in 'next'.
source: <cover.1782230024.git.phillip.wood@dunelm.org.uk>
* ps/shift-root-in-graph (2026-06-20) 3 commits
- graph: indent visual root in graph
- revision: add peek functions for lookahead
- lib-log-graph: move check_graph function
"git log --graph" has been modified to visually distinguish
parentless "root" commits (and commits that become roots due to
history simplification) by indenting them, preventing them from
appearing falsely related to unrelated commits rendered immediately
above them.
Waiting for response(s) to review comment(s).
The peek-ahead approach may need to be scratched.
cf. <CAN5EUNSj-2hkEBF7N_M6RLsuujDNFNUF3w53zR7SN1_5i2BRyg@mail.gmail.com>
cf. <CAL71e4OQ_kGb+UwHgikHG236-8BVtc7P9OdpV4i4UzYRCoPczw@mail.gmail.com>
source: <20260620-ps-pre-commit-indent-v6-0-cdc6d8fd5fbc@gmail.com>
^ permalink raw reply
* Re: [PATCH 4/6] treewide: convert users of `whence` to the new source field
From: Justin Tobler @ 2026-06-29 17:55 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <20260624-b4-pks-odb-drop-whence-v1-4-8d1877b790ac@pks.im>
On 26/06/24 02:19PM, Patrick Steinhardt wrote:
> The `whence` field has become redundant now that callers can learn about
> the exact source an object has been looked up from via the `struct
> object_info_source::source` field.
>
> Adapt callers to use the new field. Note that all callsites already set
> up the `info.sourcep` request pointer, so the conversion is rather
> straight-forward.
Ok, looks like we only adapt the callers here in this patch. I'm
guessing a subsequent patch will do the remaining cleanup.
Looking good.
-Justin
^ permalink raw reply
* Re: [PATCH 5/6] odb: drop `whence` field from object info
From: Justin Tobler @ 2026-06-29 17:57 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <20260624-b4-pks-odb-drop-whence-v1-5-8d1877b790ac@pks.im>
On 26/06/24 02:19PM, Patrick Steinhardt wrote:
> In the preceding commits we have migrated all callers to derive their
> information of how a specific object is stored to use the new object
> info source instead, and hence the field is now unused. Drop it.
Makes sense.
> Signed-off-by: Patrick Steinhardt <ps@pks.im>
> ---
[snip]
> diff --git a/odb.h b/odb.h
> index 330a55879e..e0d05eaf87 100644
> --- a/odb.h
> +++ b/odb.h
> @@ -311,13 +311,6 @@ struct object_info {
> * or multiple times in the same source.
> */
> struct object_info_source *sourcep;
> -
> - /* Response */
> - enum {
> - OI_CACHED,
> - OI_LOOSE,
> - OI_PACKED,
> - } whence;
> };
Nice. This patch also looks good.
-Justin
^ permalink raw reply
* Re: [PATCH v5 0/4] history: add squash subcommand to fold a range
From: Harald Nordgren @ 2026-06-29 18:03 UTC (permalink / raw)
To: Phillip Wood
Cc: Patrick Steinhardt, phillip.wood,
Harald Nordgren via GitGitGadget, git
In-Reply-To: <3b3af3ef-a043-4af9-964e-429237789c97@gmail.com>
> So instead of
>
> # This is the combination of 4 commits
> # This is the first commit message
> Base subject
>
> Base body
>
> # This is the second commit message
> # Another subject
>
> # Another body
>
> # This is the third commit message
> # fixup! Base subject
>
> # This is the fourth commit message
> # amend! Another subject
> A better subject
>
> A better body
>
> We'd have
>
> # This is the combination of 4 commits
> # 123 Base subject
> # 456 Another subject
> # 789 fixup! Base subject
> # abc amend! Another subject
>
> Base Subject
>
> Base Body
>
> Another subject
>
> Another Body
I think this makes it a lot harder to read. If every commit body was
always just a single paragraph it could make sense, but it's generally
not. Look at the commits in this series, with no delimiter of where
one commit message ends and the next one starts, it would be very
confusing.
> It would be good to error out if the user tries squash a fixup! style
> commit and range does not contain its target commit.
Good point, I don't see a good reason to allow this.
> There does seem to be some support for merges in this patch series which
> I think behaves pretty sensibly. If we have
>
> C - D
> / \
> - A - B - E - F - G
>
> Then squashing A..G should be fine because the parents of F are in the
> range and it looks like we support that. Squashing should B..G without
> --ancestry-path should be safe as well because B ends up as the parent
> of the squashed commit but we don't have a way to disable
> --ancestry-path (and maybe we don't want to add one). Squashing F^@..G
> might be useful to fixup a merge (though perhaps amending F rather than
> creating G is a simpler way to fix a broken merge). Squashing E..G does
> not make sense because the range does not include one of the merge parents.
Thanks for a good explanation here!
Harald
^ permalink raw reply
* Re: [PATCH 1/6] object-file: rename files transaction prepare function
From: Justin Tobler @ 2026-06-29 18:11 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, ps
In-Reply-To: <xmqqse6biyma.fsf@gitster.g>
On 26/06/24 11:26AM, Junio C Hamano wrote:
> Justin Tobler <jltobler@gmail.com> writes:
>
> > The "files" ODB transaction backend lazily creates a temporary object
> > directory when the first loose object is written to the transaction via
> > `prepare_loose_object_transaction()`. In a subsequent commit, the
> > temporary directory is used to also write packfiles to.
> >
> > Rename the function to `odb_transaction_files_prepare()` accordingly.
>
> Taken by itself this renaming does make sense, but there are many
> other function that follow the historical naming convention, like
> {fsync,flush}_loose_object_transaction(). Should we rename them for
> consistency with the new naming scheme, not necessarily as part of
> this series but with a todo comment to do so once the dust settles,
> or something?
Ya, both {fsync,flush}_loose_object_transaction() are probably good
candidates to be renamed to odb_transaction_files_{flush,flush} also. In
the next version, I'll probably add another patch to do so accordingly.
-Justin
^ permalink raw reply
* [ANNOUNCE] Git for Windows 2.55.0
From: Johannes Schindelin @ 2026-06-29 18:26 UTC (permalink / raw)
To: git, git-packagers
Dear Git users,
I hereby announce that Git for Windows 2.55.0 is available from:
https://gitforwindows.org/
Changes since Git for Windows v2.54.0 (April 20th 2026)
Following the MSYS2 project, on which Git for Windows is based, Windows
8.1 support will be dropped after Git for Windows v2.55.
New Features
* Comes with Git v2.55.0.
* Comes with the MSYS2 runtime (Git for Windows flavor) based on
Cygwin v3.6.9.
* Comes with Git Credential Manager v2.8.0.
* Comes with less 702.
* The FSCache now accelerates more git add scenarios.
* Comes with OpenSSL v3.5.7.
* The diff helper handling Word documents was ported from Perl to
Rust.
* Comes with Bash v5.3.15.
* Comes with cURL v8.21.0.
Bug Fixes
* A regression in v2.54.0 that could cause endless "Unlink of file
'.git/objects/pack/pack-.idx' failed. Should I try again?" loops on
older Windows 10 versions during git fetch operations was fixed.
* A bug that prevented proper shutdown of processes launched via Git
Bash under certain circumstances was fixed.
* A bug was fixed which could cause parallel checkouts to fail under
certain circumstances when the FSCache is enabled.
* Git Bash (MinTTY) now respects screen scaling settings under more
circumstances.
* A couple of bugs revolving around very large clones/packfiles/
objects were fixed.
* Following TortoiseGit v2.19, .git file validations have been
tightened. As a consequence, access to remote repositories via UNC
file paths needs to be allowed explicitly via the safe.directory
configuration.
Git-2.55.0-64-bit.exe | 0c66e4a5875da5a74f9754386de7555ba301503b03bbdcdbafa69dc6464e548d
Git-2.55.0-arm64.exe | 1c28f00262df9e2721036492d5e206862420325516a9a074d3fec1b9f44431d8
PortableGit-2.55.0-64-bit.7z.exe | dfa8cad3ce7e685b9bfbbb2125afcf7c68d4f53490426702ffac367dac62e928
PortableGit-2.55.0-arm64.7z.exe | b1fe421482c6e5a1aa1135406d7eeb89adf5436b3e5af183cdcd6ffe3c6bc8f2
MinGit-2.55.0-64-bit.zip | 31497e7968196332263459ee319d2524e3ebc5786ab895e2abad34ffdd4f4ebf
MinGit-2.55.0-arm64.zip | 377e283290e2de455cdd5cdbd99653bd911db752a8986d1ad914a5ac2fbd1192
MinGit-2.55.0-32-bit.zip | 04e432c04015e07fc01f3fd2d1b2e1d5c3340e44ba1ebb88dd2397a28444f2ae
MinGit-2.55.0-busybox-64-bit.zip | c6e2825dbb596afc89f27e205b4c3d573c3533f7f8c2fd2c1e02baaaaabf219b
MinGit-2.55.0-busybox-32-bit.zip | 393405be25c80aa3825a556f9ab94f85344ac199bdac10f7e02d6a3ecc5d89bf
Git-2.55.0-64-bit.tar.bz2 | 25bc3235291249f39bd463cd9fb86d9b4295b19d53d81af0238414bc68e16110
Git-2.55.0-arm64.tar.bz2 | 440998321e239588588ce5c8df1a45ffe99551691ac47d148dbbdae76776b582
Ciao,
Johannes
^ permalink raw reply
* Re: [PATCH 0/2] commit-reach: fix !FIND_ALL early exit with v1 commit graph
From: Kristofer Karlsson @ 2026-06-29 18:27 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Kristofer Karlsson via GitGitGadget, git, Derrick Stolee
In-Reply-To: <xmqqldbxw81i.fsf@gitster.g>
On Mon, 29 Jun 2026 at 19:50, Junio C Hamano <gitster@pobox.com> wrote:
>
> Where should this new "gen_ordered" flag go in the world with
> kk/merge-base-exhaustion topic merged in? Does it also belong
> to the paint_state struct or can it be on-stack independent variable
> to the function?
I don't think kk/merge-base-exhaustion is ready to be merged as-is
and you are right that these two topics would conflict.
I will need to reroll v5 and exactly how/when I do that
depends on what we do here.
I wanted to quickly share this small patch as a bugfix
since the related code is already merged. I think the bug
itself might be a very unlikely edge case but I can't really be
sure.
My preference would be to merge this as-is, and then I can rework
v5 of kk/merge-base-exhaustion on top of it later - it will
add some delay but I don't want to rush it since it's a non-trivial
change.
The other option is to drop this topic if the risk is deemed low
enough, and then I will rework v5 to either apply a similar
gen_ordered flag or eliminate that different ordering entirely -
I see that as a good long-term goal that simplifies the code while
retaining or improving the performance.
I realize the timing is terrible, I wish I had spotted this a week
ago instead of right at the 2.55 finalization period.
Thanks,
Kristofer
^ permalink raw reply
* Re: [PATCH 0/2] commit-reach: fix !FIND_ALL early exit with v1 commit graph
From: Junio C Hamano @ 2026-06-29 18:52 UTC (permalink / raw)
To: Kristofer Karlsson
Cc: Kristofer Karlsson via GitGitGadget, git, Derrick Stolee
In-Reply-To: <CAL71e4P4GbYYv1LdarAbeodm06q841wj4gdGpn0QYADQjOB5gw@mail.gmail.com>
Kristofer Karlsson <krka@spotify.com> writes:
> My preference would be to merge this as-is, and then I can rework
> v5 of kk/merge-base-exhaustion on top of it later - it will
> add some delay but I don't want to rush it since it's a non-trivial
> change.
That sounds very sensible. Let's do that.
I've taken a look at both of these two patches and found the
solution quite sensible, but I'd prefer a second set of eyes
to confirm.
Thanks.
^ permalink raw reply
* Re: [PATCH 2/6] object-file: propagate files transaction errors
From: Justin Tobler @ 2026-06-29 18:58 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <aju-7Z-ecJG_ORow@pks.im>
On 26/06/24 01:26PM, Patrick Steinhardt wrote:
> On Tue, Jun 23, 2026 at 11:19:16PM -0500, Justin Tobler wrote:
> > The "files" transaction backend may encounter errors related to managing
> > the temporary directory used to stage objects, but silently ignores
> > these errors. Instead return errors encountered in the
> > `odb_transaction_files_{prepare,begin,commit}()` interfaces to allow
> > callers to handle as needed.
>
> Missing a then? "to handle as needed" -> "to handle them as needed"
Will fix.
[snip]
> > diff --git a/object-file.c b/object-file.c
> > index a3eb8d71dd..18c2df75fb 100644
> > --- a/object-file.c
> > +++ b/object-file.c
> > @@ -499,7 +499,7 @@ struct odb_transaction_files {
> > struct transaction_packfile packfile;
> > };
> >
> > -static void odb_transaction_files_prepare(struct odb_transaction *base)
> > +static int odb_transaction_files_prepare(struct odb_transaction *base)
> > {
> > struct odb_transaction_files *transaction =
> > container_of_or_null(base, struct odb_transaction_files, base);
>
> By the way, is there any reason why those functions are still hosted in
> "object-file.c" instead of in "odb/source-files.c"? I should probably
> know, but I forgot.
There are currently a couple spots in the "files" object write path in
"object-file.c" that still reach into some of these transaction function
that are not part of the generic ODB transaction interface. I'm hoping
in a future followup series to detangle this a bit and be able to get
all the "files" ODB transaction related code moved into
"odb/source-files.c".
> > @@ -511,11 +511,15 @@ static void odb_transaction_files_prepare(struct odb_transaction *base)
> > * added at the time they call odb_transaction_files_begin.
> > */
> > if (!transaction || transaction->objdir)
> > - return;
> > + return 0;
> >
> > transaction->objdir = tmp_objdir_create(base->source->odb->repo, "bulk-fsync");
> > - if (transaction->objdir)
> > - tmp_objdir_replace_primary_odb(transaction->objdir, 0);
> > + if (!transaction->objdir)
> > + return -1;
>
> Huh. So previously we just didn't handle this error at all and just
> continued to tag along? Did that result in anything sensible or was this
> just YOLOing it?
Good question. Previously if there was an error, we wouldn't end up
creating any tmpdir and would instead continue to use the primary ODB to
write objects in. This change would make it a hard error if we fail to
create the temp dir. This matches the behavior that git-receive-pack(1)
expects, but I didn't consider that the existing callers could
transparently handle there being no temp dir.
I suspect we may want existing ODB transaction users to continue being
resilient in the same manner. In the next version, I'll maintain the
same behavior.
> > @@ -542,13 +546,13 @@ static void fsync_loose_object_transaction(struct odb_transaction *base,
> > /*
> > * Cleanup after batch-mode fsync_object_files.
> > */
> > -static void flush_loose_object_transaction(struct odb_transaction_files *transaction)
> > +static int flush_loose_object_transaction(struct odb_transaction_files *transaction)
>
> Feels like this function should've been renamed in the preceding commit,
> as well.
Ya I agree, will address in the next version.
> > {
> > struct strbuf temp_path = STRBUF_INIT;
> > struct tempfile *temp;
> >
> > if (!transaction->objdir)
> > - return;
> > + return 0;
> >
> > /*
> > * Issue a full hardware flush against a temporary file to ensure
> > @@ -570,8 +574,12 @@ static void flush_loose_object_transaction(struct odb_transaction_files *transac
>
> There is a call to `xmks_tempfile()` hidden that can fail, but that
> failure is already handled in that function itself by dying.
>
> > * Make the object files visible in the primary ODB after their data is
> > * fully durable.
> > */
> > - tmp_objdir_migrate(transaction->objdir);
> > + if (tmp_objdir_migrate(transaction->objdir))
> > + return -1;
>
> Feels like another case of YOLOing it. The migration could have failed,
> but we just ignored that failure and never told the user about it. The
> result may be silent corruption, I assume?
Ya in this case, if the migration failed, we would just continue on
which would likely result in silent corruption.
>
> > @@ -1670,27 +1678,34 @@ int read_loose_object(struct repository *repo,
> > return ret;
> > }
> >
> > -static void odb_transaction_files_commit(struct odb_transaction *base)
> > +static int odb_transaction_files_commit(struct odb_transaction *base)
> > {
> > struct odb_transaction_files *transaction =
> > container_of(base, struct odb_transaction_files, base);
> >
> > - flush_loose_object_transaction(transaction);
> > + if (flush_loose_object_transaction(transaction))
> > + return -1;
> > flush_packfile_transaction(transaction);
> > +
> > + return 0;
> > }
> >
> > -struct odb_transaction *odb_transaction_files_begin(struct odb_source *source)
> > +int odb_transaction_files_begin(struct odb_source *source,
> > + struct odb_transaction **out)
> > {
> > struct odb_transaction_files *transaction;
> > struct object_database *odb = source->odb;
> >
> > - if (odb->transaction)
> > - return NULL;
> > + if (odb->transaction) {
> > + *out = NULL;
> > + return 0;
> > + }
> >
> > transaction = xcalloc(1, sizeof(*transaction));
> > transaction->base.source = source;
> > transaction->base.commit = odb_transaction_files_commit;
> > transaction->base.write_object_stream = odb_transaction_files_write_object_stream;
> > + *out = &transaction->base;
> >
> > - return &transaction->base;
> > + return 0;
> > }
>
> It's still somewhat fishy that we have this ODB-level transaction, but
> that's a preexisting issue and thus outside the scope of this patch
> series. Ideally though, it would be possible for there to be multiple
> transactions, and it would be the caller's responsibility for juggling
> these transactions. Just as it happens with reference transactions.
I completely agree. One of the current problems preventing this is that
only a single instance of tmp_objdir is allowed and stored globally.
This is done to keep atexit() cleanup simple.
My plan is to eventually convert all existing tmp_objdir callsites to
use ODB transactions which should hopefully allow us to remove the need
for a separate tmp_objdir system. At that point, we can also work to
change how temp dir cleanup is handled at exit.
Another problem is that there are also a couple of ODB transaction
callsites that require to know if there is already a pending transaction
for the repository and the transaction has not been wired down to these
callsites. My hope is that this can be addressed though as we expand ODB
transaction usage for object writes.
> > diff --git a/odb/transaction.h b/odb/transaction.h
> > index 854fda06f5..f4c1ebfaaa 100644
> > --- a/odb/transaction.h
> > +++ b/odb/transaction.h
> > @@ -17,7 +17,7 @@ struct odb_transaction {
> > struct odb_source *source;
> >
> > /* The ODB source specific callback invoked to commit a transaction. */
> > - void (*commit)(struct odb_transaction *transaction);
> > + int (*commit)(struct odb_transaction *transaction);
>
> We might want to document the returned error code here.
Will do in the next version.
Thanks,
-Justin
^ permalink raw reply
* Re: [PATCH 2/6] object-file: propagate files transaction errors
From: Justin Tobler @ 2026-06-29 19:04 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <akK1roQJknYstX0u@denethor>
On 26/06/29 01:58PM, Justin Tobler wrote:
> On 26/06/24 01:26PM, Patrick Steinhardt wrote:
> > On Tue, Jun 23, 2026 at 11:19:16PM -0500, Justin Tobler wrote:
> > > @@ -511,11 +511,15 @@ static void odb_transaction_files_prepare(struct odb_transaction *base)
> > > * added at the time they call odb_transaction_files_begin.
> > > */
> > > if (!transaction || transaction->objdir)
> > > - return;
> > > + return 0;
> > >
> > > transaction->objdir = tmp_objdir_create(base->source->odb->repo, "bulk-fsync");
> > > - if (transaction->objdir)
> > > - tmp_objdir_replace_primary_odb(transaction->objdir, 0);
> > > + if (!transaction->objdir)
> > > + return -1;
> >
> > Huh. So previously we just didn't handle this error at all and just
> > continued to tag along? Did that result in anything sensible or was this
> > just YOLOing it?
>
> Good question. Previously if there was an error, we wouldn't end up
> creating any tmpdir and would instead continue to use the primary ODB to
> write objects in. This change would make it a hard error if we fail to
> create the temp dir. This matches the behavior that git-receive-pack(1)
> expects, but I didn't consider that the existing callers could
> transparently handle there being no temp dir.
>
> I suspect we may want existing ODB transaction users to continue being
> resilient in the same manner. In the next version, I'll maintain the
> same behavior.
I think I got a bit ahead of myself. The existing callers of
odb_transaction_files_prepare() still continue to ignore this error. So
the behavior already does remain the same here.
-Justin
^ permalink raw reply
* Re: [PATCH 2/6] object-file: propagate files transaction errors
From: Justin Tobler @ 2026-06-29 19:10 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, ps
In-Reply-To: <xmqqjyrniy6r.fsf@gitster.g>
On 26/06/24 11:35AM, Junio C Hamano wrote:
> Justin Tobler <jltobler@gmail.com> writes:
>
> > The "files" transaction backend may encounter errors related to managing
> > the temporary directory used to stage objects, but silently ignores
> > these errors. Instead return errors encountered in the
> > `odb_transaction_files_{prepare,begin,commit}()` interfaces to allow
> > callers to handle as needed.
>
> "handle them as needed", perhaps.
Will fix, thanks
[snip]
> The caller of this function does react to a failure of it, ...
>
> > @@ -1670,27 +1678,34 @@ int read_loose_object(struct repository *repo,
> > return ret;
> > }
> >
> > -static void odb_transaction_files_commit(struct odb_transaction *base)
> > +static int odb_transaction_files_commit(struct odb_transaction *base)
> > {
> > struct odb_transaction_files *transaction =
> > container_of(base, struct odb_transaction_files, base);
> >
> > - flush_loose_object_transaction(transaction);
> > + if (flush_loose_object_transaction(transaction))
> > + return -1;
> > flush_packfile_transaction(transaction);
> > +
> > + return 0;
> > }
>
> ... like this, which is good. Do we need an explicit "abort-transaction",
> or is that implicit?
So this is currently handled implicitly via
`tmp-objdir.c:remove_tmp_objdir()` which gets registered as an atexit()
handler. As long as the tmp_objdir global remains set, it will
automatically get cleaned up.
In a subsequent series, I do plan to add `odb_transaction_abort()` to
the transaction interface. It may make sense to also use that here to
make the cleanup a bit more explicit though.
-Justin
^ permalink raw reply
* Re: [PATCH 3/6] odb/transaction: propagate begin errors
From: Justin Tobler @ 2026-06-29 19:15 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <aju-8hUeuyL6gnNU@pks.im>
On 26/06/24 01:26PM, Patrick Steinhardt wrote:
> On Tue, Jun 23, 2026 at 11:19:17PM -0500, Justin Tobler wrote:
> > diff --git a/odb/transaction.c b/odb/transaction.c
> > index b16e07aebf..d3de01db50 100644
> > --- a/odb/transaction.c
> > +++ b/odb/transaction.c
> > @@ -2,14 +2,20 @@
> > #include "odb/source.h"
> > #include "odb/transaction.h"
> >
> > -struct odb_transaction *odb_transaction_begin(struct object_database *odb)
> > +int odb_transaction_begin(struct object_database *odb,
> > + struct odb_transaction **out)
> > {
> > - if (odb->transaction)
> > - return NULL;
> > + int ret;
> >
> > - odb_source_begin_transaction(odb->sources, &odb->transaction);
> > + if (odb->transaction) {
> > + *out = NULL;
> > + return 0;
> > + }
>
> Hm. So we may return successful, but not set the `out` pointer to a
> transaction. And...
>
> > diff --git a/odb/transaction.h b/odb/transaction.h
> > index f4c1ebfaaa..cd6d50f2e5 100644
> > --- a/odb/transaction.h
> > +++ b/odb/transaction.h
> > @@ -33,11 +35,20 @@ struct odb_transaction {
> > };
> >
> > /*
> > - * Starts an ODB transaction. Subsequent objects are written to the transaction
> > - * and not committed until odb_transaction_commit() is invoked on the
> > - * transaction. If the ODB already has a pending transaction, NULL is returned.
> > + * Starts an ODB transaction and returns it via `out`. Subsequent objects are
> > + * written to the transaction and not committed until odb_transaction_commit()
> > + * is invoked on the transaction. Returns 0 on success and a negative value on
> > + * error. If the ODB already has a pending transaction, `out` is set to NULL.
> > */
> > -struct odb_transaction *odb_transaction_begin(struct object_database *odb);
> > +int odb_transaction_begin(struct object_database *odb,
> > + struct odb_transaction **out);
> > +
> > +static inline void odb_transaction_begin_or_die(struct object_database *odb,
> > + struct odb_transaction **out)
> > +{
> > + if (odb_transaction_begin(odb, out))
> > + die(_("failed to start ODB transaction"));
> > +}
>
> ... we don't special-case that here, either. So a caller may invoke the
> function, not die, but it might still not have a valid transaction. That
> feels wrong to me.
Ya, the original idea for a NULL transaction to signal that there is
already a transaction in flight and nested ODB transaction users to use
that to determine whether they needed to start a new transaction or not.
I completely agree thought that this is rather ackward.
Instead we could just make the callers that are worried about
potentially nested transactions handle this explicitly. I'll do that in
the next version.
-Justin
^ permalink raw reply
* Re: [PATCH 4/6] odb/transaction: propagate commit errors
From: Justin Tobler @ 2026-06-29 19:16 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <aju-90Uayxwsevm7@pks.im>
On 26/06/24 01:26PM, Patrick Steinhardt wrote:
> On Tue, Jun 23, 2026 at 11:19:18PM -0500, Justin Tobler wrote:
> > diff --git a/odb/transaction.h b/odb/transaction.h
> > index cd6d50f2e5..7898770071 100644
> > --- a/odb/transaction.h
> > +++ b/odb/transaction.h
> > @@ -54,7 +54,7 @@ static inline void odb_transaction_begin_or_die(struct object_database *odb,
> > * Commits an ODB transaction making the written objects visible. If the
> > * specified transaction is NULL, the function is a no-op.
> > */
> > -void odb_transaction_commit(struct odb_transaction *transaction);
> > +int odb_transaction_commit(struct odb_transaction *transaction);
>
> Should the function comment be amended, as well? We should definitely
> point out that calling this with a NULL transaction also returns
> success.
Will do in the next version.
Thanks,
-Justin
^ permalink raw reply
* Re: [PATCH 5/6] odb/transaction: add transaction env interface
From: Justin Tobler @ 2026-06-29 19:20 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <aju-_Nf3kmoIidue@pks.im>
On 26/06/24 01:26PM, Patrick Steinhardt wrote:
> On Tue, Jun 23, 2026 at 11:19:19PM -0500, Justin Tobler wrote:
> > The ODB transaction backend is responsible for creating/managing its own
> > staging area for writing objects. Other child processes spawned by Git
> > may need to access to uncommitted objects or write new objects in the
>
> s/may need to access to/may need access to/
Will fix.
> > staging area though.
> >
> > Introduce `odb_transaction_env()` which is expected to provide the set
> > of environment variables needed by a child process to access the
> > transaction staging area.
>
> Possessive s is missing, I think.
Yes. :)
[snip]
> > +
> > + /*
> > + * This callback is expected to return a NULL-terminated array of
> > + * environment variables that a child process should inherit so
> > + * that its object writes participate in the transaction. The
> > + * returned array is owned by the backend and remains valid until
> > + * the transaction ends. May return NULL when the backend does not
> > + * need to expose any state to child processes.
> > + */
> > + const char **(*env)(struct odb_transaction *transaction);
>
> Would it make more sense to adapt this function so that:
>
> - It receives a `struct strvec` as input that the environment
> variables are to be amended to.
>
> - It returns a normal error code to indicate errors?
Ya, that is probably a more sensible interface as it would be nice to be
able to signal an error. Will do in the next version.
Thanks,
-Justin
^ permalink raw reply
* Re: [PATCH v5 0/4] history: add squash subcommand to fold a range
From: Phillip Wood @ 2026-06-29 19:48 UTC (permalink / raw)
To: Harald Nordgren
Cc: Patrick Steinhardt, phillip.wood,
Harald Nordgren via GitGitGadget, git
In-Reply-To: <CAHwyqnWQmObWr3N81_EU6F13iyKp3FfY8KSNFfoAjS4r_0qJrQ@mail.gmail.com>
On 29/06/2026 19:03, Harald Nordgren wrote:
>> So instead of
>>
>> # This is the combination of 4 commits
>> # This is the first commit message
>> Base subject
>>
>> Base body
>>
>> # This is the second commit message
>> # Another subject
>>
>> # Another body
>>
>> # This is the third commit message
>> # fixup! Base subject
>>
>> # This is the fourth commit message
>> # amend! Another subject
>> A better subject
>>
>> A better body
>>
>> We'd have
>>
>> # This is the combination of 4 commits
>> # 123 Base subject
>> # 456 Another subject
>> # 789 fixup! Base subject
>> # abc amend! Another subject
>>
>> Base Subject
>>
>> Base Body
>>
>> Another subject
>>
>> Another Body
>
> I think this makes it a lot harder to read. If every commit body was
> always just a single paragraph it could make sense, but it's generally
> not. Look at the commits in this series, with no delimiter of where
> one commit message ends and the next one starts, it would be very
> confusing.
You've trimmed the line where I said
>> Possibly with a comment before each message saying where it came
>> from.
So I'm not against adding a comment before each message, but I do think
we should omit any messages that would be commented out completely. If
you look at the rebase example above you can see there is a mass of
comments between the two pieces of text that make up the new message.
That makes it hard to see what is actually going to be included in the
new message.
Thanks
Phillip
>> It would be good to error out if the user tries squash a fixup! style
>> commit and range does not contain its target commit.
>
> Good point, I don't see a good reason to allow this.
>
>> There does seem to be some support for merges in this patch series which
>> I think behaves pretty sensibly. If we have
>>
>> C - D
>> / \
>> - A - B - E - F - G
>>
>> Then squashing A..G should be fine because the parents of F are in the
>> range and it looks like we support that. Squashing should B..G without
>> --ancestry-path should be safe as well because B ends up as the parent
>> of the squashed commit but we don't have a way to disable
>> --ancestry-path (and maybe we don't want to add one). Squashing F^@..G
>> might be useful to fixup a merge (though perhaps amending F rather than
>> creating G is a simpler way to fix a broken merge). Squashing E..G does
>> not make sense because the range does not include one of the merge parents.
>
> Thanks for a good explanation here!
>
>
> Harald
>
^ permalink raw reply
* Re: [PATCH v7 11/11] builtin/history: implement "drop" subcommand
From: Junio C Hamano @ 2026-06-29 19:49 UTC (permalink / raw)
To: Patrick Steinhardt
Cc: git, Pablo Sabater, Kristoffer Haugsbakk, Phillip Wood,
Christian Couder
In-Reply-To: <20260629-b4-pks-history-drop-v7-11-6e9392a957d8@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
> +static int find_head_tree_change(struct repository *repo,
> + const struct replay_result *result,
> + struct commit **old_head,
> + struct commit **new_head,
> + bool *changed)
> +{
> + const struct replay_ref_update *head_update = NULL;
> + struct commit *old_head_commit, *new_head_commit;
> + struct tree *old_head_tree, *new_head_tree;
> + const char *head_target;
> + int head_flags;
> +
> + *changed = false;
> +
> + head_target = refs_resolve_ref_unsafe(get_main_ref_store(repo),
> + "HEAD", RESOLVE_REF_NO_RECURSE,
> + NULL, &head_flags);
> + if (!head_target)
> + return error(_("cannot look up HEAD"));
Here head_target would be something like "refs/heads/master", or
whatever the "HEAD" happens to point at.
> + if (!(head_flags & REF_ISSYMREF))
> + head_target = "HEAD";
But if it is not a symref, then it is a detached HEAD. We manually
set it to "HEAD" again. We know head_target was not NULL, so what
did we receive in it from refs_resolve_ref_unsafe() call, before we
overwrite it here?
> + for (size_t i = 0; i < result->updates_nr; i++) {
> + if (!strcmp(result->updates[i].refname, head_target)) {
> + head_update = &result->updates[i];
> + break;
> + }
> + }
We see if we are going to update the currently checked out branch.
The .updates[] array was earlier populated by the caller that called
compute_pending_ref_updates() before it called us.
> + if (!head_update)
> + return 0;
And we return if not. That is a simple and happy case. Otherwise
we'd tell the caller about the updated commit and tree (strictly
speaking that would be redundant, but since we have it already, it
is better to give them to the caller instead of forcing the caller
to unwrap the commit).
> +static int cmd_history_drop(int argc,
> + const char **argv,
> + const char *prefix,
> + struct repository *repo)
> +{
> +...
> + struct option options[] = {
> + OPT_CALLBACK_F(0, "update-refs", &action, "(branches|head)",
> + N_("control which refs should be updated"),
> + PARSE_OPT_NONEG, parse_ref_action),
> ...
> + OPT_END(),
> + };
> ...
> + ret = compute_pending_ref_updates(&revs, action, original, rewritten,
> + empty, &result);
Here we call the function. When action is "--update-refs=head",
doesn't this code in compute_pending_ref_updates() ...
if (action == REF_ACTION_HEAD &&
decoration->type != DECORATION_REF_HEAD)
continue;
... skip any reference name (loaded by load_ref_decorations() lazily
by calling get_name_decoration()) that is not "HEAD", which would
mean we end up not finding any hits in the find_head_tree_change()
function call we make later ...
> + if (ret) {
> + ret = error(_("failed replaying descendants"));
> + goto out;
> + }
> + ...
> + if (!is_bare_repository()) {
> + ret = find_head_tree_change(repo, &result, &old_head,
> + &new_head, &head_moves);
... here?
^ permalink raw reply
* Re: [PATCH 6/6] builtin/receive-pack: stage incoming objects via ODB transactions
From: Justin Tobler @ 2026-06-29 20:25 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <aju_AmlKVi5UZaiQ@pks.im>
On 26/06/24 01:26PM, Patrick Steinhardt wrote:
> On Tue, Jun 23, 2026 at 11:19:20PM -0500, Justin Tobler wrote:
> > Objects received by git-receive-pack(1) are quarantined in a temporary
> > "incoming" directory and migrated into the object database prior to the
> > reference updates. The quarantine is currently managed through
> > `tmp_objdir` directly. In a pluggable ODB future, how exactly an object
> > gets written to a transaction may vary for a given ODB source. Refactor
> > git-receive-pack(1) to use the ODB transaction interfaces to manage the
> > object staging area in a more agnostic manner accordingly.
> >
> > Note that the temporary directory created for git-receive-pack(1) is
> > eagerly created and uses a different prefix name. This behavior is
>
> A different prefix name compared to what?
Currently the temporary directories created for ODB transactions all use
the prefix "bulk-fsync". The temp dir created by git-receive-pack(1) is
expected to have the prefix "incoming".
> > special cased in the "files" backend by having `odb_transaction_begin()`
> > callers that require this behavior provide an `ODB_TRANSACTION_RECEIVE`
> > flag.
>
> Okay. I guess this is to retain existing behaviour where the temporary
> directory is created lazily everywhere else. Makes me wonder whether we
> should eventually change this to just unconditionally create the
> directory in all cases so that we can drop this new flag.
It would be nice to not have to have a flag here, but if we want to also
keep the existing temp dir prefixes, we would also need to keep the
flags.
> It might've also made sense to split this commit up into two: one to
> introduce the flag parameter, and then one to do the changes to
> git-receive-pack(1).
Ya, I think you are right. I actually originally had it this way but
squashed these two commits together for some reason. I'll split them
back up in the next version.
> > diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
> > index 19eb6a1b61..ee8e03e2ab 100644
> > --- a/builtin/receive-pack.c
> > +++ b/builtin/receive-pack.c
> > @@ -112,8 +112,6 @@ static enum {
> > } use_keepalive;
> > static int keepalive_in_sec = 5;
> >
> > -static struct tmp_objdir *tmp_objdir;
> > -
> > static struct proc_receive_ref {
> > unsigned int want_add:1,
> > want_delete:1,
>
> I assume the goal is that we convert all other users of the tmp-objdir
> subsystem to also use transactions eventually, so that this becomes an
> implementation detail fo the files transaction?
Yes, that is exactly my plan :)
> > @@ -2106,14 +2104,13 @@ static void execute_commands(struct command *commands,
> > * Now we'll start writing out refs, which means the objects need
> > * to be in their final positions so that other processes can see them.
> > */
> > - if (tmp_objdir_migrate(tmp_objdir) < 0) {
> > + if (odb_transaction_commit(the_repository->objects->transaction)) {
> > for (cmd = commands; cmd; cmd = cmd->next) {
> > if (!cmd->error_string)
> > cmd->error_string = "unable to migrate objects to permanent storage";
> > }
> > return;
> > }
> > - tmp_objdir = NULL;
>
> We don't need to unset the transaction because that's what
> `odb_transaction_commit()` already does for us, I assume?
That is correct. The tmp_objdir global is actually removed and now
competely managed by the ODB transaction. We can probably actuall remove
the "tmp-objdir" include now too. I'll do that in the next version.
> > @@ -2326,7 +2323,8 @@ static void push_header_arg(struct strvec *args, struct pack_header *hdr)
> > ntohl(hdr->hdr_version), ntohl(hdr->hdr_entries));
> > }
> >
> > -static const char *unpack(int err_fd, struct shallow_info *si)
> > +static const char *unpack(int err_fd, struct shallow_info *si,
> > + struct odb_transaction *transaction)
> > {
> > struct pack_header hdr;
> > const char *hdr_err;
>
> It feels a bit weird that we sometimes pass the transaction as
> parameter, whereas othertimes we access it via `the_repository`.
That's fair. I was trying to avoid the churn of wiring to all its
callsites, but it's probably best to be consistent. Maybe it would be
fine to just create a transaction global like we do for the reference
transaction?
> > @@ -2351,20 +2349,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
> > strvec_push(&child.args, alt_shallow_file);
> > }
> >
> > - tmp_objdir = tmp_objdir_create(the_repository, "incoming");
> > - if (!tmp_objdir) {
> > - if (err_fd > 0)
> > - close(err_fd);
> > - return "unable to create temporary object directory";
> > - }
> > - strvec_pushv(&child.env, tmp_objdir_env(tmp_objdir));
> > -
> > - /*
> > - * Normally we just pass the tmp_objdir environment to the child
> > - * processes that do the heavy lifting, but we may need to see these
> > - * objects ourselves to set up shallow information.
> > - */
> > - tmp_objdir_add_as_alternate(tmp_objdir);
> > + strvec_pushv(&child.env, odb_transaction_env(transaction));
>
> Interesting, this here seems like a change in behaviour. Previously we
> added the transactions as an alternate, but now we only propagate it via
> the environment. I didn't see this mentioned in the commit message.
That's not quite correct. By using the ODB transaction interface, the
underlying tmp_objdir is managed transparently. When we begin the ODB
transaction, the temp directory that gets created is automatically
created and applied as the primary ODB. This ultimately produces an
equivalent result, its just now set up when the transaction is started
(which happens a little bit earlier).
The only behavior change here is that the temp directory is being
applied as the primary instead of an alternate in the main
git-receive-pack(1) process. Since all writes though are handled by the
child processes that get spawned, this shouldn't really matter though.
This is certainly rather confusing though, and should be mentioned in
the commit message. I'll do this in the next version.
> > @@ -2707,7 +2694,10 @@ int cmd_receive_pack(int argc,
> > if (!si.nr_ours && !si.nr_theirs)
> > shallow_update = 0;
> > if (!delete_only(commands)) {
> > - unpack_status = unpack_with_sideband(&si);
> > + if (odb_transaction_begin(the_repository->objects, &transaction, ODB_TRANSACTION_RECEIVE))
> > + unpack_status = "unable to start ODB transaction";
>
> s/ODB/object/
>
> This may be visible to the user, and "ODB" may mean nothing to them.
Will change in the next version.
> > diff --git a/object-file.c b/object-file.c
> > index 14064d188a..e7958753ec 100644
> > --- a/object-file.c
> > +++ b/object-file.c
> > @@ -1702,7 +1703,8 @@ static const char **odb_transaction_files_env(struct odb_transaction *base)
> > }
> >
> > int odb_transaction_files_begin(struct odb_source *source,
> > - struct odb_transaction **out)
> > + struct odb_transaction **out,
> > + enum odb_transaction_flags flags)
> > {
> > struct odb_transaction_files *transaction;
> > struct object_database *odb = source->odb;
> > @@ -1717,6 +1719,20 @@ int odb_transaction_files_begin(struct odb_source *source,
> > transaction->base.commit = odb_transaction_files_commit;
> > transaction->base.write_object_stream = odb_transaction_files_write_object_stream;
> > transaction->base.env = odb_transaction_files_env;
> > +
> > + transaction->prefix = "bulk-fsync";
> > + if (flags & ODB_TRANSACTION_RECEIVE) {
> > + /*
> > + * ODB transactions for git-receive-pack(1) eagerly create a
> > + * temporary directory and use a different prefix.
> > + */
> > + transaction->prefix = "incoming";
> > + if (odb_transaction_files_prepare(&transaction->base)) {
> > + free(transaction);
> > + return -1;
> > + }
> > + }
> > +
>
> Okay, makes sense. I really wonder whether we need to insist this much
> on the exact name used by this, but better be safe than sorry for now I
> guess.
>
> And as mentioned before, I also wonder whether it really makes sense to
> have the lazy creation of the tmp-objdir. Maybe add a NEEDSWORK item
> here that mentions we want to investigate whether this is even needed at
> all?
Ya, I was worried that there would be some reason the temp dir prefix
should remain the same or there would be some performance reason to
lazily create directories. I didn't investigate too deeply though. I'll
add a NEEDSWORK comment to make note of this.
> > diff --git a/odb/transaction.h b/odb/transaction.h
> > index 536458297b..78392ff13d 100644
> > --- a/odb/transaction.h
> > +++ b/odb/transaction.h
> > @@ -44,6 +43,10 @@ struct odb_transaction {
> > const char **(*env)(struct odb_transaction *transaction);
> > };
> >
> > +enum odb_transaction_flags {
> > + ODB_TRANSACTION_RECEIVE = (1 << 0),
> > +};
>
> It's not clear at all what this flag does based on its name, so we
> should have documentation for it.
Will update.
Thanks,
-Justin
^ permalink raw reply
* Re: [PATCH 3/3] t5551: pack refs after creating many tags
From: Jeff King @ 2026-06-29 20:35 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: Michael Montalbo, git, Junio C Hamano
In-Reply-To: <akIJQbOUbdBbkTef@pks.im>
On Mon, Jun 29, 2026 at 07:57:21AM +0200, Patrick Steinhardt wrote:
> > It would be nice if we had a way to generate all of these refs without
> > writing so many individual files. But even if we taught the ref code to
> > write large cases directly to the packed-refs file, we'd still need to
> > take individual locks. The real solution is a backend like reftable,
> > which shaves ~30% off of the test runtime.
>
> We kind of already have this with the `REF_TRANSACTION_FLAG_INITIAL`
> flag, but right now it is only used when performing a clone or when
> migrating references. Also, it requires an empty repository that has no
> references yet.
>
> It raises the question whether we could also extend git-fast-import(1)
> to use it, as it would typically be run on an almost-empty repository.
> It's the "almost" that kills it though, as we already do have at least
> the HEAD reference. So it could be feasible, but it's not as trivial as
> just setting the flag and then we're magically faster.
>
> And besides, in this particular test here we run git-fast-import(1)
> multiple times in the same repository, so it wouldn't help us.
>
> We could of course extend all of this so that Git is able to write into
> the packed-refs directly, even with preexisting refs. But I agree with
> your sentiment: it doesn't feel worth it as the reftable backend fixes
> scenarios like this anyway.
Yup. In the past I've pondered exposing this via update-ref, but I think
it's too weird and/or dangerous to do so. Especially because you are
still stuck creating all of the .lock files, so the performance is not
even that much better (though it does save you doing so _twice_ when you
then pack the refs).
So the performance option you really want is "YOLO, just write some
packed-refs without locking". But that is not something I think we want
to expose to users. ;)
We could do it ad-hoc within this test like so:
diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
index dcff0bc7d4..276c7ac002 100755
--- a/t/t5551-http-fetch-smart.sh
+++ b/t/t5551-http-fetch-smart.sh
@@ -389,11 +389,15 @@ create_tags () {
echo "from :$1"
done | git fast-import --export-marks=marks &&
+ # should be mostly a noop, but makes sure we have the right header
+ git pack-refs &&
+
# now assign tags to all the dangling commits we created above
+ # It is OK to write directly to the packed-refs file because we know
+ # that our entries are sorted by refname, and that they all
+ # come after what we wrote earlier.
tag=$(perl -e "print \"bla\" x 30") &&
- sed -e "s|^:\([^ ]*\) \(.*\)$|create refs/tags/$tag-\1 \2|" <marks >input &&
- git update-ref --stdin <input &&
- rm input
+ sed -e "s|^:\([^ ]*\) \(.*\)$|\2 refs/tags/$tag-\1|" <marks >>packed-refs
}
test_expect_success 'create 2,000 tags in the repo' '
That gives us the same ~30% speedup that using reftables does, but it
still is quite gross and fragile. And it is not even strictly correct,
because we don't zero-pad the numbered tags (so our file is subtly out
of order). Plus it would need to be conditional on the ref backend
being used. Yuck.
There's one other thing you might find interesting. While poking at the
timings here the other day, I noticed that reftable is very eager to
stat the tables.list file. Try this:
git init --ref-format=reftable
blob=$(echo foo | git hash-object -w --stdin)
seq -f "create refs/tags/foo-%g $blob" 2000 |
strace -c git update-ref --stdin
We make 2000 fstat, which strace claims takes 85% of the time. I suspect
this is over-emphasized because strace inherently makes syscalls slow,
but running with perf also highlights it as a non-trivial cost.
It has been a long time since I've thought about reftable internals, but
it feels like we ought to be able to take the lock and then trust that
the stack has not been manipulated.
It may not be worth digging into too much, though. I can make 50,000
refs in 150ms on my system, which is probably good enough (especially
compared to the files backend).
-Peff
^ permalink raw reply related
* Re: [PATCH 2/3] t5551: put many-tags case into its own repo
From: Jeff King @ 2026-06-29 20:36 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Michael Montalbo, Patrick Steinhardt, git
In-Reply-To: <xmqqh5mlz9uw.fsf@gitster.g>
On Mon, Jun 29, 2026 at 07:42:31AM -0700, Junio C Hamano wrote:
> > Ah, yeah. It should work either way, but it is slightly confusing for it
> > to be non-bare. I'll wait to re-send (though if nothing else comes up,
> > it may be simpler for you to just amend on your side).
>
> OK. It seems both Patrick and you are in favor of using only [1/3]
> & [2/3] but dropping [3/3]? If that is the concensus I can just
> tweak this one and apply before 2.55 final.
Yep, that sounds great. Looks like it already happened. :)
-Peff
^ permalink raw reply
* Re: [PATCH v4 0/3] Reuse --contains traversal results
From: Junio C Hamano @ 2026-06-29 20:40 UTC (permalink / raw)
To: Tamir Duberstein
Cc: git, Jeff King, Karthik Nayak, Victoria Dye, Derrick Stolee,
Elijah Newren, Kristofer Karlsson
In-Reply-To: <20260612-ref-filter-memoized-contains-v4-0-5ed39fd001dd@gmail.com>
Tamir Duberstein <tamird@gmail.com> writes:
> git tag uses a memoized traversal for --contains, while git branch
> and git for-each-ref repeat a reachability walk for each ref. Reuse
> the memoized traversal when generation numbers can bound the walk.
>
> The first patch makes the memoized traversal reject cyclic replacement
> histories. The last makes the non-memoized path report reachability
> errors.
This unfortunately hasn't heard any responses since June 12th. Are
there remaining issues with it? Or do people fundamentally have
objections against this change? Or things are too busy in general
that there are more patches than there are folks willing to review
them?
^ permalink raw reply
* Re: [PATCH 3/6] odb: add `source` field to struct object_info_source
From: Junio C Hamano @ 2026-06-29 20:47 UTC (permalink / raw)
To: Justin Tobler; +Cc: Patrick Steinhardt, git
In-Reply-To: <akKtc4ybxFRVJmNv@denethor>
Justin Tobler <jltobler@gmail.com> writes:
>> @@ -1424,6 +1424,10 @@ int packed_object_info_with_index_pos(struct odb_source_packed *source UNUSED,
>> oi->whence = OI_PACKED;
>>
>> if (oi->sourcep) {
>> + if (!source)
>> + BUG("cannot request source without an owning source");
>> + oi->sourcep->source = &source->base;
>
> And here it is set for the packed backend. Looks good.
>
> Naive question: I understand that some `packed_info_object()` callers
> may not have the `struct odb_source` on hand, but when the `struct
> packed_git` is intially setup, is it not always known the ODB source it
> comes from? It makes me wonder if the ODB source should also be recorded
> when `struct packed_git` is initialized.
As with your reaction to [PATCH 1/6], I do share this puzzlement: if
the source can almost always be NULL, what is it good for and isn't
it something that can be computed from the available information?
Perhaps it is the naming?
I am confused what the above quoted code actually is doing ("if you
have a source, then grab its base and set it to .source member of
the struct the out parameter points at", makes it sound like the out
parameter sourcep should be pointing at a structure with .base
member, not .source member, or perhaps the caller should be passing
&oi->sourcep->source as *base to be assigned to, or something).
^ permalink raw reply
* Re: [PATCH v2 0/5] builtin/refs: add ability to write references
From: Junio C Hamano @ 2026-06-29 20:52 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <20260617-pks-refs-writing-subcommands-v2-0-07f3d18336f9@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
> Reference-related functionality in Git is currently spread across many
> different commands: git-update-ref(1), git-for-each-ref(1),
> git-show-ref(1), git-pack-refs(1) and git-symbolic-ref(1). This makes it
> hard for users to discover what functionality we have available to work
> with references.
>
> We have thus started to consolidate this functionality into git-refs(1),
> which is a toolbox of everything related to references. Until now, the
> command doesn't handle functionality of git-update-ref(1).
This unfortunately hasn't heard any responses since June 17th, so I
took a look at it again myself. All the things we discussed during
the review of the initial round has been addressed, it seems.
Shall we mark the topic ready for 'next' now?
^ permalink raw reply
* Re: [PATCH v4 0/3] environment: migrate 'trust_executable_bit' into 'repo_config_values'
From: Junio C Hamano @ 2026-06-29 20:55 UTC (permalink / raw)
To: Tian Yuchen
Cc: git, ps, Christian Couder, Ayush Chandekar, Olamide Caleb Bello
In-Reply-To: <20260619162105.648495-1-cat@malon.dev>
Tian Yuchen <cat@malon.dev> writes:
> The 'core.filemode' (stored as 'trust_executable_bit') configuration
> act as a core filesystem capability flag.
This unfortunately hasn't heard any responses since June 19th. Are
there remaining issues with it? Or do people fundamentally have
objections against this change? Or things are too busy in general
that there are more patches than there are folks willing to review
them?
^ permalink raw reply
* Re: [PATCH v2 4/5] builtin/refs: add "create" subcommand
From: Junio C Hamano @ 2026-06-29 20:58 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git
In-Reply-To: <20260617-pks-refs-writing-subcommands-v2-4-07f3d18336f9@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
> + if (repo_get_oid_with_flags(repo, argv[1], &newoid, GET_OID_SKIP_AMBIGUITY_CHECK))
> + die(_("invalid object ID: '%s'"), argv[1]);
> + if (is_null_oid(&newoid))
> + die(_("cannot create reference with null old object ID"));
An apparent typo here, "with null old" -> "with null new object
name".
Other than that, I think this one is good.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox