Git development
 help / color / mirror / Atom feed
* [PATCH] help: prompt user to run corrected command on typo
From: calicomills @ 2026-06-18 14:26 UTC (permalink / raw)
  To: git; +Cc: gitster

From 0dc9e5c4593611b75e7003e8fdbea9370524c05b Mon Sep 17 00:00:00 2001
From: calicomills <jishnuck26@gmail.com>
Date: Thu, 18 Jun 2026 19:47:12 +0530
Subject: [PATCH] help: prompt user to run corrected command on typo

When a user mistypes a git command and there is exactly one similar
command, git currently prints a suggestion but exits, requiring the
user to retype the corrected command manually.

Instead, when stdin and stderr are both connected to a terminal and
there is a single best match, prompt the user with:

  Did you mean 'git checkout neo'? [y/N]

The full corrected invocation (command + original arguments) is shown
in the prompt so the user knows exactly what will run. Answering 'y'
re-executes git with the corrected command and all original arguments.
Answering anything else exits as before.

When there are multiple similarly-named commands, or when running
non-interactively (scripts, pipes), the original behaviour of printing
the suggestion list and exiting is preserved.

The help_unknown_cmd() signature is updated to accept the full args
vector so the prompt can include the original arguments alongside the
corrected command name.

Add tests to t9003 covering:
- non-interactive single match: falls back to suggestion list
- non-interactive multiple matches: falls back to suggestion list
- interactive single match, 'y': corrected command runs (TTY prereq)
- interactive single match, 'n': exits cleanly (TTY prereq)

Signed-off-by: calicomills <jishnuck26@gmail.com>
---
 builtin/help.c              |  2 +-
 git.c                       |  2 +-
 help.c                      | 40 ++++++++++++++++++++++------
 help.h                      |  3 ++-
 t/t9003-help-autocorrect.sh | 53 +++++++++++++++++++++++++++++++++++++
 5 files changed, 89 insertions(+), 11 deletions(-)

diff --git a/builtin/help.c b/builtin/help.c
index a140339999..b17e61ccc8 100644
--- a/builtin/help.c
+++ b/builtin/help.c
@@ -618,7 +618,7 @@ static char *check_git_cmd(const char *cmd)
 	}
 
 	if (exclude_guides)
-		return help_unknown_cmd(cmd);
+		return help_unknown_cmd(cmd, NULL);
 
 	return xstrdup(cmd);
 }
