Commit Graph

17570 Commits (c331d73b3e03853aa7a8a7bed273f11aebda4ee6)

Author SHA1 Message Date
Junio C Hamano c73e85354c The 20th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-28 11:04:57 -07:00
Junio C Hamano 9c94d206f0 Merge branch 'kh/format-rev-doc-synopsis'
The documentation for 'git format-rev' has been updated to use the
[synopsis] block definition on code blocks to properly highlight
placeholders, and a quoting inconsistency in the running text has
been fixed.

* kh/format-rev-doc-synopsis:
  doc: format-rev: use [synopsis] on code block
  doc: format-rev: quote subject placeholder before and after
2026-08-28 11:04:57 -07:00
Junio C Hamano f78ce2f7b6 The 19th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-25 10:53:34 -07:00
Junio C Hamano 6d7be5f7fd Merge branch 'ss/submittingpatches-typofix'
Typofix.

* ss/submittingpatches-typofix:
  doc: fix typo in submitting patches
2026-08-25 10:53:32 -07:00
Junio C Hamano 6730f07098 Merge branch 'ss/repack-drop-filtered'
'git repack' has been taught '--drop-filtered' to delete local
promisor blobs exceeding a limit (currently 'blob:limit=') in partial
clones, reclaiming space.  Guards prevent running during other
operations or if referenced by the index.

* ss/repack-drop-filtered:
  builtin/repack: add guards for --drop-filtered
  builtin/repack: actually drop filtered promisor blobs
  builtin/repack: enumerate promisor blobs for --drop-filtered
  repack-promisor: allow excluding objects from the rebuilt promisor pack
  list-objects-filter: add list_objects_filter__filter_oidset()
  builtin/repack: add --drop-filtered and --dry-run options
2026-08-25 10:53:32 -07:00
Junio C Hamano 2c3adbb2c4 The 18th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-24 13:17:51 -07:00
Junio C Hamano 593c42fe07 The 17th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-23 18:01:47 -07:00
Junio C Hamano 679a72c6b8 Merge branch 'kk/merge-base-exhaustion'
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.

* kk/merge-base-exhaustion:
  commit-reach: remove commit-date ordering fallback
  commit-reach: move min_generation check into paint_queue_get()
  commit-reach: terminate merge-base walk when one paint side is exhausted
  commit-reach: introduce struct paint_state with per-side counters
  t6600: add clock-skew topologies and step counts for edge cases
  commit-reach: add trace2 instrumentation to paint_down_to_common()
  t6099: add side-exhaustion regression test
  t6600: add test cases for side-exhaustion edge cases
  test-lib-functions: improve diagnostic output for trace2 data assertions
  Documentation/technical: add paint-down-to-common doc
2026-08-23 18:01:46 -07:00
Junio C Hamano 10d3ea2469 Merge branch 'cc/fast-import-usage'
The usage string of 'git fast-import' has been updated to use the
parse_options() API for displaying help, and its SYNOPSIS in the
documentation has been standardized to match.

* cc/fast-import-usage:
  fast-import: remove useless from_stream argument
  fast-import: use parse_options() for command line options
  fast-import: use callbacks to parse some options
  fast-import: use struct option for usage string
  fast-import: move command state globals into 'struct fast_import_state'
  fast-import: introduce 'struct fast_import_state'
  fast-import: factor out option_*() functions
  fast-import: use int for some bool flags
  fast-import: localize 'i' into the 'for' loops using it
  api-parse-options.adoc: document hidden and OPT_*_F option macros
  api-parse-options.adoc: document per-option flags
  parse-options: introduce OPT_HIDDEN_GROUP
2026-08-23 18:01:42 -07:00
Junio C Hamano 4b27b7c707 Merge branch 'ps/cat-file-remote-object-info-type'
The 'remote-object-info' command for 'git cat-file --batch-command'
has been extended to support the '%(objecttype)' placeholder.

