Skip to content

Commit ca0542f

Browse files
committed
Merge branch 'ms/refs-list' into seen
The "list" subcommand of "git refs" acts as a front-end for "git for-each-ref". Comments? * ms/refs-list: t: add test for git refs list subcommand t6300: refactor tests to be shareable builtin/refs: add list subcommand builtin/for-each-ref: factor out core logic into a helper builtin/for-each-ref: align usage string with the man page doc: factor out common option
2 parents 7171fe5 + fed66d9 commit ca0542f

11 files changed

+2316
-2244
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<pattern>...::
2+
If one or more patterns are given, only refs are shown that
3+
match against at least one pattern, either using fnmatch(3) or
4+
literally, in the latter case matching completely or from the
5+
beginning up to a slash.
6+
7+
--stdin::
8+
If `--stdin` is supplied, then the list of patterns is read from
9+
standard input instead of from the argument list.
10+
11+
--count=<count>::
12+
By default the command shows all refs that match
13+
`<pattern>`. This option makes it stop after showing
14+
that many refs.
15+
16+
--sort=<key>::
17+
A field name to sort on. Prefix `-` to sort in
18+
descending order of the value. When unspecified,
19+
`refname` is used. You may use the --sort=<key> option
20+
multiple times, in which case the last key becomes the primary
21+
key.
22+
23+
--format=<format>::
24+
A string that interpolates `%(fieldname)` from a ref being shown and
25+
the object it points at. In addition, the string literal `%%`
26+
renders as `%` and `%xx` - where `xx` are hex digits - renders as
27+
the character with hex code `xx`. For example, `%00` interpolates to
28+
`\0` (NUL), `%09` to `\t` (TAB), and `%0a` to `\n` (LF).
29+
+
30+
When unspecified, `<format>` defaults to `%(objectname) SPC %(objecttype)
31+
TAB %(refname)`.
32+
33+
--color[=<when>]::
34+
Respect any colors specified in the `--format` option. The
35+
`<when>` field must be one of `always`, `never`, or `auto` (if
36+
`<when>` is absent, behave as if `always` was given).
37+
38+
--shell::
39+
--perl::
40+
--python::
41+
--tcl::
42+
If given, strings that substitute `%(fieldname)`
43+
placeholders are quoted as string literals suitable for
44+
the specified host language. This is meant to produce
45+
a scriptlet that can directly be `eval`ed.
46+
47+
--points-at=<object>::
48+
Only list refs which points at the given object.
49+
50+
--merged[=<object>]::
51+
Only list refs whose tips are reachable from the
52+
specified commit (HEAD if not specified).
53+
54+
--no-merged[=<object>]::
55+
Only list refs whose tips are not reachable from the
56+
specified commit (HEAD if not specified).
57+
58+
--contains[=<object>]::
59+
Only list refs which contain the specified commit (HEAD if not
60+
specified).
61+
62+
--no-contains[=<object>]::
63+
Only list refs which don't contain the specified commit (HEAD
64+
if not specified).
65+
66+
--ignore-case::
67+
Sorting and filtering refs are case insensitive.
68+
69+
--omit-empty::
70+
Do not print a newline after formatted refs where the format expands
71+
to the empty string.
72+
73+
--exclude=<pattern>::
74+
If one or more patterns are given, only refs which do not match
75+
any excluded pattern(s) are shown. Matching is done using the
76+
same rules as `<pattern>` above.
77+
78+
--include-root-refs::
79+
List root refs (HEAD and pseudorefs) apart from regular refs.
80+
81+
--start-after=<marker>::
82+
Allows paginating the output by skipping references up to and including the
83+
specified marker. When paging, it should be noted that references may be
84+
deleted, modified or added between invocations. Output will only yield those
85+
references which follow the marker lexicographically. Output begins from the
86+
first reference that would come after the marker alphabetically. Cannot be
87+
used with `--sort=<key>` or `--stdin` options, or the _<pattern>_ argument(s)
88+
to limit the refs.

Documentation/git-for-each-ref.adoc

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -28,94 +28,7 @@ host language allowing their direct evaluation in that language.
2828

