[GSoC][RFC PATCH v2 0/2] Add refs list subcommand
- From
Meet Soni <meetsoni3017@gmail.com>
- Date
- Jul 17, 2025, 07:50 UTC
- Message-ID
- <20250717075009.26262-1-meetsoni3017@gmail.com>
- In-Reply-To
- <20250627074934.1761897-1-meetsoni3017@gmail.com>
Hello everyone,
This is the second version of the patch series that introduces the `git refs list` subcommand as a modern alternative to `git for-each-ref`.
Thank you to everyone who provided valuable feedback on the first version. This new version incorporates the suggestions, improving both the code's implementation and the documentation's structure.
Changes in v2:
- Refactored the implementation of `refs list`. Instead of duplicating
the logic from `for-each-ref`, it is now a thin wrapper that
calls the original command. This avoids code duplication while
maintaining identical behavior. - Refactored the documentation by moving the common command options
shared by `refs list` and `for-each-ref` into a new standalone
file (`ref-list-options.adoc`). - Both man pages now use the AsciiDoc `include::` macro to embed these
shared options, ensuring documentation stays consistent.---
(v1 cover-letter text)
This patch series introduces `git refs list` as a modern replacement for `git for-each-ref`, as part of an effort to consolidate ref-related functionality under a unified `git refs` command.
Git's ref-related operations are currently handled by several distinct commands, such as `git show-ref`, `git for-each-ref`, `git update-ref`, `git pack-refs`, etc. This distribution has a few practical drawbacks:
- Users need to rely on multiple commands for related tasks involving refs.
- The commands may differ slightly in behavior and option syntax, leading to inconsistency.
We propose a long-term consolidation effort to bring ref-related subcommands under the umbrella of a single command: `git refs`.
The implementation of `git refs list` is functionally identical to `git for-each-ref`. It reuses the same internal logic (cmd_for_each_ref) to ensure complete backward compatibility. The purpose of this patch is not to introduce new behavior but to provide an alternate entry point under the consolidated `git refs` namespace.
The motivation behind this change is twofold:
- Consolidation: Centralizing ref-related operations makes them easier to discover, use, and maintain.
- Evolution: While the initial goal is parity with existing commands, this consolidation allows for careful reconsideration of which features are essential. Over time, we can:
- Remove legacy or obscure options that are no longer needed.
- Add improvements that wouldn't make sense to bolt onto legacy
commands.
- Offering a more consistent and user-friendly surface.To verify backward compatibility, this patch also includes a test `t/t1461-refs-list.sh`, which runs the full `t6300-for-each-ref.sh` test using `git refs list`. The test uses ${GIT_REFS_LIST_CMD:-for-each-ref} to allow substitution without duplicating tests.
This patch is deliberately conservative: it introduces no behavioral changes and leaves `for-each-ref` untouched. The goal is to lay groundwork and demonstrate viability of ref consolidation within `git refs`.
Going forward, I'd like to initiate a discussion on what the ideal surface of `git refs list` should look like. Which options and features from `for-each-ref` should be carried over? Are there any that are obsolete or overly niche? What improvements might be worth considering now that we have a new, consolidated interface?
Feedback on this, especially from those who rely on `for-each-ref` in scripts or tooling would be very helpful.
Meet Soni (2): builtin/refs: add list subcommand t: add test for git refs list subcommand
Documentation/git-for-each-ref.adoc | 80 +------ Documentation/git-refs.adoc | 16 ++ Documentation/refs-list-options.adoc | 80 +++++++ builtin/for-each-ref.c | 24 +- builtin/refs.c | 35 +++ t/meson.build | 1 + t/t1461-refs-list.sh | 8 + t/t6300-for-each-ref.sh | 333 ++++++++++++++------------- 8 files changed, 331 insertions(+), 246 deletions(-) create mode 100644 Documentation/refs-list-options.adoc create mode 100755 t/t1461-refs-list.sh
Range-diff against v1:
1: e7b19c71eb ! 1: b2d3026520 builtin/refs: add list subcommand
@@ Commit message
instead of duplicating its logic. Forward all arguments to the existing
function to ensure behavior is identical.
- This prevents code duplication and allows `refs list` to benefit from
- any future fixes to the underlying `for-each-ref` machinery.
+ Add documentation for the new command. To keep the documentation DRY and
+ consistent with `git-for-each-ref(1)`, refactor the shared command
+ options into a standalone file. Use the AsciiDoc `include::` macro to
+ embed these options in both man pages.
+
+ This prevents duplication in both code and documentation, ensuring that
+ `refs list` benefits from any future fixes to the underlying
+ `for-each-ref` machinery and its shared documentation.
Mentored-by: Patrick Steinhardt <ps@pks.im>
Mentored-by: shejialuo <shejialuo@gmail.com>
Mentored-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Meet Soni <meetsoni3017@gmail.com>
+ ## Documentation/git-for-each-ref.adoc ##
+@@ Documentation/git-for-each-ref.adoc: host language allowing their direct evaluation in that language.
+
+ OPTIONS
+ -------
+-<pattern>...::
+- If one or more patterns are given, only refs are shown that
+- match against at least one pattern, either using fnmatch(3) or
+- literally, in the latter case matching completely or from the
+- beginning up to a slash.
+-
+---stdin::
+- If `--stdin` is supplied, then the list of patterns is read from
+- standard input instead of from the argument list.
+-
+---count=<count>::
+- By default the command shows all refs that match
+- `<pattern>`. This option makes it stop after showing
+- that many refs.
+-
+---sort=<key>::
+- A field name to sort on. Prefix `-` to sort in
+- descending order of the value. When unspecified,
+- `refname` is used. You may use the --sort=<key> option
+- multiple times, in which case the last key becomes the primary
+- key.
+-
+---format=<format>::
+- A string that interpolates `%(fieldname)` from a ref being shown and
+- the object it points at. In addition, the string literal `%%`
+- renders as `%` and `%xx` - where `xx` are hex digits - renders as
+- the character with hex code `xx`. For example, `%00` interpolates to
+- `\0` (NUL), `%09` to `\t` (TAB), and `%0a` to `\n` (LF).
+-+
+-When unspecified, `<format>` defaults to `%(objectname) SPC %(objecttype)
+-TAB %(refname)`.
+-
+---color[=<when>]::
+- Respect any colors specified in the `--format` option. The
+- `<when>` field must be one of `always`, `never`, or `auto` (if
+- `<when>` is absent, behave as if `always` was given).
+-
+---shell::
+---perl::
+---python::
+---tcl::
+- If given, strings that substitute `%(fieldname)`
+- placeholders are quoted as string literals suitable for
+- the specified host language. This is meant to produce
+- a scriptlet that can directly be `eval`ed.
+-
+---points-at=<object>::
+- Only list refs which points at the given object.
+-
+---merged[=<object>]::
+- Only list refs whose tips are reachable from the
+- specified commit (HEAD if not specified).
+-
+---no-merged[=<object>]::
+- Only list refs whose tips are not reachable from the
+- specified commit (HEAD if not specified).
+-
+---contains[=<object>]::
+- Only list refs which contain the specified commit (HEAD if not
+- specified).
+-
+---no-contains[=<object>]::
+- Only list refs which don't contain the specified commit (HEAD
+- if not specified).
+-
+---ignore-case::
+- Sorting and filtering refs are case insensitive.
+-
+---omit-empty::
+- Do not print a newline after formatted refs where the format expands
+- to the empty string.
+-
+---exclude=<pattern>::
+- If one or more patterns are given, only refs which do not match
+- any excluded pattern(s) are shown. Matching is done using the
+- same rules as `<pattern>` above.
+-
+---include-root-refs::
+- List root refs (HEAD and pseudorefs) apart from regular refs.
++include::refs-list-options.adoc[]
+
+ FIELD NAMES
+ -----------
+
## Documentation/git-refs.adoc ##
@@ Documentation/git-refs.adoc: SYNOPSIS
[synopsis]
@@ Documentation/git-refs.adoc: migrate::
Verify reference database consistency.
+list::
-+ List references in the repository with support for filtering, formatting,
-+ and sorting. This subcommand uses the same core logic as
-+ linkgit:git-for-each-ref[1] and offers equivalent functionality.
++ List references in the repository with support for filtering,
++ formatting, and sorting. This subcommand is an alias for
++ linkgit:git-for-each-ref[1] and offers identical functionality.
+
OPTIONS
-------
@@ Documentation/git-refs.adoc: The following options are specific to 'git refs ver
+The following options are specific to 'git refs list':
+
++include::refs-list-options.adoc[]
++
+ KNOWN LIMITATIONS
+ -----------------
+
+
+ ## Documentation/refs-list-options.adoc (new) ##
+@@
++// Shared options for for-each-ref and refs list
+<pattern>...::
+ If one or more patterns are given, only refs are shown that
+ match against at least one pattern, either using fnmatch(3) or
@@ Documentation/git-refs.adoc: The following options are specific to 'git refs ver
+
+--include-root-refs::
+ List root refs (HEAD and pseudorefs) apart from regular refs.
-+
-+
- KNOWN LIMITATIONS
- -----------------
-
## builtin/for-each-ref.c ##
@@ builtin/for-each-ref.c: static char const * const for_each_ref_usage[] = {
2: 8ce521880c = 2: 2d6534841f t: add test for git refs list subcommand-- 2.34.1