Commit Graph

17237 Commits

Author SHA1 Message Date
Junio C Hamano
1adf5bca8c A handful before -rc1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-06 15:42:51 -07:00
Junio C Hamano
a2dc765251 Merge branch 'qb/doc-git-stash-push-optionality'
Doc update.

* qb/doc-git-stash-push-optionality:
  docs: fix "git stash [push]" documentation
2026-04-06 15:42:50 -07:00
Junio C Hamano
e44fbc2afa Merge branch 'sp/doc-gitignore-oowt'
Doc update.

* sp/doc-gitignore-oowt:
  doc: gitignore: clarify pattern base for info/exclude and core.excludesFile
2026-04-06 15:42:50 -07:00
Junio C Hamano
03311dca7f Merge branch 'tb/stdin-packs-excluded-but-open'
pack-objects's --stdin-packs=follow mode learns to handle
excluded-but-open packs.

* tb/stdin-packs-excluded-but-open:
  repack: mark non-MIDX packs above the split as excluded-open
  pack-objects: support excluded-open packs with --stdin-packs
  t7704: demonstrate failure with once-cruft objects above the geometric split
  pack-objects: refactor `read_packs_list_from_stdin()` to use `strmap`
  pack-objects: plug leak in `read_stdin_packs()`
2026-04-06 15:42:49 -07:00
Junio C Hamano
2855562ca6 A couple more on top of -rc0
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-03 15:26:34 -07:00
Junio C Hamano
8de2f1b07a A bit more on top of 2.54-rc0
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-03 13:01:10 -07:00
Junio C Hamano
e0613d24f9 Merge branch 'sa/replay-revert'
"git replay" (experimental) learns, in addition to "pick" and
"replay", a new operating mode "revert".

* sa/replay-revert:
  replay: add --revert mode to reverse commit changes
  sequencer: extract revert message formatting into shared function
2026-04-03 13:01:09 -07:00
Junio C Hamano
0cd4fb9f46 Merge branch 'ar/config-hook-cleanups'
Code clean-up around the recent "hooks defined in config" topic.

* ar/config-hook-cleanups:
  hook: reject unknown hook names in git-hook(1)
  hook: show disabled hooks in "git hook list"
  hook: show config scope in git hook list
  hook: introduce hook_config_cache_entry for per-hook data
  t1800: add test to verify hook execution ordering
  hook: make consistent use of friendly-name in docs
  hook: replace hook_list_clear() -> string_list_clear_func()
  hook: detect & emit two more bugs
  hook: rename cb_data_free/alloc -> hook_data_free/alloc
  hook: fix minor style issues
  builtin/receive-pack: properly init receive_hook strbuf
  hook: move unsorted_string_list_remove() to string-list.[ch]
2026-04-03 13:01:09 -07:00
Junio C Hamano
4e5821732e Merge branch 'ds/backfill-revs'
`git backfill` learned to accept revision and pathspec arguments.

* ds/backfill-revs:
  t5620: test backfill's unknown argument handling
  path-walk: support wildcard pathspecs for blob filtering
  backfill: work with prefix pathspecs
  backfill: accept revision arguments
  t5620: prepare branched repo for revision tests
  revision: include object-name.h
2026-04-03 13:01:08 -07:00
Junio C Hamano
cd79c76a51 Merge branch 'mf/format-patch-commit-list-format-doc'
Doc updates.

* mf/format-patch-commit-list-format-doc:
  format-patch: removing unconditional wrapping
  docs: fix --commit-list-format related entries
2026-04-03 13:01:08 -07:00
Junio C Hamano
aafabe2fc4 Merge branch 'mf/format-patch-commit-list-format'
Improve the recently introduced `git format-patch
--commit-list-format` (formerly `--cover-letter-format`) option,
including a new "modern" preset and better CLI ergonomics.

* mf/format-patch-commit-list-format:
  format-patch: --commit-list-format without prefix
  format-patch: add preset for --commit-list-format
  format-patch: wrap generate_commit_list_cover()
  format.commitListFormat: strip meaning from empty
  docs/pretty-formats: add %(count) and %(total)
  format-patch: rename --cover-letter-format option
  format-patch: refactor generate_commit_list_cover
  pretty.c: better die message %(count) and %(total)
