From: Jean-Noël Avila Date: Fri, 06 Feb 2026 04:58:21 GMT Subject: Re: [PATCH 05/11] config-batch: add NUL-terminated I/O format 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 : > From: Derrick Stolee > > 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 : 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 > --- > 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… > + 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 `. > - The next `` lines are of the form `help ` > + line provides the count of possible commands via `help 1 count `. > + The next `` lines are of the form `help 1 ` > to state that this Git version supports that `` at > 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. > + > ------------ > help 1 count 2 > @@ -102,6 +111,48 @@ get 1 missing [|] > where `` or `` 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 `:` where `` 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. > +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]