| git-format-rev(1) |
| ================= |
| |
| NAME |
| ---- |
| git-format-rev - EXPERIMENTAL: Pretty format revisions on demand |
| |
| |
| SYNOPSIS |
| -------- |
| [synopsis] |
| (EXPERIMENTAL!) git format-rev --stdin-mode=<mode> --format=<pretty> [--[no-]notes=<ref>] [-z] [--[no-]null-output] [--[no-]null-input] |
| |
| DESCRIPTION |
| ----------- |
| |
| Pretty format revisions from standard input. |
| |
| THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. |
| |
| OPTIONS |
| ------- |
| |
| `--stdin-mode=<mode>`:: |
| How to interpret standard input data: |
| + |
| -- |
| `revs`;; Each line or record (see the <<io,INPUT AND OUTPUT FORMATS>> |
| section) is interpreted as a commit. Any kind of revision |
| expression can be used (see linkgit:gitrevisions[7]). Annotated |
| tags are peeled (see linkgit:gitglossary[7]). |
| + |
| The argument `rev` is also accepted. |
| |
| `text`;; Formats all commit object names found in freeform text. These |
| must the full object names, i.e. abbreviated hexidecimal object |
| names will not be interpreted. |
| + |
| Anything that is parsed as an object name but that is not found to be a |
| commit object name is left alone (echoed). |
| -- |
| |
| `--format=<pretty>`:: |
| Pretty format string. |
| |
| `--notes=<ref>`:: |
| `--no-notes`:: |
| Custom notes ref. Notes are displayed when using the `%N` |
| atom. See linkgit:git-notes[1]. |
| |
| `-z`:: |
| `--null`:: |
| Use _NUL_ character to terminate both input and output instead |
| of newline. This option cannot be negated. |
| + |
| This is useful if both the input and output could contain newlines or if |
| the input to this command also uses _NUL_ character termination; see the |
| <<io,INPUT AND OUTPUT FORMATS>> section below. |
| + |
| The mode `--stdin-mode=text` can have use for this option when it needs |
| to process input like for example `git last-modified -z`; see the |
| <<examples,EXAMPLES>> section below. |
| |
| `--null-output`:: |
| `--no-null-output`:: |
| Use _NUL_ character to terminate output instead of newline. The |
| default is `--no-null-output`. |
| + |
| This is useful if the output could contain newlines, for example if the |
| `%n` (newline) atom is used. |
| |
| `--null-input`:: |
| `--no-null-input`:: |
| Use _NUL_ character to terminate input instead of newline. The |
| default is `--no-null-input`. |
| + |
| This is useful if the input revision expressions could contain newlines. |
| |
| [[io]] |
| INPUT AND OUTPUT FORMAT |
| ----------------------- |
| |
| The command uses newlines for both input and output termination by |
| default. See the `-z`, `--null-output`, and `--null-input` options for |
| using _NUL_ character as the terminator. |
| |
| The mode `--stdin-mode=revs` outputs one formatted commit followed by |
| the terminator. This could either be called a _line_ or a _record_ in |
| case "line" is too suggestive of newline termination. |
| |
| Note that this means that the terminator character (newline or _NUL_) |
| acts as a _terminator_, not a _separator_. In other words, the final |
| line or record is also terminated by the terminator character. |
| |
| The mode `--stdin-mode=text` replaces each object name with the |
| formatted commit, i.e. the format `%s` would transform some commit |
| object name to `<subject>` without any termination. Like this: |
| |
| ---- |
| Did we not fix this in "<subject>"? |
| ---- |
| |
| It is safe to interactively read and write from this command since each |
| record is immediately flushed. |
| |
| [[examples]] |
| EXAMPLES |
| -------- |
| |
| The command linkgit:git-last-modified[1] shows the commit that each file |
| was last modified in. |
| |
| ---- |
| $ git last-modified -- README.md Makefile |
| 7798034171030be0909c56377a4e0e10e6d2df93 Makefile |
| c50fbb2dd225e7e82abba4380423ae105089f4d7 README.md |
| ---- |
| |
| We can pipe the result to this command in order to replace the object |
| name with the commit author. |
| |
| ---- |
| $ git last-modified -- README.md Makefile | |
| git format-rev --stdin-mode=text --format=%an |
| Junio C Hamano Makefile |
| Todd Zullinger README.md |
| ---- |
| |
| Another example is _formatting commits in commit messages_. Given this commit message: |
| |
| ---- |
| 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. |
| ---- |
| |
| We can format the commits and use par(1) to reflow the text, say in a |
| `commit-msg` hook: |
| |
| ---- |
| $ 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" |
| ---- |
| |
| Which will produce something like this: |
| |
| ---- |
| 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. |
| ---- |
| |
| DISCUSSION |
| ---------- |
| |
| This command lets you format any number of revisions in any order |
| through one command invocation. Consider the |
| linkgit:git-last-modified[1] case from the <<examples,EXAMPLES>> section |
| above: |
| |
| 1. There might be hundreds of files |
| 2. Commits can be repeated, i.e. two or more files were last modified in |
| the same commit |
| |
| Two widely-used commands which pretty formats commits are |
| linkgit:git-log[1] and linkgit:git-show[1]. It turns out that they are |
| not a good fit for the above use case. |
| |
| - The output of linkgit:git-last-modified[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. |
| - You can feed each commit to `git show` or `git log --no-walk -1`. But |
| that means that you need to create a process for each line. |
| - Let’s 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 `--stdin` 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. |
| - 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. |
| |
| 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. |
| |
| SEE ALSO |
| -------- |
| linkgit:git-name-rev[1], |
| linkgit:git-log[1]. |
| |
| GIT |
| --- |
| Part of the linkgit:git[1] suite |