2026-04-03 13:01:08 -07:00
Junio C Hamano
63901789bc Merge branch 'mf/format-patch-cover-letter-format'
"git format-patch --cover-letter" learns to use a simpler format
instead of the traditional shortlog format to list its commits with
a new --cover-letter-format option and format.commitListFormat
configuration variable.

* mf/format-patch-cover-letter-format:
  docs: add usage for the cover-letter fmt feature
  format-patch: add commitListFormat config
  format-patch: add ability to use alt cover format
  format-patch: move cover letter summary generation
  pretty.c: add %(count) and %(total) placeholders
2026-04-03 13:01:08 -07:00
Todd Zullinger
6cc95979c6 RelNotes: minor typo fixes in 2.54.0 draft
Signed-off-by: Todd Zullinger <tmz@pobox.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-01 21:15:26 -07:00
Junio C Hamano
cf2139f8e1 The 24th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-04-01 10:28:20 -07:00
Junio C Hamano
0a39ec283c Merge branch 'vp/http-rate-limit-retries'
The HTTP transport learned to react to "429 Too Many Requests".

* vp/http-rate-limit-retries:
  http: add support for HTTP 429 rate limit retries
  strbuf_attach: fix call sites to pass correct alloc
  strbuf: pass correct alloc to strbuf_attach() in strbuf_reencode()
2026-04-01 10:28:18 -07:00
Junio C Hamano
270e10ad6d The 23rd batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-30 13:57:03 -07:00
Quentin Bernet
3402850ee1 docs: fix "git stash [push]" documentation
Both the synopsis and explanation are incorrect and contradict each
other.
The synopsis claims "push" can only be omitted when you do not give any
options and arguments.
The explanation correctly claims that non-option arguments are not
allowed, except pathspec elements preceded by double hyphens.
But it also adds "-p" to the list of exceptions, even though it is an
option argument.

Signed-off-by: Quentin Bernet <quentin.bernet@bluewin.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-30 08:19:40 -07:00
Shreyansh Paliwal
0f0ce07625 doc: gitignore: clarify pattern base for info/exclude and core.excludesFile
The pattern format section describes how patterns are interpreted
relative to the location of a .gitignore file, but does not mention
the behavior for exclude sources outside the working tree.

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

Reported-by: Dan Drake <dan@dandrake.org>
Signed-off-by: Shreyansh Paliwal <shreyanshpaliwalcmsmn@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-28 11:41:59 -07:00
Taylor Blau
3f7c0e722e pack-objects: support excluded-open packs with --stdin-packs
In cd846bacc7 (pack-objects: introduce '--stdin-packs=follow',
2025-06-23), pack-objects learned to traverse through commits in
included packs when using '--stdin-packs=follow', rescuing reachable
objects from unlisted packs into the output.

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

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

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

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

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

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

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

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

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-27 13:40:40 -07:00
Mirko Faina
0284046ad0 format-patch: removing unconditional wrapping
Using format-patch with --commit-list-format different than shortlog,
causes the commit entry lines to wrap if they get longer than
MAIL_DEFAULT_WRAP (72 characters).

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

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

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-27 13:10:12 -07:00
Mirko Faina
acee42d3e5 docs: fix --commit-list-format related entries
Documentation specifies that "git format-patch" would default to
format.commitListFormat if --commit-list-format is not given, but
doesn't specify the default if the format.commitListFormat is not set.
The text for --cover-letter is also obsolete as the commit list can now
be something other than a shortlog.

Document to reflect changes.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-27 13:09:50 -07:00
Junio C Hamano
5361983c07 The 22nd batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-27 11:00:03 -07:00
Junio C Hamano
18396dc97d Merge branch 'kh/doc-interpret-trailers-1'
Doc updates.

* kh/doc-interpret-trailers-1:
  interpret-trailers: use placeholder instead of *
  doc: config: convert trailers section to synopsis style
  doc: interpret-trailers: normalize and fill out options
  doc: interpret-trailers: convert to synopsis style
2026-03-27 11:00:02 -07:00
Junio C Hamano
ae55b12bb3 Merge branch 'ej/ref-transaction-hook-preparing'
The reference-transaction hook was taught to be triggered before
taking locks on references in the "preparing" phase.

