| 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 |