* [PATCH v2 2/3] commit-reach: deduplicate queue entries in paint_down_to_common
From: Kristofer Karlsson via GitGitGadget @ 2026-05-25 14:28 UTC (permalink / raw)
To: git
Cc: Derrick Stolee, Jeff King, Kristofer Karlsson, Kristofer Karlsson,
Kristofer Karlsson
In-Reply-To: <pull.2124.v2.git.1779719286.gitgitgadget@gmail.com>
From: Kristofer Karlsson <krka@spotify.com>
paint_down_to_common() can enqueue the same commit multiple times
when it is reached through different parents with different flag
combinations. Add an ENQUEUED flag to track whether a commit is
currently in the priority queue, and skip it if already present.
Introduce prio_queue_put_dedup() and prio_queue_get_dedup()
wrappers that manage the ENQUEUED flag on enqueue and dequeue.
This change is performance-neutral on its own: the O(n)
queue_has_nonstale() scan still dominates the per-iteration cost.
However, the deduplication guarantee (each commit appears in the
queue at most once) is a prerequisite for the next commit, which
replaces that scan with O(1) tracking.
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
---
commit-reach.c | 27 ++++++++++++++++++++++-----
object.h | 2 +-
2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/commit-reach.c b/commit-reach.c
index 5a52be90a6..85583ae359 100644
--- a/commit-reach.c
+++ b/commit-reach.c
@@ -17,8 +17,9 @@
#define PARENT2 (1u<<17)
#define STALE (1u<<18)
#define RESULT (1u<<19)
+#define ENQUEUED (1u<<20)
-static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT);
+static const unsigned all_flags = (PARENT1 | PARENT2 | STALE | RESULT | ENQUEUED);
static int compare_commits_by_gen(const void *_a, const void *_b)
{
@@ -39,6 +40,22 @@ static int compare_commits_by_gen(const void *_a, const void *_b)
return 0;
}
+static void prio_queue_put_dedup(struct prio_queue *queue, struct commit *c)
+{
+ if (c->object.flags & ENQUEUED)
+ return;
+ c->object.flags |= ENQUEUED;
+ prio_queue_put(queue, c);
+}
+
+static struct commit *prio_queue_get_dedup(struct prio_queue *queue)
+{
+ struct commit *commit = prio_queue_get(queue);
+ if (commit)
+ commit->object.flags &= ~ENQUEUED;
+ return commit;
+}
+
static int queue_has_nonstale(struct prio_queue *queue)
{
for (size_t i = 0; i < queue->nr; i++) {
@@ -70,15 +87,15 @@ static int paint_down_to_common(struct repository *r,
commit_list_append(one, result);
return 0;
}
- prio_queue_put(&queue, one);
+ prio_queue_put_dedup(&queue, one);
for (i = 0; i < n; i++) {
twos[i]->object.flags |= PARENT2;
- prio_queue_put(&queue, twos[i]);
+ prio_queue_put_dedup(&queue, twos[i]);
}
while (queue_has_nonstale(&queue)) {
- struct commit *commit = prio_queue_get(&queue);
+ struct commit *commit = prio_queue_get_dedup(&queue);
struct commit_list *parents;
int flags;
timestamp_t generation = commit_graph_generation(commit);
@@ -132,7 +149,7 @@ static int paint_down_to_common(struct repository *r,
oid_to_hex(&p->object.oid));
}
p->object.flags |= flags;
- prio_queue_put(&queue, p);
+ prio_queue_put_dedup(&queue, p);
}
}
diff --git a/object.h b/object.h
index 2b26de3044..8fb03ff90a 100644
--- a/object.h
+++ b/object.h
@@ -75,7 +75,7 @@ void object_array_init(struct object_array *array);
* bundle.c: 16
* http-push.c: 11-----14
* commit-graph.c: 15
- * commit-reach.c: 16-----19
+ * commit-reach.c: 16-------20
* builtin/last-modified.c: 1617
* object-name.c: 20
* list-objects-filter.c: 21
--
gitgitgadget
^ permalink raw reply related
* [PATCH v2 1/3] object.h: fix stale entries in object flag allocation table
From: Kristofer Karlsson via GitGitGadget @ 2026-05-25 14:28 UTC (permalink / raw)
To: git
Cc: Derrick Stolee, Jeff King, Kristofer Karlsson, Kristofer Karlsson,
Kristofer Karlsson
In-Reply-To: <pull.2124.v2.git.1779719286.gitgitgadget@gmail.com>
From: Kristofer Karlsson <krka@spotify.com>
Update three stale entries found during an audit of the flag
allocation table:
- sha1-name.c was renamed to object-name.c
- builtin/show-branch.c uses bits 0 and 2-28, not 0-26
(REV_SHIFT=2, MAX_REVS=FLAG_BITS-REV_SHIFT=27)
- negotiator/skipping.c uses bits 2-5 like negotiator/default.c
(ADVERTISED on bit 3 instead of COMMON_REF)
Signed-off-by: Kristofer Karlsson <krka@spotify.com>
---
object.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/object.h b/object.h
index d814647ebe..2b26de3044 100644
--- a/object.h
+++ b/object.h
@@ -67,6 +67,7 @@ void object_array_init(struct object_array *array);
* revision.h: 0---------10 15 23--------28
* fetch-pack.c: 01 67
* negotiator/default.c: 2--5
+ * negotiator/skipping.c: 2--5
* walker.c: 0-2
* upload-pack.c: 4 11-----14 16-----19
* builtin/blame.c: 12-13
@@ -76,13 +77,13 @@ void object_array_init(struct object_array *array);
* commit-graph.c: 15
* commit-reach.c: 16-----19
* builtin/last-modified.c: 1617
- * sha1-name.c: 20
+ * object-name.c: 20
* list-objects-filter.c: 21
* bloom.c: 2122
* builtin/fsck.c: 0--3
* builtin/index-pack.c: 2021
* reflog.c: 10--12
- * builtin/show-branch.c: 0-------------------------------------------26
+ * builtin/show-branch.c: 0-----------------------------------------------28
* builtin/unpack-objects.c: 2021
* pack-bitmap.h: 2122
*/
--
gitgitgadget
^ permalink raw reply related
* Re: [PATCH 0/4] doc: hook: small improvements
From: Junio C Hamano @ 2026-05-25 11:09 UTC (permalink / raw)
To: Adrian Ratiu; +Cc: kristofferhaugsbakk, git, Kristoffer Haugsbakk, jn.avila
In-Reply-To: <87fr3fsql2.fsf@gentoo.mail-host-address-is-not-set>
Adrian Ratiu <adrian.ratiu@collabora.com> writes:
> On Thu, 21 May 2026, kristofferhaugsbakk@fastmail.com wrote:
>> From: Kristoffer Haugsbakk <code@khaugsbakk.name>
>>
>> Topic name: kh/doc-hook
>>
>> Topic summary: Small improvements to git-hook(1) and the associated config.
>>
>> [1/4] doc: hook: remove stray backtick
>> [2/4] doc: hook: consistently capitalize Git
>> [3/4] doc: config: include existing git-hook(1) section
>> [4/4] doc: hook: don’t self-link via config include
>>
>> Documentation/config.adoc | 2 ++
>> Documentation/config/hook.adoc | 19 +++++++++++++------
>> Documentation/git-hook.adoc | 11 ++++++-----
>> 3 files changed, 21 insertions(+), 11 deletions(-)
>>
>>
>> base-commit: aec3f587505a472db67e9462d0702e7d463a449d
>
> LGTM as well. Thanks!
Thanks, all of you. The topic has now hit 'next'.
^ permalink raw reply
* Re: [PATCH 0/4] doc: hook: small improvements
From: Adrian Ratiu @ 2026-05-25 10:58 UTC (permalink / raw)
To: kristofferhaugsbakk, git; +Cc: Kristoffer Haugsbakk, jn.avila
In-Reply-To: <CV_doc_hook.6f0@msgid.xyz>
On Thu, 21 May 2026, kristofferhaugsbakk@fastmail.com wrote:
> From: Kristoffer Haugsbakk <code@khaugsbakk.name>
>
> Topic name: kh/doc-hook
>
> Topic summary: Small improvements to git-hook(1) and the associated config.
>
> [1/4] doc: hook: remove stray backtick
> [2/4] doc: hook: consistently capitalize Git
> [3/4] doc: config: include existing git-hook(1) section
> [4/4] doc: hook: don’t self-link via config include
>
> Documentation/config.adoc | 2 ++
> Documentation/config/hook.adoc | 19 +++++++++++++------
> Documentation/git-hook.adoc | 11 ++++++-----
> 3 files changed, 21 insertions(+), 11 deletions(-)
>
>
> base-commit: aec3f587505a472db67e9462d0702e7d463a449d
LGTM as well. Thanks!
^ permalink raw reply
* Re: [PATCH 0/3] commit-reach: replace queue_has_nonstale with a counter
From: Kristofer Karlsson @ 2026-05-25 10:47 UTC (permalink / raw)
To: Jeff King; +Cc: Kristofer Karlsson via GitGitGadget, git
In-Reply-To: <20260525095506.GA3868724@coredump.intra.peff.net>
Good point, it may not truly be amortized O(1) — you can construct cases
where all the interesting commits cluster at the front and the cache is
repeatedly invalidated.
That said, I started thinking about what happens if we upgrade the cache
on every enqueue, and I think there is a clean O(1) solution that
eliminates scanning entirely.
The key observation: commits transition from non-stale to stale but
never the other way. So if we track the lowest-priority non-stale
commit in the queue and maintain it on every enqueue, we get a tight
invariant:
struct nonstale_queue {
struct prio_queue pq;
struct commit *max_nonstale;
};
static void nonstale_queue_put(struct nonstale_queue *nsq,
struct commit *commit) {
prio_queue_put(&nsq->pq, commit);
if (commit->object.flags & STALE)
return;
if (!nsq->max_nonstale ||
nsq->pq.compare(nsq->max_nonstale, commit,
nsq->pq.cb_data) < 0)
nsq->max_nonstale = commit;
}
static struct commit *nonstale_queue_get(struct nonstale_queue *nsq)
{
struct commit *commit = prio_queue_get(&nsq->pq);
if (commit == nsq->max_nonstale) nsq->max_nonstale = NULL;
return commit;
}
The loop condition becomes while (nsq.max_nonstale).
Why this works:
1. max_nonstale always points to the lowest-priority non-stale entry
we have seen. Everything behind it in the priority order was stale
at enqueue time, and stale is a one-way transition, so it stays
stale.
2. When max_nonstale is popped, every remaining entry has lower
priority and is therefore stale. The popped commit's parents get
enqueued though, and if any are non-stale they restore
max_nonstale via nonstale_queue_put().
3. If max_nonstale becomes stale between pops (e.g. painted from
both sides), we don't notice immediately — the walk does a few
extra iterations until it's popped. That's a small bounded cost.
This seems like the best of both worlds: O(1) like the counter
approach but with the simplicity of the cache, and no new flags.
I have it implemented and tested it locally and the performance is identical
to the cache version on the monorepo.
I can push an updated v2 patch with this approach later, unless something
else pops up from the discussions (maybe I am wrong about all this!)
-- Kristofer
On Mon, 25 May 2026 at 11:55, Jeff King <peff@peff.net> wrote:
>
> On Mon, May 25, 2026 at 09:59:59AM +0200, Kristofer Karlsson wrote:
>
> > That's an excellent approach! Much cleaner in general.
> >
> > I benchmarked it against the counter on a monorepo with wide-frontier DAGs
> > (2.4M commits, component import merges). Using merge-base --all to bypass
> > the early-exit optimization from kk/paint-down-to-common-optim:
> >
> > Baseline Cache Counter
> > import(A) 8079ms 3686ms 3723ms
> > import(B) 5498ms 3993ms 4038ms
> > import(C) 4350ms 1748ms 1766ms
> >
> > The cache performs on par with the counter - within noise on all three
> > cases. No new flags needed, much simpler diff.
> > The amortized O(1) is just as good as true O(1) in practice, and it avoids
> > the ENQUEUED flag and counter bookkeeping entirely.
>
> I'm not sure if it's technically amortized O(1), as I think in the worst
> case we are still quadratic. That would happen if we've cached some
> non-stale X, then pop it and put on some new commit Y. And then the next
> round we have no cache (X was popped), but have to walk the whole queue
> to find Y.
>
> So I think it's more of a "heuristically O(1)" or something.
>
> > I went with back-to-front scanning as you suggested
>
> Out of curiosity, did you also time it front-to-back? What I wonder is
> if we might commonly hit that worst case for back-to-front when we're
> continually popping and inserting one new commit at the front of the
> queue. If there's a bunch of stale cruft in the back end of the queue,
> we'll walk over it repeatedly to find the new commit, and our cache will
> never (or seldom) remain valid. (I know it's a heap, not a real queue,
> but I think the far end of the array will still tend to represent stuff
> that is further away from being popped due to the heap property).
>
> Whereas looking from front to back, we are likely to cache something
> that is going to be popped soon. But in that case we find it quickly,
> and the longer we search the more likely it is to hang around in the
> queue and remain valid.
>
> > and also clear the cache when the cached entry goes stale.
>
> I think this happens naturally when we call into queue_has_nonstale().
> We only use the cached value if it's still non-stale. If it's gone stale
> then we either find a new commit, or if we can't then we return false
> (everything is stale). I guess the stale commit is left in the cache in
> the latter case, but it doesn't matter because the loop ends anyway (and
> even if it didn't, it is OK to repeatedly ignore the stale commit, as
> doing so is O(1) and we have nothing better to cache).
>
> That said, it is probably only one line to explicitly set it to NULL in
> queue_has_nonstale(), so I am OK with that. ;)
>
> If you're proposing to notice when we set the STALE flag on a commit
> which matches the cached value, I'd prefer to avoid that, just because
> it muddies up the code.
>
> > I can rewrite the patchset with this approach and add you as co-author or
> > suggested-by? Or I think I can wait for you to push it yourself.
> > You did all the work here, and just didn't have enough data points to
> > motivate it?
>
> I think testing and writing the commit messages will be more work than
> the code. I am happy to live on in a trailer if you will do those other
> parts. ;)
>
> -Peff
^ permalink raw reply
* Re: [PATCH] doc: clarify push.default=simple in triangular workflows
From: Иван Балута @ 2026-05-25 10:32 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Ivan Baluta via GitGitGadget, git
In-Reply-To: <xmqq8q9bu8vf.fsf@gitster.g>
On Fri, May 22, 2026 at 3:49 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> "Ivan Baluta via GitGitGadget" <gitgitgadget@gmail.com> writes:
>
> > From: ivanbaluta <ivanbaluta.dev@gmail.com>
>
> Just noticing, but don't you want to spell your name just like you
> spell it in your e-mails? I.e.,
>
> From: Ivan Baluta <ivanbaluta.dev@gmail.com>
>
> Use the same name for your sign-off below.
>
> > The documentation for 'simple' push mode currently focuses on the
> > centralized workflow. However, the implementation in builtin/push.c
> > falls back to 'current' behavior when pushing to a remote different
> > from the upstream (a triangular workflow).
>
> It is not just implementation, but that is how it was designed to
> do.
>
> Whether centralized or triangular, "simple" works as a restricted
> form as "current", with the same restriction. That is, both
> "current" and "simple" push out only the current branch to a single
> destination that is configured, and "simple" insists that the
> destination has the same name as the local branch.
>
> So I am not sure if this three-line patch adds much value.
>
> I agree that it _is_ confusing that the current text singles out the
> centralized workflow when describing "simple". But the remedy may
> not be to add "what happens in triangular, then?", but it may be to
> clarify that the need to configure the push destination whether your
> push destination is the same as or different from your upstream, no?
>
> Something along this line, perhaps?
>
> `simple`;;
> push the current branch with the same name on the remote.
> +
> This mode requires that the remote repository to be pushed to is
> known. When pushing back to the same remote you pull from, the
> current branch must also have an upstream tracking branch with the
> same name.
> +
> This mode is the default since Git 2.0, and is the safest option
> suited for beginners.
>
> That way, the description would be more self standing and the
> readers hopefully do not have to refer to another mode (`current`)
> to understand what happens, no?
Thanks, I have corrected my name formatting.
I completely agree with your feedback. Your suggested phrasing is indeed
much clearer and prevents the reader from having to cross-reference the
"current" mode to understand "simple".
I will submit v2 shortly with your suggested text.
^ permalink raw reply
* [PATCH v2 6/6] doc: convert git-imap-send synopsis and options to new style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-25 10:28 UTC (permalink / raw)
To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.v2.git.1779704908.gitgitgadget@gmail.com>
From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
Convert git-imap-send from [verse]/single-quote style to the modern
synopsis-block style:
- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms
- Backtick-quote all config keys in config/imap.adoc
- Backtick-quote bare config key references in prose
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
Documentation/config/imap.adoc | 30 +++++++++++++++---------------
Documentation/git-imap-send.adoc | 24 ++++++++++++------------
2 files changed, 27 insertions(+), 27 deletions(-)
diff --git a/Documentation/config/imap.adoc b/Documentation/config/imap.adoc
index 4682a6bd03..cb8f5e2700 100644
--- a/Documentation/config/imap.adoc
+++ b/Documentation/config/imap.adoc
@@ -1,44 +1,44 @@
-imap.folder::
+`imap.folder`::
The folder to drop the mails into, which is typically the Drafts
folder. For example: `INBOX.Drafts`, `INBOX/Drafts` or
`[Gmail]/Drafts`. The IMAP folder to interact with MUST be specified;
the value of this configuration variable is used as the fallback
default value when the `--folder` option is not given.
-imap.tunnel::
+`imap.tunnel`::
Command used to set up a tunnel to the IMAP server through which
commands will be piped instead of using a direct network connection
- to the server. Required when imap.host is not set.
+ to the server. Required when `imap.host` is not set.
-imap.host::
+`imap.host`::
A URL identifying the server. Use an `imap://` prefix for non-secure
connections and an `imaps://` prefix for secure connections.
- Ignored when imap.tunnel is set, but required otherwise.
+ Ignored when `imap.tunnel` is set, but required otherwise.
-imap.user::
+`imap.user`::
The username to use when logging in to the server.
-imap.pass::
+`imap.pass`::
The password to use when logging in to the server.
-imap.port::
+`imap.port`::
An integer port number to connect to on the server.
- Defaults to 143 for imap:// hosts and 993 for imaps:// hosts.
- Ignored when imap.tunnel is set.
+ Defaults to 143 for `imap://` hosts and 993 for `imaps://` hosts.
+ Ignored when `imap.tunnel` is set.
-imap.sslverify::
+`imap.sslverify`::
A boolean to enable/disable verification of the server certificate
used by the SSL/TLS connection. Default is `true`. Ignored when
- imap.tunnel is set.
+ `imap.tunnel` is set.
-imap.preformattedHTML::
+`imap.preformattedHTML`::
A boolean to enable/disable the use of html encoding when sending
- a patch. An html encoded patch will be bracketed with <pre>
+ a patch. An html encoded patch will be bracketed with `<pre>`
and have a content type of text/html. Ironically, enabling this
option causes Thunderbird to send the patch as a plain/text,
format=fixed email. Default is `false`.
-imap.authMethod::
+`imap.authMethod`::
Specify the authentication method for authenticating with the IMAP server.
If Git was built with the NO_CURL option, or if your curl version is older
than 7.34.0, or if you're running git-imap-send with the `--no-curl`
diff --git a/Documentation/git-imap-send.adoc b/Documentation/git-imap-send.adoc
index 278e5ccd36..538b91afc0 100644
--- a/Documentation/git-imap-send.adoc
+++ b/Documentation/git-imap-send.adoc
@@ -8,9 +8,9 @@ git-imap-send - Send a collection of patches from stdin to an IMAP folder
SYNOPSIS
--------
-[verse]
-'git imap-send' [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>]
-'git imap-send' --list
+[synopsis]
+git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>]
+git imap-send --list
DESCRIPTION
@@ -32,30 +32,30 @@ $ git format-patch --signoff --stdout --attach origin | git imap-send
OPTIONS
-------
--v::
---verbose::
+`-v`::
+`--verbose`::
Be verbose.
--q::
---quiet::
+`-q`::
+`--quiet`::
Be quiet.
--f <folder>::
---folder=<folder>::
+`-f <folder>`::
+`--folder=<folder>`::
Specify the folder in which the emails have to saved.
For example: `--folder=[Gmail]/Drafts` or `-f INBOX/Drafts`.
---curl::
+`--curl`::
Use libcurl to communicate with the IMAP server, unless tunneling
into it. Ignored if Git was built without the USE_CURL_FOR_IMAP_SEND
option set.
---no-curl::
+`--no-curl`::
Talk to the IMAP server using git's own IMAP routines instead of
using libcurl. Ignored if Git was built with the NO_OPENSSL option
set.
---list::
+`--list`::
Run the IMAP LIST command to output a list of all the folders present.
CONFIGURATION
--
gitgitgadget
^ permalink raw reply related
* [PATCH v2 5/6] doc: convert git-apply synopsis and options to new style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-25 10:28 UTC (permalink / raw)
To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.v2.git.1779704908.gitgitgadget@gmail.com>
From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
Convert git-apply from [verse]/single-quote style to the modern
synopsis-block style:
- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms and config keys in config/apply.adoc
- Convert single-quoted inline commands ('git apply', 'diff', etc.)
- Wrap standalone placeholders in underscores (<n>, <root>, <action>)
- Backtick-quote `*.rej` and GNU `patch` tool references
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
Documentation/config/apply.adoc | 17 +++--
Documentation/git-apply.adoc | 125 ++++++++++++++++----------------
2 files changed, 74 insertions(+), 68 deletions(-)
diff --git a/Documentation/config/apply.adoc b/Documentation/config/apply.adoc
index f9908e210a..36fcea6291 100644
--- a/Documentation/config/apply.adoc
+++ b/Documentation/config/apply.adoc
@@ -1,11 +1,16 @@
-apply.ignoreWhitespace::
- When set to 'change', tells 'git apply' to ignore changes in
+`apply.ignoreWhitespace`::
+ When set to `change`, tells `git apply` to ignore changes in
whitespace, in the same way as the `--ignore-space-change`
option.
- When set to one of: no, none, never, false, it tells 'git apply' to
+ When set to one of: `no`, `none`, `never`, `false`, it tells `git apply` to
respect all whitespace differences.
+ifndef::git-apply[]
See linkgit:git-apply[1].
+endif::git-apply[]
-apply.whitespace::
- Tells 'git apply' how to handle whitespace, in the same way
- as the `--whitespace` option. See linkgit:git-apply[1].
+`apply.whitespace`::
+ Tells `git apply` how to handle whitespace, in the same way
+ as the `--whitespace` option.
+ifndef::git-apply[]
+ See linkgit:git-apply[1].
+endif::git-apply[]
diff --git a/Documentation/git-apply.adoc b/Documentation/git-apply.adoc
index 6c71ee69da..3f22dac1ce 100644
--- a/Documentation/git-apply.adoc
+++ b/Documentation/git-apply.adoc
@@ -8,8 +8,8 @@ git-apply - Apply a patch to files and/or to the index
SYNOPSIS
--------
-[verse]
-'git apply' [--stat] [--numstat] [--summary] [--check]
+[synopsis]
+git apply [--stat] [--numstat] [--summary] [--check]
[--index | --intent-to-add] [--3way] [--ours | --theirs | --union]
[--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
[--allow-binary-replacement | --binary] [--reject] [-z]
@@ -35,33 +35,33 @@ linkgit:git-format-patch[1] and/or received by email.
OPTIONS
-------
-<patch>...::
- The files to read the patch from. '-' can be used to read
+`<patch>...`::
+ The files to read the patch from. `-` can be used to read
from the standard input.
---stat::
+`--stat`::
Instead of applying the patch, output diffstat for the
input. Turns off "apply".
---numstat::
+`--numstat`::
Similar to `--stat`, but shows the number of added and
deleted lines in decimal notation and the pathname without
abbreviation, to make it more machine friendly. For
binary files, outputs two `-` instead of saying
`0 0`. Turns off "apply".
---summary::
+`--summary`::
Instead of applying the patch, output a condensed
summary of information obtained from git diff extended
headers, such as creations, renames, and mode changes.
Turns off "apply".
---check::
+`--check`::
Instead of applying the patch, see if the patch is
applicable to the current working tree and/or the index
file and detects errors. Turns off "apply".
---index::
+`--index`::
Apply the patch to both the index and the working tree (or
merely check that it would apply cleanly to both if `--check` is
in effect). Note that `--index` expects index entries and
@@ -70,13 +70,13 @@ OPTIONS
raise an error if they are not, even if the patch would apply
cleanly to both the index and the working tree in isolation.
---cached::
+`--cached`::
Apply the patch to just the index, without touching the working
tree. If `--check` is in effect, merely check that it would
apply cleanly to the index entry.
--N::
---intent-to-add::
+`-N`::
+`--intent-to-add`::
When applying the patch only to the working tree, mark new
files to be added to the index later (see `--intent-to-add`
option in linkgit:git-add[1]). This option is ignored if
@@ -84,8 +84,8 @@ OPTIONS
repository. Note that `--index` could be implied by other options
such as `--3way`.
--3::
---3way::
+`-3`::
+`--3way`::
Attempt 3-way merge if the patch records the identity of blobs it is supposed
to apply to and we have those blobs available locally, possibly leaving the
conflict markers in the files in the working tree for the user to
@@ -94,14 +94,14 @@ OPTIONS
When used with the `--cached` option, any conflicts are left at higher stages
in the cache.
---ours::
---theirs::
---union::
+`--ours`::
+`--theirs`::
+`--union`::
Instead of leaving conflicts in the file, resolve conflicts favouring
- our (or their or both) side of the lines. Requires --3way.
+ our (or their or both) side of the lines. Requires `--3way`.
---build-fake-ancestor=<file>::
- Newer 'git diff' output has embedded 'index information'
+`--build-fake-ancestor=<file>`::
+ Newer `git diff` output has embedded 'index information'
for each blob to help identify the original version that
the patch applies to. When this flag is given, and if
the original versions of the blobs are available locally,
@@ -110,18 +110,18 @@ OPTIONS
When a pure mode change is encountered (which has no index information),
the information is read from the current index instead.
--R::
---reverse::
+`-R`::
+`--reverse`::
Apply the patch in reverse.
---reject::
- For atomicity, 'git apply' by default fails the whole patch and
+`--reject`::
+ For atomicity, `git apply` by default fails the whole patch and
does not touch the working tree when some of the hunks
do not apply. This option makes it apply
the parts of the patch that are applicable, and leave the
- rejected hunks in corresponding *.rej files.
+ rejected hunks in corresponding `*.rej` files.
--z::
+`-z`::
When `--numstat` has been given, do not munge pathnames,
but use a NUL-terminated machine-readable format.
+
@@ -129,20 +129,20 @@ Without this option, pathnames with "unusual" characters are quoted as
explained for the configuration variable `core.quotePath` (see
linkgit:git-config[1]).
--p<n>::
- Remove <n> leading path components (separated by slashes) from
+`-p<n>`::
+ Remove _<n>_ leading path components (separated by slashes) from
traditional diff paths. E.g., with `-p2`, a patch against
`a/dir/file` will be applied directly to `file`. The default is
1.
--C<n>::
- Ensure at least <n> lines of surrounding context match before
+`-C<n>`::
+ Ensure at least _<n>_ lines of surrounding context match before
and after each change. When fewer lines of surrounding
context exist they all must match. By default no context is
ever ignored.
---unidiff-zero::
- By default, 'git apply' expects that the patch being
+`--unidiff-zero`::
+ By default, `git apply` expects that the patch being
applied is a unified diff with at least one line of context.
This provides good safety measures, but breaks down when
applying a diff generated with `--unified=0`. To bypass these
@@ -151,34 +151,34 @@ linkgit:git-config[1]).
Note, for the reasons stated above, the usage of context-free patches is
discouraged.
---apply::
+`--apply`::
If you use any of the options marked "Turns off
- 'apply'" above, 'git apply' reads and outputs the
+ 'apply'" above, `git apply` reads and outputs the
requested information without actually applying the
patch. Give this flag after those flags to also apply
the patch.
---no-add::
+`--no-add`::
When applying a patch, ignore additions made by the
patch. This can be used to extract the common part between
- two files by first running 'diff' on them and applying
+ two files by first running `diff` on them and applying
the result with this option, which would apply the
deletion part but not the addition part.
---allow-binary-replacement::
---binary::
+`--allow-binary-replacement`::
+`--binary`::
Historically we did not allow binary patch application
without an explicit permission from the user, and this
flag was the way to do so. Currently, we always allow binary
patch application, so this is a no-op.
---exclude=<path-pattern>::
- Don't apply changes to files matching the given path pattern. This can
+`--exclude=<path-pattern>`::
+ Don't apply changes to files matching _<path-pattern>_. This can
be useful when importing patchsets, where you want to exclude certain
files or directories.
---include=<path-pattern>::
- Apply changes to files matching the given path pattern. This can
+`--include=<path-pattern>`::
+ Apply changes to files matching the _<path-pattern>_. This can
be useful when importing patchsets, where you want to include certain
files or directories.
+
@@ -188,15 +188,15 @@ patch to each path is used. A patch to a path that does not match any
include/exclude pattern is used by default if there is no include pattern
on the command line, and ignored if there is any include pattern.
---ignore-space-change::
---ignore-whitespace::
+`--ignore-space-change`::
+`--ignore-whitespace`::
When applying a patch, ignore changes in whitespace in context
lines if necessary.
Context lines will preserve their whitespace, and they will not
undergo whitespace fixing regardless of the value of the
`--whitespace` option. New lines will still be fixed, though.
---whitespace=<action>::
+`--whitespace=<action>`::
When applying a patch, detect a new or modified line that has
whitespace errors. What are considered whitespace errors is
controlled by `core.whitespace` configuration. By default,
@@ -209,7 +209,7 @@ By default, the command outputs warning messages but applies the patch.
When `git-apply` is used for statistics and not applying a
patch, it defaults to `nowarn`.
+
-You can use different `<action>` values to control this
+You can use different _<action>_ values to control this
behavior:
+
* `nowarn` turns off the trailing whitespace warning.
@@ -223,48 +223,48 @@ behavior:
to apply the patch.
* `error-all` is similar to `error` but shows all errors.
---inaccurate-eof::
- Under certain circumstances, some versions of 'diff' do not correctly
+`--inaccurate-eof`::
+ Under certain circumstances, some versions of `diff` do not correctly
detect a missing new-line at the end of the file. As a result, patches
- created by such 'diff' programs do not record incomplete lines
+ created by such `diff` programs do not record incomplete lines
correctly. This option adds support for applying such patches by
working around this bug.
--v::
---verbose::
+`-v`::
+`--verbose`::
Report progress to stderr. By default, only a message about the
current patch being applied will be printed. This option will cause
additional information to be reported.
--q::
---quiet::
+`-q`::
+`--quiet`::
Suppress stderr output. Messages about patch status and progress
will not be printed.
---recount::
+`--recount`::
Do not trust the line counts in the hunk headers, but infer them
by inspecting the patch (e.g. after editing the patch without
adjusting the hunk headers appropriately).
---directory=<root>::
- Prepend <root> to all filenames. If a "-p" argument was also passed,
+`--directory=<root>`::
+ Prepend _<root>_ to all filenames. If a `-p` argument was also passed,
it is applied before prepending the new root.
+
For example, a patch that talks about updating `a/git-gui.sh` to `b/git-gui.sh`
can be applied to the file in the working tree `modules/git-gui/git-gui.sh` by
running `git apply --directory=modules/git-gui`.
---unsafe-paths::
+`--unsafe-paths`::
By default, a patch that affects outside the working area
(either a Git controlled working tree, or the current working
- directory when "git apply" is used as a replacement of GNU
- patch) is rejected as a mistake (or a mischief).
+ directory when `git apply` is used as a replacement of GNU
+ `patch`) is rejected as a mistake (or a mischief).
+
-When `git apply` is used as a "better GNU patch", the user can pass
+When `git apply` is used as a "better GNU `patch`", the user can pass
the `--unsafe-paths` option to override this safety check. This option
has no effect when `--index` or `--cached` is in use.
---allow-empty::
+`--allow-empty`::
Don't return an error for patches containing no diff. This includes
empty patches and patches with commit text only.
@@ -273,11 +273,12 @@ CONFIGURATION
include::includes/cmd-config-section-all.adoc[]
+:git-apply: 1
include::config/apply.adoc[]
SUBMODULES
----------
-If the patch contains any changes to submodules then 'git apply'
+If the patch contains any changes to submodules then `git apply`
treats these changes as follows.
If `--index` is specified (explicitly or implicitly), then the submodule
--
gitgitgadget
^ permalink raw reply related
* [PATCH v2 4/6] doc: convert git-am synopsis and options to new style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-25 10:28 UTC (permalink / raw)
To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.v2.git.1779704908.gitgitgadget@gmail.com>
From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
Convert git-am from [verse]/single-quote style to the modern
synopsis-block style:
- Replace [verse] with [synopsis] in SYNOPSIS block
- Backtick-quote all OPTIONS terms
- Convert inline man page refs
- Convert inline command refs
- Convert prose placeholders:
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
Documentation/config/am.adoc | 6 +-
Documentation/format-patch-caveats.adoc | 2 +-
.../format-patch-end-of-commit-message.adoc | 4 +-
Documentation/git-am.adoc | 132 +++++++++---------
4 files changed, 72 insertions(+), 72 deletions(-)
diff --git a/Documentation/config/am.adoc b/Documentation/config/am.adoc
index e9561e12d7..250e6b5047 100644
--- a/Documentation/config/am.adoc
+++ b/Documentation/config/am.adoc
@@ -1,11 +1,11 @@
-am.keepcr::
+`am.keepcr`::
If true, linkgit:git-am[1] will call linkgit:git-mailsplit[1]
for patches in mbox format with parameter `--keep-cr`. In this
case linkgit:git-mailsplit[1] will
not remove `\r` from lines ending with `\r\n`. Can be overridden
by giving `--no-keep-cr` from the command line.
-am.threeWay::
+`am.threeWay`::
By default, linkgit:git-am[1] will fail if the patch does not
apply cleanly. When set to true, this setting tells
linkgit:git-am[1] to fall back on 3-way merge if the patch
@@ -13,7 +13,7 @@ am.threeWay::
have those blobs available locally (equivalent to giving the
`--3way` option from the command line). Defaults to `false`.
-am.messageId::
+`am.messageId`::
Add a `Message-ID` trailer based on the email header to the
commit when using linkgit:git-am[1] (see
linkgit:git-interpret-trailers[1]). See also the `--message-id`
diff --git a/Documentation/format-patch-caveats.adoc b/Documentation/format-patch-caveats.adoc
index 807a65b885..133e4757e7 100644
--- a/Documentation/format-patch-caveats.adoc
+++ b/Documentation/format-patch-caveats.adoc
@@ -28,6 +28,6 @@ repositories. This goes to show that this behavior does not only impact
email workflows.
Given these limitations, one might be tempted to use a general-purpose
-utility like patch(1) instead. However, patch(1) will not only look for
+utility like `patch`(1) instead. However, `patch`(1) will not only look for
unindented diffs (like linkgit:git-am[1]) but will try to apply indented
diffs as well.
diff --git a/Documentation/format-patch-end-of-commit-message.adoc b/Documentation/format-patch-end-of-commit-message.adoc
index ec1ef79f5e..a1a624d2ac 100644
--- a/Documentation/format-patch-end-of-commit-message.adoc
+++ b/Documentation/format-patch-end-of-commit-message.adoc
@@ -1,8 +1,8 @@
Any line that is of the form:
* three-dashes and end-of-line, or
-* a line that begins with "diff -", or
-* a line that begins with "Index: "
+* a line that begins with `diff -`, or
+* a line that begins with `Index: `
is taken as the beginning of a patch, and the commit log message
is terminated before the first occurrence of such a line.
diff --git a/Documentation/git-am.adoc b/Documentation/git-am.adoc
index ac65852918..28adf4cf65 100644
--- a/Documentation/git-am.adoc
+++ b/Documentation/git-am.adoc
@@ -8,17 +8,17 @@ git-am - Apply a series of patches from a mailbox
SYNOPSIS
--------
-[verse]
-'git am' [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] [--[no-]verify]
+[synopsis]
+git am [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] [--[no-]verify]
[--[no-]3way] [--interactive] [--committer-date-is-author-date]
[--ignore-date] [--ignore-space-change | --ignore-whitespace]
[--whitespace=<action>] [-C<n>] [-p<n>] [--directory=<dir>]
[--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet]
- [--[no-]scissors] [-S[<keyid>]] [--patch-format=<format>]
+ [--[no-]scissors] [-S[<key-id>]] [--patch-format=<format>]
[--quoted-cr=<action>]
[--empty=(stop|drop|keep)]
[(<mbox> | <Maildir>)...]
-'git am' (--continue | --skip | --abort | --quit | --retry | --show-current-patch[=(diff|raw)] | --allow-empty)
+git am (--continue | --skip | --abort | --quit | --retry | --show-current-patch[=(diff|raw)] | --allow-empty)
DESCRIPTION
-----------
@@ -30,45 +30,45 @@ history without merges.
OPTIONS
-------
-(<mbox>|<Maildir>)...::
+`(<mbox>|<Maildir>)...`::
The list of mailbox files to read patches from. If you do not
supply this argument, the command reads from the standard input.
If you supply directories, they will be treated as Maildirs.
--s::
---signoff::
+`-s`::
+`--signoff`::
Add a `Signed-off-by` trailer to the commit message (see
linkgit:git-interpret-trailers[1]), using the committer identity
of yourself. See the signoff option in linkgit:git-commit[1]
for more information.
--k::
---keep::
+`-k`::
+`--keep`::
Pass `-k` flag to linkgit:git-mailinfo[1].
---keep-non-patch::
+`--keep-non-patch`::
Pass `-b` flag to linkgit:git-mailinfo[1].
---keep-cr::
---no-keep-cr::
+`--keep-cr`::
+`--no-keep-cr`::
With `--keep-cr`, call linkgit:git-mailsplit[1]
with the same option, to prevent it from stripping CR at the end of
lines. `am.keepcr` configuration variable can be used to specify the
default behaviour. `--no-keep-cr` is useful to override `am.keepcr`.
--c::
---scissors::
+`-c`::
+`--scissors`::
Remove everything in body before a scissors line (see
linkgit:git-mailinfo[1]). Can be activated by default using
the `mailinfo.scissors` configuration variable.
---no-scissors::
+`--no-scissors`::
Ignore scissors lines (see linkgit:git-mailinfo[1]).
---quoted-cr=<action>::
+`--quoted-cr=<action>`::
This flag will be passed down to linkgit:git-mailinfo[1].
---empty=(drop|keep|stop)::
+`--empty=(drop|keep|stop)`::
How to handle an e-mail message lacking a patch:
+
--
@@ -82,23 +82,23 @@ OPTIONS
session. This is the default behavior.
--
--m::
---message-id::
+`-m`::
+`--message-id`::
Pass the `-m` flag to linkgit:git-mailinfo[1],
so that the `Message-ID` header is added to the commit message.
The `am.messageid` configuration variable can be used to specify
the default behaviour.
---no-message-id::
+`--no-message-id`::
Do not add the Message-ID header to the commit message.
`--no-message-id` is useful to override `am.messageid`.
--q::
---quiet::
+`-q`::
+`--quiet`::
Be quiet. Only print error messages.
--u::
---utf8::
+`-u`::
+`--utf8`::
Pass `-u` flag to linkgit:git-mailinfo[1].
The proposed commit log message taken from the e-mail
is re-coded into UTF-8 encoding (configuration variable
@@ -108,57 +108,57 @@ OPTIONS
This was optional in prior versions of git, but now it is the
default. You can use `--no-utf8` to override this.
---no-utf8::
+`--no-utf8`::
Pass `-n` flag to linkgit:git-mailinfo[1].
--3::
---3way::
---no-3way::
+`-3`::
+`--3way`::
+`--no-3way`::
When the patch does not apply cleanly, fall back on
3-way merge if the patch records the identity of blobs
it is supposed to apply to and we have those blobs
available locally. `--no-3way` can be used to override
- am.threeWay configuration variable. For more information,
- see am.threeWay in linkgit:git-config[1].
+ `am.threeWay` configuration variable. For more information,
+ see `am.threeWay` in linkgit:git-config[1].
include::rerere-options.adoc[]
---ignore-space-change::
---ignore-whitespace::
---whitespace=<action>::
--C<n>::
--p<n>::
---directory=<dir>::
---exclude=<path>::
---include=<path>::
---reject::
+`--ignore-space-change`::
+`--ignore-whitespace`::
+`--whitespace=<action>`::
+`-C<n>`::
+`-p<n>`::
+`--directory=<dir>`::
+`--exclude=<path>`::
+`--include=<path>`::
+`--reject`::
These flags are passed to the linkgit:git-apply[1] program that
applies the patch.
+
-Valid <action> for the `--whitespace` option are:
+Valid _<action>_ for the `--whitespace` option are:
`nowarn`, `warn`, `fix`, `error`, and `error-all`.
---patch-format::
+`--patch-format`::
By default the command will try to detect the patch format
automatically. This option allows the user to bypass the automatic
detection and specify the patch format that the patch(es) should be
interpreted as. Valid formats are mbox, mboxrd,
stgit, stgit-series, and hg.
--i::
---interactive::
+`-i`::
+`--interactive`::
Run interactively.
---verify::
--n::
---no-verify::
+`--verify`::
+`-n`::
+`--no-verify`::
Run the `pre-applypatch` and `applypatch-msg` hooks. This is the
default. Skip these hooks with `-n` or `--no-verify`. See also
linkgit:githooks[5].
+
Note that `post-applypatch` cannot be skipped.
---committer-date-is-author-date::
+`--committer-date-is-author-date`::
By default the command records the date from the e-mail
message as the commit author date, and uses the time of
commit creation as the committer date. This allows the
@@ -172,29 +172,29 @@ committer date when applying commits on top of a base which commit is
older (in terms of the commit date) than the oldest patch you are
applying.
---ignore-date::
+`--ignore-date`::
By default the command records the date from the e-mail
message as the commit author date, and uses the time of
commit creation as the committer date. This allows the
user to lie about the author date by using the same
value as the committer date.
---skip::
+`--skip`::
Skip the current patch. This is only meaningful when
restarting an aborted patch.
--S[<keyid>]::
---gpg-sign[=<keyid>]::
---no-gpg-sign::
- GPG-sign commits. The `keyid` argument is optional and
+`-S[<key-id>]`::
+`--gpg-sign[=<key-id>]`::
+`--no-gpg-sign`::
+ GPG-sign commits. The _<key-id>_ is optional and
defaults to the committer identity; if specified, it must be
stuck to the option without a space. `--no-gpg-sign` is useful to
countermand both `commit.gpgSign` configuration variable, and
earlier `--gpg-sign`.
---continue::
--r::
---resolved::
+`--continue`::
+`-r`::
+`--resolved`::
After a patch failure (e.g. attempting to apply
conflicting patch), the user has applied it by hand and
the index file stores the result of the application.
@@ -202,36 +202,36 @@ applying.
extracted from the e-mail message and the current index
file, and continue.
---resolvemsg=<msg>::
- When a patch failure occurs, <msg> will be printed
+`--resolvemsg=<msg>`::
+ When a patch failure occurs, _<msg>_ will be printed
to the screen before exiting. This overrides the
standard message informing you to use `--continue`
or `--skip` to handle the failure. This is solely
for internal use between linkgit:git-rebase[1] and
linkgit:git-am[1].
---abort::
+`--abort`::
Restore the original branch and abort the patching operation.
Revert the contents of files involved in the am operation to their
pre-am state.
---quit::
- Abort the patching operation but keep HEAD and the index
+`--quit`::
+ Abort the patching operation but keep `HEAD` and the index
untouched.
---retry::
+`--retry`::
Try to apply the last conflicting patch again. This is generally
only useful for passing extra options to the retry attempt
(e.g., `--3way`), since otherwise you'll just see the same
failure again.
---show-current-patch[=(diff|raw)]::
+`--show-current-patch[=(diff|raw)]`::
Show the message at which linkgit:git-am[1] has stopped due to
conflicts. If `raw` is specified, show the raw contents of
the e-mail message; if `diff`, show the diff portion only.
Defaults to `raw`.
---allow-empty::
+`--allow-empty`::
After a patch failure on an input e-mail message lacking a patch,
create an empty commit with the contents of the e-mail message
as its log message.
@@ -278,11 +278,11 @@ operation is finished, so if you decide to start over from scratch,
run `git am --abort` before running the command with mailbox
names.
-Before any patches are applied, ORIG_HEAD is set to the tip of the
+Before any patches are applied, `ORIG_HEAD` is set to the tip of the
current branch. This is useful if you have problems with multiple
commits, like running linkgit:git-am[1] on the wrong branch or an error
in the commits that is more easily fixed by changing the mailbox (e.g.
-errors in the "From:" lines).
+errors in the `From:` lines).
[[caveats]]
CAVEATS
--
gitgitgadget
^ permalink raw reply related
* [PATCH v2 3/6] doc: convert git-grep synopsis and options to new style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-25 10:28 UTC (permalink / raw)
To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.v2.git.1779704908.gitgitgadget@gmail.com>
From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
Convert git-grep.adoc from [verse]/single-quote style to the modern
synopsis-block style:
- Replace [verse] with [synopsis] in SYNOPSIS block
- Change 'git grep' to git grep (no single quotes)
- Backtick-quote all OPTIONS terms
- Convert inline man page refs: grep(1) -> `grep`(1)
- Convert inline command refs: 'git diff' -> `git diff`
- Convert prose placeholders: <file> -> _<file>_
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
Documentation/config/grep.adoc | 36 +++---
Documentation/git-grep.adoc | 196 ++++++++++++++++-----------------
2 files changed, 116 insertions(+), 116 deletions(-)
diff --git a/Documentation/config/grep.adoc b/Documentation/config/grep.adoc
index 10041f27b0..83d4b76dd3 100644
--- a/Documentation/config/grep.adoc
+++ b/Documentation/config/grep.adoc
@@ -1,28 +1,28 @@
-grep.lineNumber::
- If set to true, enable `-n` option by default.
+`grep.lineNumber`::
+ If set to `true`, enable `-n` option by default.
-grep.column::
- If set to true, enable the `--column` option by default.
+`grep.column`::
+ If set to `true`, enable the `--column` option by default.
-grep.patternType::
- Set the default matching behavior. Using a value of 'basic', 'extended',
- 'fixed', or 'perl' will enable the `--basic-regexp`, `--extended-regexp`,
+`grep.patternType`::
+ Set the default matching behavior. Using a value of `basic`, `extended`,
+ `fixed`, or `perl` will enable the `--basic-regexp`, `--extended-regexp`,
`--fixed-strings`, or `--perl-regexp` option accordingly, while the
- value 'default' will use the `grep.extendedRegexp` option to choose
- between 'basic' and 'extended'.
+ value `default` will use the `grep.extendedRegexp` option to choose
+ between `basic` and `extended`.
-grep.extendedRegexp::
- If set to true, enable `--extended-regexp` option by default. This
+`grep.extendedRegexp`::
+ If set to `true`, enable `--extended-regexp` option by default. This
option is ignored when the `grep.patternType` option is set to a value
- other than 'default'.
+ other than `default`.
-grep.threads::
+`grep.threads`::
Number of grep worker threads to use. If unset (or set to 0), Git will
use as many threads as the number of logical cores available.
-grep.fullName::
- If set to true, enable `--full-name` option by default.
+`grep.fullName`::
+ If set to `true`, enable `--full-name` option by default.
-grep.fallbackToNoIndex::
- If set to true, fall back to `git grep --no-index` if `git grep`
- is executed outside of a git repository. Defaults to false.
+`grep.fallbackToNoIndex`::
+ If set to `true`, fall back to `git grep --no-index` if `git grep`
+ is executed outside of a git repository. Defaults to `false`.
diff --git a/Documentation/git-grep.adoc b/Documentation/git-grep.adoc
index a548585d4c..19b3ade16d 100644
--- a/Documentation/git-grep.adoc
+++ b/Documentation/git-grep.adoc
@@ -8,8 +8,8 @@ git-grep - Print lines matching a pattern
SYNOPSIS
--------
-[verse]
-'git grep' [-a | --text] [-I] [--textconv] [-i | --ignore-case] [-w | --word-regexp]
+[synopsis]
+git grep [-a | --text] [-I] [--textconv] [-i | --ignore-case] [-w | --word-regexp]
[-v | --invert-match] [-h|-H] [--full-name]
[-E | --extended-regexp] [-G | --basic-regexp]
[-P | --perl-regexp]
@@ -41,139 +41,139 @@ characters. An empty string as search expression matches all lines.
OPTIONS
-------
---cached::
+`--cached`::
Instead of searching tracked files in the working tree, search
blobs registered in the index file.
---untracked::
+`--untracked`::
In addition to searching in the tracked files in the working
tree, search also in untracked files.
---no-index::
+`--no-index`::
Search files in the current directory that is not managed by Git,
or by ignoring that the current directory is managed by Git. This
- is rather similar to running the regular `grep(1)` utility with its
+ is rather similar to running the regular `grep`(1) utility with its
`-r` option specified, but with some additional benefits, such as
- using pathspec patterns to limit paths; see the 'pathspec' entry
+ using pathspec patterns to limit paths; see the `pathspec` entry
in linkgit:gitglossary[7] for more information.
+
This option cannot be used together with `--cached` or `--untracked`.
See also `grep.fallbackToNoIndex` in 'CONFIGURATION' below.
---no-exclude-standard::
+`--no-exclude-standard`::
Also search in ignored files by not honoring the `.gitignore`
mechanism. Only useful with `--untracked`.
---exclude-standard::
+`--exclude-standard`::
Do not pay attention to ignored files specified via the `.gitignore`
mechanism. Only useful when searching files in the current directory
with `--no-index`.
---recurse-submodules::
+`--recurse-submodules`::
Recursively search in each submodule that is active and
checked out in the repository. When used in combination with the
_<tree>_ option the prefix of all submodule output will be the name of
the parent project's _<tree>_ object. This option cannot be used together
with `--untracked`, and it has no effect if `--no-index` is specified.
--a::
---text::
+`-a`::
+`--text`::
Process binary files as if they were text.
---textconv::
+`--textconv`::
Honor textconv filter settings.
---no-textconv::
+`--no-textconv`::
Do not honor textconv filter settings.
This is the default.
--i::
---ignore-case::
+`-i`::
+`--ignore-case`::
Ignore case differences between the patterns and the
files.
--I::
+`-I`::
Don't match the pattern in binary files.
---max-depth <depth>::
- For each <pathspec> given on command line, descend at most <depth>
+`--max-depth <depth>`::
+ For each _<pathspec>_ given on command line, descend at most _<depth>_
levels of directories. A value of -1 means no limit.
- This option is ignored if <pathspec> contains active wildcards.
+ This option is ignored if _<pathspec>_ contains active wildcards.
In other words if "a*" matches a directory named "a*",
- "*" is matched literally so --max-depth is still effective.
+ "*" is matched literally so `--max-depth` is still effective.
--r::
---recursive::
+`-r`::
+`--recursive`::
Same as `--max-depth=-1`; this is the default.
---no-recursive::
+`--no-recursive`::
Same as `--max-depth=0`.
--w::
---word-regexp::
+`-w`::
+`--word-regexp`::
Match the pattern only at word boundary (either begin at the
beginning of a line, or preceded by a non-word character; end at
the end of a line or followed by a non-word character).
--v::
---invert-match::
+`-v`::
+`--invert-match`::
Select non-matching lines.
--h::
--H::
+`-h`::
+`-H`::
By default, the command shows the filename for each
match. `-h` option is used to suppress this output.
`-H` is there for completeness and does not do anything
except it overrides `-h` given earlier on the command
line.
---full-name::
+`--full-name`::
When run from a subdirectory, the command usually
outputs paths relative to the current directory. This
option forces paths to be output relative to the project
top directory.
--E::
---extended-regexp::
--G::
---basic-regexp::
+`-E`::
+`--extended-regexp`::
+`-G`::
+`--basic-regexp`::
Use POSIX extended/basic regexp for patterns. Default
is to use basic regexp.
--P::
---perl-regexp::
+`-P`::
+`--perl-regexp`::
Use Perl-compatible regular expressions for patterns.
+
Support for these types of regular expressions is an optional
compile-time dependency. If Git wasn't compiled with support for them
providing this option will cause it to die.
--F::
---fixed-strings::
+`-F`::
+`--fixed-strings`::
Use fixed strings for patterns (don't interpret pattern
as a regex).
--n::
---line-number::
+`-n`::
+`--line-number`::
Prefix the line number to matching lines.
---column::
+`--column`::
Prefix the 1-indexed byte-offset of the first match from the start of the
matching line.
--l::
---files-with-matches::
---name-only::
--L::
---files-without-match::
+`-l`::
+`--files-with-matches`::
+`--name-only`::
+`-L`::
+`--files-without-match`::
Instead of showing every matched line, show only the
names of files that contain (or do not contain) matches.
- For better compatibility with 'git diff', `--name-only` is a
+ For better compatibility with `git diff`, `--name-only` is a
synonym for `--files-with-matches`.
--O[<pager>]::
---open-files-in-pager[=<pager>]::
- Open the matching files in the pager (not the output of 'grep').
+`-O[<pager>]`::
+`--open-files-in-pager[=<pager>]`::
+ Open the matching files in the pager (not the output of `grep`).
If the pager happens to be "less" or "vi", and the user
specified only one pattern, the first file is positioned at
the first match automatically. The `pager` argument is
@@ -181,65 +181,65 @@ providing this option will cause it to die.
without a space. If `pager` is unspecified, the default pager
will be used (see `core.pager` in linkgit:git-config[1]).
--z::
---null::
+`-z`::
+`--null`::
Use \0 as the delimiter for pathnames in the output, and print
them verbatim. Without this option, pathnames with "unusual"
characters are quoted as explained for the configuration
variable `core.quotePath` (see linkgit:git-config[1]).
--o::
---only-matching::
+`-o`::
+`--only-matching`::
Print only the matched (non-empty) parts of a matching line, with each such
part on a separate output line.
--c::
---count::
+`-c`::
+`--count`::
Instead of showing every matched line, show the number of
lines that match.
---color[=<when>]::
+`--color[=<when>]`::
Show colored matches.
- The value must be always (the default), never, or auto.
+ The value must be `always` (the default), `never`, or `auto`.
---no-color::
+`--no-color`::
Turn off match highlighting, even when the configuration file
gives the default to color output.
Same as `--color=never`.
---break::
+`--break`::
Print an empty line between matches from different files.
---heading::
+`--heading`::
Show the filename above the matches in that file instead of
at the start of each shown line.
--p::
---show-function::
+`-p`::
+`--show-function`::
Show the preceding line that contains the function name of
the match, unless the matching line is a function name itself.
The name is determined in the same way as `git diff` works out
patch hunk headers (see 'Defining a custom hunk-header' in
linkgit:gitattributes[5]).
--<num>::
--C <num>::
---context <num>::
- Show <num> leading and trailing lines, and place a line
+`-<num>`::
+`-C <num>`::
+`--context <num>`::
+ Show _<num>_ leading and trailing lines, and place a line
containing `--` between contiguous groups of matches.
--A <num>::
---after-context <num>::
- Show <num> trailing lines, and place a line containing
+`-A <num>`::
+`--after-context <num>`::
+ Show _<num>_ trailing lines, and place a line containing
`--` between contiguous groups of matches.
--B <num>::
---before-context <num>::
- Show <num> leading lines, and place a line containing
+`-B <num>`::
+`--before-context <num>`::
+ Show _<num>_ leading lines, and place a line containing
`--` between contiguous groups of matches.
--W::
---function-context::
+`-W`::
+`--function-context`::
Show the surrounding text from the previous line containing a
function name up to the one before the next function name,
effectively showing the whole function in which the match was
@@ -247,22 +247,22 @@ providing this option will cause it to die.
`git diff` works out patch hunk headers (see 'Defining a
custom hunk-header' in linkgit:gitattributes[5]).
--m <num>::
---max-count <num>::
+`-m <num>`::
+`--max-count <num>`::
Limit the amount of matches per file. When using the `-v` or
`--invert-match` option, the search stops after the specified
number of non-matches. A value of -1 will return unlimited
results (the default). A value of 0 will exit immediately with
a non-zero status.
---threads <num>::
- Number of `grep` worker threads to use. See 'NOTES ON THREADS'
+`--threads <num>`::
+ Number of `grep` worker threads to use. See `NOTES ON THREADS`
and `grep.threads` in 'CONFIGURATION' for more information.
--f <file>::
- Read patterns from <file>, one per line.
+`-f <file>`::
+ Read patterns from _<file>_, one per line.
+
-Passing the pattern via <file> allows for providing a search pattern
+Passing the pattern via _<file>_ allows for providing a search pattern
containing a \0.
+
Not all pattern types support patterns containing \0. Git will error
@@ -279,44 +279,44 @@ In future versions we may learn to support patterns containing \0 for
more search backends, until then we'll die when the pattern type in
question doesn't support them.
--e::
+`-e`::
The next parameter is the pattern. This option has to be
used for patterns starting with `-` and should be used in
scripts passing user input to grep. Multiple patterns are
- combined by 'or'.
+ combined by `or`.
---and::
---or::
---not::
-( ... )::
+`--and`::
+`--or`::
+`--not`::
+`( ... )`::
Specify how multiple patterns are combined using Boolean
expressions. `--or` is the default operator. `--and` has
higher precedence than `--or`. `-e` has to be used for all
patterns.
---all-match::
+`--all-match`::
When giving multiple pattern expressions combined with `--or`,
this flag is specified to limit the match to files that
have lines to match all of them.
--q::
---quiet::
+`-q`::
+`--quiet`::
Do not output matched lines; instead, exit with status 0 when
there is a match and with non-zero status when there isn't.
-<tree>...::
+`<tree>...`::
Instead of searching tracked files in the working tree, search
blobs in the given trees.
-\--::
+`--`::
Signals the end of options; the rest of the parameters
- are <pathspec> limiters.
+ are _<pathspec>_ limiters.
-<pathspec>...::
+`<pathspec>...`::
If given, limit the search to paths matching at least one pattern.
- Both leading paths match and glob(7) patterns are supported.
+ Both leading paths match and `glob`(7) patterns are supported.
+
-For more details about the <pathspec> syntax, see the 'pathspec' entry
+For more details about the _<pathspec>_ syntax, see the `pathspec` entry
in linkgit:gitglossary[7].
EXAMPLES
--
gitgitgadget
^ permalink raw reply related
* [PATCH v2 2/6] doc: git bisect: clarify the usage of the synopsis vs actual command
From: Jean-Noël Avila via GitGitGadget @ 2026-05-25 10:28 UTC (permalink / raw)
To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.v2.git.1779704908.gitgitgadget@gmail.com>
From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
The difference between a synopsis and an actual command is that the synopsis
is a more abstract representation of the command, which may include
placeholders for arguments and options. The actual command is the specific
instance of the command with all the arguments and options filled in.
The formatting of an actual command is a code block, with the command
prefixed by a dollar sign ($) to indicate that it is a command to be run in
the terminal. It can also include comments with a hash sign (#) to explain
the command or provide additional information, just like in a regular
terminal session.
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
Documentation/git-bisect.adoc | 19 +++++++++----------
1 file changed, 9 insertions(+), 10 deletions(-)
diff --git a/Documentation/git-bisect.adoc b/Documentation/git-bisect.adoc
index 4765d3b969..d2115b2990 100644
--- a/Documentation/git-bisect.adoc
+++ b/Documentation/git-bisect.adoc
@@ -96,9 +96,8 @@ Bisect reset
After a bisect session, to clean up the bisection state and return to
the original `HEAD`, issue the following command:
-------------------------------------------------
-$ git bisect reset
-------------------------------------------------
+[synopsis]
+git bisect reset
By default, this will return your tree to the commit that was checked
out before `git bisect start`. (A new `git bisect start` will also do
@@ -108,7 +107,8 @@ With an optional argument, you can return to a different commit
instead:
[synopsis]
-$ git bisect reset <commit>
+git bisect reset <commit>
+
For example, `git bisect reset bisect/bad` will check out the first
bad revision, while `git bisect reset HEAD` will leave you on the
@@ -174,13 +174,13 @@ For example, if you are looking for a commit that introduced a
performance regression, you might use
------------------------------------------------
-git bisect start --term-old fast --term-new slow
+$ git bisect start --term-old fast --term-new slow
------------------------------------------------
Or if you are looking for the commit that fixed a bug, you might use
------------------------------------------------
-git bisect start --term-new fixed --term-old broken
+$ git bisect start --term-new fixed --term-old broken
------------------------------------------------
Then, use `git bisect <term-old>` and `git bisect <term-new>` instead
@@ -328,11 +328,10 @@ Bisect run
If you have a script that can tell if the current source code is good
or bad, you can bisect by issuing the command:
-------------
-$ git bisect run my_script arguments
-------------
+[synopsis]
+git bisect run <cmd> [<arg>...]
-Note that the script (`my_script` in the above example) should exit
+Note that _<cmd>_ run with _<arg>_ should exit
with code 0 if the current source code is good/old, and exit with a
code between 1 and 127 (inclusive), except 125, if the current source
code is bad/new.
--
gitgitgadget
^ permalink raw reply related
* [PATCH v2 1/6] doc: convert git-bisect to synopsis style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-25 10:28 UTC (permalink / raw)
To: git; +Cc: Jean-Noël Avila, Jean-Noël Avila
In-Reply-To: <pull.2117.v2.git.1779704908.gitgitgadget@gmail.com>
From: =?UTF-8?q?Jean-No=C3=ABl=20Avila?= <jn.avila@free.fr>
Convert Documentation/git-bisect.adoc to the modern synopsis style.
- Replace [verse] with [synopsis] in the SYNOPSIS block
- Remove single quotes around command names in the synopsis
- Use backticks for inline commands, options, refs, and special values
- Apply [synopsis] attribute to in-body command-form code blocks
- Format OPTIONS entries with backtick-quoted terms and direct
- Add synopsis-style formatting to listing blocks
- Format man page references as `command`(N)
Signed-off-by: Jean-Noël Avila <jn.avila@free.fr>
---
Documentation/asciidoc.conf.in | 6 +++
Documentation/git-bisect.adoc | 90 ++++++++++++++++------------------
2 files changed, 48 insertions(+), 48 deletions(-)
diff --git a/Documentation/asciidoc.conf.in b/Documentation/asciidoc.conf.in
index 31b883a72c..93c63b284a 100644
--- a/Documentation/asciidoc.conf.in
+++ b/Documentation/asciidoc.conf.in
@@ -84,6 +84,9 @@ ifdef::doctype-manpage[]
[blockdef-open]
synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|…\\)!\\1<literal>\\2</literal>!g;s!<[-a-zA-Z0-9.]\\+>!<emphasis>\\0</emphasis>!g'"
+[blockdef-listing]
+synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|…\\)!\\1<literal>\\2</literal>!g;s!<[-a-zA-Z0-9.]\\+>!<emphasis>\\0</emphasis>!g'"
+
[paradef-default]
synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<phrase>\\0</phrase>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|…\\)!\\1<literal>\\2</literal>!g;s!<[-a-zA-Z0-9.]\\+>!<emphasis>\\0</emphasis>!g'"
endif::doctype-manpage[]
@@ -93,6 +96,9 @@ ifdef::backend-xhtml11[]
[blockdef-open]
synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|…\\)!\\1<code>\\2</code>!g;s!<[-a-zA-Z0-9.]\\+>!<em>\\0</em>!g'"
+[blockdef-listing]
+synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|…\\)!\\1<code>\\2</code>!g;s!<[-a-zA-Z0-9.]\\+>!<em>\\0</em>!g'"
+
[paradef-default]
synopsis-style=template="verseparagraph",filter="sed 's!…\\(\\]\\|$\\)!<span>\\0</span>!g;s!\\([\\[ |()]\\|^\\|\\]\\|>\\)\\([-=a-zA-Z0-9:+@,\\/_^\\$.\\\\\\*]\\+\\|…\\)!\\1<code>\\2</code>!g;s!<[-a-zA-Z0-9.]\\+>!<em>\\0</em>!g'"
endif::backend-xhtml11[]
diff --git a/Documentation/git-bisect.adoc b/Documentation/git-bisect.adoc
index b0078dda0e..4765d3b969 100644
--- a/Documentation/git-bisect.adoc
+++ b/Documentation/git-bisect.adoc
@@ -8,20 +8,20 @@ git-bisect - Use binary search to find the commit that introduced a bug
SYNOPSIS
--------
-[verse]
-'git bisect' start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>]
- [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]
-'git bisect' (bad|new|<term-new>) [<rev>]
-'git bisect' (good|old|<term-old>) [<rev>...]
-'git bisect' terms [--term-(good|old) | --term-(bad|new)]
-'git bisect' skip [(<rev>|<range>)...]
-'git bisect' next
-'git bisect' reset [<commit>]
-'git bisect' (visualize|view)
-'git bisect' replay <logfile>
-'git bisect' log
-'git bisect' run <cmd> [<arg>...]
-'git bisect' help
+[synopsis]
+git bisect start [--term-(bad|new)=<term-new> --term-(good|old)=<term-old>]
+ [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<pathspec>...]
+git bisect (bad|new|<term-new>) [<rev>]
+git bisect (good|old|<term-old>) [<rev>...]
+git bisect terms [--term-(good|old) | --term-(bad|new)]
+git bisect skip [(<rev>|<range>)...]
+git bisect next
+git bisect reset [<commit>]
+git bisect (visualize|view)
+git bisect replay <logfile>
+git bisect log
+git bisect run <cmd> [<arg>...]
+git bisect help
DESCRIPTION
-----------
@@ -94,7 +94,7 @@ Bisect reset
~~~~~~~~~~~~
After a bisect session, to clean up the bisection state and return to
-the original HEAD, issue the following command:
+the original `HEAD`, issue the following command:
------------------------------------------------
$ git bisect reset
@@ -107,9 +107,8 @@ that, as it cleans up the old bisection state.)
With an optional argument, you can return to a different commit
instead:
-------------------------------------------------
+[synopsis]
$ git bisect reset <commit>
-------------------------------------------------
For example, `git bisect reset bisect/bad` will check out the first
bad revision, while `git bisect reset HEAD` will leave you on the
@@ -143,23 +142,20 @@ To use "old" and "new" instead of "good" and bad, you must run `git
bisect start` without commits as argument and then run the following
commands to add the commits:
-------------------------------------------------
+[synopsis]
git bisect old [<rev>]
-------------------------------------------------
to indicate that a commit was before the sought change, or
-------------------------------------------------
+[synopsis]
git bisect new [<rev>...]
-------------------------------------------------
to indicate that it was after.
To get a reminder of the currently used terms, use
-------------------------------------------------
+[synopsis]
git bisect terms
-------------------------------------------------
You can get just the old term with `git bisect terms --term-old`
or `git bisect terms --term-good`; `git bisect terms --term-new`
@@ -171,9 +167,8 @@ If you would like to use your own terms instead of "bad"/"good" or
subcommands like `reset`, `start`, ...) by starting the
bisection using
-------------------------------------------------
+[synopsis]
git bisect start --term-old <term-old> --term-new <term-new>
-------------------------------------------------
For example, if you are looking for a commit that introduced a
performance regression, you might use
@@ -194,7 +189,7 @@ of `git bisect good` and `git bisect bad` to mark commits.
Bisect visualize/view
~~~~~~~~~~~~~~~~~~~~~
-To see the currently remaining suspects in 'gitk', issue the following
+To see the currently remaining suspects in `gitk`, issue the following
command during the bisection process (the subcommand `view` can be used
as an alternative to `visualize`):
@@ -203,12 +198,13 @@ $ git bisect visualize
------------
Git detects a graphical environment through various environment variables:
-`DISPLAY`, which is set in X Window System environments on Unix systems.
-`SESSIONNAME`, which is set under Cygwin in interactive desktop sessions.
-`MSYSTEM`, which is set under Msys2 and Git for Windows.
-`SECURITYSESSIONID`, which may be set on macOS in interactive desktop sessions.
-If none of these environment variables is set, 'git log' is used instead.
+`DISPLAY`:: which is set in X Window System environments on Unix systems.
+`SESSIONNAME`:: which is set under Cygwin in interactive desktop sessions.
+`MSYSTEM`:: which is set under Msys2 and Git for Windows.
+`SECURITYSESSIONID`:: which may be set on macOS in interactive desktop sessions.
+
+If none of these environment variables is set, `git log` is used instead.
You can also give command-line options such as `-p` and `--stat`.
------------
@@ -342,8 +338,8 @@ code between 1 and 127 (inclusive), except 125, if the current source
code is bad/new.
Any other exit code will abort the bisect process. It should be noted
-that a program that terminates via `exit(-1)` leaves $? = 255, (see the
-exit(3) manual page), as the value is chopped with `& 0377`.
+that a program that terminates via `exit(-1)` leaves `$?` = 255, (see the
+`exit`(3) manual page), as the value is chopped with `& 0377`.
The special exit code 125 should be used when the current source code
cannot be tested. If the script exits with this code, the current
@@ -355,12 +351,12 @@ details do not matter, as they are normal errors in the script, as far as
`bisect run` is concerned).
You may often find that during a bisect session you want to have
-temporary modifications (e.g. s/#define DEBUG 0/#define DEBUG 1/ in a
+temporary modifications (e.g. `s/#define DEBUG 0/#define DEBUG 1/` in a
header file, or "revision that does not have this commit needs this
patch applied to work around another problem this bisection is not
interested in") applied to the revision being tested.
-To cope with such a situation, after the inner 'git bisect' finds the
+To cope with such a situation, after the inner `git bisect` finds the
next revision to test, the script can apply the patch
before compiling, run the real test, and afterwards decide if the
revision (possibly with the needed patch) passed the test and then
@@ -370,20 +366,18 @@ determine the eventual outcome of the bisect session.
OPTIONS
-------
---no-checkout::
-+
-Do not checkout the new working tree at each iteration of the bisection
-process. Instead just update the reference named `BISECT_HEAD` to make
-it point to the commit that should be tested.
+`--no-checkout`::
+ Do not checkout the new working tree at each iteration of the bisection
+ process. Instead just update the reference named `BISECT_HEAD` to make
+ it point to the commit that should be tested.
+
This option may be useful when the test you would perform in each step
does not require a checked out tree.
+
If the repository is bare, `--no-checkout` is assumed.
---first-parent::
-+
-Follow only the first parent commit upon seeing a merge commit.
+`--first-parent`::
+ Follow only the first parent commit upon seeing a merge commit.
+
In detecting regressions introduced through the merging of a branch, the merge
commit will be identified as introduction of the bug and its ancestors will be
@@ -395,7 +389,7 @@ branch contained broken or non-buildable commits, but the merge itself was OK.
EXAMPLES
--------
-* Automatically bisect a broken build between v1.2 and HEAD:
+* Automatically bisect a broken build between v1.2 and `HEAD`:
+
------------
$ git bisect start HEAD v1.2 -- # HEAD is bad, v1.2 is good
@@ -403,7 +397,7 @@ $ git bisect run make # "make" builds the app
$ git bisect reset # quit the bisect session
------------
-* Automatically bisect a test failure between origin and HEAD:
+* Automatically bisect a test failure between origin and `HEAD`:
+
------------
$ git bisect start HEAD origin -- # HEAD is bad, origin is good
@@ -430,7 +424,7 @@ and `exit 1` otherwise.
+
It is safer if both `test.sh` and `check_test_case.sh` are
outside the repository to prevent interactions between the bisect,
-make and test processes and the scripts.
+`make` and test processes and the scripts.
* Automatically bisect with temporary modifications (hot-fix):
+
@@ -491,9 +485,9 @@ $ git bisect run sh -c '
$ git bisect reset # quit the bisect session
------------
+
-In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit that
+In this case, when `git bisect run` finishes, `bisect/bad` will refer to a commit that
has at least one parent whose reachable graph is fully traversable in the sense
-required by 'git pack objects'.
+required by `git pack-objects`.
* Look for a fix instead of a regression in the code
+
--
gitgitgadget
^ permalink raw reply related
* [PATCH v2 0/6] doc: convert another batch of files to synopsis style
From: Jean-Noël Avila via GitGitGadget @ 2026-05-25 10:28 UTC (permalink / raw)
To: git; +Cc: Jean-Noël Avila
In-Reply-To: <pull.2117.git.1779049615.gitgitgadget@gmail.com>
This time, 5 new conversions:
* git-bisect
* git-grep
* git-am
* git-apply
* git-imap-send
This batch was an opportunity to test AI-helped conversion.
Changes since v1:
* clarify the use of synopsis vs code block in git-bisect, which also
include using '$'
Jean-Noël Avila (6):
doc: convert git-bisect to synopsis style
doc: git bisect: clarify the usage of the synopsis vs actual command
doc: convert git-grep synopsis and options to new style
doc: convert git-am synopsis and options to new style
doc: convert git-apply synopsis and options to new style
doc: convert git-imap-send synopsis and options to new style
Documentation/asciidoc.conf.in | 6 +
Documentation/config/am.adoc | 6 +-
Documentation/config/apply.adoc | 17 +-
Documentation/config/grep.adoc | 36 ++--
Documentation/config/imap.adoc | 30 +--
Documentation/format-patch-caveats.adoc | 2 +-
.../format-patch-end-of-commit-message.adoc | 4 +-
Documentation/git-am.adoc | 132 ++++++------
Documentation/git-apply.adoc | 125 +++++------
Documentation/git-bisect.adoc | 109 +++++-----
Documentation/git-grep.adoc | 196 +++++++++---------
Documentation/git-imap-send.adoc | 24 +--
12 files changed, 346 insertions(+), 341 deletions(-)
base-commit: 56a4f3c3a221adf1df9b39da69b8a6890f803157
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2117%2Fjnavila%2Fbisect-synopsis-style-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2117/jnavila/bisect-synopsis-style-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/2117
Range-diff vs v1:
1: dca7f192f1 ! 1: 7284281fe0 doc: convert git-bisect to synopsis style
@@ Documentation/git-bisect.adoc: that, as it cleans up the old bisection state.)
With an optional argument, you can return to a different commit
instead:
+-------------------------------------------------
+[synopsis]
- ------------------------------------------------
$ git bisect reset <commit>
- ------------------------------------------------
+-------------------------------------------------
+
+ For example, `git bisect reset bisect/bad` will check out the first
+ bad revision, while `git bisect reset HEAD` will leave you on the
@@ Documentation/git-bisect.adoc: To use "old" and "new" instead of "good" and bad, you must run `git
bisect start` without commits as argument and then run the following
commands to add the commits:
+-------------------------------------------------
+[synopsis]
- ------------------------------------------------
git bisect old [<rev>]
- ------------------------------------------------
+-------------------------------------------------
to indicate that a commit was before the sought change, or
+-------------------------------------------------
+[synopsis]
- ------------------------------------------------
git bisect new [<rev>...]
- ------------------------------------------------
-@@ Documentation/git-bisect.adoc: to indicate that it was after.
+-------------------------------------------------
+
+ to indicate that it was after.
To get a reminder of the currently used terms, use
+-------------------------------------------------
+[synopsis]
- ------------------------------------------------
git bisect terms
- ------------------------------------------------
+-------------------------------------------------
+
+ You can get just the old term with `git bisect terms --term-old`
+ or `git bisect terms --term-good`; `git bisect terms --term-new`
@@ Documentation/git-bisect.adoc: If you would like to use your own terms instead of "bad"/"good" or
subcommands like `reset`, `start`, ...) by starting the
bisection using
+-------------------------------------------------
+[synopsis]
- ------------------------------------------------
git bisect start --term-old <term-old> --term-new <term-new>
- ------------------------------------------------
+-------------------------------------------------
+
+ For example, if you are looking for a commit that introduced a
+ performance regression, you might use
@@ Documentation/git-bisect.adoc: of `git bisect good` and `git bisect bad` to mark commits.
Bisect visualize/view
~~~~~~~~~~~~~~~~~~~~~
-: ---------- > 2: 4fb33dd440 doc: git bisect: clarify the usage of the synopsis vs actual command
2: 1b4efce1b2 = 3: fceaf195e8 doc: convert git-grep synopsis and options to new style
3: 4ab60a95f4 = 4: b9c2adfa1d doc: convert git-am synopsis and options to new style
4: 437e3f99c7 = 5: 60a420ea38 doc: convert git-apply synopsis and options to new style
5: dbe4d20b4b = 6: d88824bf09 doc: convert git-imap-send synopsis and options to new style
--
gitgitgadget
^ permalink raw reply
* Re: [PATCH 1/3] commit-reach: deduplicate queue entries in paint_down_to_common
From: Jeff King @ 2026-05-25 10:02 UTC (permalink / raw)
To: Kristofer Karlsson
Cc: Junio C Hamano, Derrick Stolee,
Kristofer Karlsson via GitGitGadget, git
In-Reply-To: <CAL71e4ODJeCJctKg=3o9PKD6Rw3_xHnrjc+zT_MYFc=CdNc59A@mail.gmail.com>
On Mon, May 25, 2026 at 09:53:09AM +0200, Kristofer Karlsson wrote:
> Good catch Jeff! I think it's possible that I missed the flag cleanup case
> here, but it's also possible that I got lucky and it worked anyway.
Well, you did add it to ALL_FLAGS, so it might have been your
subconscious making you lucky. :)
> That said, I think the observation in the other email thread/commit is key
> here. I will reply back in that one, but it seems like this can all be
> simplified using Jeff's idea with an amortized O(1) solution by caching a
> known non-stale entry in the queue, and thus becomes obsolete. I will post
> a new patchset when the discussion slows down.
Nifty, thanks.
> As for general flag management, I will spend some more time thinking about it.
> I don't fully trust static code analysis to work, but some cheap assertion
> based model might give a nice trade-off.
I think it would be really nice if we had per-operation flags kept
outside of the structs completely. If you're a masochist, I fiddled
around a bit with using a hash instead in this thread:
https://lore.kernel.org/git/20250826055210.GA1031277@coredump.intra.peff.net/
It's sadly (but not surprisingly) quite slow. I do wonder how a slab
would work there, but it would take a bit more surgery. We only allocate
slab ids for commits, and we'd have to do so for all objects if we want
to hold flags.
Probably a dead-end, but it would be neat if all of these flag
allocation worries just went away.
-Peff
^ permalink raw reply
* Re: [PATCH 0/3] commit-reach: replace queue_has_nonstale with a counter
From: Jeff King @ 2026-05-25 9:55 UTC (permalink / raw)
To: Kristofer Karlsson; +Cc: Kristofer Karlsson via GitGitGadget, git
In-Reply-To: <CAL71e4MOH2iPve19dKixLHSgpC3ZAZz59zLWEWRoxW1a7vhMwg@mail.gmail.com>
On Mon, May 25, 2026 at 09:59:59AM +0200, Kristofer Karlsson wrote:
> That's an excellent approach! Much cleaner in general.
>
> I benchmarked it against the counter on a monorepo with wide-frontier DAGs
> (2.4M commits, component import merges). Using merge-base --all to bypass
> the early-exit optimization from kk/paint-down-to-common-optim:
>
> Baseline Cache Counter
> import(A) 8079ms 3686ms 3723ms
> import(B) 5498ms 3993ms 4038ms
> import(C) 4350ms 1748ms 1766ms
>
> The cache performs on par with the counter - within noise on all three
> cases. No new flags needed, much simpler diff.
> The amortized O(1) is just as good as true O(1) in practice, and it avoids
> the ENQUEUED flag and counter bookkeeping entirely.
I'm not sure if it's technically amortized O(1), as I think in the worst
case we are still quadratic. That would happen if we've cached some
non-stale X, then pop it and put on some new commit Y. And then the next
round we have no cache (X was popped), but have to walk the whole queue
to find Y.
So I think it's more of a "heuristically O(1)" or something.
> I went with back-to-front scanning as you suggested
Out of curiosity, did you also time it front-to-back? What I wonder is
if we might commonly hit that worst case for back-to-front when we're
continually popping and inserting one new commit at the front of the
queue. If there's a bunch of stale cruft in the back end of the queue,
we'll walk over it repeatedly to find the new commit, and our cache will
never (or seldom) remain valid. (I know it's a heap, not a real queue,
but I think the far end of the array will still tend to represent stuff
that is further away from being popped due to the heap property).
Whereas looking from front to back, we are likely to cache something
that is going to be popped soon. But in that case we find it quickly,
and the longer we search the more likely it is to hang around in the
queue and remain valid.
> and also clear the cache when the cached entry goes stale.
I think this happens naturally when we call into queue_has_nonstale().
We only use the cached value if it's still non-stale. If it's gone stale
then we either find a new commit, or if we can't then we return false
(everything is stale). I guess the stale commit is left in the cache in
the latter case, but it doesn't matter because the loop ends anyway (and
even if it didn't, it is OK to repeatedly ignore the stale commit, as
doing so is O(1) and we have nothing better to cache).
That said, it is probably only one line to explicitly set it to NULL in
queue_has_nonstale(), so I am OK with that. ;)
If you're proposing to notice when we set the STALE flag on a commit
which matches the cached value, I'd prefer to avoid that, just because
it muddies up the code.
> I can rewrite the patchset with this approach and add you as co-author or
> suggested-by? Or I think I can wait for you to push it yourself.
> You did all the work here, and just didn't have enough data points to
> motivate it?
I think testing and writing the commit messages will be more work than
the code. I am happy to live on in a trailer if you will do those other
parts. ;)
-Peff
^ permalink raw reply
* Re: [PATCH v5 0/2] includeIf: add "worktree" condition for matching working tree path
From: Junio C Hamano @ 2026-05-25 9:24 UTC (permalink / raw)
To: Chen Linxuan
Cc: Chen Linxuan via B4 Relay, git, Kristoffer Haugsbakk,
Patrick Steinhardt, Phillip Wood
In-Reply-To: <CAC1kPDPbyxs-aTrAOi_PNTZF7EApG31iLYwm+Eddpeh2hT8a-w@mail.gmail.com>
Chen Linxuan <me@black-desk.cn> writes:
> On Mon, May 25, 2026 at 3:31 PM Junio C Hamano <gitster@pobox.com> wrote:
>>
>> Chen Linxuan via B4 Relay <devnull+me.black-desk.cn@kernel.org>
>> writes:
>>
>> > Changes in v5:
>> > - Fix Windows CI failure: use `**` glob pattern instead of `/` in the
>> > "worktree without repository" tests, since `/` as a path pattern is
>> > Unix-specific and does not match Windows paths.
>>
>> Would it have worked if you used something like "[/\\].path",
>> instead of "/.path", to cover directory delimiters for both systems?
>>
>> I am not asking to make further changes. I am trying to understand
>> what the extent of the problem was.
>
> The root cause is that on Windows,
> strbuf_realpath() returns paths with a drive letter prefix (e.g.
> D:/a/git/...), which does not start with /.
Ahh, OK, so the "Changes in v5" description was misleading.
This exchange suggests that the use of **/.path in the test deserves
some in-code comment to explain why we use such an unusual and loose
construct.
Thanks.
^ permalink raw reply
* Re: [PATCH v3] config: suggest the correct form when key contains "=" in set context
From: Junio C Hamano @ 2026-05-25 9:15 UTC (permalink / raw)
To: Harald Nordgren via GitGitGadget
Cc: git, Kristoffer Haugsbakk, Harald Nordgren
In-Reply-To: <pull.2302.v3.git.git.1779697995418.gitgitgadget@gmail.com>
"Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com> writes:
> Emit a "did you mean ..." hint suggesting the split form. Restrict it
> to plausible-set contexts ("git config set", bare "git config <key>",
> and their 2-arg forms); explicit "get"/"unset" keep the existing error.
I understand that it would be a good idea to give this warning
against these two where $A is an arbitrary string with at least one
dot in it (making it a likely variable name), and $B is an arbitrary
string that may contain anything:
git config set "$A=$B"
git config "$A=$B"
It is plausible that the user wanted to make the value of the
variable "$A" to "$B", so telling them the right syntax would be
valuable.
If "$A" is a syntactically valid variable name, then I would imagine
that we want to say something like this:
$ git config set "$A=$B"
error: missing value to set to the variable "$A=$B"
hint: did you mean 'git config set "$A" "$B"'?
If "$A" is *not* a syntactically valid variable name, then giving a
hint to try to assing to it is a counter-productive. Ideally we
probably want something like:
$ git config set "foo=bar"
error: missing value to set to a variable with an invalid name 'foo=bar'
It is pointless to say the user may have meant "git config set foo bar",
as "foo" is clearly not a valid variable.
I do not understand what you mean by "their 2-arg forms". Do you
mean
git config set "$A=$B" "$C"
by that? If so, I doubt that user meant an assignment to "$A" by
this form with explicit "set". If "$A=$B" is a variable whose name
is valid (i.e. three-level name whose the second level component
contains a "="), we should just take it as asked. E.g.,
git config set "foo.bar=baz.boo" "some-string"
needs no hand holding. But
if "$A=$B" is not a valid variable name, we should just complain
that the user is trying to assign to a variable with an invalid
name.
$ git config set "foo.bar=baz" "some-string"
error: setting to a variable with invalid name 'foo.bar=baz'
I think
git config "$A=$B" "$C"
that implicitly uses the 'set' verb can be left as an exercise to
readers. If "$A=$B" is a valid name, we shouldn't do any complaint.
If it is not,
$ git config "foo.bar=baz" "some-string"
error: setting to a variable with invalid name 'foo.bar=baz'
It makes it clear to the user that (1) we interpreted the command
line to be "implicit set", (2) we interpreted the command line to
set variable 'foo.bar=baz', and (3) 'foo.bar=baz' is not a valid
name. I do not think there is anything more needed for this case.
> "=" is legal inside a subsection, so only fire when "=" lands after
> the last ".". When the user supplied a separate value, use it in the
> suggestion instead of the suffix after "=":
>
> $ git config set pull.rebase=false true
> error: invalid key: pull.rebase=false
> hint: did you mean "git config set pull.rebase true"?
I really do not think '=' needs *any* special casing in this case.
If we used "pull.rebase*false" as the variable instead, the message
would say that "pull.rebase*false" is an invalid key. Two important
things for this message to convey are (1) the command correctly
parsed the command line to mean that the user wants to assign to a
variable whose name is 'pull.rebase*false' and (2) that variable
name *is* invalid.
If you find the current message suboptimal, I think we should try to
clarify the message, as '=' or '*' or any letter that makes the
variable name invalid would benefit from the same improvement.
Perhaps something like:
$ git config set pull.rebase*false true
error: setting to a variable with invalid name: 'pull.rebase*false'
perhaps?
> Signed-off-by: Harald Nordgren <harald.nordgren@kostdoktorn.se>
> Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
Interesting. We typically do not do this.
^ permalink raw reply
* Re: [PATCH v5 0/2] includeIf: add "worktree" condition for matching working tree path
From: Chen Linxuan @ 2026-05-25 9:00 UTC (permalink / raw)
To: Junio C Hamano
Cc: Chen Linxuan via B4 Relay, git, Kristoffer Haugsbakk,
Patrick Steinhardt, Chen Linxuan, Phillip Wood
In-Reply-To: <xmqqjysseyid.fsf@gitster.g>
On Mon, May 25, 2026 at 3:31 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Chen Linxuan via B4 Relay <devnull+me.black-desk.cn@kernel.org>
> writes:
>
> > Changes in v5:
> > - Fix Windows CI failure: use `**` glob pattern instead of `/` in the
> > "worktree without repository" tests, since `/` as a path pattern is
> > Unix-specific and does not match Windows paths.
>
> Would it have worked if you used something like "[/\\].path",
> instead of "/.path", to cover directory delimiters for both systems?
>
> I am not asking to make further changes. I am trying to understand
> what the extent of the problem was.
The root cause is that on Windows,
strbuf_realpath() returns paths with a drive letter prefix (e.g.
D:/a/git/...), which does not start with /.
Here is the trace output from the Windows CI [1]:
include_by_path: text='D:/a/git/git/t/trash
directory.t1305-config-include', pattern='/**', prefix=0
The pattern worktree:/ becomes /** after add_trailing_starstar_for_dir().
Then wildmatch("/**", "D:/a/git/...", WM_PATHNAME) fails because the text
does not start with /.
[1] https://github.com/black-desk/git/actions/runs/26391768962/job/77683708185
^ permalink raw reply
* Re: [PATCH 2/3] commit-reach: optimize queue scan in paint_down_to_common
From: Kristofer Karlsson @ 2026-05-25 8:54 UTC (permalink / raw)
To: Derrick Stolee; +Cc: Kristofer Karlsson via GitGitGadget, git
In-Reply-To: <42aef000-7952-482d-8532-2287cf32b275@gmail.com>
I have been thinking a bit about encapsulation too - the problem is twofold:
1. ENQUEUED is a tag on the commit object but it represents membership
inside the queue and so we already have an implicit assumption that it only
matches one queue (at a time).
2. The counter is touched on enqueue/dequeue BUT also when mutating objects -
that last part is tricky to encapsulate as a part of the queue.
That said, I think if we go in the direction of Jeff's idea with an amortized
O(1) staleness check, this becomes simpler - and we can perhaps do something
to structure _that_ code instead. Something like this perhaps:
struct stale_prio_queue {
prio_queue pq;
commit *nonstale_cache;
}
and add the corresponding wrapper functions.
I think the encapsulation idea becomes even stronger with that approach than
with the counter based approach.
- Kristofer
On Mon, 25 May 2026 at 03:59, Derrick Stolee <stolee@gmail.com> wrote:
>
> On 5/24/26 1:42 PM, Kristofer Karlsson via GitGitGadget wrote:
> > From: Kristofer Karlsson <krka@spotify.com>
> >
> > paint_down_to_common() terminates when every commit remaining in its
> > priority queue is STALE. This was checked by queue_has_nonstale(),
> > which performed an O(n) linear scan of the entire queue on every
> > iteration, resulting in O(n*m) total overhead where n is the queue
> > size and m is the number of commits processed.
> >
> > Replace this with an O(1) nonstale_count that tracks the number of
> > non-stale commits currently in the queue. The counter is incremented
> > by maybe_enqueue() and decremented on dequeue and by mark_stale()
> > when a commit transitions to STALE while still in the queue. Since
> > each commit appears at most once (guaranteed by the ENQUEUED flag
> > from the previous commit), the counter is exact.
>
> This idea has a lot of merit, but I'm a bit concerned about the
> organization of data. My ideas of how to improve things may also
> impact patch 1's use of ENQUEUED.
>
> > -static void maybe_enqueue(struct prio_queue *queue, struct commit *c)
> > +static void maybe_enqueue(struct prio_queue *queue, struct commit *c,
> > + int *nonstale_count)
> > {
> > if (c->object.flags & ENQUEUED)
> > return;
> > c->object.flags |= ENQUEUED;
> > prio_queue_put(queue, c);
> > + if (!(c->object.flags & STALE))
> > + (*nonstale_count)++;
> > +}
> > +
> > +static void mark_stale(struct commit *c, unsigned queued_flag,
> > + int *nonstale_count)
> > +{
> > + if (!(c->object.flags & STALE)) {
> > + if (c->object.flags & queued_flag)
> > + (*nonstale_count)--;
> > + c->object.flags |= STALE;
> > + }
> > }
>
> These two methods have some concerns on my end:
>
> 1. We need to store the nonstale count somewhere other than the
> priority queue, even though it's necessarily representing a
> subset of the commits within the queue.
>
> 2. mark_stale() needs a queued_flag. (I need to check to see if
> this is indeed changing in multiple callers or should always
> be ENQUEUED).
>
> > static int queue_has_nonstale(struct prio_queue *queue)
> > @@ -68,6 +81,7 @@ static int paint_down_to_common(struct repository *r,
> > {
> > struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
> > int i;
> > + int nonstale_count = 0;
>
> My preference would be to create a new struct that contains a
> prio_queue as a member _and_ a nonstale_count. It could initialize
> with compare_commits_by_gen_then_commit_date by default.
>
> The important thing is that consumers of such a "stale-tracking"
> queue would not be setting the STALE or ENQUEUED bits themselves,
> but instead the queue would be responsible for that.
>
> This could allow us to simplify callers by always assuming we can
> "add" an element to the queue and the queue will use its ENQUEUED
> bit to prevent duplicates from reaching its internal prio_queue.
>
> Such a data structure could be private to commit-reach.c for now,
> since all the methods that would use it seem to be colocated there.
>
> This is a big ask, but I'm interested to see if such an approach
> would simplify things here.
>
> Here's a potential breakdown of how to build such a thing in
> "small" patches:
>
> 1. Create the data structure and update paint_down_to_common and
> ahead_behind to use that structure, but still use the existing
> prio_queue methods on its internal member.
>
> 2. Add the ENQUEUED bit and methods on the new struct that add
> that bit as it adds commits to the inner prio_queue. It would
> also ignore commits that already have that bit. (Should it
> also remove the bit as commits are removed from the queue?)
>
> 3. Now add the nonstale_count (or stale count?) to the struct and
> have it control the STALE bit modifications, with increasing
> the stale count when ENQUEUED is live, and decreasing the stale
> count as such a STALE object is dequeued.
>
> I like the idea of this being encapsulated within the struct and
> its helper methods. But the proof will be in the implementation.
>
> Thanks,
> -Stolee
>
^ permalink raw reply
* Re: [PATCH 0/3] commit-reach: replace queue_has_nonstale with a counter
From: Junio C Hamano @ 2026-05-25 8:38 UTC (permalink / raw)
To: Kristofer Karlsson; +Cc: Jeff King, Kristofer Karlsson via GitGitGadget, git
In-Reply-To: <CAL71e4MOH2iPve19dKixLHSgpC3ZAZz59zLWEWRoxW1a7vhMwg@mail.gmail.com>
Kristofer Karlsson <krka@spotify.com> writes:
> That's an excellent approach! Much cleaner in general.
>
> I benchmarked it against the counter on a monorepo with wide-frontier DAGs
> (2.4M commits, component import merges). Using merge-base --all to bypass
> the early-exit optimization from kk/paint-down-to-common-optim:
>
> Baseline Cache Counter
> import(A) 8079ms 3686ms 3723ms
> import(B) 5498ms 3993ms 4038ms
> import(C) 4350ms 1748ms 1766ms
>
> The cache performs on par with the counter - within noise on all three
> cases. No new flags needed, much simpler diff.
> The amortized O(1) is just as good as true O(1) in practice, and it avoids
> the ENQUEUED flag and counter bookkeeping entirely.
Nice.
> I went with back-to-front scanning as you suggested, and also clear
> the cache when the cached entry goes stale. Applied to both
> paint_down_to_common and ahead_behind.
>
> I can rewrite the patchset with this approach and add you as co-author or
> suggested-by? Or I think I can wait for you to push it yourself.
> You did all the work here, and just didn't have enough data points to
> motivate it?
I can take from either of you two ;-). Thanks for working so well
together, as always.
^ permalink raw reply
* [PATCH v3] config: suggest the correct form when key contains "=" in set context
From: Harald Nordgren via GitGitGadget @ 2026-05-25 8:33 UTC (permalink / raw)
To: git; +Cc: Kristoffer Haugsbakk, Harald Nordgren, Harald Nordgren
In-Reply-To: <pull.2302.v2.git.git.1778935976330.gitgitgadget@gmail.com>
From: Harald Nordgren <haraldnordgren@gmail.com>
A user who types "git config pull.rebase=false" gets only "error:
invalid key: pull.rebase=false" with no clue what went wrong.
Emit a "did you mean ..." hint suggesting the split form. Restrict it
to plausible-set contexts ("git config set", bare "git config <key>",
and their 2-arg forms); explicit "get"/"unset" keep the existing error.
"=" is legal inside a subsection, so only fire when "=" lands after
the last ".". When the user supplied a separate value, use it in the
suggestion instead of the suffix after "=":
$ git config set pull.rebase=false true
error: invalid key: pull.rebase=false
hint: did you mean "git config set pull.rebase true"?
Signed-off-by: Harald Nordgren <harald.nordgren@kostdoktorn.se>
Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
---
config: suggest the correct form when key contains "="
* Skip the hint when the inferred value contains whitespace, so git
config set pull.rebase=false "hello world" no longer suggests a
malformed command.
* Replace the inline actions == 0 check with a named actions_implicit
flag, simplfied the code.
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2302%2FHaraldNordgren%2Fconfig-hint-equals-key-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2302/HaraldNordgren/config-hint-equals-key-v3
Pull-Request: https://github.com/git/git/pull/2302
Range-diff vs v2:
1: 40d9eb3e5c ! 1: 6b9d66361d config: suggest the correct form when key contains "=" in set context
@@ Commit message
hint: did you mean "git config set pull.rebase true"?
Signed-off-by: Harald Nordgren <harald.nordgren@kostdoktorn.se>
+ Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
## builtin/config.c ##
@@
@@ builtin/config.c: static void check_argc(int argc, int min, int max)
+ return;
+ if (!value)
+ value = eq + 1;
++ if (!*value || strpbrk(value, " \t\n"))
++ return;
+ advise(_("did you mean \"git config set %.*s %s\"?"),
+ (int)(eq - key), key, value);
+}
@@ builtin/config.c: static int cmd_config_actions(int argc, const char **argv, con
exit(129);
}
+- if (actions == 0)
+ actions_implicit = (actions == 0);
- if (actions == 0)
++ if (actions_implicit)
switch (argc) {
case 1: actions = ACTION_GET; break;
+ case 2: actions = ACTION_SET; break;
@@ builtin/config.c: static int cmd_config_actions(int argc, const char **argv, const char *prefix)
if (ret == CONFIG_NOTHING_SET)
error(_("cannot overwrite multiple values with a single value\n"
@@ t/t1300-config.sh: test_expect_success 'invalid key' '
+ test_grep ! "did you mean" err
+'
+
++test_expect_success 'misplaced "=" in key: value with whitespace skips hint' '
++ test_must_fail git config set pull.rebase=false "hello world" 2>err &&
++ test_grep "invalid key: pull\\.rebase=false" err &&
++ test_grep ! "did you mean" err
++'
++
+test_expect_success '"=" inside subsection is valid, no hint' '
+ test_when_finished "rm -f subsection.cfg" &&
+ git config set -f subsection.cfg foo.bar=baz.boo qux 2>err &&
builtin/config.c | 34 +++++++++++++++++++++++++++++-
t/t1300-config.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/builtin/config.c b/builtin/config.c
index cf4ba0f7cc..8c7ab36fcb 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -1,6 +1,7 @@
#define USE_THE_REPOSITORY_VARIABLE
#include "builtin.h"
#include "abspath.h"
+#include "advice.h"
#include "config.h"
#include "color.h"
#include "date.h"
@@ -210,6 +211,24 @@ static void check_argc(int argc, int min, int max)
exit(129);
}
+static void advise_setting_with_equals(const char *key, const char *value)
+{
+ const char *last_dot = strrchr(key, '.');
+ const char *eq;
+
+ if (!last_dot)
+ return;
+ eq = strchr(last_dot + 1, '=');
+ if (!eq)
+ return;
+ if (!value)
+ value = eq + 1;
+ if (!*value || strpbrk(value, " \t\n"))
+ return;
+ advise(_("did you mean \"git config set %.*s %s\"?"),
+ (int)(eq - key), key, value);
+}
+
static void show_config_origin(const struct config_display_options *opts,
const struct key_value_info *kvi,
struct strbuf *buf)
@@ -1133,6 +1152,11 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix,
argc = parse_options(argc, argv, prefix, opts, builtin_config_set_usage,
PARSE_OPT_STOP_AT_NON_OPTION);
+ if (argc == 1 && strchr(argv[0], '=')) {
+ error(_("wrong number of arguments, should be 2"));
+ advise_setting_with_equals(argv[0], NULL);
+ exit(129);
+ }
check_argc(argc, 2, 2);
if ((flags & CONFIG_FLAGS_FIXED_VALUE) && !value_pattern)
@@ -1160,6 +1184,8 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix,
error(_("cannot overwrite multiple values with a single value\n"
" Use --value=<pattern>, --append or --all to change %s."), argv[0]);
}
+ if (ret == CONFIG_INVALID_KEY)
+ advise_setting_with_equals(argv[0], argv[1]);
location_options_release(&location_opts);
free(comment);
@@ -1371,6 +1397,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
};
char *value = NULL, *comment = NULL;
int ret = 0;
+ int actions_implicit;
struct key_value_info default_kvi = KVI_INIT;
argc = parse_options(argc, argv, prefix, opts,
@@ -1385,7 +1412,8 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
exit(129);
}
- if (actions == 0)
+ actions_implicit = (actions == 0);
+ if (actions_implicit)
switch (argc) {
case 1: actions = ACTION_GET; break;
case 2: actions = ACTION_SET; break;
@@ -1485,6 +1513,8 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
if (ret == CONFIG_NOTHING_SET)
error(_("cannot overwrite multiple values with a single value\n"
" Use a regexp, --add or --replace-all to change %s."), argv[0]);
+ else if (ret == CONFIG_INVALID_KEY)
+ advise_setting_with_equals(argv[0], argv[1]);
}
else if (actions == ACTION_SET_ALL) {
check_write(&location_opts.source);
@@ -1515,6 +1545,8 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix)
check_argc(argc, 1, 2);
ret = get_value(&location_opts, &display_opts, argv[0], argv[1],
0, flags);
+ if (ret == CONFIG_INVALID_KEY && actions_implicit)
+ advise_setting_with_equals(argv[0], NULL);
}
else if (actions == ACTION_GET_ALL) {
check_argc(argc, 1, 2);
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index 11fc976f3a..4e12b78536 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -469,6 +469,59 @@ test_expect_success 'invalid key' '
test_must_fail git config inval.2key blabla
'
+test_expect_success 'misplaced "=" in key: bare 1-arg form hints' '
+ test_must_fail git config pull.rebase=false 2>err &&
+ test_grep "invalid key: pull\\.rebase=false" err &&
+ test_grep "did you mean .git config set pull\\.rebase false." err
+'
+
+test_expect_success 'misplaced "=" in key: bare 2-arg form uses given value' '
+ test_must_fail git config pull.rebase=false true 2>err &&
+ test_grep "did you mean .git config set pull\\.rebase true." err
+'
+
+test_expect_success 'misplaced "=" in key: set subcommand uses given value' '
+ test_must_fail git config set pull.rebase=false true 2>err &&
+ test_grep "did you mean .git config set pull\\.rebase true." err
+'
+
+test_expect_success 'misplaced "=" in key: set with single arg hints' '
+ test_must_fail git config set pull.rebase=false 2>err &&
+ test_grep "wrong number of arguments" err &&
+ test_grep "did you mean .git config set pull\\.rebase false." err
+'
+
+test_expect_success 'misplaced "=" in key: explicit --get does not hint' '
+ test_must_fail git config --get pull.rebase=false 2>err &&
+ test_grep "invalid key: pull\\.rebase=false" err &&
+ test_grep ! "did you mean" err
+'
+
+test_expect_success 'misplaced "=" in key: get subcommand does not hint' '
+ test_must_fail git config get pull.rebase=false 2>err &&
+ test_grep ! "did you mean" err
+'
+
+test_expect_success 'misplaced "=" in key: unset subcommand does not hint' '
+ test_must_fail git config unset pull.rebase=false 2>err &&
+ test_grep ! "did you mean" err
+'
+
+test_expect_success 'misplaced "=" in key: value with whitespace skips hint' '
+ test_must_fail git config set pull.rebase=false "hello world" 2>err &&
+ test_grep "invalid key: pull\\.rebase=false" err &&
+ test_grep ! "did you mean" err
+'
+
+test_expect_success '"=" inside subsection is valid, no hint' '
+ test_when_finished "rm -f subsection.cfg" &&
+ git config set -f subsection.cfg foo.bar=baz.boo qux 2>err &&
+ test_grep ! "did you mean" err &&
+ echo qux >expect &&
+ git config get -f subsection.cfg foo.bar=baz.boo >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'correct key' '
git config 123456.a123 987
'
base-commit: 6a4418c36d6bad69a599044b3cf49dcbd049cb45
--
gitgitgadget
^ permalink raw reply related
* Re: [PATCH 0/3] commit-reach: replace queue_has_nonstale with a counter
From: Kristofer Karlsson @ 2026-05-25 7:59 UTC (permalink / raw)
To: Jeff King; +Cc: Kristofer Karlsson via GitGitGadget, git
In-Reply-To: <20260525064755.GA2737798@coredump.intra.peff.net>
That's an excellent approach! Much cleaner in general.
I benchmarked it against the counter on a monorepo with wide-frontier DAGs
(2.4M commits, component import merges). Using merge-base --all to bypass
the early-exit optimization from kk/paint-down-to-common-optim:
Baseline Cache Counter
import(A) 8079ms 3686ms 3723ms
import(B) 5498ms 3993ms 4038ms
import(C) 4350ms 1748ms 1766ms
The cache performs on par with the counter - within noise on all three
cases. No new flags needed, much simpler diff.
The amortized O(1) is just as good as true O(1) in practice, and it avoids
the ENQUEUED flag and counter bookkeeping entirely.
I went with back-to-front scanning as you suggested, and also clear
the cache when the cached entry goes stale. Applied to both
paint_down_to_common and ahead_behind.
I can rewrite the patchset with this approach and add you as co-author or
suggested-by? Or I think I can wait for you to push it yourself.
You did all the work here, and just didn't have enough data points to
motivate it?
- Kristofer
On Mon, 25 May 2026 at 08:47, Jeff King <peff@peff.net> wrote:
>
> On Sun, May 24, 2026 at 05:42:17PM +0000, Kristofer Karlsson via GitGitGadget wrote:
>
> > paint_down_to_common() and ahead_behind() terminate when every commit in
> > their priority queue is STALE. The current check, queue_has_nonstale(), does
> > an O(n) linear scan of the queue on every iteration, costing O(n*m) total
> > where n is the queue size and m is the number of commits processed. This
> > series replaces that scan with an O(1) counter.
>
> We faced a similar problem in limit_list() but solved it a bit
> differently (mostly because I was worried about keeping the counter up
> to date in all cases).
>
> It's described in more detail in b6e8a3b540 (limit_list: avoid quadratic
> behavior from still_interesting, 2015-04-17), but the general idea is to
> just cache the interesting element we found, and invalidate the cache
> when it gets removed from the queue or gets marked UNINTERESTING.
>
> The equivalent code for the STALE flag here is something like this:
>
> diff --git a/commit-reach.c b/commit-reach.c
> index d3a9b3ed6f..d1621be89f 100644
> --- a/commit-reach.c
> +++ b/commit-reach.c
> @@ -39,12 +39,25 @@ static int compare_commits_by_gen(const void *_a, const void *_b)
> return 0;
> }
>
> -static int queue_has_nonstale(struct prio_queue *queue)
> +static int queue_has_nonstale(struct prio_queue *queue,
> + struct commit **nonstale_cache)
> {
> + if (*nonstale_cache) {
> + struct commit *commit = *nonstale_cache;
> + if (!(commit->object.flags & STALE))
> + return 1;
> + }
> +
> + /*
> + * This might also benefit from looking back-to-front, since
> + * earlier commits are more likely to get popped sooner.
> + */
> for (size_t i = 0; i < queue->nr; i++) {
> struct commit *commit = queue->array[i].data;
> - if (!(commit->object.flags & STALE))
> + if (!(commit->object.flags & STALE)) {
> + *nonstale_cache = commit;
> return 1;
> + }
> }
> return 0;
> }
> @@ -61,6 +74,7 @@ static int paint_down_to_common(struct repository *r,
> int i;
> timestamp_t last_gen = GENERATION_NUMBER_INFINITY;
> struct commit_list **tail = result;
> + struct commit *nonstale_cache = NULL;
>
> if (!min_generation && !corrected_commit_dates_enabled(r))
> queue.compare = compare_commits_by_commit_date;
> @@ -77,12 +91,15 @@ static int paint_down_to_common(struct repository *r,
> prio_queue_put(&queue, twos[i]);
> }
>
> - while (queue_has_nonstale(&queue)) {
> + while (queue_has_nonstale(&queue, &nonstale_cache)) {
> struct commit *commit = prio_queue_get(&queue);
> struct commit_list *parents;
> int flags;
> timestamp_t generation = commit_graph_generation(commit);
>
> + if (nonstale_cache == commit)
> + nonstale_cache = NULL;
> +
> if (min_generation && generation > last_gen)
> BUG("bad generation skip %"PRItime" > %"PRItime" at %s",
> generation, last_gen,
> @@ -1053,6 +1070,7 @@ void ahead_behind(struct repository *r,
> {
> struct prio_queue queue = { .compare = compare_commits_by_gen_then_commit_date };
> size_t width = DIV_ROUND_UP(commits_nr, BITS_IN_EWORD);
> + struct commit *nonstale_cache = NULL;
>
> if (!commits_nr || !counts_nr)
> return;
> @@ -1074,11 +1092,14 @@ void ahead_behind(struct repository *r,
> insert_no_dup(&queue, c);
> }
>
> - while (queue_has_nonstale(&queue)) {
> + while (queue_has_nonstale(&queue, &nonstale_cache)) {
> struct commit *c = prio_queue_get(&queue);
> struct commit_list *p;
> struct bitmap *bitmap_c = get_bit_array(c, width);
>
> + if (c == nonstale_cache)
> + nonstale_cache = NULL;
> +
> for (size_t i = 0; i < counts_nr; i++) {
> int reach_from_tip = !!bitmap_get(bitmap_c, counts[i].tip_index);
> int reach_from_base = !!bitmap_get(bitmap_c, counts[i].base_index);
>
>
> I don't have a repo handy which reproduces the problem, so I can't see
> if it improves things. But if it's easy to do, can you report on the
> timing change with your monorepo?
>
> I do think what I've shown here is a bit hacky (just like the
> limit_list() one), as we are relying on heuristics about the order in
> which items are taken from the queue. So even if it performs well, we
> may still prefer the counter version for being truly O(1). But having
> timing numbers would be useful for comparing the two approaches.
>
> -Peff
^ permalink raw reply
* Re: [PATCH 1/3] commit-reach: deduplicate queue entries in paint_down_to_common
From: Kristofer Karlsson @ 2026-05-25 7:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Derrick Stolee, Kristofer Karlsson via GitGitGadget, git
In-Reply-To: <xmqqse7gez5l.fsf@gitster.g>
Good catch Jeff! I think it's possible that I missed the flag cleanup case
here, but it's also possible that I got lucky and it worked anyway.
That said, I think the observation in the other email thread/commit is key
here. I will reply back in that one, but it seems like this can all be
simplified using Jeff's idea with an amortized O(1) solution by caching a
known non-stale entry in the queue, and thus becomes obsolete. I will post
a new patchset when the discussion slows down.
As for general flag management, I will spend some more time thinking about it.
I don't fully trust static code analysis to work, but some cheap assertion
based model might give a nice trade-off.
Thanks for all the feedback!
- Kristofer
On Mon, 25 May 2026 at 09:17, Junio C Hamano <gitster@pobox.com> wrote:
>
> Kristofer Karlsson <krka@spotify.com> writes:
>
> > While doing the audit I noticed that reasoning about flag safety is
> > currently entirely manual. Would there be interest in something more
> > systematic (e.g. runtime registration/assertion, dynamic allocation or static
> > analysis of flag usage)? I have some local work on that already, but I was
> > not sure if this was something worth spending time on or not.
>
> If there weren't existing code that are so tied to their current
> uses of fixed flag bits and assumption that nobody else uses these
> bits outside their intended use, I'd love to have any of these.
> Uncolliding and unbounded number of usable bits per object that are
> *fast* to access would be good (and commit-slab was an attempt to
> introduce a framework that can be used as the basis for such a
> system). Independent of that, if we can statically analyze the uses
> of these bits to prove that the same flag bits are never used at the
> same time for colliding purposes, that would really be valuable.
^ permalink raw reply
* Re: [PATCH v5 0/2] includeIf: add "worktree" condition for matching working tree path
From: Junio C Hamano @ 2026-05-25 7:31 UTC (permalink / raw)
To: Chen Linxuan via B4 Relay
Cc: git, Kristoffer Haugsbakk, Patrick Steinhardt, Chen Linxuan,
Phillip Wood
In-Reply-To: <20260525-includeif-worktree-v5-0-1efe525d025a@black-desk.cn>
Chen Linxuan via B4 Relay <devnull+me.black-desk.cn@kernel.org>
writes:
> Changes in v5:
> - Fix Windows CI failure: use `**` glob pattern instead of `/` in the
> "worktree without repository" tests, since `/` as a path pattern is
> Unix-specific and does not match Windows paths.
Would it have worked if you used something like "[/\\].path",
instead of "/.path", to cover directory delimiters for both systems?
I am not asking to make further changes. I am trying to understand
what the extent of the problem was.
There are tons of [includeIf] that spells path patterns with the
assumption that '/' can be used as the directory separator, like
these lines taken from <master:t/t1305-config-include.sh>:
echo "[includeIf \"gitdir:foo/\"]path=bar" >>.git/config &&
echo "[includeIf \"gitdir:~/foo/\"]path=bar2" >>.git/config &&
echo "[includeIf \"gitdir:**/foo/**\"]path=bar3" >>.git/config &&
echo "[includeIf \"gitdir:./foo/.git\"]path=bar4" >>.gitconfig &&
echo "[includeIf \"gitdir/i:FOO/\"]path=bar5" >>.git/config &&
echo "[includeIf \"gitdir:foo/\"]path=bar6" >>.git/config &&
[includeIf "gitdir:**/foo/**/bar/**"]
echo "[includeIf \"gitdir:~/foo/\"]path=bar2" >>.git/config &&
echo "[includeIf \"gitdir:./foo/.git\"]path=bar4" >home/.gitconfig &&
echo "[includeIf \"gitdir:bar/\"]path=bar7" >>.git/config &&
echo "[includeIf \"gitdir/i:BAR/\"]path=bar8" >>.git/config &&
echo "[includeIf \"onbranch:foo-branch\"]path=bar9" >>.git/config &&
echo "[includeIf \"onbranch:?oo-*/**\"]path=bar10" >>.git/config &&
echo "[includeIf \"onbranch:foo-dir/\"]path=bar11" >>.git/config &&
and there is none, as far as I can tell, that uses a backslash as
directory separator.
Shoudln't the new worktree location code normalize the pathname
before doing a pattern matching so that it would allow '/'-separated
path pattern to match?
FWIW, here is the diff between v4 and v5.
t/t1305-config-include.sh | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git c/t/t1305-config-include.sh w/t/t1305-config-include.sh
index 07b6fb649c..25f484eec5 100755
--- c/t/t1305-config-include.sh
+++ w/t/t1305-config-include.sh
@@ -462,6 +462,19 @@ test_expect_success SYMLINKS 'conditional include, worktree resolves symlinks' '
)
'
+test_expect_success !CASE_INSENSITIVE_FS 'conditional include, worktree, case sensitive' '
+ git init wt-case &&
+ (
+ cd wt-case &&
+ test_commit initial &&
+ wt_path="$(pwd)" &&
+ wt_upper=$(echo "$wt_path" | tr a-z A-Z) &&
+ echo "[includeIf \"worktree:$wt_upper\"]path=case-inc" >>.git/config &&
+ echo "[test]wtcase=1" >.git/case-inc &&
+ test_must_fail git config test.wtcase
+ )
+'
+
test_expect_success 'conditional include, worktree, icase' '
git init wt-icase &&
(
@@ -495,7 +508,7 @@ test_expect_success 'conditional include, worktree does not match in early confi
test_expect_success 'conditional include, worktree without repository' '
test_when_finished "rm -f .gitconfig config.inc" &&
- git config set -f .gitconfig "includeIf.worktree:/.path" config.inc &&
+ git config set -f .gitconfig "includeIf.worktree:**.path" config.inc &&
git config set -f config.inc foo.bar baz &&
git config get foo.bar &&
test_must_fail nongit git config get foo.bar
@@ -503,7 +516,7 @@ test_expect_success 'conditional include, worktree without repository' '
test_expect_success 'conditional include, worktree without repository but explicit nonexistent Git directory' '
test_when_finished "rm -f .gitconfig config.inc" &&
- git config set -f .gitconfig "includeIf.worktree:/.path" config.inc &&
+ git config set -f .gitconfig "includeIf.worktree:**.path" config.inc &&
git config set -f config.inc foo.bar baz &&
git config get foo.bar &&
test_must_fail nongit git --git-dir=nonexistent config get foo.bar
^ permalink raw reply related
* Re: Expected test suite behavior
From: Jeff King @ 2026-05-25 7:27 UTC (permalink / raw)
To: Michael Montalbo; +Cc: amoghdambal1, git
In-Reply-To: <CAC2QwmKgQW2c6_OhepsB1hzXYHxpX0X4eyQS0dPcxRZLOnCdig@mail.gmail.com>
On Sun, May 24, 2026 at 11:20:54PM -0700, Michael Montalbo wrote:
> Amogh Dambal <amoghdambal1@gmail.com> writes:
> > Hey folks,
> >
> > I wanted to get started hacking on/poking around the Git source, but I'm
> > seeing some behavior with the tests that I can't quite figure out.
> > [...]
> > Is there a README/documentation I've missed reading that can help
> > explain the behavior I'm seeing?
>
> Hello. If you run `make test GIT_TEST_OPTS=--verbose` or uncomment
> L16 of t/Makefile is there more information describing the issue?
You can't use --verbose when running under the "prove" TAP harness
(which the OP seems to be doing). You can use --verbose-log instead, and
then output is in t/test-results/t1234-whatever.out.
However, when debugging tests I find it easier to focus on a single
failing test by running it individually, like:
cd t
./t1234-whatever.sh -v -i -x
That will stop at the first failure (-i), showing the output of all
commands (-v), and additionally enabling shell tracing (-x) so you can
see which command in the test failed.
-Peff
^ 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