* ej/ref-transaction-hook-preparing:
  refs: add 'preparing' phase to the reference-transaction hook
2026-03-27 11:00:02 -07:00
Junio C Hamano
f23054409b Merge branch 'gi/doc-boolean-config-typofix'
Doc typofix.

* gi/doc-boolean-config-typofix:
  doc: add missing space on git-config page
2026-03-27 11:00:02 -07:00
Derrick Stolee
302aff0922 backfill: accept revision arguments
The existing implementation of 'git backfill' only includes downloading
missing blobs reachable from HEAD. Advanced uses may desire more general
commit limiting options, such as '--all' for all references, specifying a
commit range via negative references, or specifying a recency of use such as
with '--since=<date>'.

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

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

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

Signed-off-by: Derrick Stolee <stolee@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-26 09:38:06 -07:00
Siddharth Asthana
2760ee4983 replay: add --revert mode to reverse commit changes
Add a `--revert <branch>` mode to git replay that undoes the changes
introduced by the specified commits. Like --onto and --advance, --revert
is a standalone mode: it takes a branch argument and updates that branch
with the newly created revert commits.

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

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

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

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

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

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

Helped-by: Christian Couder <christian.couder@gmail.com>
Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Elijah Newren <newren@gmail.com>
Helped-by: Phillip Wood <phillip.wood123@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-25 14:21:20 -07:00
Adrian Ratiu
5c58dbc887 hook: reject unknown hook names in git-hook(1)
Teach "git hook run" and "git hook list" to reject hook event names
that are not recognized by Git. This helps catch typos such as
"prereceive" when "pre-receive" was intended, since in 99% of the
cases users want known (already-existing) hook names.

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

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

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-25 14:00:48 -07:00
Adrian Ratiu
b66efad2b1 hook: show config scope in git hook list
Users running "git hook list" can see which hooks are configured but
have no way to tell at which config scope (local, global, system...)
each hook was defined.

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

Without the flag the output is unchanged.

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

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

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

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-25 14:00:47 -07:00
Adrian Ratiu
2e5dbaff16 hook: make consistent use of friendly-name in docs
Both `name` and `friendly-name` is being used. Standardize on
`friendly-name` for consistency since name is rather generic,
even when used in the hooks namespace.

Suggested-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-25 14:00:46 -07:00
Junio C Hamano
41688c1a23 The 21st batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-25 12:58:05 -07:00
Junio C Hamano
105a22cf69 Merge branch 'tb/incremental-midx-part-3.2'
Further work on incremental repacking using MIDX/bitmap

* tb/incremental-midx-part-3.2:
  midx: enable reachability bitmaps during MIDX compaction
  midx: implement MIDX compaction
  t/helper/test-read-midx.c: plug memory leak when selecting layer
  midx-write.c: factor fanout layering from `compute_sorted_entries()`
  midx-write.c: enumerate `pack_int_id` values directly
  midx-write.c: extract `fill_pack_from_midx()`
  midx-write.c: introduce `midx_pack_perm()` helper
  midx: do not require packs to be sorted in lexicographic order
  midx-write.c: introduce `struct write_midx_opts`
  midx-write.c: don't use `pack_perm` when assigning `bitmap_pos`
  t/t5319-multi-pack-index.sh: fix copy-and-paste error in t5319.39
  git-multi-pack-index(1): align SYNOPSIS with 'git multi-pack-index -h'
  git-multi-pack-index(1): remove non-existent incompatibility
  builtin/multi-pack-index.c: make '--progress' a common option
  midx: introduce `midx_get_checksum_hex()`
  midx: rename `get_midx_checksum()` to `midx_get_checksum_hash()`
  midx: mark `get_midx_checksum()` arguments as const
2026-03-25 12:58:04 -07:00
Junio C Hamano
ce74208c2f The 20th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-24 12:31:34 -07:00
Junio C Hamano
c006399b73 Merge branch 'ty/doc-diff-u-wo-number'
"git diff -U<num>" was too lenient in its command line parsing and
took an empty string as a valid <num>.

* ty/doc-diff-u-wo-number:
  diff: document -U without <n> as using default context
