'\" t .\" Title: git-format-rev .\" Author: [FIXME: author] [see http://www.docbook.org/tdg5/en/html/author] .\" Generator: DocBook XSL Stylesheets vsnapshot .\" Date: 2026-06-29 .\" Manual: Git Manual .\" Source: Git 2.55.0 .\" Language: English .\" .TH "GIT\-FORMAT\-REV" "1" "2026\-06\-29" "Git 2\&.55\&.0" "Git Manual" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" git-format-rev \- EXPERIMENTAL: Pretty format revisions on demand .SH "SYNOPSIS" .sp .nf (\fBEXPERIMENTAL\fR!) \fBgit\fR \fBformat\-rev\fR \fB\-\-stdin\-mode=\fR\fI\fR \fB\-\-format=\fR\fI\fR [\fB\-\-\fR[\fBno\-\fR]\fBnotes=\fR\fI\fR] [\fB\-z\fR] [\fB\-\-\fR[\fBno\-\fR]\fBnull\-output\fR] [\fB\-\-\fR[\fBno\-\fR]\fBnull\-input\fR] .fi .sp .SH "DESCRIPTION" .sp Pretty format revisions from standard input\&. .sp THIS COMMAND IS EXPERIMENTAL\&. THE BEHAVIOR MAY CHANGE\&. .SH "OPTIONS" .PP \fB\-\-stdin\-mode=\fR\fI\fR .RS 4 How to interpret standard input data: .PP \fBrevs\fR .RS 4 Each line or record (see the INPUT AND OUTPUT FORMATS section) is interpreted as a commit\&. Any kind of revision expression can be used (see \fBgitrevisions\fR(7))\&. Annotated tags are peeled (see \fBgitglossary\fR(7))\&. .sp The argument \fBrev\fR is also accepted\&. .RE .PP \fBtext\fR .RS 4 Formats all commit object names found in freeform text\&. These must be full object names, i\&.e\&. abbreviated hexadecimal object names will not be interpreted\&. .sp Anything that is parsed as an object name but that is not found to be a commit object name is left alone (echoed)\&. .RE .RE .PP \fB\-\-format=\fR\fI\fR .RS 4 Pretty format string\&. .RE .PP \fB\-\-notes=\fR\fI\fR, \fB\-\-no\-notes\fR .RS 4 Custom notes ref\&. Notes are displayed when using the \fB%N\fR atom\&. See \fBgit-notes\fR(1)\&. .RE .PP \fB\-z\fR, \fB\-\-null\fR .RS 4 Use \fINUL\fR character to terminate both input and output instead of newline\&. This option cannot be negated\&. .sp This is useful if both the input and output could contain newlines or if the input to this command also uses \fINUL\fR character termination; see the INPUT AND OUTPUT FORMATS section below\&. .sp The mode \fB\-\-stdin\-mode=text\fR can have use for this option when it needs to process input like for example \fBgit\fR \fBlast\-modified\fR \fB\-z\fR; see the EXAMPLES section below\&. .RE .PP \fB\-\-null\-output\fR, \fB\-\-no\-null\-output\fR .RS 4 Use \fINUL\fR character to terminate output instead of newline\&. The default is \fB\-\-no\-null\-output\fR\&. .sp This is useful if the output could contain newlines, for example if the \fB%n\fR (newline) atom is used\&. .RE .PP \fB\-\-null\-input\fR, \fB\-\-no\-null\-input\fR .RS 4 Use \fINUL\fR character to terminate input instead of newline\&. The default is \fB\-\-no\-null\-input\fR\&. .sp This is useful if the input revision expressions could contain newlines\&. .RE .SH "INPUT AND OUTPUT FORMAT" .sp The command uses newlines for both input and output termination by default\&. See the \fB\-z\fR, \fB\-\-null\-output\fR, and \fB\-\-null\-input\fR options for using \fINUL\fR character as the terminator\&. .sp The mode \fB\-\-stdin\-mode=revs\fR outputs one formatted commit followed by the terminator\&. This could either be called a \fIline\fR or a \fIrecord\fR in case "line" is too suggestive of newline termination\&. .sp Note that this means that the terminator character (newline or \fINUL\fR) acts as a \fIterminator\fR, not a \fIseparator\fR\&. In other words, the final line or record is also terminated by the terminator character\&. .sp The mode \fB\-\-stdin\-mode=text\fR replaces each object name with the formatted commit, i\&.e\&. the format \fB%s\fR would transform some commit object name to \fI\fR without any termination\&. Like this: .sp .if n \{\ .RS 4 .\} .nf Did we not fix this in ""? .fi .if n \{\ .RE .\} .sp .sp It is safe to interactively read and write from this command since each record is immediately flushed\&. .SH "EXAMPLES" .sp The command \fBgit-last-modified\fR(1) shows the commit that each file was last modified in\&. .sp .if n \{\ .RS 4 .\} .nf $ git last\-modified \-\- README\&.md Makefile 7798034171030be0909c56377a4e0e10e6d2df93 Makefile c50fbb2dd225e7e82abba4380423ae105089f4d7 README\&.md .fi .if n \{\ .RE .\} .sp .sp We can pipe the result to this command in order to replace the object name with the commit author\&. .sp .if n \{\ .RS 4 .\} .nf $ git last\-modified \-\- README\&.md Makefile | git format\-rev \-\-stdin\-mode=text \-\-format=%an Junio C Hamano Makefile Todd Zullinger README\&.md .fi .if n \{\ .RE .\} .sp .sp Another example is \fIformatting commits in commit messages\fR\&. Given this commit message: .sp .if n \{\ .RS 4 .\} .nf Fix off\-by\-one error Fix off\-by\-one error introduced in e83c5163316f89bfbde7d9ab23ca2e25604af290\&. We thought we fixed this in 5569bf9bbedd63a00780fc5c110e0cfab3aa97b9 but that only covered 1/3 of the faulty cases\&. .fi .if n \{\ .RE .\} .sp .sp We can format the commits and use par(1) to reflow the text, say in a \fBcommit\-msg\fR hook: .sp .if n \{\ .RS 4 .\} .nf $ git config set hook\&.reference\-commits\&.event commit\-msg $ git config set hook\&.reference\-commits\&.command reference\-commits $ cat $(which reference\-commits) #/bin/sh msg="$1" rewritten=$(mktemp) git format\-rev \-\-stdin\-mode=text \-\-format=reference <"$msg" | par >"$rewritten" mv "$rewritten" "$msg" .fi .if n \{\ .RE .\} .sp .sp Which will produce something like this: .sp .if n \{\ .RS 4 .\} .nf Fix off\-by\-one error Fix off\-by\-one error introduced in e83c5163316 (Implement better memory allocator, 2005\-04\-07)\&. We thought we fixed this in 5569bf9bbed (Fix memory allocator, 2005\-06\-22) but that only covered 1/3 of the faulty cases\&. .fi .if n \{\ .RE .\} .sp .SH "DISCUSSION" .sp This command lets you format any number of revisions in any order through one command invocation\&. Consider the \fBgit-last-modified\fR(1) case from the EXAMPLES section above: .sp .RS 4 .ie n \{\ \h'-04' 1.\h'+01'\c .\} .el \{\ .sp -1 .IP " 1." 4.2 .\} There might be hundreds of files .RE .sp .RS 4 .ie n \{\ \h'-04' 2.\h'+01'\c .\} .el \{\ .sp -1 .IP " 2." 4.2 .\} Commits can be repeated, i\&.e\&. two or more files were last modified in the same commit .RE .sp Two widely\-used commands which pretty formats commits are \fBgit-log\fR(1) and \fBgit-show\fR(1)\&. It turns out that they are not a good fit for the above use case\&. .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} The output of \fBgit-last-modified\fR(1) would have to be processed in stages since you need to transform the first column separately and then link the author to the filename\&. But this is surmountable\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} You can feed each commit to \fBgit\fR \fBshow\fR or \fBgit\fR \fBlog\fR \fB\-\-no\-walk\fR \fB\-1\fR\&. But that means that you need to create a process for each line\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} Let\(cqs say that you want to use one process, not one per line\&. So you want to feed all the commits to the command\&. Now you face the problem that you have to feed all the commits to the commands before you get any output (this is also the case for the \fB\-\-stdin\fR modes)\&. In other words, you cannot loop through each line, get the author for the commit, and output the author and the filename\&. You need to feed all the commits, get back all the output, and match the output with the filename\&. .RE .sp .RS 4 .ie n \{\ \h'-04'\(bu\h'+03'\c .\} .el \{\ .sp -1 .IP \(bu 2.3 .\} But the next problem is that commands will deduplicate the input and only output one commit one single time only\&. Thus you cannot make the output order match the input order, since a commit could have been repeated in the original input\&. .RE .sp In short, it is straightforward to use these two commands if you use one process per line\&. It is much more work if you just want to use one process, but still doable\&. In contrast, this problem is solved with just another shell pipeline with this command\&. .SH "SEE ALSO" .sp \fBgit-name-rev\fR(1), \fBgit-log\fR(1)\&. .SH "GIT" .sp Part of the \fBgit\fR(1) suite