2929
OPTIONS
3030
-------
31-
<pattern>...::
32-
If one or more patterns are given, only refs are shown that
33-
match against at least one pattern, either using fnmatch(3) or
34-
literally, in the latter case matching completely or from the
35-
beginning up to a slash.
36-
37-
--stdin::
38-
If `--stdin` is supplied, then the list of patterns is read from
39-
standard input instead of from the argument list.
40-
41-
--count=<count>::
42-
By default the command shows all refs that match
43-
`<pattern>`. This option makes it stop after showing
44-
that many refs.
45-
46-
--sort=<key>::
47-
A field name to sort on. Prefix `-` to sort in
48-
descending order of the value. When unspecified,
49-
`refname` is used. You may use the --sort=<key> option
50-
multiple times, in which case the last key becomes the primary
51-
key.
52-
53-
--format=<format>::
54-
A string that interpolates `%(fieldname)` from a ref being shown and
55-
the object it points at. In addition, the string literal `%%`
56-
renders as `%` and `%xx` - where `xx` are hex digits - renders as
57-
the character with hex code `xx`. For example, `%00` interpolates to
58-
`\0` (NUL), `%09` to `\t` (TAB), and `%0a` to `\n` (LF).
59-
+
60-
When unspecified, `<format>` defaults to `%(objectname) SPC %(objecttype)
61-
TAB %(refname)`.
62-
63-
--color[=<when>]::
64-
Respect any colors specified in the `--format` option. The
65-
`<when>` field must be one of `always`, `never`, or `auto` (if
66-
`<when>` is absent, behave as if `always` was given).
67-
68-
--shell::
69-
--perl::
70-
--python::
71-
--tcl::
72-
If given, strings that substitute `%(fieldname)`
73-
placeholders are quoted as string literals suitable for
74-
the specified host language. This is meant to produce
75-
a scriptlet that can directly be `eval`ed.
76-
77-
--points-at=<object>::
78-
Only list refs which points at the given object.
79-
80-
--merged[=<object>]::
81-
Only list refs whose tips are reachable from the
82-
specified commit (HEAD if not specified).
83-
84-
--no-merged[=<object>]::
85-
Only list refs whose tips are not reachable from the
86-
specified commit (HEAD if not specified).
87-
88-
--contains[=<object>]::
89-
Only list refs which contain the specified commit (HEAD if not
90-
specified).
91-
92-
--no-contains[=<object>]::
93-
Only list refs which don't contain the specified commit (HEAD
94-
if not specified).
95-
96-
--ignore-case::
97-
Sorting and filtering refs are case insensitive.
98-
99-
--omit-empty::
100-
Do not print a newline after formatted refs where the format expands
101-
to the empty string.
102-
103-
--exclude=<pattern>::
104-
If one or more patterns are given, only refs which do not match
105-
any excluded pattern(s) are shown. Matching is done using the
106-
same rules as `<pattern>` above.
107-
108-
--include-root-refs::
109-
List root refs (HEAD and pseudorefs) apart from regular refs.
110-
111-
--start-after=<marker>::
112-
Allows paginating the output by skipping references up to and including the
113-
specified marker. When paging, it should be noted that references may be
114-
deleted, modified or added between invocations. Output will only yield those
115-
references which follow the marker lexicographically. Output begins from the
116-
first reference that would come after the marker alphabetically. Cannot be
117-
used with `--sort=<key>` or `--stdin` options, or the _<pattern>_ argument(s)
118-
to limit the refs.
31+
include::for-each-ref-options.adoc[]
11932

12033
FIELD NAMES
12134
-----------

Documentation/git-refs.adoc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,13 @@ SYNOPSIS
1111
[synopsis]
1212
git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]
1313
git refs verify [--strict] [--verbose]
14+
git refs list [--count=<count>] [--shell|--perl|--python|--tcl]
15+
[(--sort=<key>)...] [--format=<format>]
16+
[--include-root-refs] [--points-at=<object>]
17+
[--merged[=<object>]] [--no-merged[=<object>]]
18+
[--contains[=<object>]] [--no-contains[=<object>]]
19+
[(--exclude=<pattern>)...] [--start-after=<marker>]
20+
[ --stdin | <pattern>... ]
1421

1522
DESCRIPTION
1623
-----------
@@ -26,6 +33,11 @@ migrate::
2633
verify::
2734
Verify reference database consistency.
2835

36+
list::
37+
List references in the repository with support for filtering,
38+
formatting, and sorting. This subcommand is an alias for
39+
linkgit:git-for-each-ref[1] and offers identical functionality.
40+
2941
OPTIONS
3042
-------
3143

@@ -57,6 +69,10 @@ The following options are specific to 'git refs verify':
5769
--verbose::
5870
When verifying the reference database consistency, be chatty.
5971

72+
The following options are specific to 'git refs list':
73+
74+
include::for-each-ref-options.adoc[]
75+
6076
KNOWN LIMITATIONS
6177
-----------------
6278

builtin/for-each-ref.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,15 @@
22
#include "commit.h"
33
#include "config.h"
44
#include "environment.h"
5+
#include "for-each-ref.h"
56
#include "gettext.h"
67
#include "object.h"
78
#include "parse-options.h"
89
#include "ref-filter.h"
910
#include "strbuf.h"
1011
#include "strvec.h"
1112

12-
static char const * const for_each_ref_usage[] = {
13-
N_("git for-each-ref [<options>] [<pattern>]"),
14-
N_("git for-each-ref [--points-at <object>]"),
15-
N_("git for-each-ref [--merged [<commit>]] [--no-merged [<commit>]]"),
16-
N_("git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]"),
17-
N_("git for-each-ref [--start-after <marker>]"),
18-
NULL
19-
};
20-
21-
int cmd_for_each_ref(int argc,
22-
const char **argv,
23-
const char *prefix,
24-
struct repository *repo)
13+
int for_each_ref_core(int argc, const char **argv, const char *prefix, struct repository *repo, const char *const *usage)
2514
{
2615
struct ref_sorting *sorting;
2716
struct string_list sorting_options = STRING_LIST_INIT_DUP;
@@ -70,17 +59,17 @@ int cmd_for_each_ref(int argc,
7059
/* Set default (refname) sorting */
7160
string_list_append(&sorting_options, "refname");
7261

73-
parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0);
62+
parse_options(argc, argv, prefix, opts, usage, 0);
7463
if (format.array_opts.max_count < 0) {
7564
error("invalid --count argument: `%d'", format.array_opts.max_count);
76-
usage_with_options(for_each_ref_usage, opts);
65+
usage_with_options(usage, opts);
7766
}
7867
if (HAS_MULTI_BITS(format.quote_style)) {
7968
error("more than one quoting style?");
80-
usage_with_options(for_each_ref_usage, opts);
69+
usage_with_options(usage, opts);
8170
}
8271
if (verify_ref_format(&format))
83-
usage_with_options(for_each_ref_usage, opts);
72+
usage_with_options(usage, opts);
8473

8574
if (filter.start_after && sorting_options.nr > 1)
8675
die(_("cannot use --start-after with custom sort options"));
@@ -120,3 +109,16 @@ int cmd_for_each_ref(int argc,
120109
strvec_clear(&vec);
121110
return 0;
122111
}
112+
113+
int cmd_for_each_ref(int argc,
114+
const char **argv,
115+
const char *prefix,
116+
struct repository *repo)
117+
{
118+
static char const * const for_each_ref_usage[] = {
119+
N_("git for-each-ref " COMMON_USAGE_FOR_EACH_REF),
120+
NULL
121+
};
122+
123+
return for_each_ref_core(argc, argv, prefix, repo, for_each_ref_usage);
124+
}

builtin/refs.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "refs.h"
77
#include "strbuf.h"
88
#include "worktree.h"
9+
#include "for-each-ref.h"
910

1011
#define REFS_MIGRATE_USAGE \
1112
N_("git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]")
@@ -101,6 +102,17 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix,
101102
return ret;
102103
}
103104

105+
static int cmd_refs_list(int argc, const char **argv, const char *prefix,
106+
struct repository *repo)
107+
{
108+
static char const * const refs_list_usage[] = {
109+
N_("git refs list " COMMON_USAGE_FOR_EACH_REF),
110+
NULL
111+
};
112+
113+
return for_each_ref_core(argc, argv, prefix, repo, refs_list_usage);
114+
}
115+
104116
int cmd_refs(int argc,
105117
const char **argv,
106118
const char *prefix,
@@ -109,12 +121,14 @@ int cmd_refs(int argc,
109121
const char * const refs_usage[] = {
110122
REFS_MIGRATE_USAGE,
111123
REFS_VERIFY_USAGE,
124+
"git refs list " COMMON_USAGE_FOR_EACH_REF,
112125
NULL,
113126
};
114127
parse_opt_subcommand_fn *fn = NULL;
115128
struct option opts[] = {
116129
OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate),
117130
OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify),
131+
OPT_SUBCOMMAND("list", &fn, cmd_refs_list),
118132
OPT_END(),
119133
};
120134

for-each-ref.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef FOR_EACH_REF_H
2+
#define FOR_EACH_REF_H
3+
4+
struct repository;
5+
6+
/*
7+
* Shared usage string for options common to git-for-each-ref(1)
8+
* and git-refs-list(1). The command-specific part (e.g., "git refs list ")
9+
* must be prepended by the caller.
10+
*/
11+
#define COMMON_USAGE_FOR_EACH_REF \
12+
"[--count=<count>] [--shell|--perl|--python|--tcl]\n" \
13+
" [(--sort=<key>)...] [--format=<format>]\n" \
14+
" [--include-root-refs] [--points-at=<object>]\n" \
15+
" [--merged[=<object>]] [--no-merged[=<object>]]\n" \
16+
" [--contains[=<object>]] [--no-contains[=<object>]]\n" \
17+
" [(--exclude=<pattern>)...] [--start-after=<marker>]\n" \
18+
" [ --stdin | <pattern>... ]"
19+
20+
/*
21+
* The core logic for for-each-ref and its clones.
22+
*/
23+
int for_each_ref_core(int argc, const char **argv, const char *prefix,
24+
struct repository *repo, const char *const *usage);
25+
26+
#endif /* FOR_EACH_REF_H */

0 commit comments

Comments
 (0)