2026-03-24 12:31:34 -07:00
Junio C Hamano
04a7124af0 Merge branch 'gj/user-manual-fix-grep-example'
Fix an example in the user-manual.

* gj/user-manual-fix-grep-example:
  doc: fix git grep args order in Quick Reference
2026-03-24 12:31:32 -07:00
Junio C Hamano
49e6a7cd63 Merge branch 'ps/history-split'
"git history" learned the "split" subcommand.

* ps/history-split:
  builtin/history: implement "split" subcommand
  builtin/history: split out extended function to create commits
  cache-tree: allow writing in-memory index as tree
  add-patch: allow disabling editing of hunks
  add-patch: add support for in-memory index patching
  add-patch: remove dependency on "add-interactive" subsystem
  add-patch: split out `struct interactive_options`
  add-patch: split out header from "add-interactive.h"
2026-03-24 12:31:32 -07:00
Junio C Hamano
410ab9a257 Merge branch 'jt/fast-import-sign-again'
"git fast-import" learned to optionally replace signature on
commits whose signatures get invalidated due to replaying by
signing afresh.

* jt/fast-import-sign-again:
  fast-import: add mode to sign commits with invalid signatures
  gpg-interface: allow sign_buffer() to use default signing key
  commit: remove unused forward declaration
2026-03-24 12:31:31 -07:00
Mirko Faina
36c16a5b7f format-patch: --commit-list-format without prefix
Having to prefix a custom format-string with "log:" when passed from the
CLI can be annoying. It would be great if this prefix wasn't required.

Teach make_cover_letter() to accept custom format-strings without the
"log:" prefix if a placeholder is detected.

Note that both here and in "git log --format" the check is done naively
by just checking for the presence of a '%'.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-23 13:06:59 -07:00
Mirko Faina
d022dc77ab format-patch: add preset for --commit-list-format
"git format-patch --commit-list-format" enables the user to make their
own format for the commit list in the cover letter. It would be nice to
have a ready to use format to replace shortlog.

Teach make_cover_letter() the "modern" format preset.
This new format is the same as: "log:[%(count)/%(total)] %s".

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-23 13:06:59 -07:00
Mirko Faina
344f00ef9d docs/pretty-formats: add %(count) and %(total)
When --commit-list-format was introduced to format-patch, two new
placeholders were added to the PRETTY FORMATS code without being
documented. Do so now.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-23 13:06:58 -07:00
Mirko Faina
67ea2ad7d1 format-patch: rename --cover-letter-format option
To align the name of the configuration variable and the name of the
command line option, either one should change name. By changing the name
of the option we get the added benefit of having --cover-<TAB> expand to
--cover-letter without ambiguity.

If the user gives the --cover-letter-format option it would be
reasonable to expect that the user wants to generate the cover letter
despite not giving --cover-letter.

Rename --cover-letter-format to --commit-list-format and make it imply
--cover-letter unless --no-cover-letter is given.

Signed-off-by: Mirko Faina <mroik@delayed.space>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-23 13:06:58 -07:00
Junio C Hamano
1080981ddb The 19th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-23 09:20:31 -07:00
Junio C Hamano
7ff1e8dc1e The 18th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-19 09:54:57 -07:00
Junio C Hamano
5a0ee6f793 Merge branch 'jc/doc-wholesale-replace-before-next'
Doc update.

* jc/doc-wholesale-replace-before-next:
  SubmittingPatches: spell out "replace fully to pretend to be perfect"
2026-03-19 09:54:56 -07:00
Junio C Hamano
accd0e107b Merge branch 'lc/rebase-trailer'
"git rebase" learns "--trailer" command to drive the
interpret-trailers machinery.

* lc/rebase-trailer:
  rebase: support --trailer
  commit, tag: parse --trailer with OPT_STRVEC
  trailer: append trailers without fork/exec
  trailer: libify a couple of functions
  interpret-trailers: refactor create_in_place_tempfile()
  interpret-trailers: factor trailer rewriting