* ps/cat-file-remote-object-info-type:
  cat-file: unify default format
  serve: advertise type capability
  fetch-object-info: parse type from server response
  protocol-caps: add type support to object-info
  transport: drop remote object-info fields from transport struct
  fetch-object-info: die() on the remaining error path
  fetch-object-info: use dedicated struct for the results
  fetch-object-info: pass arguments directly instead of a struct
  fetch-object-info: detect malformed server responses
  t5701: use test_file_size() to get the size of a file
2026-08-23 18:01:42 -07:00
Junio C Hamano 1a3e64c6c4 The 16th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-20 07:30:52 -07:00
Junio C Hamano 3f664917c2 Merge branch 'kh/doc-trailers'
Documentation for 'git interpret-trailers' has been updated to explain
the format of trailer keys (alphanumeric characters and hyphens),
replace outdated terminology, define key terms upfront, and document
how comment lines in the input are treated.

* kh/doc-trailers:
  doc: interpret-trailers: document comment line treatment
  doc: interpret-trailers: rewrite new-trailers paragraphs
  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
2026-08-20 07:30:52 -07:00
Junio C Hamano 006933a32c Merge branch 'hn/branch-delete-merged'
The 'git branch' command has been taught the '--delete-merged' option
to remove local branches that are already merged into their tracked
remote-tracking branches.

* hn/branch-delete-merged:
  branch: add --dry-run for --delete-merged
  branch: add branch.<name>.deleteMerged opt-out
  branch: add --delete-merged <pattern>
  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
2026-08-20 07:30:51 -07:00
Junio C Hamano dea0ea3582 The 15th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-18 09:31:36 -07:00
Junio C Hamano e23356ae1a Merge branch 'hn/bisect-reset-when-found'
The 'git bisect' command has been taught a
'--reset-when-found[=<where>]' option that tells the command to
automatically run 'git bisect reset' to jump back to the original
state or to the found culprit.

* hn/bisect-reset-when-found:
  bisect: add --reset-when-found to leave when done
  bisect: let bisect_reset() optionally check out quietly
2026-08-18 09:31:36 -07:00
Junio C Hamano 1428b15baf Merge branch 'kh/doc-refs-migrate-limitations'
The known limitations of the ref format migration in 'git refs' have
been moved to be displayed as a warning admonition directly under the
description of the 'migrate' subcommand, improving visibility.  A
reference to 'git-maintenance' has also been corrected to use the
'linkgit' macro.

* kh/doc-refs-migrate-limitations:
  doc: refs: linkgit to git-maintenance(1)
  doc: refs: put ref migration warning under the command
