Re: [PATCH 05/11] config-batch: add NUL-terminated I/O format
- From
Jean-Noël Avila <jn.avila@free.fr>
- Date
- Feb 6, 2026, 04:58 UTC
- Message-ID
- <7204ff93-79d3-44f6-989d-184f00b86a2a@free.fr>
- In-Reply-To
- <33faa3f134c81761631c34600477dcbf82e619e5.1770214803.git.gitgitgadget@gmail.com>
Le 04/02/2026 à 15:19, Derrick Stolee via GitGitGadget a écrit :
Show 38 quoted lines
> From: Derrick Stolee <stolee@gmail.com> > > When using automated tools, it is critical to allow for input/output formats > that include special characters such as spaces and newlines. While the > existing protocol for 'git config-batch' is human-readable and has some > capacity for some spaces in certain positions, it is not available for > spaces in the config key or newlines in the config values. > > Add the '-z' option to signal the use of NUL-terminated strings. To > understand where commands end regardless of potential future formats, use > two NUL bytes in a row to terminate a command. To allow for empty string > values, each token is provided in a <length>:<value> format, making "0:" > the empty string value. > > Update the existing 'help' and 'get' commands to match this format. Create > helper methods that make it easy to parse and print in both formats > simultaneously. > > Signed-off-by: Derrick Stolee <stolee@gmail.com> > --- > Documentation/git-config-batch.adoc | 57 ++++++++- > builtin/config-batch.c | 188 +++++++++++++++++++++++++--- > t/t1312-config-batch.sh | 69 ++++++++++ > 3 files changed, 293 insertions(+), 21 deletions(-) > > diff --git a/Documentation/git-config-batch.adoc b/Documentation/git-config-batch.adoc > index 1fff68a13c..3c9a3bb763 100644 > --- a/Documentation/git-config-batch.adoc > +++ b/Documentation/git-config-batch.adoc > @@ -21,6 +21,15 @@ multiple configuration values, the `git config-batch` command allows a > single process to handle multiple requests using a machine-parseable > interface across `stdin` and `stdout`. > > +OPTIONS > +------- > + > +`-z`:: > + If specified, then use the NUL-terminated input and output
This boilerplate preliminary does not convey information, it is simpler to just jump to the action performed by the option:
Use the _NUL_-terminated input and output…
Show 21 quoted lines
> + format instead of the space and newline format. This format is > + useful when the strings involved may include spaces or newlines. > + See PROTOCOL for more details. > + > PROTOCOL > -------- > By default, the protocol uses line feeds (`LF`) to signal the end of a > @@ -41,13 +50,13 @@ These are the commands that are currently understood: > `help` version 1:: > The `help` command lists the currently-available commands in > this version of Git. The output is multi-line, but the first > - line provides the count of possible commands via `help count <N>`. > - The next `<N>` lines are of the form `help <command> <version>` > + line provides the count of possible commands via `help 1 count <N>`. > + The next `<N>` lines are of the form `help 1 <command> <version>` > to state that this Git version supports that `<command>` at > version `<version>`. Note that the same command may have multiple > available versions. > + > -Here is the currentl output of the help text at the latest version: > +Here is the current output of the help text at the latest version:
OK, the typo was fixed here.
Show 21 quoted lines
> + > ------------ > help 1 count 2 > @@ -102,6 +111,48 @@ get 1 missing <key> [<value-pattern>|<value>] > where `<value-pattern>` or `<value>` is only supplied if provided in > the command. > > +NUL-Terminated Format > +~~~~~~~~~~~~~~~~~~~~~ > + > +When `-z` is given, the protocol changes in some structural ways. > + > +First, each command is terminated with two NUL bytes, providing a clear > +boundary between commands regardless of future possibilities of new > +command formats. > + > +Second, any time that a space _would_ be used to partition tokens in a > +command, a NUL byte is used instead. Further, each token is prefixed > +with `<N>:` where `<N>` is a decimal representation of the length of > +the string between the `:` and the next NUL byte. Any disagreement in > +these lengths is treated as a parsing error. This use of a length does
I thought this length encoding was used to allow _NUL_ in the config values. But here it is considered a parse error.
Show 31 quoted lines
> +imply that "`0:`" is the representation of an empty string, if relevant. > + > +The decimal representation must have at most five numerals, thus the > +maximum length of a string token can have 99999 characters. > + > +For example, the `get` command, version 1, could have any of the > +following forms: > + > +------------ > +3:get NUL 1:1 NUL 5:local NUL 14:key.with space NUL NUL > +3:get NUL 1:1 NUL 9:inherit NUL 8:test.key NUL 9:arg:regex NUL 6:.*\ .* NUL NUL > +3:get NUL 1:1 NUL 6:global NUL 8:test.key NUL 15:arg:fixed-value NUL 3:a b NUL NUL > +------------ > + > +The output is modified similarly, such as the following output examples, > +as if the input has a parse error, a valid `help` command, a `get` > +command that had a match, and a `get` command that did not match. > + > +------------ > +15:unknown_command NUL NUL > +4:help NUL 1:1 NUL 5:count NUL 1:2 NUL NUL > +4:help NUL 1:1 NUL 4:help NUL 1:1 NUL NUL > +4:help NUL 1:1 NUL 3:get NUL 1:1 NUL NUL > +3:get NUL 1:1 NUL 5:found NUL 8:test.key NUL 5:value NUL NUL > +3:get NUL 1:1 NUL 7:missing NUL 8:test.key NUL NUL > +------------ > + > + > SEE ALSO > -------- > linkgit:git-config[1]