2026-03-19 09:54:56 -07:00
Gabriel “gabldotink”
fc8a4f15e7 doc: add missing space on git-config page
Signed-off-by: Gabriel “gabldotink” <gabl@gabl.ink>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-18 14:50:27 -07:00
Vaidas Pilkauskas
640657ffd0 http: add support for HTTP 429 rate limit retries
Add retry logic for HTTP 429 (Too Many Requests) responses to handle
server-side rate limiting gracefully. When Git's HTTP client receives
a 429 response, it can now automatically retry the request after an
appropriate delay, respecting the server's rate limits.

The implementation supports the RFC-compliant Retry-After header in
both delay-seconds (integer) and HTTP-date (RFC 2822) formats. If a
past date is provided, Git retries immediately without waiting.

Retry behavior is controlled by three new configuration options
(http.maxRetries, http.retryAfter, and http.maxRetryTime) which are
documented in git-config(1).

The retry logic implements a fail-fast approach: if any delay
(whether from server header or configuration) exceeds maxRetryTime,
Git fails immediately with a clear error message rather than capping
the delay. This provides better visibility into rate limiting issues.

The implementation includes extensive test coverage for basic retry
behavior, Retry-After header formats (integer and HTTP-date),
configuration combinations, maxRetryTime limits, invalid header
handling, environment variable overrides, and edge cases.

Signed-off-by: Vaidas Pilkauskas <vaidas.pilkauskas@shopify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-17 09:14:19 -07:00
Eric Ju
60d8c1e97d refs: add 'preparing' phase to the reference-transaction hook
The "reference-transaction" hook is invoked multiple times during a ref
transaction. Each invocation corresponds to a different phase:

- The "prepared" phase indicates that references have been locked.
- The "committed" phase indicates that all updates have been written to disk.
- The "aborted" phase indicates that the transaction has been aborted and that
  all changes have been rolled back.

This hook can be used to learn about the updates that Git wants to perform.
For example, forges use it to coordinate reference updates across multiple
nodes.

However, the phases are insufficient for some specific use cases. The earliest
observable phase in the "reference-transaction" hook is "prepared", at which
point Git has already taken exclusive locks on every affected reference. This
makes it suitable for last-chance validation, but not for serialization. So by
the time a hook sees the "prepared" phase, it has no way to defer locking, and
thus it cannot rearrange multiple concurrent ref transactions relative to one
another.

Introduce a new "preparing" phase that runs before the "prepared" phase, that
is before Git acquires any reference lock on disk. This gives callers a
well-defined window to perform validation, enable higher-level ordering of
concurrent transactions, or reject the transaction entirely, all without
interfering with the locking state.

This change is strictly speaking not backwards compatible. Existing hook
scripts that do not know how to handle unknown phases may treat 'preparing'
as an error and return non-zero. But the hook is considered to expose
internal implementation details of how Git works, and as such we have
been a bit more lenient with changing its exact semantics, like for example
in a8ae923f85 (refs: support symrefs in 'reference-transaction' hook, 2024-05-07).

An alternative would be to introduce a "reference-transaction-v2" hook that
knows about the new phase. This feels like a rather heavy-weight option though,
and was thus discarded.

Helped-by: Patrick Steinhardt <ps@pks.im>
Helped-by: Justin Tobler <jltobler@gmail.com>
Helped-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Eric Ju <eric.peijian@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-16 21:00:44 -07:00
Kristoffer Haugsbakk
95bd86772e doc: config: convert trailers section to synopsis style
Convert this part of the configuration documentation to synopsis style
so that all of git-interpret-trailers(1) is consistent.

See the commit message from two commits ago.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-16 15:04:37 -07:00
Kristoffer Haugsbakk
bec94f79e4 doc: interpret-trailers: normalize and fill out options
Some negated options are missing according to
`git interpret-trailers -h`.

Also normalize to the “stuck form” (see gitcli(7)) like what was done
in 806337c7 (doc: notes: use stuck form throughout, 2025-05-27).[1]

Also normalize the order of the regular and negated options according to
the current convention.[2]

Also note that `--no-trailer` will reset the list.

† 1: See also https://lore.kernel.org/git/6f7d027e-088a-4d66-92af-b8d1c32d730c@app.fastmail.com/
† 2: https://lore.kernel.org/git/xmqqcyct1mtq.fsf@gitster.g/

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-03-16 15:04:37 -07:00