diff --git a/git.c b/git.c
index 36f08891ef..d379cc85bb 100644
--- a/git.c
+++ b/git.c
@@ -994,7 +994,7 @@ int cmd_main(int argc, const char **argv)
 			exit(1);
 		}
 		if (!done_help) {
-			char *assumed = help_unknown_cmd(cmd);
+			char *assumed = help_unknown_cmd(cmd, &args);
 			strvec_replace(&args, 0, assumed);
 			free(assumed);
 			cmd = args.v[0];
diff --git a/help.c b/help.c
index 46241492ce..30f32a7206 100644
--- a/help.c
+++ b/help.c
@@ -641,7 +641,7 @@ static const char bad_interpreter_advice[] =
 	N_("'%s' appears to be a git command, but we were not\n"
 	"able to execute it. Maybe git-%s is broken?");
 
-char *help_unknown_cmd(const char *cmd)
+char *help_unknown_cmd(const char *cmd, const struct strvec *args)
 {
 	struct help_unknown_cmd_config cfg = { 0 };
 	int i, n, best_similarity = 0;
@@ -762,13 +762,37 @@ char *help_unknown_cmd(const char *cmd)
 	fprintf_ln(stderr, _("git: '%s' is not a git command. See 'git --help'."), cmd);
 
 	if (SIMILAR_ENOUGH(best_similarity)) {
-		fprintf_ln(stderr,
-			   Q_("\nThe most similar command is",
-			      "\nThe most similar commands are",
-			   n));
-
-		for (i = 0; i < n; i++)
-			fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
+		if (n == 1 && isatty(0) && isatty(2)) {
+			char *answer;
+			struct strbuf msg = STRBUF_INIT;
+			struct strbuf full_cmd = STRBUF_INIT;
+			strbuf_addstr(&full_cmd, main_cmds.names[0]->name);
+			if (args) {
+				for (size_t j = 1; j < args->nr; j++) {
+					strbuf_addch(&full_cmd, ' ');
+					strbuf_addstr(&full_cmd, args->v[j]);
+				}
+			}
+			strbuf_addf(&msg, _("\nDid you mean 'git %s'? [y/N] "),
+				    full_cmd.buf);
+			strbuf_release(&full_cmd);
+			answer = git_prompt(msg.buf, PROMPT_ECHO);
+			strbuf_release(&msg);
+			if (starts_with(answer, "y") || starts_with(answer, "Y")) {
+				char *assumed = xstrdup(main_cmds.names[0]->name);
+				cmdnames_release(&cfg.aliases);
+				cmdnames_release(&main_cmds);
+				cmdnames_release(&other_cmds);
+				return assumed;
+			}
+		} else {
+			fprintf_ln(stderr,
+				   Q_("\nThe most similar command is",
+				      "\nThe most similar commands are",
+				   n));
+			for (i = 0; i < n; i++)
+				fprintf(stderr, "\t%s\n", main_cmds.names[i]->name);
+		}
 	}
 
 	exit(1);
diff --git a/help.h b/help.h
index c54bf0977d..a8c465b3df 100644
--- a/help.h
+++ b/help.h
@@ -32,7 +32,8 @@ void list_all_other_cmds(struct string_list *list);
 void list_cmds_by_category(struct string_list *list,
 			   const char *category);
 void list_cmds_by_config(struct string_list *list);
-char *help_unknown_cmd(const char *cmd);
+#include "strvec.h"
+char *help_unknown_cmd(const char *cmd, const struct strvec *args);
 void load_command_list(const char *prefix,
 		       struct cmdnames *main_cmds,
 		       struct cmdnames *other_cmds);
diff --git a/t/t9003-help-autocorrect.sh b/t/t9003-help-autocorrect.sh
index 8da318d2b5..6fe2da1595 100755
--- a/t/t9003-help-autocorrect.sh
+++ b/t/t9003-help-autocorrect.sh
@@ -70,4 +70,57 @@ test_expect_success 'autocorrect works in work tree created from bare repo' '
 	git -C worktree -c help.autocorrect=immediate status
 '
 
+# Default behaviour (no help.autocorrect set): when there is exactly one
+# similar command but the session is non-interactive, fall back to printing
+# the suggestion list and exiting rather than showing a prompt.
+test_expect_success 'default: single match non-interactive shows suggestion and fails' '
+	test_might_fail git config --unset help.autocorrect &&
+
+	test_must_fail git lfg 2>actual &&
+	grep "most similar command" actual &&
+	grep "lgf" actual
+'
+
+test_expect_success 'default: multiple matches non-interactive shows list and fails' '
+	test_might_fail git config --unset help.autocorrect &&
+
+	test_must_fail git com 2>actual &&
+	grep "most similar commands" actual &&
+	grep "commit" actual
+'
+
+# Interactive prompt tests require a real TTY.  On macOS the TTY prereq is
+# skipped due to IO::Pty reliability issues; these tests run on Linux CI.
+test_expect_success TTY 'default: single match interactive, answer y runs command' '
+	git config --unset help.autocorrect &&
+
+	write_script git-typotest <<-\EOF &&
+		echo typotest-ran
+	EOF
+	PATH="$PATH:." export PATH &&
+
+	# Feed "y" to /dev/tty via a wrapper that answers the prompt
+	write_script answer-prompt <<-\EOF &&
+		# Write the answer to the controlling terminal
+		printf "y\n" >/dev/tty
+		exec "$@"
+	EOF
+
+	test_terminal ./answer-prompt git typotest 2>err >out &&
+	grep "typotest-ran" out &&
+	grep "Did you mean" err
+'
+
+test_expect_success TTY 'default: single match interactive, answer n exits cleanly' '
+	git config --unset help.autocorrect &&
+
+	write_script answer-prompt-no <<-\EOF &&
+		printf "n\n" >/dev/tty
+		exec "$@"
+	EOF
+
+	test_must_fail test_terminal ./answer-prompt-no git typotest 2>err &&
+	grep "Did you mean" err
+'
+
 test_done
-- 
2.50.1



^ permalink raw reply related

* Re: [PATCH v2] SubmittingPatches: address design critiques
From: Kristoffer Haugsbakk @ 2026-06-18 14:43 UTC (permalink / raw)
  To: Junio C Hamano, git
In-Reply-To: <xmqqpl1oteoi.fsf@gitster.g>

On Thu, Jun 18, 2026, at 10:50, Junio C Hamano wrote:
> Contributors sometimes fail to answer fundamental design or
> viability comments from reviewers and submit subsequent rounds
> without addressing them.  When design decisions are resolved on the
> mailing list, the final justification should be recorded in the
> commit messages.

It’s useful to explain design decisions etc. that were not committed to
in the commit message. It’s yet another thing that might be far from
obvious during review, but when the message is written only the option
that was landed on is explained.

>[snip]
> diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
> index f042bb5aaf..bbe759f3d9 100644
> --- a/Documentation/SubmittingPatches
> +++ b/Documentation/SubmittingPatches
> @@ -51,6 +51,21 @@ area.
>    respond to them with "Reply-All" on the mailing list, while taking
>    them into account while preparing an updated set of patches.
>  +
> +You should be particularly mindful of critiques regarding the
> +high-level design or viability of your proposal (e.g., questioning
> +whether the feature is worth implementing, or if the chosen approach
> +is appropriate).  Defend your design decisions on the list first, to
> +avoid wasting effort on an implementation whose design is not yet
> +solid.

To take it to the other extreme, there are “contributions” which are
design decisions *only*, no implementation. Namely emails which sketch a
design like a new option. Those are often met with a stock response
saying:[1] submit some code, doesn’t have to implement it fully, but we
will need some code to proceed here. I’ve never understood that stance,
and I don’t think it harmonizes with the sentence here of sparing effort
if the design is not solid.

Many of these emails are straightforward.

1. I want this thing
2. I can implement it but I don’t know if *would be* accepted (and
   implementing things here would be a lot of effort for me, personally)
3. Would it be?

And the only thing I personally would change is to weaken “would be?” to
“could be?”. Then with that out in the world, maybe someone finds this
message this day or the next week or month and reports that at least
they would like this thing.

Some people could change something small in this code base as easily as
they could propose the change idea for it (so it seems to me). They
would just have to take a walk and watch a movie to let their
subconscious process whether it was a good idea or not... But for most
people, committing to implementing something in a new codebase without
spooky assistance (...) is a task that takes a lot of effort.

To illustrate a related point, there are at least three kinds of Git
users out there:

1. Experienced C developers
2. Experienced Git developers (heavy overlap with (1))
3. Experienced and partisan Git users (knows it, believes in it)

You can imagine someone from group number 1 who is *not* in group number
3 use a weekend to implement something. But then when it is submitted it
turns out that is a very “centralized CVS” idea which doesn’t fit into
git(1) at all. That’s easily spotted by group number 3 by just looking
at the proposed docs or design. Now that group number 1 individual might
just have a bunch of code that is dead weight for any proper Git
workflow.

So I don’t understand this canned response.

There is the unofficial project idea tracker on the GitGitGadget
fork. But it seems weird to post things there and not on the mailing
list.

† 1: From `git show todo:CannedResponses`:

     | [make us come to you, begging]
     |
     | I've seen from time to time people ask "I am thinking of doing this;
     | will a patch be accepted?  If so, I'll work on it." before showing
     | any work, and my response always has been:
     |
     |  (1) We don't know how useful and interesting your contribution would
     |      be for our audience, until we see it; and
     |
     |  (2) If you truly believe in your work (find it useful, find writing
     |      it fun, etc.), that would be incentive enough for you to work
     |      on it, whether or not the result will land in my tree.  You
     |      should instead aim for something so brilliant that we would
     |      come to you begging for your permission to include it in our
     |      project.

    Note that point (2) is a bit more ambitious than it looks; if the
    idea is to implement your own thing for your own fork/tree and then
    maintain it yourself if upstream git.git doesn not accept it, well,
    now you need to learn how to maintain a fork for however long you
    want that feature. If you did not already know that.

> ++
> +Make sure that any new version is accompanied by a much clearer
> +explanation and justification (in the cover letter, your responses,
> +and in the revised commit messages).  Aim to make the reviewers say
> +"it is now clear why we may want to do this with the updated version".
> ++
> +Topics that fail to address fundamental design critiques without
> +resolution will not be considered ready for merging.

Nicely explained.
> ++
>  It is often beneficial to allow some time for reviewers to provide
>  feedback before sending a new version, rather than sending an updated
>  series immediately after receiving a review. This helps collect broader
> @@ -323,6 +338,10 @@ The body should provide a meaningful commit message, which:
>
>  . alternate solutions considered but discarded, if any.
>
> +. records the resolution of design or viability concerns raised by the
> +  community during the review, if any, ensuring the historical record
> +  explains why the chosen approach was accepted over alternatives.
> +

Okay.

>  [[present-tense]]
>[snip]

^ permalink raw reply

* Re: t5563-simple-http-auth failures with v2.55.0-rc0
From: Todd Zullinger @ 2026-06-18 14:49 UTC (permalink / raw)
  To: Matthew John Cheetham; +Cc: git@vger.kernel.org
In-Reply-To: <20260612180203.s2qSgDUs@teonanacatl.net>

Hi,

I wrote:
> Matthew John Cheetham wrote:
>> Thanks for the report. The failure is not in Git, it is a libcurl
>> behaviour change, and there is already an open upstream issue:
>> 
>>   https://github.com/curl/curl/issues/21943
>>   "Negotiate ignored with --anyauth" (Dan Fandrich, 2026-06-10)
>> 
>> Dan also bisected it to the same commit I had locally,
>> `8f71d0fde515` ("creds: hold credentials", curl PR #21548).
> [...]
>> Daniel Stenberg has acknowledged the curl issue but has not yet
>> posted a fix. I will follow curl#21943 and, if the upstream answer
>> is "the new behaviour is intended", come back here with a proposal
>> for what Git should do about `http.emptyAuth` and test 18.
> 
> Excellent.  This is it good hands all around.
[...]
> 
> If there is a curl update, I imagine it will be picked up
> reasonably quickly in Fedora (and elsewhere that was testing
> 8.21.0 release candidates) and there will hopefully be no
> strong need to make any changes on the git side.

I saw Fedora picked up curl-8.21.0-rc3 this morning and
confirmed it resolves the git test failures.  Someone else
has already commented on the upstream curl issue to note
that.

Thanks,

-- 
Todd

^ permalink raw reply

* Re: [PATCH v2 7/8] refs: fix recursing `get_main_ref_store()` with "onbranch" config
From: Patrick Steinhardt @ 2026-06-18 14:51 UTC (permalink / raw)
  To: Justin Tobler; +Cc: git, Karthik Nayak, Jeff King
In-Reply-To: <ajP7W7KsXz4Wk262@denethor>

On Thu, Jun 18, 2026 at 09:15:00AM -0500, Justin Tobler wrote:
> On 26/06/18 07:59AM, Patrick Steinhardt wrote:
> > On Wed, Jun 17, 2026 at 01:41:40PM -0500, Justin Tobler wrote:
> > > Is this really the best signal to indicate that a repository ref store
> > > has not been initialized? Temporarily setting the storage format to
> > > REF_STORAGE_FORMAT_UNKNOWN feels rather awkward and suggests to me that
> > > `include_by_branch()` probably shouldn't be using it to begin with if
> > > its not reliable.
> > 
> > True, but we don't really have a better signal to the best of my
> > knowledge. Ideally, we'd be able to use the existence `r->refs_private`
> > as signal. But that doesn't really work as the reference database is
> > lazily constructed, and the recursion happens in the exact function that
> > would construct it in the first place. And there indeed are cases where
> > reading the configuration is the first caller of `get_main_ref_store()`.
> 
> Ok, my first thought was also whether we could use the existence of the
> ref store as a signal, but I guess that won't work here.
> 
> > My first internal iteration tried to make this non-lazily constructed so
> > that we can use it as a proper signal. But that led to a bunch of
> > problems where we now parsed configuration way earlier than we currently
> > do, and that in turn led to all kinds of errors. I was able to fix all
> > of those errors except one: we expect `git config set` to work in a
> > misconfigured repository so that the user can fix the misconfig without
> > having to manually edit the Git configuration files. But when
> > constructing the refdb eagerly we will die early in such cases.
> > 
> > We could again work around that issue, but that unfortunately evolved
> > into a proper mess that I eventually discarded as unworkable. I think
> > this is an inherent design flaw: constructing the refdb requires us to
> > be able to parse the configuration, but constructing the configuration
> > may require us to construct the refdb. So this awkwardness is built into
> > Git's design, unfortunately.
> > 
> > So I'd really love to have a better signal, as I fully agree that the
> > above workaround is nothing more but a hack. But I'm just not sure what
> > that signal would be. And this version here does exactly what we want:
> > we honor "onbranch" conditionals in all cases, except when constructing
> > the main reference store. Even if it's ugly.
> 
> Could we embed an `initialized` boolean in `struct ref_store` that gets
> set when the ref store is properly initialized and use that as a signal
> instead? I'm not sure how complex introducing this would be though.

We could, but I'm not sure what that would really buy us. It would
basically be one more bit of state that we have to track going forward,
and thus one more source of inconsistencies.

Patrick

^ permalink raw reply

* Re: t5563-simple-http-auth failures with v2.55.0-rc0
From: Matthew John Cheetham @ 2026-06-18 15:02 UTC (permalink / raw)
  To: Todd Zullinger; +Cc: git@vger.kernel.org
In-Reply-To: <20260618144953.l6Ng-dvv@teonanacatl.net>

On 2026-06-18 15:49, Todd Zullinger wrote:

> I saw Fedora picked up curl-8.21.0-rc3 this morning and
> confirmed it resolves the git test failures.  Someone else
> has already commented on the upstream curl issue to note
> that.
Thanks for confirming rc3 fixes things!

The CURLOPT_USERPWD = ":" behaviour was never codified in curl's 
documentation, but given the fix they've put in place it's probably a 
good sign we can continue to rely on this.

I may propose a patch to curl documentation's patch to say that this
behaviour is expected and supported, if the they don't do it themselves 
soon already.

Thanks,
Matthew


^ permalink raw reply

* Re: [PATCH] Fix typo in MaintNotes regarding versioning scheme
From: Junio C Hamano @ 2026-06-18 15:08 UTC (permalink / raw)
  To: Tuomas Ahola; +Cc: Silas Poulson, gitgitgadget, git
In-Reply-To: <20260618114837.0_RVf%taahol@utu.fi>

Tuomas Ahola <taahol@utu.fi> writes:

> Junio C Hamano <gitster@pobox.com> wrote:
>
>> Silas Poulson <silas@dyalog.com> writes:
>> 
>> > I'm aware this is a very minor change, but it would be good to not let 
>> > this fall through the cracks.
>> 
>> Thanks for noticing a typo.
>> 
>> Will update before the next issue is sent to the mailing list.  No
>> point in changing it before that.
>
> On that occasion, please consider also these fixes:

Thanks.  Will squash in.  The next issue of Maintotes will come
right after 2.55 final gets tagged, so we have a bit more time.



^ permalink raw reply

* Re: [PATCH v2 0/7] More work supporting objects larger than 4GB on Windows
From: Junio C Hamano @ 2026-06-18 15:08 UTC (permalink / raw)
  To: Patrick Steinhardt
  Cc: Johannes Schindelin via GitGitGadget, git, Kristofer Karlsson,
	Johannes Schindelin
In-Reply-To: <ajPhBn7n1wR-sii4@pks.im>

Patrick Steinhardt <ps@pks.im> writes:

> On Mon, Jun 15, 2026 at 11:52:22AM +0000, Johannes Schindelin via GitGitGadget wrote:
>> This patch series tries to address the problems pointed out by the expensive
>> tests that now run in CI: t5608 and t7508 verify various aspects about
>> objects larger than 4GB, which Git does not currently handle correctly when
>> run on a platform where size_t is 64-bit and unsigned long is 32-bit.
>> 
>> Changes vs v1:
>> 
>>  * Rebased onto master, which merged ps/odb-source-loose (with which these
>>    patches previously conflicted rather badly).
>>  * Removed superfluous size_t s variables (thanks, Patrick!).
>
> I skimmed those parts that I was previously commenting on and am
> happy with those changes. Thanks!

Thanks.  I looked at them and found nothing iffy, either.

^ permalink raw reply

* Re: [PATCH] SubmittingPatches: address design critiques
From: Michael Montalbo @ 2026-06-18 15:17 UTC (permalink / raw)
  To: Michael Montalbo; +Cc: git, Junio C Hamano

On Wed, Jun 17, 2026 at 8:53 PM Michael Montalbo <mmontalbo@gmail.com> wrote:
>
> Junio C Hamano wrote:
> > +You would want to be particularly mindful of critiques regarding the
> > +high-level design or viability of your proposal (e.g., questioning
> > +whether the feature is worth implementing, or if the chosen approach
> > +is appropriate).  You want to defend your design decisions on the list
> > +first, because you do not want to spend too much effort in the
> > +implementation if the design is not yet solid.
>
> Two small suggestions: open with a direct imperative and replace
> "effort in the implementation" with "effort on the implementation".
>
>     [B]e particularly mindful of...
>     ... too much effort [on] the implementation...

(resending to fix threading)

Maybe we can even more directly say:

Do not spend too much effort on the implementation if the design is not
yet solid. Be able to defend your design decisions on the list first.

^ permalink raw reply

* Re: [PATCH v2] SubmittingPatches: address design critiques
From: Michael Montalbo @ 2026-06-18 15:36 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

Junio C Hamano <gitster@pobox.com> wrote:
> +You should be particularly mindful of critiques regarding the
> +high-level design or viability of your proposal (e.g., questioning
> +whether the feature is worth implementing, or if the chosen approach
> +is appropriate).  Defend your design decisions on the list first, to
> +avoid wasting effort on an implementation whose design is not yet
> +solid.
> ++
> +Make sure that any new version is accompanied by a much clearer
> +explanation and justification (in the cover letter, your responses,
> +and in the revised commit messages).  Aim to make the reviewers say
> +"it is now clear why we may want to do this with the updated version".
> ++
> +Topics that fail to address fundamental design critiques without
> +resolution will not be considered ready for merging.

This wording looks good to me.

^ permalink raw reply

* Re: [PATCH] SubmittingPatches: address design critiques
From: Junio C Hamano @ 2026-06-18 15:40 UTC (permalink / raw)
  To: Michael Montalbo; +Cc: git
In-Reply-To: <CAC2QwmJdF+YzAQE3WDEaUrurLVkYcAA0Cgs1YAqyxYcQ0jKfqA@mail.gmail.com>

Michael Montalbo <mmontalbo@gmail.com> writes:

> Two small suggestions: open with a direct imperative and replace
> "effort in the implementation" with "effort on the implementation".
>
>     [B]e particularly mindful of...
>     ... too much effort [on] the implementation...

Yeah, I started from something like that then toned it down, but I
agree that it is more appropriate to be more assertive here.

> Maybe it would help to spell out what the explanation/justification is
> for more explicitly (though it may be a bit redundant with the
> "meaningful message" blurb):

Yeah, and it depends on what kind of higher level issues the
reviewer comment is about, so ...

>     Make sure that any new version explains and justifies those
>     design decisions more clearly: why the change is worth making,
>     what alternatives were considered, and why the chosen approach
>     is correct.  Put that justification in the cover letter, your
>     responses, and the revised commit messages.  Aim to make the
>     reviewers say "it is now clear why we may want to do this with
>     the updated version".

... I find the beginning part of the above very much better than
what I had in my version, but part of the first sentence after the
colon is probably a bit too much.

I'll send out v3 sometime before the next week.

Thanks.


^ permalink raw reply

* Re: [PATCH v2 0/7] Introduce fetch.followRemoteHEAD config variable
From: Junio C Hamano @ 2026-06-18 15:47 UTC (permalink / raw)
  To: Matt Hunter; +Cc: git, Bence Ferdinandy, Jeff King
In-Reply-To: <DJBVYP58YNTU.LQ7VXFIQE84H@lfurio.us>

"Matt Hunter" <m@lfurio.us> writes:

>> Other than that, this looks excellent.  Thanks.
>
> Thanks for the great feedback and consideration!
>
> If you like, I can apply the appropriate NEEDSWORK comment, possibly add
> a warning to 'fetch.followRemoteHEAD' parsing (matching the 'remote'
> side), and we can call this good to go for now.

Sounds like a plan.  Thanks.

^ permalink raw reply

* Re: [PATCH v2 7/8] refs: fix recursing `get_main_ref_store()` with "onbranch" config
From: Justin Tobler @ 2026-06-18 15:53 UTC (permalink / raw)
  To: Patrick Steinhardt; +Cc: git, Karthik Nayak, Jeff King
In-Reply-To: <ajQF1yyCUOdzC4Jq@pks.im>

On 26/06/18 04:51PM, Patrick Steinhardt wrote:
> On Thu, Jun 18, 2026 at 09:15:00AM -0500, Justin Tobler wrote:
> > Could we embed an `initialized` boolean in `struct ref_store` that gets
> > set when the ref store is properly initialized and use that as a signal
> > instead? I'm not sure how complex introducing this would be though.
> 
> We could, but I'm not sure what that would really buy us. It would
> basically be one more bit of state that we have to track going forward,
> and thus one more source of inconsistencies.

My naive thought here is that if the ref store knows when it is
initialized, this could be used as a more reliable signal by
`include_by_branch()`. I guess the problem though would be that, at that
point in time, we are still inside `ref_store_init()` and thus the ref
store is not fully initialized anyways. 

I was hoping we could avoid the hack of temporarily setting the ref
format here, but introducing state specific to tracking whether its ok
to parse onbranch conditions in the config is probably not worth it I
guess.

-Justin

^ permalink raw reply

* Re: [PATCH v4] ref-filter: restore prefix-scoped iteration
From: Junio C Hamano @ 2026-06-18 15:54 UTC (permalink / raw)
  To: Tamir Duberstein
  Cc: git, Karthik Nayak, Patrick Steinhardt, Victoria Dye, ZheNing Hu
In-Reply-To: <20260612-fix-git-branch-regression-v4-1-f150038c02f4@gmail.com>

Tamir Duberstein <tamird@gmail.com> writes:

> Changes in v4:
> - Explain the historical references in the commit message.
> - Run the new performance cases with both ref backends.
> - Drop the Assisted-by trailer.
> - Link to v3: https://patch.msgid.link/20260610-fix-git-branch-regression-v3-1-6fd48fad7a53@gmail.com

This seems to fully address comments by Patrick in
https://lore.kernel.org/git/aivx-7VOKE_TC50R@pks.im/

Let me mark the topic for 'next'.  Thanks all who discussed this patch.

^ permalink raw reply

* Re: [PATCH v5 2/2] graph: indent visual root in graph
From: Jeff King @ 2026-06-18 16:05 UTC (permalink / raw)
  To: Pablo Sabater
  Cc: Kristofer Karlsson, git, ayu.chandekar, chandrapratap3519,
	christian.couder, gitster, jltobler, karthik.188, phillip.wood,
	siddharthasthana31
In-Reply-To: <CAN5EUNSQY2oK7BE4J9Y8APfkP6eJxta050OUu=RoJYhXOjX_OA@mail.gmail.com>

On Thu, Jun 18, 2026 at 02:42:16PM +0200, Pablo Sabater wrote:

> > > +     for (cl = graph->revs->commits; cl; cl = cl->next) {
> > > +             if (get_commit_action(graph->revs, cl->item) != commit_show)
> > > +                     continue;
> [...]
> > I'm not sure what the solution is. This function wants to peek ahead in
> > queue order, possibly through multiple entries. But a heap-based queue
> > inherently only supports peeking at the first entry.
> 
> Yeah, I haven't read dd4bc01c0a yet but from what you say it prob
> won't work anymore, I didn't know about that series, about the
> lookahead I think it could still work with some tweaks, the important
> part is to set the three lookahead flags.

Thanks for looking into it. I meant to also cc the Kristofer, the author
of dd4bc01c0a, for any thoughts (adding him now).

> From what I understood, we can only get the direct next commit, but no
> more reliably ordered.

Right. There are other queue implementations that could allow full
in-order traversal (e.g., a binary tree), but our prio_queue does not. I
suspect performance for other cases would suffer if we switched the
underlying data structure.

> The flags should be fine:
> 
> - 'is_next_visible' could need to traverse multiple entries, but it
> doesn't need them to be in order. We just need to know if something
> will be rendered after.

Yeah, this one seems easy. We are just setting a bit based on whether
we'd find any commit to show. So order doesn't matter.

> - 'next_has_column' only needs the first entry.

But this was the one I was worried about. Walking the linked list in
order will find us the next commit we're going to show, and the result
of the flag depends on graph_find_new_column_by_commit(). Is it OK to
find _any_ such commit?

(I'm looking at this purely based on reading the existing code, and
haven't really thought hard about the problem space).

> - 'is_next_visual_root' only needs the first entry to know if it could
> be a visual root, and also if it is not the last one (but we don't
> need them to be ordered for this last part).

This one just iterates looking for any other commit we'll show after the
next one. So finding any two entries would be equivalent to the current
code (though we only get to this loop if the first one passes the test
for graph_is_visual_root_candidate).

So if you say order doesn't matter for checking the column and the
visual-root-candidate function, I'm happy to believe you. It makes life
much easier. :)

> Should I work with 'next' as a base to have dd4bc01c0a? (Sorry I've
> just worked with master).

As Junio noted, that's already in master, so I think you're OK to just
base there.

But for future reference, no, you probably don't want to build off of
'next'. If your commit has a dependency on another topic it is best to
build directly off of that topic (and note it in the cover letter of the
series). That way you do not accidentally depend on other things in
'next' which might not ever make it to 'master' (and would thus hold
your topic hostage).

-Peff

^ permalink raw reply

* Re: [PATCH v5 2/2] graph: indent visual root in graph
From: Jeff King @ 2026-06-18 16:07 UTC (permalink / raw)
  To: Pablo Sabater
  Cc: Kristofer Karlsson, git, ayu.chandekar, chandrapratap3519,
	christian.couder, gitster, jltobler, karthik.188, phillip.wood,
	siddharthasthana31
In-Reply-To: <20260618160504.GA818042@coredump.intra.peff.net>

On Thu, Jun 18, 2026 at 12:05:05PM -0400, Jeff King wrote:

> > From what I understood, we can only get the direct next commit, but no
> > more reliably ordered.
> 
> Right. There are other queue implementations that could allow full
> in-order traversal (e.g., a binary tree), but our prio_queue does not. I
> suspect performance for other cases would suffer if we switched the
> underlying data structure.

BTW, there's one extra trick here in the iteration: you might see
commits in _both_ revs->commits and revs->commit_queue. So you'll have
to iterate over both of them (and I guess push the loop body into a
function to avoid duplication).

We may eventually settle on having just one queue sturcture, but I think
dd4bc01c0a used that to avoid disrupting existing callers.

-Peff

^ permalink raw reply

* Re: [PATCH v14 4/6] branch: add --prune-merged <branch>
From: Junio C Hamano @ 2026-06-18 16:08 UTC (permalink / raw)
  To: Phillip Wood
  Cc: Harald Nordgren, Harald Nordgren via GitGitGadget, git,
	Kristoffer Haugsbakk, Johannes Sixt
In-Reply-To: <37f2a483-c8bf-4c24-84de-c6233cc20b25@gmail.com>

Phillip Wood <phillip.wood123@gmail.com> writes:

> One thing I've just thought of related to this patch is whether we want 
> to protect branches that are the upstreams of branches that are not 
> slated for deletion. With stacked branches it is possible that a branch 
> has been merged but has other branches stacked on top of it that have 
> not been merged.

An interesting point.  We do have "this topic is built on the result
of merging these other topics into main" and I expect the practice
is wide spread.  These base topics may graduate first, but other
topics may still be updated.

But when you rewrite these other topics, wouldn't you leave their
bases untouched?  IOW, a new iteration (i.e. "rebase -i") would
reuse the base that was used in an earlier iteration, i.e. the
result of an earlier merge of the other topics, some of which might
have been pruned since then, into an older 'main', so it is OK to
lose these other topics once they have graduated, simply because you
wouldn't be recreating the merge that you used as the base of this
remaining topic, no?

Or am I missing something?

Thanks.

^ permalink raw reply

* Re: t5563-simple-http-auth failures with v2.55.0-rc0
From: Junio C Hamano @ 2026-06-18 16:18 UTC (permalink / raw)
  To: Todd Zullinger; +Cc: Matthew John Cheetham, git@vger.kernel.org
In-Reply-To: <20260618144953.l6Ng-dvv@teonanacatl.net>

Todd Zullinger <tmz@pobox.com> writes:

> I saw Fedora picked up curl-8.21.0-rc3 this morning and
> confirmed it resolves the git test failures.  Someone else
> has already commented on the upstream curl issue to note
> that.

Thanks.

^ permalink raw reply

* Re: [PATCH v2] SubmittingPatches: address design critiques
From: Junio C Hamano @ 2026-06-18 16:26 UTC (permalink / raw)
  To: Kristoffer Haugsbakk; +Cc: git
In-Reply-To: <95cd81dc-baea-4318-9f01-6a795f8eb5bb@app.fastmail.com>

"Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com> writes:

> You can imagine someone from group number 1 who is *not* in group number
> 3 use a weekend to implement something. But then when it is submitted it
> turns out that is a very “centralized CVS” idea which doesn’t fit into
> git(1) at all. That’s easily spotted by group number 3 by just looking
> at the proposed docs or design. Now that group number 1 individual might
> just have a bunch of code that is dead weight for any proper Git
> workflow.

That depends on how obviously wrong the idea is.  If your proposal
is to write another CVS into Git, that may be too obvious it may not
fly, but the thing is, "proposals" that get the canned response you
quoted are often vague enough that crucial details that divide
"iffy" and "obviously wrong" are missing.

One way to make these proposals sufficiently clear to allow
reviewers to tell the difference is with a code that builds.  There
may be other ways, but that is one obvious way to start a meaningful
discussion.

^ permalink raw reply

* Re: [PATCH v2 7/8] refs: fix recursing `get_main_ref_store()` with "onbranch" config
From: Jeff King @ 2026-06-18 16:40 UTC (permalink / raw)
  To: Patrick Steinhardt; +Cc: git, Karthik Nayak
In-Reply-To: <20260615-b4-pks-refs-avoid-chdir-notify-reparent-v2-7-f4854aa99859@pks.im>

On Mon, Jun 15, 2026 at 03:56:53PM +0200, Patrick Steinhardt wrote:

> When we have an "onbranch" condition we need to ask the reference
> database whether HEAD currently points at the configured branch. This
> unfortunately creates a chicken-and-egg problem:
> 
>   - The reference database needs to read the configuration so that it
>     can configure itself.
> 
>   - The configuration needs to construct a reference database to fully
>     parse all of its conditionals.
> 
> The way we handle this is by simply excluding "onbranch" conditionals
> when we haven't yet configured the reference database.

My gut feeling upon reading this is that some part of the config reading
is being done wrong to create this chicken-and-egg situation.

I'd expect the ref database config (like the ref format) to be read not
through the regular config subsystem, but via read_repository_format()
and friends. And while that does build on the regular config code, it
should never enable includes at all. So includeIf.onbranch:foo.path is
just another uninteresting config key to it.

In other words, there should be two passes over the config file: one to
load basic repository information (and not respect includes), and one to
actually load what we think of as user-visible config[1].

And it seems to work. If I do this:

diff --git a/config.c b/config.c
index 45144f73c5..343af2cf9a 100644
--- a/config.c
+++ b/config.c
@@ -303,7 +303,7 @@ static int include_by_branch(struct config_include_data *data,
 	const char *refname, *shortname;
 
 	if (!data->repo || data->repo->ref_storage_format == REF_STORAGE_FORMAT_UNKNOWN)
-		return 0;
+		BUG("chicken and egg");
 
 	refname = refs_resolve_ref_unsafe(get_main_ref_store(data->repo),
 					  "HEAD", 0, NULL, &flags);

and then:

  git config includeIf.onbranch:main.path alt-config
  git config -f .git/alt-config foo.bar baz
  git config foo.bar

then we correctly read the value without triggering this code path.

Looking back at the last commit that touched include_by_branch(), the
problem does not appear to be about a chicken-and-egg at all, though. It
is about reading config with includes when there is _no_ repository at
all. I.e., this:

  git config -f main-config includeIf.onbranch:main.path alt-config
  git config -f  alt-config foo.bar baz
  GIT_DIR=/does/not/exist git.compile config --include -f main-config foo.bar

will trigger that BUG() marker, and quietly returning "no match" (like
the current code does) is the right thing.

Looking below...

> The consequence is that we have recursion:
> 
>   1. We call `get_main_ref_store()`.
> 
>   2. We don't yet have a reference store, so we call `ref_store_init()`.
> 
>   3. We parse the configuration required for the reference store.
> 
>   4. We eventually end up in `include_by_branch()`.
> 
>   5. We have already configured the reference storage format, so we end
>      up calling `get_main_ref_store()` again.

Ah, the culprit seems to be ref_store_init() calling into the regular
config parser via repo_settings_get_log_all_ref_updates(). But that
feels weird to me. Either:

  1. It is application config that should not be something we need to
     load in order to initialize the backend. We could lazy-load it
     later, or rely on higher level code to set the option.

  2. It is crucial to the ref backend functioning, in which case we
     ought to be reading it alongside core.repositoryFormatVersion, etc.

-Peff

^ permalink raw reply related

* Re: [PATCH] zlib: properly clamp to uLong
From: Junio C Hamano @ 2026-06-18 17:03 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget; +Cc: git, Johannes Schindelin
In-Reply-To: <pull.2153.git.1781790619424.gitgitgadget@gmail.com>

The original in js/objects-larger-than-4gb-on-windows says things
like:

+	s->z.total_in = (uLong)(s->total_in & ULONG_MAX_VALUE);
+	s->z.total_out = (uLong)(s->total_out & ULONG_MAX_VALUE);

Your patch ...

> +static inline uLong zlib_uLong_cap(size_t s)
> +{
> +	return s < ULONG_MAX_VALUE ? (uLong)s : ULONG_MAX_VALUE;
> +}
> +
>  static void zlib_pre_call(git_zstream *s)
>  {
>  	s->z.next_in = s->next_in;
>  	s->z.next_out = s->next_out;
> -	s->z.total_in = (uLong)(s->total_in & ULONG_MAX_VALUE);
> -	s->z.total_out = (uLong)(s->total_out & ULONG_MAX_VALUE);
> +	s->z.total_in = zlib_uLong_cap(s->total_in);
> +	s->z.total_out = zlib_uLong_cap(s->total_out);

... is an obvious fix for that.

> @@ -60,7 +65,7 @@ static void zlib_post_call(git_zstream *s, int status)
>  	 * We track our own totals and verify only the low bits match.
>  	 */
>  	if ((s->z.total_out & ULONG_MAX_VALUE) !=
> -	    ((s->total_out + bytes_produced) & ULONG_MAX_VALUE))
> +	    ((zlib_uLong_cap(s->total_out) + bytes_produced) & ULONG_MAX_VALUE))
>  		BUG("total_out mismatch");

Because we now clamp (not "taking lower bits of") s->total_out to a
value between 0..4GB and store it in s->z.total_out in pre-call, let
zlib do its thing that increments s->z.total_out modulo 4GB, and we
clamp the s->total_out (before incrementing) the same way in
post_call here, both sides of "!=" above even out.  But the comment
before this comparison that claims that "we ... verify only the low
bits match" is a bit off the reality, I suspect.

> @@ -68,7 +73,7 @@ static void zlib_post_call(git_zstream *s, int status)
>  	 */
>  	if (status != Z_NEED_DICT &&
>  	    (s->z.total_in & ULONG_MAX_VALUE) !=
> -	    ((s->total_in + bytes_consumed) & ULONG_MAX_VALUE))
> +	    ((zlib_uLong_cap(s->total_in) + bytes_consumed) & ULONG_MAX_VALUE))
>  		BUG("total_in mismatch");
>  
>  	s->total_out += bytes_produced;
>
> base-commit: 7a094d68a27e321a99c8ab6b700909e503904bd9

^ permalink raw reply

* [PATCH] doc: detail LMAP binary format specification
From: irsalshydiq @ 2026-04-16  5:55 UTC (permalink / raw)
  To: git; +Cc: irsalshydiq

The experimental Rust implementation in 'loose.rs' introduces a new
binary format called 'LMAP' for mapping between different object ID
formats (e.g., SHA-1 and SHA-256).

However, the technical documentation for this format was missing from
the 'Documentation/technical/' directory, making it difficult for
C developers to understand the format's layout and logic.

Add 'Documentation/technical/loose-object-map.adoc' to provide a bit-by-bit
specification of the 'LMAP' format and register it in the build systems.

Signed-off-by: irsalshydiq <ichalprov@gmail.com>
---
 Documentation/Makefile                        |  1 +
 Documentation/technical/loose-object-map.adoc | 72 +++++++++++++++++++
 Documentation/technical/meson.build           |  1 +
 3 files changed, 74 insertions(+)
 create mode 100644 Documentation/technical/loose-object-map.adoc

diff --git a/Documentation/Makefile b/Documentation/Makefile
index 2699f0b24a..8ad908d62c 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -126,6 +126,7 @@ TECH_DOCS += technical/directory-rename-detection
 TECH_DOCS += technical/hash-function-transition
 TECH_DOCS += technical/large-object-promisors
 TECH_DOCS += technical/long-running-process-protocol
+TECH_DOCS += technical/loose-object-map
 TECH_DOCS += technical/multi-pack-index
 TECH_DOCS += technical/packfile-uri
 TECH_DOCS += technical/pack-heuristics
diff --git a/Documentation/technical/loose-object-map.adoc b/Documentation/technical/loose-object-map.adoc
new file mode 100644
index 0000000000..6e8dbd6c6f
--- /dev/null
+++ b/Documentation/technical/loose-object-map.adoc
@@ -0,0 +1,72 @@
+Loose Object Map (LMAP) format
+============================
+
+The loose object map file (LMAP) provides a way to map between different object
+ID formats (e.g., SHA-1 and SHA-256) for loose objects. It is designed for
+efficient lookup and storage of these mappings.
+
+All multi-byte integers are in network byte order (big-endian).
+
+== File Layout
+
+- A header (20 bytes)
+- An Object Format Table (16 bytes per format)
+- A Trailer Offset (8 bytes)
+- Data Sections (variable length, 4-byte aligned)
+- A Trailer (variable length, defined by hash algorithm)
+
+=== Header
+
+- 4-byte signature: `LMAP`
+- 4-byte version number: The current version is 1.
+- 4-byte header size: The total size of the header, including the Object Format Table and Trailer Offset.
+- 4-byte number of items: The number of object IDs mapped in this file.
+- 4-byte number of object formats: The number of different hash algorithms supported in this file (minimum 2).
+
+=== Object Format Table
+
+For each object format (as specified in the header), there is a 16-byte entry:
+
+- 4-byte Format ID: The identifier for the hash algorithm (e.g., `0x73686131` for SHA-1, `0x73323536` for SHA-256).
+- 4-byte Shortened Length: The minimum number of bytes needed to unambiguously identify an object ID in this format within this file.
+- 8-byte Data Offset: The absolute offset from the beginning of the file to the start of the data section for this format.
+
+=== Trailer Offset
+
+- 8-byte Trailer Offset: The absolute offset from the beginning of the file to the start of the Trailer.
+
+=== Data Sections
+
+Each object format has a corresponding data section starting at the offset provided in the Object Format Table. Each data section is aligned to a 4-byte boundary.
+
+==== Format 1 (Storage Format) Data Section
+
+The first format listed is considered the "storage" or "main" format. Its data section contains:
+
+1. **Shortened Index**: `(number of items) * (shortened length)` bytes.
+   This table contains the first `shortened length` bytes of each object ID, sorted lexicographically. This allows for binary search lookup.
+
+2. **Full OID Table**: `(number of items) * (hash length)` bytes.
+   The full object IDs for the storage format, in the same order as the Shortened Index.
+
+3. **Metadata Table**: `(number of items) * 4` bytes.
+   A table of 32-bit integers representing the type of each object:
+   - 0: Reserved (e.g., null OID, empty tree/blob)
+   - 1: Loose Object
+   - 2: Shallow Commit
+   - 3: Submodule Commit
+
+==== Subsequent Format (Compatibility) Data Section
+
+For each subsequent format, the data section contains:
+
+1. **Shortened Index**: Similar to the storage format, but for the compatibility algorithm's OIDs.
+
+2. **Full OID Table**: The full object IDs in the compatibility algorithm.
+
+3. **Mapping Table**: `(number of items) * 4` bytes.
+   A table of 32-bit integers. Each entry at index `i` provides the index in the **storage format's** tables that corresponds to this compatibility object ID.
+
+=== Trailer
+
+- Variable length: The hash of all preceding bytes in the file, calculated using the main hash algorithm.
diff --git a/Documentation/technical/meson.build b/Documentation/technical/meson.build
index ec07088c57..dc1249f9aa 100644
--- a/Documentation/technical/meson.build
+++ b/Documentation/technical/meson.build
@@ -16,6 +16,7 @@ articles = [
   'large-object-promisors.adoc',
   'long-running-process-protocol.adoc',
   'multi-pack-index.adoc',
+  'loose-object-map.adoc',
   'packfile-uri.adoc',
   'pack-heuristics.adoc',
   'parallel-checkout.adoc',
-- 
2.50.1 (Apple Git-155)


^ permalink raw reply related

* Re: [PATCH] completion: zsh: support completion after "git -C <path>"
From: D. Ben Knoble @ 2026-06-18 17:43 UTC (permalink / raw)
  To: Lutz Lengemann via GitGitGadget; +Cc: git, Lutz Lengemann, Junio C Hamano
In-Reply-To: <pull.2155.git.1781710256081.gitgitgadget@gmail.com>

[apologies in advance for the strange format below]

On Wed, Jun 17, 2026 at 11:37 AM Lutz Lengemann via GitGitGadget
<gitgitgadget@gmail.com> wrote:
>
> From: Lutz Lengemann <lutz@lengemann.net>
>
> The zsh completion wrapper (__git_zsh_main) did not handle the global -C
> option, so "git -C <path> <command> <TAB>" offered nothing and could not
> complete a command's arguments.
>
> Three things are needed to make it work, all scoped to -C:
>
>   - Add -C to the _arguments specification, so completion no longer stops
>     at it.
>
>   - Advance __git_cmd_idx past any leading "-C <path>" options. The index
>     is hard-coded to 1, i.e. the command is assumed to be the first
>     argument; with -C present the command sits two words later for each
>     -C, so the bash helpers otherwise look at the wrong word and produce
>     nothing.
>
>   - Collect the -C paths into __git_C_args, as __git_main does. The bash
>     helpers run git to resolve aliases and list refs; without the -C
>     paths they run in the current directory, so completion fails whenever
>     the cwd is not the target repository or the command is an alias.
>
> With these, "git -C <path> <command> <TAB>" completes the command, its
> options and its arguments, including outside the repository, through
> aliases, and with repeated -C options.
>
> Signed-off-by: Lutz Lengemann <lutz@lengemann.net>
> ---
>     completion: zsh: support completion after "git -C "
>
>     This patch is intentionally scoped to -C, but the underlying problem is
>     more general. The zsh wrapper hard-codes __git_cmd_idx=1, i.e. it
>     assumes the command is always the first argument. That assumption breaks
>     argument completion after any global option that precedes the command,
>     not just -C — e.g. --git-dir, --work-tree, --namespace, -c, and
>     -p/--paginate. After those, git <opt> <command> <TAB> currently
>     completes the command name but not its arguments.
>
>     The same approach generalizes cleanly: instead of skipping only leading
>     -C options, walk all leading global options and their arguments to
>     locate the command and its true index (mirroring the option scan in
>     __git_main in git-completion.bash), while collecting -C into
>     __git_C_args and --git-dir into __git_dir as today.
>
>     I kept this revision narrow for reviewability and because git -C is the
>     case where I miss the completion, but I'm happy to extend it to cover
>     the other global options in a follow-up (or fold it into this patch) if
>     that's preferred.

See Junio's review for whether we should expand in this patch or a follow-up.

In reply to Junio:

> [the new handling only knows about -C]
> Doesn't it want to do something similar to what __git_main in
> git-completion.bash does at the beginning, namely, this part?

Yeah, we probably do want to skip over -c, etc. (I see some support for
--bare and --git-dir, but not skipping over it.) Still, this patch makes
things no worse in that regard, and improves the situation for -C
AFAICT.

In reply to Lutz:

> +        local -a __git_C_args
> +        local -i i=2
> +
> +        while [[ ${orig_words[i]} == -C ]]; do
> +            __git_C_args+=(-C ${orig_words[i+1]})
> +            (( __git_cmd_idx += 2 ))
> +            (( i += 2 ))
> +        done

I don't see either of these 2 local variables used anywhere else…

…well, except the Bash completion helpers, I suppose. But we mark these
local, so how do they propagate to the other functions?

Still, I was able to try this out with the somewhat hacky

    zsh # new shell :)
    # absolute path important
    autoload -Uz $PWD/contrib/completion/git-completion.zsh
    compdef git-completion.zsh git

    git -C <tab>

and it does prioritize directories there (though I still get a listing
of files afterwards, so the screen is taken up by that gigantic listing
in git.git, for example).

By the way, I've realized that "git -<tab>" has the same problem (a
giant list of files after the other option completions), and worse has
some _funky_ output!

    git -<tab> # without patch
    (option)
    --bare
    --exec-path
    --git-dir
    --help
    --html-path
    --info-path
    --man-path
    --namespace
    --no-pager
    --no-replace-objects
    --paginate
    --version
    --work-tree

    -p

    # treat the repository as a bare repository
    # path to where your core git programs are installed
    # set the path to the repository
    # prints the synopsis and a list of the most commonly used commands
    # print the path where gits HTML documentation is installed
    # print the path where the Info files are installed
    # print the manpath (see `man(1)`) for the man pages
    # set the git namespace
    # do not pipe git output into a pager
    # do not use replacement refs to replace git objects
    # pipe all output into less
    # prints the git suite version
    # set the path to the working tree
    [ed: the above block repeats twice more before the (file) listing below]
    (file)
    […]

Here's the output of _complete_help (^Xh by default) in both situations,
in case that helps to understand either the extra files listing (1) in
the example further back or the issue with single letter options (2)
just mentioned:

1: tags in context :completion::complete:git::
    option-C-1     (_arguments __git_zsh_main _git git-completion.zsh)
    use-compctl    (_default _git git-completion.zsh)
    globbed-files  (_files _default _git git-completion.zsh)
tags in context :completion::complete:git:option-C-1:
    directories    (_directories _arguments __git_zsh_main _git
git-completion.zsh)
    globbed-files  (_files _directories _arguments __git_zsh_main _git
git-completion.zsh)
    all-files      (_files _directories _arguments __git_zsh_main _git
git-completion.zsh)

2: tags in context :completion::complete:git::
    argument-1 options  (_arguments __git_zsh_main _git)
    use-compctl         (_default _git)
    globbed-files       (_files _default _git)
tags in context :completion::complete:git:argument-1:
    common-commands alias-commands all-commands  (__git_zsh_main _git)
    common-commands                              (__git_zsh_cmd_common
__git_zsh_main _git)
    alias-commands                               (__git_zsh_cmd_alias
__git_zsh_main _git)
    all-commands                                 (__git_zsh_cmd_all
__git_zsh_main _git)
tags in context :completion::complete:git:options:
    options  (_arguments __git_zsh_main _git)

> +        '*-C[run as if git was started in <path>]: :_directories' \

We should probably note in the log message that the _directories
completion will not account for previous -C; that is, after typing

    git -C dir -C <tab>

we will complete directories in ".", not "dir". That's probably a
reasonable limitation for now, but I think we could do _slightly_ better
by using a state "->dir" or something, accumulating the current prefix,
and passing that to _directories as a prefix with -W (see _path_files in
zshcompsys, which _directories delegates to via _files, IIUC).

-- 
D. Ben Knoble

^ permalink raw reply

* Re: [PATCH] checkout: add --fetch to fetch remote before resolving start-point
From: D. Ben Knoble @ 2026-06-18 17:47 UTC (permalink / raw)
  To: Harald Nordgren; +Cc: Harald Nordgren via GitGitGadget, git
In-Reply-To: <CAHwyqnU4xuw9ZDjarWKKua_s1Qywt07GyP1kJO2HM+XQTcE8hA@mail.gmail.com>

Hi Harald,

On Thu, Jun 18, 2026 at 8:36 AM Harald Nordgren
<haraldnordgren@gmail.com> wrote:
>
> Hi Ben!
>
> Trying to shore up some support for this topic. How do you feel about this now?
>
>
> Harald

I haven't followed the series too closely; it sounds like the code is
in decent shape.

I stand by my thought that this could be convenient, but that's not
much one way or another in terms of how it fits in overall with Git's
vision.

There are some conveniences I recommend universally. This one requires
caveats, as pointed out by others, depending on the project, so… from
that point of view I wonder if keeping "fetch + switch" as 2 distinct
steps is better? I truly don't know.

-- 
D. Ben Knoble

^ permalink raw reply

* Re: [PATCH] help: prompt user to run corrected command on typo
From: Justin Tobler @ 2026-06-18 17:48 UTC (permalink / raw)
  To: calicomills; +Cc: git, gitster
In-Reply-To: <6a340006.60da1a74.20db39.8f57@mx.google.com>

On 26/06/18 07:26AM, calicomills wrote:
> From 0dc9e5c4593611b75e7003e8fdbea9370524c05b Mon Sep 17 00:00:00 2001
> From: calicomills <jishnuck26@gmail.com>
> Date: Thu, 18 Jun 2026 19:47:12 +0530
> Subject: [PATCH] help: prompt user to run corrected command on typo
> 
> When a user mistypes a git command and there is exactly one similar
> command, git currently prints a suggestion but exits, requiring the
> user to retype the corrected command manually.
> 
> Instead, when stdin and stderr are both connected to a terminal and
> there is a single best match, prompt the user with:
> 
>   Did you mean 'git checkout neo'? [y/N]
> 
> The full corrected invocation (command + original arguments) is shown
> in the prompt so the user knows exactly what will run. Answering 'y'
> re-executes git with the corrected command and all original arguments.
> Answering anything else exits as before.

Isn't this already possible via setting `help.autoCorrect=prompt` in the
config? For example:

  git -c help.autoCorrect=prompt comit --allow-empty -m init

seems to already do exactly what is proposed here.

-Justin

^ permalink raw reply

* Re: [PATCH v15 0/7] branch: delete-merged
From: Harald Nordgren @ 2026-06-18 17:53 UTC (permalink / raw)
  To: phillip.wood
  Cc: Harald Nordgren via GitGitGadget, git, Kristoffer Haugsbakk,
	Johannes Sixt
In-Reply-To: <feac3d8b-e291-48e8-ac73-3b1f5321799b@gmail.com>

> > I received the same feedback from Junio before, so I'm not unaware of
> > this problem. I am trying to slow down. I often prepare the work as
> > soon as I get some comments -- I'm on paternity leave so I have a lot
> > of time when the baby is sleeping --
>
> Congratulations - I hope the baby is sleeping at night as well in the day!

Thanks! It's our third, so hopefully we got the hang of it now.

He sleeps -- some of the time.

> > then I actively hold off on
> > sending to not overload the rest of you. But at the same time I think
> > it's valuable to keep up a certain pace. It's a balancing act.
> It is worth waiting for the discussion to settle on each round, I'll try
> and be clear when I've finished looking at each revision. I'm sure other
> folks would appreciate you looking at their patches and commenting on
> them while you're waiting for feedback on yours, especially the GSoC
> project students.

That's a good point!


Harald

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox