public inbox for git@vger.kernel.org
 help / color / mirror / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: Derrick Stolee via GitGitGadget <gitgitgadget@gmail.com>,
	git@vger.kernel.org
Cc: gitster@pobox.com, Derrick Stolee <stolee@gmail.com>
Subject: Re: [PATCH 00/11] [RFC] config-batch: a new builtin for tools querying config
Date: Thu, 5 Feb 2026 14:45:40 +0000	[thread overview]
Message-ID: <55e2e1f0-da51-4413-a20b-542140004fb6@gmail.com> (raw)
In-Reply-To: <pull.2033.git.1770214803.gitgitgadget@gmail.com>

Hi Stolee

On 04/02/2026 14:19, Derrick Stolee via GitGitGadget wrote:
> This RFC explores a new git config-batch builtin that allows tools to
> interact with Git's config data with multiple queries using a single
> process. This is an orthogonal alternative to the effort to create a stable,
> linkable config API. Both approaches have different strengths.
> 
> My main motivation is the performance of git-credential-manager on Windows
> platforms as it can call git config get dozens of times. At 150-200ms per
> execution, that adds up significantly, leading to multiple seconds just to
> load a credential that already exists. I believe that there are other
> benefits to having this interface available, but I can't recall any
> specifics at the moment.

It would be helpful to explain what the advantage of this new command is 
over using "git config --list -z" or "git config --get-regex 
'^(some|section|names)\.' -z". I've found those to be effective in 
programs that read several config keys. Elsewhere brian has mentioned 
that git-lfs does something similar and I believe git-filter-repo uses 
"git config --list -z" as well.

One potential advantage would be if this command supported specifying 
the type of the value. When using "git config --list" it is a pain to 
have to normalize boolean values and parse color descriptions into 
terminal escape codes.

Being able to set multiple keys at once would also be an advantage if 
there is a convincing use case for it.

> This RFC adds git config-batch with a protocol over stdin/stdout for
> executing multiple config queries. The implementation has a limited set of
> potential queries, but also creates a model for compatibility for tools to
> automatically adapt to different Git versions.
> 
> I'm submitting this as an RFC before I've polished all of the details
> because I want to make sure I'm going down a good direction. Please focus
> feedback in these questions:
> 
>   * Is this a worthwhile feature to add to Git?

Possibly, if there are clear benefits over "git config --list". I'm not 
sure it needs to be a separate command though - I agree with Junio that 
it would be more discoverable if this was a subcommand of "git config"

>   * Is this a reasonable protocol for stdin/stdout?

The protocol sounds quite complicated with capability queries and 
versioning. At the same time it looks like the line oriented version 
does not support keys that contain spaces, values that contain newlines 
or retrieving settings from a file whose path contains a newline. I 
think it might be better to have a single protocol variant based using 
NUL delimiters like "git merge-tree --stdin" and "git diff-pairs". Those 
commands use a simple NUL terminated protocol without the need to 
specify the length of the input.

> Each command has an associated version, in case we need to expand or alter
> the functionality in the future. This includes the potential to deprecate
> and remove certain versions that we no longer want to support, such as
> replacing set version 1 with a version 2 and making version 1 no longer
> available. I do hope that we will mostly be able to move with new command
> names, such as a set-all command including the options for git config set
> --all ... instead of increasing the version of the set command.

It's good that you're thinking about future functionality but I wonder 
if we really need to specify the version on a per command basis rather 
than as a command line option or simply adding commands like "get-v2".

> There is a -z option that changes the command interface to use
> NUL-terminated strings. Two NULs specify a command boundary, which promotes
> compatibility with a caller that sends an unknown command.

That also allows optional fields such as the file to read the config 
from or the value to match to be NUL delimited while making the end of a 
record unambiguous.

> However, this
> means that we cannot specify an empty string as a token within a command
> unless we add more data. 

Is there a need to do that? Can we require key=value pairs or possibly a 
fixed number of positional parameters if there is a chance the value 
will be empty?

> This format uses <N>:<string> to provide the
> integer <N> which specifies the length of <string>. This is a little
> cumbersome, but the format is intended for tools, not humans.

It does seem cumbersome. I can see that it might be helpful to have the 
length of the complete query and response to avoid deadlocks when 
reading and writing but I'm not sure requiring the length of each field 
is helpful.

> I have a test integration with git-credential-manager available [1] for
> testing. This includes a model for interacting with git config-batch in a
> compatible way that will respond to certain features not being available:
> 
>   1. If git config-batch fails immediately, then all queries are handled by
>      git config.
>   2. If git config-batch starts without failure, then the first query is for
>      the help command.
>   3. As queries come to the config system, the query is checked against the
>      available commands advertised by git config-batch. If the appropriate
>      command is available, then the query is made in that process. If not,
>      then the query uses the existing git config command.

This seems like quite a lot of effort just to check a few config settings.

> I have a few concerns with this implementation that I'd like to improve
> before submitting a version for full review. I list them here so you can see
> the flaws that I already see, but also so you can add to this list:
> 
>   * The use of arg:<arg> to specify an optional argument creates the
>     inability to submit a value that starts with arg:. Consider alternative
>     ways to specify arguments or to specify that the remaining data in the
>     command (including spaces) is a final positional argument.

The protocol should be unambiguous. Requiring key=value pairs for all 
fields would be one way to achieve that

	set key=my.key scope=global value-regex=my-regex value=new-value

or we could force all optional fields to come first and count the number 
of fields to figure out whether any optional fields have been passed

	set value-regex=my-regex global my.key new-value

(I've used spaces above to delimit fields but we'd want to use NUL in 
the protocol)

Thanks

Phillip

