Subject: [GSoC PATCH v10 0/5] repo: declare the repo command

From: Lucas Seiki Oshiro <[email-masked]>
Date: Fri, 15 Aug 2025 10:55:16 -0300

Hi!

The only major change in this v10 is that git-repo-info now returns the
values following the same order as they were requested instead of
sorting the keys. In past versions, the sorting existed for dropping
duplicated keys, but after the discussion with Eric, Phillip and Junio,
we agreed that returning the values following the keys order was more
important than removing the duplications, which weren't exactly a bad
thing. Consequently, the duplication checks were also removed.

Other minor issues pointed by Eric were also addressed.

Thanks!

Here's the range-diff versus v9:

1:  3c2ede66be = 1:  6767028da3 repo: declare the repo command
2:  b18e74763d ! 2:  c44e2d1619 repo: add the field references.format
    @@ Documentation/git-repo.adoc: COMMANDS
      	the requested data will be returned based on their keys (see "INFO KEYS"
      	section below).
     ++
    -+The returned data is lexicographically sorted by the keys.
    ++The values are returned in the same order in which their respective keys were
    ++requested.
     ++
     +The output format consists of key-value pairs one per line using the `=`
     +character as the delimiter between the key and the value. Values containing
     +"unusual" characters are quoted as explained for the configuration variable
    -+`core.quotePath` (see linkgit:git-config[1]). This is the default.
    ++`core.quotePath` (see linkgit:git-config[1]).
     +
     +INFO KEYS
     +---------
    @@ builtin/repo.c
      	return 0;
      }
      
    -+/* repo_info_fields keys should be in lexicographical order */
    ++/* repo_info_fields keys must be in lexicographical order */
     +static const struct field repo_info_fields[] = {
     +	{ "references.format", get_references_format },
     +};
    @@ builtin/repo.c
     +	return found ? found->get_value : NULL;
     +}
     +
    -+static int qsort_strcmp(const void *va, const void *vb)
    -+{
    -+	const char *a = *(const char **)va;
    -+	const char *b = *(const char **)vb;
    -+
    -+	return strcmp(a, b);
    -+}
    -+
     +static int print_fields(int argc, const char **argv, struct repository *repo)
     +{
     +	int ret = 0;
    -+	const char *last = "";
     +	struct strbuf valbuf = STRBUF_INIT;
     +	struct strbuf quotbuf = STRBUF_INIT;
     +
    -+	QSORT(argv, argc, qsort_strcmp);
    -+
     +	for (int i = 0; i < argc; i++) {
     +		get_value_fn *get_value;
     +		const char *key = argv[i];
     +
    -+		strbuf_reset(&valbuf);
    -+		strbuf_reset(&quotbuf);
    -+
    -+		if (!strcmp(key, last))
    -+			continue;
    -+
    -+		last = key;
     +		get_value = get_value_fn_for_key(key);
     +
     +		if (!get_value) {
    @@ builtin/repo.c
     +			continue;
     +		}
     +
    ++		strbuf_reset(&valbuf);
    ++		strbuf_reset(&quotbuf);
    ++
     +		get_value(repo, &valbuf);
     +		quote_c_style(valbuf.buf, &quotbuf, NULL, 0);
     +		printf("%s=%s\n", key, quotbuf.buf);
    @@ t/t1900-repo.sh (new)
     +
     +# Test whether a key-value pair is correctly returned
     +#
    -+# Usage: test_repo_info <label> <init command> <key> <expected value>
    ++# Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value>
     +#
     +# Arguments:
     +#   label: the label of the test
    @@ t/t1900-repo.sh (new)
     +	'
     +}
     +
    -+test_repo_info 'ref format files is retrieved correctly' '
    -+	git init --ref-format=files' 'format-files' 'references.format' 'files'
    ++test_repo_info 'ref format files is retrieved correctly' \
    ++	'git init --ref-format=files' 'format-files' 'references.format' 'files'
     +
    -+test_repo_info 'ref format reftable is retrieved correctly' '
    -+	git init --ref-format=reftable' 'format-reftable' 'references.format' 'reftable'
    ++test_repo_info 'ref format reftable is retrieved correctly' \
    ++	'git init --ref-format=reftable' 'format-reftable' 'references.format' 'reftable'
     +
     +test_expect_success 'git-repo-info fails if an invalid key is requested' '
     +	echo "error: key ${SQ}foo${SQ} not found" >expected_err &&
    @@ t/t1900-repo.sh (new)
     +	test_cmp expected actual
     +'
     +
    -+test_expect_success 'only one value is returned if the same key is requested twice' '
    -+	val=$(git rev-parse --show-ref-format) &&
    -+	echo "references.format=$val" >expect &&
    -+	git repo info references.format references.format >actual &&
    -+	test_cmp expect actual
    -+'
    -+
     +test_done
3:  35916b210e ! 3:  e3009a85e1 repo: add the field layout.bare
    @@ builtin/repo.c: struct field {
      	strbuf_addstr(buf,
     @@ builtin/repo.c: static int get_references_format(struct repository *repo, struct strbuf *buf)
      
    - /* repo_info_fields keys should be in lexicographical order */
    + /* repo_info_fields keys must be in lexicographical order */
      static const struct field repo_info_fields[] = {
     +	{ "layout.bare", get_layout_bare },
      	{ "references.format", get_references_format },
    @@ builtin/repo.c: static int get_references_format(struct repository *repo, struct

      ## t/t1900-repo.sh ##
    -@@ t/t1900-repo.sh: test_repo_info 'ref format files is retrieved correctly' '
    - test_repo_info 'ref format reftable is retrieved correctly' '
    - 	git init --ref-format=reftable' 'format-reftable' 'references.format' 'reftable'
    +@@ t/t1900-repo.sh: test_repo_info 'ref format files is retrieved correctly' \
    + test_repo_info 'ref format reftable is retrieved correctly' \
    + 	'git init --ref-format=reftable' 'format-reftable' 'references.format' 'reftable'
      
     +test_repo_info 'bare repository = false is retrieved correctly' \
     +	'git init' 'nonbare' 'layout.bare' 'false'
    @@ t/t1900-repo.sh: test_repo_info 'ref format files is retrieved correctly' '
     +test_repo_info 'bare repository = true is retrieved correctly' \
     +	'git init --bare' 'bare' 'layout.bare' 'true'
     +
    - test_expect_success 'git-repo-info fails if an invalid key is requested' '
    - 	echo "error: key ${SQ}foo${SQ} not found" >expected_err &&
    - 	test_must_fail git repo info foo 2>actual_err &&
    -@@ t/t1900-repo.sh: test_expect_success 'only one value is returned if the same key is requested twi
    - 	test_cmp expect actual
    - '
    - 
    -+test_expect_success 'output is returned correctly when two keys are requested' '
    -+	cat >expected <<-\EOF &&
    ++test_expect_success 'values returned in order requested' '
    ++	cat >expect <<-\EOF &&
     +	layout.bare=false
     +	references.format=files
    ++	layout.bare=false
     +	EOF
    -+	git init --ref-format=files two-keys &&
    -+	git -C two-keys repo info layout.bare references.format >actual &&
    -+	test_cmp expected actual
    ++	git init --ref-format=files ordered &&
    ++	git -C ordered repo info layout.bare references.format layout.bare >actual &&
    ++	test_cmp expect actual
     +'
     +
    - test_done
    + test_expect_success 'git-repo-info fails if an invalid key is requested' '
    + 	echo "error: key ${SQ}foo${SQ} not found" >expected_err &&
    + 	test_must_fail git repo info foo 2>actual_err &&
4:  91fc5c4e50 ! 4:  3837899c32 repo: add the field layout.shallow
    @@ builtin/repo.c: static int get_layout_bare(struct repository *repo UNUSED, struc
      {
      	strbuf_addstr(buf,
     @@ builtin/repo.c: static int get_references_format(struct repository *repo, struct strbuf *buf)
    - /* repo_info_fields keys should be in lexicographical order */
    + /* repo_info_fields keys must be in lexicographical order */
      static const struct field repo_info_fields[] = {
      	{ "layout.bare", get_layout_bare },
     +	{ "layout.shallow", get_layout_shallow },
    @@ t/t1900-repo.sh: test_repo_info 'bare repository = false is retrieved correctly'
     +test_repo_info 'shallow repository = false is retrieved correctly' \
     +	'git init' 'nonshallow' 'layout.shallow' 'false'
     +
    -+test_repo_info 'shallow repository = true is retrieved correctly' \
    -+	'git init remote &&
    ++test_expect_success 'setup remote' '
    ++	git init remote &&
     +	echo x >remote/x &&
     +	git -C remote add x &&
    -+	git -C remote commit -m x &&
    -+	git clone --depth 1 "file://$PWD/remote"' 'shallow' 'layout.shallow' 'true'
    ++	git -C remote commit -m x
    ++'
    ++
    ++test_repo_info 'shallow repository = true is retrieved correctly' \
    ++	'git clone --depth 1 "file://$PWD/remote"' 'shallow' 'layout.shallow' 'true'
     +
    - test_expect_success 'git-repo-info fails if an invalid key is requested' '
    - 	echo "error: key ${SQ}foo${SQ} not found" >expected_err &&
    - 	test_must_fail git repo info foo 2>actual_err &&
    + test_expect_success 'values returned in order requested' '
    + 	cat >expect <<-\EOF &&
    + 	layout.bare=false
5:  8af32d7066 ! 5:  19fdfce646 repo: add the --format flag
    @@ Documentation/git-repo.adoc: THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHAN
      	Retrieve metadata-related information about the current repository. Only
      	the requested data will be returned based on their keys (see "INFO KEYS"
      	section below).
    - +
    - The returned data is lexicographically sorted by the keys.
    +@@ Documentation/git-repo.adoc: COMMANDS
    + The values are returned in the same order in which their respective keys were
    + requested.
      +
     -The output format consists of key-value pairs one per line using the `=`
     -character as the delimiter between the key and the value. Values containing
     -"unusual" characters are quoted as explained for the configuration variable
    +-`core.quotePath` (see linkgit:git-config[1]).
     +The output format can be chosen through the flag `--format`. Two formats are
     +supported:
     ++
     +* `keyvalue`: output key-value pairs one per line using the `=` character as
     +the delimiter between the key and the value. Values containing "unusual"
     +characters are quoted as explained for the configuration variable
    - `core.quotePath` (see linkgit:git-config[1]). This is the default.
    - 
    ++`core.quotePath` (see linkgit:git-config[1]). This is the default.
    ++
     +* `nul`: similar to `keyvalue`, but using a newline character as the delimiter
     +between the key and the value and using a null character after each value.
     +This format is better suited for being parsed by another applications than
     +`keyvalue`. Unlike in the `keyvalue` format, the values are never quoted.
    -+
    + 
      INFO KEYS
      ---------
     -
    @@ builtin/repo.c
      struct field {
      	const char *key;
      	get_value_fn *get_value;
    -@@ builtin/repo.c: static int qsort_strcmp(const void *va, const void *vb)
    - 	return strcmp(a, b);
    +@@ builtin/repo.c: static get_value_fn *get_value_fn_for_key(const char *key)
    + 	return found ? found->get_value : NULL;
      }
      
     -static int print_fields(int argc, const char **argv, struct repository *repo)
    @@ builtin/repo.c: static int qsort_strcmp(const void *va, const void *vb)
     +			enum output_format format)
      {
      	int ret = 0;
    - 	const char *last = "";
    + 	struct strbuf valbuf = STRBUF_INIT;
     @@ builtin/repo.c: static int print_fields(int argc, const char **argv, struct repository *repo)
    - 		}
    + 		strbuf_reset(&quotbuf);
      
      		get_value(repo, &valbuf);
     -		quote_c_style(valbuf.buf, &quotbuf, NULL, 0);
    @@ t/t1900-repo.sh: test_repo_info () {
     +	'
      }
      
    - test_repo_info 'ref format files is retrieved correctly' '
    -@@ t/t1900-repo.sh: test_repo_info 'bare repository = true is retrieved correctly' \
    - test_repo_info 'shallow repository = false is retrieved correctly' \
    - 	'git init' 'nonshallow' 'layout.shallow' 'false'
    - 
    --test_repo_info 'shallow repository = true is retrieved correctly' \
    --	'git init remote &&
    -+test_expect_success 'setup remote' '
    -+	git init remote &&
    - 	echo x >remote/x &&
    - 	git -C remote add x &&
    --	git -C remote commit -m x &&
    --	git clone --depth 1 "file://$PWD/remote"' 'shallow' 'layout.shallow' 'true'
    -+	git -C remote commit -m x
    -+'
    -+
    -+test_repo_info 'shallow repository = true is retrieved correctly' \
    -+	'git clone --depth 1 "file://$PWD/remote"' 'shallow' 'layout.shallow' 'true'
    - 
    - test_expect_success 'git-repo-info fails if an invalid key is requested' '
    - 	echo "error: key ${SQ}foo${SQ} not found" >expected_err &&
    -@@ t/t1900-repo.sh: test_expect_success 'output is returned correctly when two keys are requested' '
    + test_repo_info 'ref format files is retrieved correctly' \
    +@@ t/t1900-repo.sh: test_expect_success 'git-repo-info outputs data even if there is an invalid fiel
      	test_cmp expected actual
      '
      
     +test_expect_success 'git-repo-info aborts when requesting an invalid format' '
    -+	echo "fatal: invalid format '\'foo\''" >expected &&
    ++	echo "fatal: invalid format ${SQ}foo${SQ}" >expected &&
     +	test_must_fail git repo info --format=foo 2>err &&
     +	test_cmp expected err
     +'

Lucas Seiki Oshiro (5):
  repo: declare the repo command
  repo: add the field references.format
  repo: add the field layout.bare
  repo: add the field layout.shallow
  repo: add the --format flag

 .gitignore                  |   1 +
 Documentation/git-repo.adoc |  82 ++++++++++++++++++++
 Documentation/meson.build   |   1 +
 Makefile                    |   1 +
 builtin.h                   |   1 +
 builtin/repo.c              | 150 ++++++++++++++++++++++++++++++++++++
 command-list.txt            |   1 +
 git.c                       |   1 +
 meson.build                 |   1 +
 t/meson.build               |   1 +
 t/t1900-repo.sh             |  96 +++++++++++++++++++++++
 11 files changed, 336 insertions(+)
 create mode 100644 Documentation/git-repo.adoc
 create mode 100644 builtin/repo.c
 create mode 100755 t/t1900-repo.sh

-- 
2.39.5 (Apple Git-154)