2026-08-18 09:31:36 -07:00
Kristoffer Haugsbakk 634257a89b doc: format-rev: use [synopsis] on code block
This code block uses the placeholder `<subject>`. Let’s highlight this
placeholder properly by using the `synopsis` open block definition which
was introduced in a34d1d53 (doc: convert git-show to synopsis style,
2026-02-06). This renders the block like a code block but with emphasis
styling on placeholders, just like inline-verbatim (`) in running text.

Yes, note that open blocks since commit a34d1d53 can, on synopsis-style
docs like this one, be immediately preceded by `[synopsis]`, just like
the command synopsis is:

    [synopsis]
    (EXPERIMENTAL!) git format-rev - [...]

Cf. verse-style:

    [verse]
    'git name-rev' [...]

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-17 13:33:06 -07:00
Kristoffer Haugsbakk ddd7de1341 doc: format-rev: quote subject placeholder before and after
We first talk about just `%s`, but then show the result with
quotes. That is inconsistent. Let’s use quotes both in the format
as well as in the result.

The implied input here, which is not spelled out for brevity, is:

    Did we not fix this in <commit object name>?

Which is then supposed to be formatted to `"<subject>"`.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-17 13:33:06 -07:00
Junio C Hamano 18e66859d8 The 14th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-15 09:20:27 -07:00
Junio C Hamano 230296d560 Merge branch 'jc/add-resolved'
'git add' has been taught a new '--resolved' option to stage
conflict-resolved paths, while leaving unrelated local changes
unstaged.  It scans the unmerged paths for leftover conflict
markers and aborts if any are found.

* jc/add-resolved:
  add: introduce '--resolved' option
  read-cache: add remove_file_from_index_with_flags()
  merge-ll: consolidate conflict marker scanning logic
  read-cache: reindent
2026-08-15 09:20:27 -07:00
Junio C Hamano 8b34c1f352 Merge branch 'tn/packfile-uri-concurrency'
Concurrent downloads of packfiles via packfile URIs and dumb HTTP are
safer by avoiding concurrent appends to the staging file.  Opening in
read-write mode with separate file offsets prevents corruption and
preserves resumability.  'fetch-pack' now tolerates pre-existing
'.keep' files.

* tn/packfile-uri-concurrency:
  fetch-pack: accept "pack" output for packfile URIs
  http: permit unlinking partial packs on Windows
  http: avoid concurrent appends to partial packs
  http: accept HTTP 416 for complete partial packs
  http: avoid closing index-pack input twice
  http-fetch: correct --index-pack-arg documentation
2026-08-15 09:20:27 -07:00
Swapnil Saste | INDIA 026636128f doc: fix typo in submitting patches
Remove the article "an" before "incremental updates".

Signed-off-by: Swapnil Saste | INDIA <theswapnilsaste@gmail.Com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-14 12:21:29 -07:00
Siddharth Shrimali c6fed8b7a6 builtin/repack: add guards for --drop-filtered
--drop-filtered removes local promisor blobs. That is only safe when the
repository is not mid-operation and when the blobs are not actively in
use, so add two guards, both skipped for bare repositories which have
neither a worktree nor an index.

First, refuse to run while a merge, rebase, am, cherry-pick, revert, or
bisect is in progress. During these operations the working tree and
index are in an intermediate state, and rewriting packs and deleting
objects underneath a half-finished operation is unsafe.

Second, refuse to drop a blob that the current index references. Such a
blob is needed by the working tree, so dropping it would only cause the
next command that touches the worktree to lazy-fetch it straight back,
reclaiming nothing. The offending path is reported so the user can see
why the drop was refused.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 13:34:50 -07:00
Siddharth Shrimali 0c4142a25b builtin/repack: actually drop filtered promisor blobs
Make --drop-filtered remove the enumerated promisor blobs instead of
only listing them.

The drop set is computed before repack_promisor_objects() runs, and on
a real run it is passed in so the rebuilt promisor pack omits those
blobs. --drop-filtered implies -d so the old promisor packs, which
still contain the dropped blobs, are removed. Without this the blobs
would survive in the redundant packs. The existing repack machinery
performs the write-before-delete and fsync, so the drop is crash-safe.

The dropped blobs become absent locally but remain recoverable from the
promisor remote, so a later access lazy-fetches them back
transparently. --dry-run keeps its previous behavior, i.e. it lists the
candidates and changes nothing.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 13:34:49 -07:00
Junio C Hamano 11c6700f10 The 13th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 10:07:00 -07:00
Junio C Hamano 461ed7e1b3 Merge branch 'kh/doc-replay-config'
Documentation for 'git replay' has been updated to refer to its
configuration variables.

* kh/doc-replay-config:
  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)
2026-08-11 10:07:00 -07:00
Junio C Hamano bf6bc2ae42 Merge branch 'ja/doc-synopsis-style-yet-more'
Synopsis and options in the documentation for 'git format-patch',
'git imap-send', 'git send-email', and 'git request-pull' have been
updated to the modern style.

* ja/doc-synopsis-style-yet-more:
  doc: convert git-request-pull synopsis and options to new style
  doc: convert git-send-email synopsis and options to new style
  doc: convert git-format-patch synopsis and options to new style
  doc: convert git-imap-send synopsis and options to new style
2026-08-11 10:06:59 -07:00
Kristofer Karlsson 56c9056e30 commit-reach: remove commit-date ordering fallback
Remove the fallback that switched paint_down_to_common() from
generation ordering to commit-date ordering when the commit-graph
lacks corrected commit dates (v1 graph with topo levels only).

The fallback was added in 091f4cf3 (commit: don't use generation
numbers if not needed, 2018-08-30) to avoid a performance
regression on the Linux kernel repo where v1 topo levels caused
"git merge-base v4.8 v4.9" to walk 636k commits instead of 167k.
A side branch with a low topo level stayed in the queue behind a
long chain, preventing early STALE propagation.

Side-exhaustion (added in the previous commits) solves this
differently by terminating the walk as soon as one paint side
empties from the queue, preventing the deep walk regardless of
queue ordering. Benchmarks of "git merge-base --all v4.8 v4.9"
on the Linux kernel repo show that side-exhaustion reduces the
step count far below what the date-ordering fallback achieved:

                         steps      time
  no graph, baseline:   167,413    3.25 s
  v1 graph, baseline:   167,413    0.25 s
  v2 graph, baseline:   167,441    0.29 s
  v1 graph, this series:  5,725    0.02 s
  v2 graph, this series:  3,887    0.01 s

With generation ordering always active, the existing min_generation
check in paint_queue_get() can safely terminate once the walk
crosses below the caller's generation floor. The date ordering
fallback broke this invariant: a commit could have a finite topo
level while the queue was date-ordered, causing the early exit to
fire before all merge bases were found.

With the fallback removed, gen_ordered is always true and can be
dropped. The topo_ceiling field (introduced earlier) already
handles V1_MAX saturation, so the early exit gates need no further
changes.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:34:32 -07:00
Kristofer Karlsson 02d7ba092d commit-reach: terminate merge-base walk when one paint side is exhausted
Add an early termination check to paint_down_to_common() using the
per-side counters introduced earlier. Once the walk enters the
ordered region, terminate early when one side's exclusive count
drops to zero -- no new merge-base can form without both paint
sides meeting.

The check also waits for pending_merge_bases to reach zero, ensuring
all merge-base candidates have been dequeued and recorded before
exiting.

The optimization is gated by gen_ordered (which excludes v1
commit-graphs that use the date-ordering fallback) and by a
generation check against topo_ceiling. topo_ceiling is
GENERATION_NUMBER_INFINITY for v2 graphs and
GENERATION_NUMBER_V1_MAX for v1 graphs, so that saturated commits
are treated as unordered. Together these ensure the check only
fires in the ordered region where topological ordering holds.

The same topo_ceiling boundary is applied to the existing
single-result early exit so that all generation-dependent gates
express the same saturation-aware boundary consistently.

Step counts measured with trace2 on git.git with commit-graph:

  merge-base --all v2.0.0 v2.55.0-rc1:
    before: 72264 steps    after: 44589 steps

  merge-base --all v2.55.0-rc1 v2.55.0-rc1~5:
    before:   110 steps    after:     7 steps

Helped-by: Derrick Stolee <stolee@gmail.com>
Helped-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:34:32 -07:00
Kristofer Karlsson a3e5bad734 commit-reach: introduce struct paint_state with per-side counters
Add a paint_state struct for use by paint_down_to_common() that
wraps a prio_queue with per-side commit counters. Each non-stale
queued commit occupies exactly one counter bucket based on its
paint flags: PARENT1-only, PARENT2-only, or both sides (a pending
merge-base candidate).

The counters are maintained by paint_count_update() which adjusts
the appropriate bucket by a signed delta. An exhaustive switch on
the paint+stale bits documents all valid flag combinations in one
place.

Convert paint_down_to_common() to use paint_state. The loop now
drains the queue via paint_queue_get() which returns NULL when all
counters reach zero, replacing the old pointer-based termination
(max_nonstale). This is equivalent behavior -- both conditions
detect that no non-stale entries remain.

paint_queue_get() uses a "pop first" form: it dequeues a commit,
then checks the counters. This means the loop exits one iteration
earlier than the old code in some topologies (the popped stale
commit is never processed), so a few step counts drop by one.

The existing nonstale_queue is left in place for ahead_behind(),
though nonstale_queue_put_dedup() and nonstale_queue_get_dedup()
become unused and are removed.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:34:32 -07:00
Kristofer Karlsson cd2ab0e128 Documentation/technical: add paint-down-to-common doc
Add a technical document describing the paint_down_to_common()
algorithm used for merge-base computation, covering the paint
walk, generation number regions, and termination conditions.

Signed-off-by: Kristofer Karlsson <krka@spotify.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:34:31 -07:00
Christian Couder 863937696e fast-import: use parse_options() for command line options
Previous commits have started to use the parse-options API to display
output from `git fast-import -h` and `git fast-import --help-all` and
to prepare for parsing the command line options using this API.

Let's now actually use the API to parse command line options.

This brings a number of changes that are mostly beneficial:

  - The `--alias`, `--get-mark`, `--cat-blob`, `--ls` and `--notes`
    options are no longer accepted on the command line. They were
    previously accepted as no-ops because parse_argv() fell through to
    parse_one_feature(). They are not documented in the OPTIONS section
    and are only meaningful as in-stream feature assertions, so
    accepting them on the command line was an accident of code sharing
    dating back to 9c8398f0c9 (fast-import: add option command,
    2009-12-04).

  - Abbreviated options like `--dep=5` now work since parse_options()
    allows unambiguous prefixes.

  - As `--cat-blob` is an abbreviation of `--cat-blob-fd`, using the
    former on the command line will fail with "option `cat-blob-fd'
    requires a value" unlike the other four options that are not
    accepted anymore on the command line (see above).

  - Value-taking options now also accept the space-separated
    `--opt value` form, like `--depth 5`, in addition to the
    `--opt=value` form.

  - A bare or trailing `--` is now accepted and the stream is read
    normally, while it used to be a usage error.

  - The error messages for some options might differ a bit.

  - The code is shorter and more standard.

Note that parse_one_feature() is now always called with its
`from_stream` argument set to 1, but the code simplifications that
can be made are left for a following clean-up commit.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder 27ab5815f7 fast-import: use struct option for usage string
Currently `git fast-import -h` shows the following on a single line:

  usage : git fast-import [--date-format=<f>] [--max-pack-size=<n>] \
                          [--big-file-threshold=<n>] [--depth=<n>] \
                          [--active-branches=<n>] \
                          [--export-marks=<marks.file>]

This output has a number of issues like:

  - It's missing a lot of options.
  - It's not consistent with the SYNOPSIS section of the doc.
  - With `--help-all` instead of `-h` additional hidden options should
    be shown, but that's not the case.
  - It's not standard style anymore.
  - Most other Git commands show additional lines for most of the
    options they support.

Also while most commands use the parse-options API to handle their
options, "builtin/fast-import.c" still doesn't use it.

Let's improve on that by using the parse-options API to display the
options when `-h` and `--help-all` are used.

While at it, let's make the SYNOPSIS section of
"Documentation/git-fast-import.adoc" consistent with the new usage
string.

This deliberately leaves it to future work to also use the
parse-options API to actually parse the options.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:17 -07:00
Christian Couder 08b7e358e3 api-parse-options.adoc: document hidden and OPT_*_F option macros
In "Documentation/technical/api-parse-options.adoc", the list of option
macros does not mention the `OPT_*_F()` macro variants that take a
trailing `flags` argument, nor the `OPT_HIDDEN_GROUP()` and
`OPT_HIDDEN_BOOL()` convenience macros.

Now that a previous commit documents the per-option flags, let's
document these macros too:

  - Add a paragraph explaining the `OPT_*_F` convention and how it
    relates to the per-option flags.

  - Document `OPT_HIDDEN_GROUP()`, introduced in a previous commit,
    right after `OPT_GROUP()`.

  - Document `OPT_HIDDEN_BOOL()` right after `OPT_BOOL()`.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:16 -07:00
Christian Couder e455bade3a api-parse-options.adoc: document per-option flags
The "Flags" section in "Documentation/technical/api-parse-options.adoc"
documents the flags that can be passed to parse_options() itself. It
does not, however, document the flags that can be set on individual
options through the `flags` member of `struct option` (and through the
`OPT_*_F()` macro variants).

These per-option flags are used throughout the codebase (for example
`PARSE_OPT_HIDDEN` is used to hide an option from `-h` while still
showing it with `--help-all`), but a reader currently has to dig into
"parse-options.h" to find them.

To remediate that, let's add an "Option flags" subsection to the
"Data Structure" section, just before the list of option macros.

Let's also make it explicit that these are distinct from the
parse_options() flags described earlier, and let's describe the `-h`
versus `--help-all` behavior for `PARSE_OPT_HIDDEN`.

Signed-off-by: Christian Couder <christian.couder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-11 07:33:16 -07:00
Kristoffer Haugsbakk 4515c86fd9 doc: interpret-trailers: document comment line treatment
Comment lines have always been ignored but this is not documented.

The primary motivation here is to be reasonably complete in the
documentation of how trailers are parsed; this is after all the only
documentation page that documents this format. However, and going beyond
that point, we could imagine that someone would want to use this format
outside a commit (or tag) message context, like say in Git notes.

On the other hand, it seems far-fetched that someone would be caught
off guard by this considering that comment characters/strings are not
likely to be alphanumeric,[1] which would mean that these comment lines
would be treated as non-trailer lines if they were *not* detected and
removed as comment lines.

† 1: A notable exception is that Jujutsu VCS uses `JJ:` as
     the comment string

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:52 -07:00
Kristoffer Haugsbakk cb657364d5 doc: interpret-trailers: rewrite new-trailers paragraphs
Two commits ago we moved new-trailers paragraph next to each other.
But there is something curious about two of them:

    By default the new trailer will appear at the end of the trailer
    block. [...]

Then a source block and a paragraph later:

    By default, a `<key>=<value>` or `<key>:<value>` argument given
    using `--trailer` will be appended after the existing trailers only
    if [...]

Why are there two paragraphs that talk about how “By default” a trailer
will be appended?

We can make these paragraphs flow better, and with a more distinct
character each, by dividing the flow like this:

1. Declare that we are about to talk about `--trailer` appending
2. Explain the default behavior
3. Explain how this affects the trailer block
4. Then discuss what each trailer line will look like

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:52 -07:00
Kristoffer Haugsbakk 4d45e571ae doc: interpret-trailers: commit to “trailer block” term
We chose to introduce the term “trailer block” into the documentation a
few commits ago.[1] It is used in the code though, so it is not a newly
invented term.

That term was useful to explain where the trailers are found (they
*trail* the message). But it is also useful here, where we explain
how trailers are added to existing messages, how trailer blocks are
found (beyond the simple case in the introduction), and how the end
of the message is found.

Also note that we simplify the “blank line” point. The text says:

    A blank line will be added before the new trailer if there isn't one
    already.

But this isn’t quite coherent. The previous sentence says “If there is
no existing trailer”, so we are in one of these modes:

1. discussing trailer blocks in general; or
2. discussing creating a new trailer block in particular.

If (1), then we shouldn’t add a blank line before the new trailer if
there exists a trailer block already. And if (2), then the “if there
isn’t one already” is redundant.[2] So just talking about the higher-
level “trailer block” simplifies the text, since we don’t have to worry
about the different contexts that *trailers* can find themselves in.

† 1: in commit “explain the format after the intro”
† 2: Note that non-trailer lines don’t matter here; if you have a
     trailer block consisting of `(cherry picked from commit <commit>)`,
     then you still shouldn’t insert a blank line before the new trailer
     since that would create a new trailer block

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:52 -07:00
Kristoffer Haugsbakk 1e4200ede5 doc: interpret-trailers: join new-trailers again
There are three paragraphs that talk about how a new trailer is added.
But the first one is separated from the other two by two paragraphs
about how `key-alias` can make using `--trailer` more convenient. This
short how-to does not follow thematically from the previous paragraph,
and can wait until we have fully described how a new trailer is
added. So let’s move the three paragraphs about the new-trailer topic
together and move the how-to paragraphs after that.

***

Let’s now review the history of the document. Even if the document
is not quite correct in its current state, just doing the apparently
obvious edit without considering the history does not respect the
effort that went into changing the document in the past.

These three paragraphs were originally next to each other, in the first
version of the doc.[1] But extra sentences about this how-to topic was
added to the first paragraph nine years later:[2]

    [...]
    `': '` (one colon followed by one space). For convenience, the
    <token> can be a shortened string key (e.g., "sign") instead of the
    full string which should [...]

And then it was split into it’s own paragraph a little later.[3]

This evolution shows, in my opinion, that this how-to never followed
thematically from the existing topic. Which means that there is nothing
that was potentially lost to time that we need to restore or respect.

† 1: dfd66ddf (Documentation: add documentation for 'git
     interpret-trailers', 2014-10-13)
† 2: eda2c44c (doc: trailer: mention 'key' in DESCRIPTION, 2023-06-15)
† 3: 6ccbc667 (trailer doc: <token> is a <key> or <keyAlias>, not both,
     2023-09-07)

Suggested-by: D. Ben Knoble <ben.knoble+github@gmail.com>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:52 -07:00
Kristoffer Haugsbakk fddec1fe11 doc: interpret-trailers: add key format example
All of the examples speak of the Happy Path where everything works
as intended. But failure examples can also be instructive. Especially
for explaining again, by example, the key format (see previous commit).

This also allows us to demonstrate trailer block detection with a
concrete example.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:52 -07:00
Kristoffer Haugsbakk fd39e5a481 doc: interpret-trailers: explain key format
A trailer key must consist of ASCII alphanumeric characters and
hyphens *only*. Let’s document it explicitly instead of relying on
readers being conservative and only basing their trailer keys on the
documentation examples.[1]

The previous commit provided us with an appropriate paragraph to
describe the key format.

† 1: Technically they would then miss out on using digits in them since
     all of the example keys just use letters and hyphens

Reported-by: Brendan Jackman <jackmanb@google.com>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:52 -07:00
Kristoffer Haugsbakk c88d60db44 doc: interpret-trailers: explain the format after the intro
You need to read the entire “Description” section in order to understand
the full trailer format. But there are many nuances, so that’s fine.
As a starter though we have an introductory example.[1] That turns out
to be crucial; the rest of this section talks about the mechanics of the
command and only incidentally the format itself.

Now, although the example might arguably be self-explanatory, we can
add a little preamble which defines the format in its simplest form as
well as define the most important terms.

Note that we name the “blank line” rule since I want to use that term
every time it comes up. It gets very mildly obfuscated if you call it
a “blank line” in one place[2] and “empty (or whitespace-only) ...” in
another one.[3]

We will define the format of the *key* in the next commit.

† 1: from d57fa7fc (doc: trailer: add more examples in DESCRIPTION,
     2023-06-15)
† 2: `Documentation/git-interpret-trailers.adoc:86` in
     5361983c (The 22nd batch, 2026-03-27)
† 3: `Documentation/git-interpret-trailers.adoc:93` in
     5361983c (The 22nd batch, 2026-03-27)

Suggested-by: D. Ben Knoble <ben.knoble+github@gmail.com>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:51 -07:00
Kristoffer Haugsbakk 33691bc9d7 doc: interpret-trailers: not just for commit messages
This command doesn’t interface with commits directly. You can
interpret or modify any kind of text, even though commit messages
are the most relevant.

The git(1) suite also isn’t restricted to only direct commit support
since git-tag(1) learned `--trailer` in 066cef77 (builtin/tag: add
--trailer option, 2024-05-05)

Now, we already introduce the command in the “Name” section as dealing
with commit messages as well. That is fine since that intro line needs
to remain pretty short.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:51 -07:00
Kristoffer Haugsbakk 500257fd2b doc: interpret-trailers: use “metadata” in Name as well
We now since the previous commit introduce the format as “trailer
metadata”. We can replace “structured information” with “metadata”
in the “Name” section to be consistent.

While “structured information” does emphasize that the data is not
loosely structured, we also say that this command adds to or parses
this format. I don’t think that we need to emphasize that it is
structured since clearly there is some structure there.

Both “metadata” and “structured information” can convey the same
information. But “metadata” is shorter and easier to deploy since
it’s just one word.

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:51 -07:00
Kristoffer Haugsbakk abb0d859f8 doc: interpret-trailers: replace “lines” with “metadata”
We removed the initial comparison to email headers in the previous
commit. Now the introduction paragraph just says “trailer lines”, and
the only hint that this is metadata/structured information is the
“otherwise free-form” phrase.

Let’s replace “lines” with “metadata” since that is their purpose.
This also makes the introduction more consistent with how I chose
to define trailers in the glossary:[1] “Key-value metadata”. (We will
introduce “key–value” in the upcoming commit “explain the format after
the intro”.)

† 1: 68e3c69e (Documentation/glossary: describe "trailer", 2024-11-17)

Let’s not emphasize “trailer” here since we are going to define the term
in the upcoming commit “explain the format after the intro”.

Let’s call it “trailer metadata” rather than “trailers metadata”.
At first it seemed better to use the latter:

1. We’re introducing the jargon, and the format is often discussed as
   plural “trailers”, with its constituent parts being singular
   “trailer”
2. What this replaces uses “trailer”, but it rescues the plural mood
   with “lines”
3. This is very soon going to go into the constituent parts, including
   each trailer, so we’re contrasting the concept name (trailers) with
   its parts

But:

1. The former reads better (most important)
2. “Trailer *metadata*” suggests plurality, similar to “trailer *lines*”

Helped-by: Matt Hunter <m@lfurio.us>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:51 -07:00
Kristoffer Haugsbakk bc27e75a0e doc: interpret-trailers: stop fixating on RFC 822
This command handles the trailer metadata format. But the command
isn’t introduced as such; it is instead introduced by stating that
these trailer lines look similar to RFC 822 email headers.

This is overwrought; most people do not deal directly with email
headers, and certainly not email RFCs.

Trailers are just key–value pairs that, like email headers, use colon
as the separator. The format in its simplest form is easy to describe
directly without comparing it to anything else; we will do that in the
upcoming commit “explain the format after the intro”.

For now, let’s:

• remove the first mention of email headers;
• keep the second, innocuous comparison with email line folding in the
  middle; and
• remove the now-unneeded disclaimer that trailers do not share many of
  the features of RFC 822 email headers—there is no invitation to
  speculate that trailers would follow any other email format rules
  since we do not compare them directly any more.

***

Talking about trailers as an RFC 822/2822-like format seems to go back
to the `--fixes`/`Fixes:` trailer topic,[1] the thread that precipitated
this command and in turn the first trailer support in git(1) beyond
adding s-o-b lines.

† 1: https://lore.kernel.org/all/20131027071407.GA11683@leaf/

Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-10 11:05:51 -07:00
Pablo Sabater 245f2a8b2e cat-file: unify default format
%(objecttype) is supported both by the client and by the server.
Change the temporary default format to the unified version that the
other commands use.

Update documentation to remove %(objecttype) from the caveats of
remote-object-info and show %(objecttype) support.

Now that type is supported and the default format unified, update the
tests to expect the new default format.

Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Mentored-by: Chandra Pratap <chandrapratap3519@gmail.com>
Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07 18:50:08 -07:00
Junio C Hamano 010afd3166 The 12th batch
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-07 14:48:01 -07:00
Kristoffer Haugsbakk 0dc68f404a doc: refs: linkgit to git-maintenance(1)
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-06 10:32:49 -07:00
Kristoffer Haugsbakk 4cc9039ff0 doc: refs: put ref migration warning under the command
I have to scroll down at least three screens in man(1) from the
`migrate` description in order to see the “known limitations” for
it. This is important information since the text says that concurrent
writes can lead to an inconsistent migrated state. Let’s move that text
up to the command description and put it inside a Warning admonition.

This section made sense when it was added in 25a0023f (builtin/refs:
new command to migrate ref storage formats, 2024-06-06); `migrate` was
the only subcommand, and this section was visible from the command
description. A one-page man page. But that is not the case anymore
now that the command has nine subcommands to describe.

Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Kristoffer Haugsbakk <code@khaugsbakk.name>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-06 10:32:49 -07:00