Raw
1 git-format-rev(1)
2 =================
3
4 NAME
5 ----
6 git-format-rev - EXPERIMENTAL: Pretty format revisions on demand
7
8
9 SYNOPSIS
10 --------
11 [synopsis]
12 (EXPERIMENTAL!) git format-rev --stdin-mode=<mode> --format=<pretty> [--[no-]notes=<ref>] [-z] [--[no-]null-output] [--[no-]null-input]
13
14 DESCRIPTION
15 -----------
16
17 Pretty format revisions from standard input.
18
19 THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE.
20
21 OPTIONS
22 -------
23
24 `--stdin-mode=<mode>`::
25 How to interpret standard input data:
26 +
27 --
28 `revs`;; Each line or record (see the <<io,INPUT AND OUTPUT FORMATS>>
29 section) is interpreted as a commit. Any kind of revision
30 expression can be used (see linkgit:gitrevisions[7]). Annotated
31 tags are peeled (see linkgit:gitglossary[7]).
32 +
33 The argument `rev` is also accepted.
34
35 `text`;; Formats all commit object names found in freeform text. These
36 must be full object names, i.e. abbreviated hexadecimal object
37 names will not be interpreted.
38 +
39 Anything that is parsed as an object name but that is not found to be a
40 commit object name is left alone (echoed).
41 --
42
43 `--format=<pretty>`::
44 Pretty format string.
45
46 `--notes=<ref>`::
47 `--no-notes`::
48 Custom notes ref. Notes are displayed when using the `%N`
49 atom. See linkgit:git-notes[1].
50
51 `-z`::
52 `--null`::
53 Use _NUL_ character to terminate both input and output instead
54 of newline. This option cannot be negated.
55 +
56 This is useful if both the input and output could contain newlines or if
57 the input to this command also uses _NUL_ character termination; see the
58 <<io,INPUT AND OUTPUT FORMATS>> section below.
59 +
60 The mode `--stdin-mode=text` can have use for this option when it needs
61 to process input like for example `git last-modified -z`; see the
62 <<examples,EXAMPLES>> section below.
63
64 `--null-output`::
65 `--no-null-output`::
66 Use _NUL_ character to terminate output instead of newline. The
67 default is `--no-null-output`.
68 +
69 This is useful if the output could contain newlines, for example if the
70 `%n` (newline) atom is used.
71
72 `--null-input`::
73 `--no-null-input`::
74 Use _NUL_ character to terminate input instead of newline. The
75 default is `--no-null-input`.
76 +
77 This is useful if the input revision expressions could contain newlines.
78
79 [[io]]
80 INPUT AND OUTPUT FORMAT
81 -----------------------
82
83 The command uses newlines for both input and output termination by
84 default. See the `-z`, `--null-output`, and `--null-input` options for
85 using _NUL_ character as the terminator.
86
87 The mode `--stdin-mode=revs` outputs one formatted commit followed by
88 the terminator. This could either be called a _line_ or a _record_ in
89 case "line" is too suggestive of newline termination.
90
91 Note that this means that the terminator character (newline or _NUL_)
92 acts as a _terminator_, not a _separator_. In other words, the final
93 line or record is also terminated by the terminator character.
94
95 The mode `--stdin-mode=text` replaces each object name with the
96 formatted commit, i.e. the format `%s` would transform some commit
97 object name to `<subject>` without any termination. Like this:
98
99 ----
100 Did we not fix this in "<subject>"?
101 ----
102
103 It is safe to interactively read and write from this command since each
104 record is immediately flushed.
105
106 [[examples]]
107 EXAMPLES
108 --------
109
110 The command linkgit:git-last-modified[1] shows the commit that each file
111 was last modified in.
112
113 ----
114 $ git last-modified -- README.md Makefile
115 7798034171030be0909c56377a4e0e10e6d2df93 Makefile
116 c50fbb2dd225e7e82abba4380423ae105089f4d7 README.md
117 ----
118
119 We can pipe the result to this command in order to replace the object
120 name with the commit author.
121
122 ----
123 $ git last-modified -- README.md Makefile |
124 git format-rev --stdin-mode=text --format=%an
125 Junio C Hamano Makefile
126 Todd Zullinger README.md
127 ----
128
129 Another example is _formatting commits in commit messages_. Given this commit message:
130
131 ----
132 Fix off-by-one error
133
134 Fix off-by-one error introduced in
135 e83c5163316f89bfbde7d9ab23ca2e25604af290.
136
137 We thought we fixed this in 5569bf9bbedd63a00780fc5c110e0cfab3aa97b9 but
138 that only covered 1/3 of the faulty cases.
139 ----
140
141 We can format the commits and use par(1) to reflow the text, say in a
142 `commit-msg` hook:
143
144 ----
145 $ git config set hook.reference-commits.event commit-msg
146 $ git config set hook.reference-commits.command reference-commits
147 $ cat $(which reference-commits)
148 #/bin/sh
149
150 msg="$1"
151 rewritten=$(mktemp)
152 git format-rev --stdin-mode=text --format=reference <"$msg" |
153 par >"$rewritten"
154 mv "$rewritten" "$msg"
155 ----
156
157 Which will produce something like this:
158
159 ----
160 Fix off-by-one error
161
162 Fix off-by-one error introduced in e83c5163316 (Implement better memory
163 allocator, 2005-04-07).
164
165 We thought we fixed this in 5569bf9bbed (Fix memory allocator,
166 2005-06-22) but that only covered 1/3 of the faulty cases.
167 ----
168
169 DISCUSSION
170 ----------
171
172 This command lets you format any number of revisions in any order
173 through one command invocation. Consider the
174 linkgit:git-last-modified[1] case from the <<examples,EXAMPLES>> section
175 above:
176
177 1. There might be hundreds of files
178 2. Commits can be repeated, i.e. two or more files were last modified in
179 the same commit
180
181 Two widely-used commands which pretty formats commits are
182 linkgit:git-log[1] and linkgit:git-show[1]. It turns out that they are
183 not a good fit for the above use case.
184
185 - The output of linkgit:git-last-modified[1] would have to be processed
186 in stages since you need to transform the first column separately and
187 then link the author to the filename. But this is surmountable.
188 - You can feed each commit to `git show` or `git log --no-walk -1`. But
189 that means that you need to create a process for each line.
190 - Let’s say that you want to use one process, not one per line. So you
191 want to feed all the commits to the command. Now you face the problem
192 that you have to feed all the commits to the commands before you get
193 any output (this is also the case for the `--stdin` modes). In other
194 words, you cannot loop through each line, get the author for the
195 commit, and output the author and the filename. You need to feed all
196 the commits, get back all the output, and match the output with the
197 filename.
198 - But the next problem is that commands will deduplicate the input and
199 only output one commit one single time only. Thus you cannot make the
200 output order match the input order, since a commit could have been
201 repeated in the original input.
202
203 In short, it is straightforward to use these two commands if you use one
204 process per line. It is much more work if you just want to use one
205 process, but still doable. In contrast, this problem is solved with just
206 another shell pipeline with this command.
207
208 SEE ALSO
209 --------
210 linkgit:git-name-rev[1],
211 linkgit:git-log[1].
212
213 GIT
214 ---
215 Part of the linkgit:git[1] suite