>   * In general, I found myself implementing behavior based on the deprecated
>     forms of git config that use the --get or --unset style arguments instead
>     of git config (set|unset|get) subcommands. It's worth making sure that
>     any references to equivalent git config commands use the new modes.
>   * I need to add an --[no-]includes option as a command-line argument that
>     signals whether include sections should be followed. I don't believe this
>     should be specified on a per-command basis, but I'm open to suggestions.
>   * I have an early draft of a technical document detailing the plan for this
>     builtin. It has some lists of intended future commands that have not been
>     implemented. This would also be a good place to document any parsing APIs
>     built to help contributors adding to this builtin.
> 
> Thanks, -Stolee
> 
> Derrick Stolee (11):
>    config-batch: basic boilerplate of new builtin
>    config-batch: create parse loop and unknown command
>    config-batch: implement get v1
>    config-batch: create 'help' command
>    config-batch: add NUL-terminated I/O format
>    docs: add design doc for config-batch
>    config: extract location structs from builtin
>    config-batch: pass prefix through commands
>    config-batch: add 'set' v1 command
>    t1312: create read/write test
>    config-batch: add unset v1 command
> 
>   .gitignore                                |   1 +
>   Documentation/git-config-batch.adoc       | 214 ++++++
>   Documentation/meson.build                 |   1 +
>   Documentation/technical/config-batch.adoc |  70 ++
>   Makefile                                  |   1 +
>   builtin.h                                 |   7 +
>   builtin/config-batch.c                    | 772 ++++++++++++++++++++++
>   builtin/config.c                          | 117 +---
>   command-list.txt                          |   1 +
>   config.c                                  | 116 ++++
>   config.h                                  |  26 +
>   git.c                                     |   1 +
>   meson.build                               |   1 +
>   t/meson.build                             |   1 +
>   t/t1312-config-batch.sh                   | 372 +++++++++++
>   15 files changed, 1592 insertions(+), 109 deletions(-)
>   create mode 100644 Documentation/git-config-batch.adoc
>   create mode 100644 Documentation/technical/config-batch.adoc
>   create mode 100644 builtin/config-batch.c
>   create mode 100755 t/t1312-config-batch.sh
> 
> 
> base-commit: 83a69f19359e6d9bc980563caca38b2b5729808c
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2033%2Fderrickstolee%2Fbatched-config-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2033/derrickstolee/batched-config-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/2033


  parent reply	other threads:[~2026-02-05 14:45 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-04 14:19 [PATCH 00/11] [RFC] config-batch: a new builtin for tools querying config Derrick Stolee via GitGitGadget
2026-02-04 14:19 ` [PATCH 01/11] config-batch: basic boilerplate of new builtin Derrick Stolee via GitGitGadget
2026-02-04 23:23   ` Junio C Hamano
2026-02-05 14:17     ` Derrick Stolee
2026-02-05 17:26       ` Kristoffer Haugsbakk
2026-02-05 17:29   ` Kristoffer Haugsbakk
2026-02-06  4:11   ` Jean-Noël Avila
2026-02-04 14:19 ` [PATCH 02/11] config-batch: create parse loop and unknown command Derrick Stolee via GitGitGadget
2026-02-04 23:26   ` Junio C Hamano
2026-02-05 17:30   ` Kristoffer Haugsbakk
2026-02-06  4:15   ` Jean-Noël Avila
2026-02-04 14:19 ` [PATCH 03/11] config-batch: implement get v1 Derrick Stolee via GitGitGadget
2026-02-06  4:41   ` Jean-Noël Avila
2026-02-04 14:19 ` [PATCH 04/11] config-batch: create 'help' command Derrick Stolee via GitGitGadget
2026-02-06  4:49   ` Jean-Noël Avila
2026-02-10  4:20     ` Derrick Stolee
2026-02-04 14:19 ` [PATCH 05/11] config-batch: add NUL-terminated I/O format Derrick Stolee via GitGitGadget
2026-02-05 17:44   ` Kristoffer Haugsbakk
2026-02-06  4:58   ` Jean-Noël Avila
2026-02-04 14:19 ` [PATCH 06/11] docs: add design doc for config-batch Derrick Stolee via GitGitGadget
2026-02-05 17:38   ` Kristoffer Haugsbakk
2026-02-10  4:22     ` Derrick Stolee
2026-02-04 14:19 ` [PATCH 07/11] config: extract location structs from builtin Derrick Stolee via GitGitGadget
2026-02-04 14:20 ` [PATCH 08/11] config-batch: pass prefix through commands Derrick Stolee via GitGitGadget
2026-02-04 14:20 ` [PATCH 09/11] config-batch: add 'set' v1 command Derrick Stolee via GitGitGadget
2026-02-05 17:21   ` Kristoffer Haugsbakk
2026-02-05 18:58     ` Kristoffer Haugsbakk
2026-02-05 19:01   ` Kristoffer Haugsbakk
2026-02-10  4:25     ` Derrick Stolee
2026-02-06  5:04   ` Jean-Noël Avila
2026-02-04 14:20 ` [PATCH 10/11] t1312: create read/write test Derrick Stolee via GitGitGadget
2026-02-04 14:20 ` [PATCH 11/11] config-batch: add unset v1 command Derrick Stolee via GitGitGadget
2026-02-05 17:36   ` Kristoffer Haugsbakk
2026-02-04 23:04 ` [PATCH 00/11] [RFC] config-batch: a new builtin for tools querying config Junio C Hamano
2026-02-05 14:10   ` Derrick Stolee
2026-02-05  0:04 ` brian m. carlson
2026-02-05 13:52   ` Derrick Stolee
2026-02-10  4:49     ` Derrick Stolee
2026-02-05 14:45 ` Phillip Wood [this message]
2026-02-05 17:20 ` Kristoffer Haugsbakk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55e2e1f0-da51-4413-a20b-542140004fb6@gmail.com \
    --to=phillip.wood123@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitgitgadget@gmail.com \
    --cc=gitster@pobox.com \
    --cc=phillip.wood@dunelm.org.uk \
    --cc=stolee@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox