Skip to content

Commit 9f613dd

Browse files
author
Junio C Hamano
committed
Add git-for-each-ref: helper for language bindings
This adds a new command, git-for-each-ref. You can have it iterate over refs and have it output various aspects of the objects they refer to. Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent e7676d2 commit 9f613dd

File tree

10 files changed

+1132
-28
lines changed

10 files changed

+1132
-28
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ git-fetch
3636
git-fetch-pack
3737
git-findtags
3838
git-fmt-merge-msg
39+
git-for-each-ref
3940
git-format-patch
4041
git-fsck-objects
4142
git-get-tar-commit-id

Documentation/git-for-each-ref.txt

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
git-for-each-ref(1)
2+
===================
3+
4+
NAME
5+
----
6+
git-for-each-ref - Output information on each ref
7+
8+
SYNOPSIS
9+
--------
10+
'git-for-each-ref' [--count=<count>]* [--shell|--perl|--python] [--sort=<key>]* [--format=<format>] [<pattern>]
11+
12+
DESCRIPTION
13+
-----------
14+
15+
Iterate over all refs that match `<pattern>` and show them
16+
according to the given `<format>`, after sorting them according
17+
to the given set of `<key>`s. If `<max>` is given, stop after
18+
showing that many refs. The interporated values in `<format>`
19+
can optionally be quoted as string literals in the specified
20+
host language.
21+
22+
OPTIONS
23+
-------
24+
<count>::
25+
By default the command shows all refs that match
26+
`<pattern>`. This option makes it stop after showing
27+
that many refs.
28+
29+
<key>::
30+
A field name to sort on. Prefix `-` to sort in
31+
descending order of the value. When unspecified,
32+
`refname` is used. More than one sort keys can be
33+
given.
34+
35+
<format>::
36+
A string that interpolates `%(fieldname)` from the
37+
object pointed at by a ref being shown. If `fieldname`
38+
is prefixed with an asterisk (`*`) and the ref points
39+
at a tag object, the value for the field in the object
40+
tag refers is used. When unspecified, defaults to
41+
`%(refname)`.
42+
43+
<pattern>::
44+
If given, the name of the ref is matched against this
45+
using fnmatch(3). Refs that do not match the pattern
46+
are not shown.
47+
48+
--shell, --perl, --python::
49+
If given, strings that substitute `%(fieldname)`
50+
placeholders are quoted as string literals suitable for
51+
the specified host language. This is meant to produce
52+
a scriptlet that can directly be `eval`ed.
53+
54+
55+
FIELD NAMES
56+
-----------
57+
58+
Various values from structured fields in referenced objects can
59+
be used to interpolate into the resulting output, or as sort
60+
keys.
61+
62+
For all objects, the following names can be used:
63+
64+
refname::
65+
The name of the ref (the part after $GIT_DIR/refs/).
66+
67+
objecttype::
68+
The type of the object (`blob`, `tree`, `commit`, `tag`).
69+
70+
objectsize::
71+
The size of the object (the same as `git-cat-file -s` reports).
72+
73+
objectname::
74+
The object name (aka SHA-1).
75+
76+
In addition to the above, for commit and tag objects, the header
77+
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
78+
be used to specify the value in the header field.
79+
80+
Fields that have name-email-date tuple as its value (`author`,
81+
`committer`, and `tagger`) can be suffixed with `name`, `email`,
82+
and `date` to extract the named component.
83+
84+
The first line of the message in a commit and tag object is
85+
`subject`, the remaining lines are `body`. The whole message
86+
is `contents`.
87+
88+
For sorting purposes, fields with numeric values sort in numeric
89+
order (`objectsize`, `authordate`, `committerdate`, `taggerdate`).
90+
All other fields are used to sort in their byte-value order.
91+
92+
In any case, a field name that refers to a field inapplicable to
93+
the object referred by the ref does not cause an error. It
94+
returns an empty string instead.
95+
96+
97+
EXAMPLES
98+
--------
99+
100+
Show the most recent 3 tagged commits::
101+
102+
------------
103+
#!/bin/sh
104+
105+
git-for-each-ref --count=3 --sort='-*authordate' \
106+
--format='From: %(*authorname) %(*authoremail)
107+
Subject: %(*subject)
108+
Date: %(*authordate)
109+
Ref: %(*refname)
110+
111+
%(*body)
112+
' 'refs/tags'
113+
------------
114+
115+
A bit more elaborate report on tags::
116+
------------
117+
#!/bin/sh
118+
119+
fmt='
120+
r=%(refname)
121+
t=%(*objecttype)
122+
T=${r#refs/tags/}
123+
124+
o=%(*objectname)
125+
n=%(*authorname)
126+
e=%(*authoremail)
127+
s=%(*subject)
128+
d=%(*authordate)
129+
b=%(*body)
130+
131+
kind=Tag
132+
if test "z$t" = z
133+
then
134+
# could be a lightweight tag
135+
t=%(objecttype)
136+
kind="Lightweight tag"
137+
o=%(objectname)
138+
n=%(authorname)
139+
e=%(authoremail)
140+
s=%(subject)
141+
d=%(authordate)
142+
b=%(body)
143+
fi
144+
echo "$kind $T points at a $t object $o"
145+
if test "z$t" = zcommit
146+
then
147+
echo "The commit was authored by $n $e
148+
at $d, and titled
149+
150+
$s
151+
152+
Its message reads as:
153+
"
154+
echo "$b" | sed -e "s/^/ /"
155+
echo
156+
fi
157+
'
158+
159+
eval=`git-for-each-ref -s --format="$fmt" \
160+
--sort='*objecttype' \
161+
--sort=-taggerdate \
162+
refs/tags`
163+
eval "$eval"
164+
------------

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ BUILTIN_OBJS = \
267267
builtin-diff-stages.o \
268268
builtin-diff-tree.o \
269269
builtin-fmt-merge-msg.o \
270+
builtin-for-each-ref.o \
270271
builtin-grep.o \
271272
builtin-init-db.o \
272273
builtin-log.o \

0 commit comments

Comments
 (0)