如何使git log截断长注释?

51
我有一个git log的别名,它将每个提交打印为一行。由于有些人在提交日志中写了太长的一行,所以许多提交会换行。我该如何格式化git log的输出,以在50个字符后截断注释?
我在git-log手册中找到了这个方法,但它只会填充短注释,而不会截断长注释。
%<(<N>[,trunc|ltrunc|mtrunc]): make the next placeholder take at least N columns,
  padding spaces on the right if necessary. Optionally truncate at the beginning (ltrunc),
  the middle (mtrunc) or the end (trunc) if the output is longer than N columns. Note that
  truncating only works correctly with N >= 2.
8个回答

89

文档中并没有明确说明需要哪些字符,但以下示例将主题行裁剪为50个字符:

git log --oneline --format="%h %<(50,trunc)%s"

格式规范为%<,其参数需要用括号括起来。在这种情况下,保留前50个字符并截断超出部分。

例如,对msysGit仓库执行此操作如下:

C:\src\msysgit>git log -n 5 --format="%h [%<(12,trunc)%aN] [%<(12,trunc)%cN] %<(50,trunc)%s"

218ed04 [Sebastian ..] [Sebastian ..] Merge pull request #154 from csware/tortoisegitp..
8a920b9 [Sven Stric..] [Sven Stric..] Installer: Detect TortoiseGitPlink from Tortoise..
448e125 [dscho       ] [dscho       ] Merge pull request #152 from csware/syscommand
db8d1bf [Sven Stric..] [Sven Stric..] Perl readline creates empty sys$command files if..
753d3d6 [Johannes S..] [Johannes S..] Git for Windows 1.8.5.2-preview20131230

2
谢谢!“trunc”部分正是我所需要的。 - Marcus Ahlberg
1
谢谢-我试了30分钟才弄清楚这个魔法咒语-固定宽度 :) - Gishu
这个格式字符串对我来说在Git for Windows x64 2.6.1上有效。使用Windows cmd提示符,我得到与上面显示的相同的布局,并在截断行的末尾显示截断标记。 - patthoyts
3
对我来说,这不仅仅是将长主题截断为50个字符,它还会填充短主题以使它们达到50个字符。 - dumbledad
2
最好不要填充。我无法弄清如何做到这一点。 - Sridhar Sarnobat
显示剩余2条评论

21

虽然来晚了,但这些选项也可以:

$ git config --global core.pager 'less -S'

或者(例如)

$ echo $LESS
-R
$ export LESS=-RS

1
运行得非常好。此外,行长度会自适应终端宽度。从 less --help 中可以看到:"-S ... chop long lines rather than wrapping"。这使得图表更易读,例如在使用 git log --oneline --decorate --all --graph 时。 - djvg
太好了!能否将此与--no-pager结合使用,即同时使用此选项并立即将结果输出到终端而不会在less上阻塞? - avp
很好知道,但它盲目地截断整行,导致意外的行为,比如这个:git log --format="%h %ad \"%s\" (%an)" --date=short(在末尾打印作者)。此外,OP和我一样,要求仅截断“注释”。 - FractalSpace
1
如果你想让'less'在输出少于一页时退出,也可以添加-E(--QUIT-AT-EOF)选项。 - tanager
1
我无法感谢你的足够。这解决了我90%的git日志格式化头痛:“当X太长时,如何让它不再难看?”。谢谢! - Patrick

11

仅截断和填充提交信息

根据其他答案,格式占位符%<(50,trunc)%s将打印截断为50个字符的提交信息。但那也会将较短的值填充到相同长度,没有办法告诉它不要这样做。

如果那适合您,那么就完成了。如果不是,需要另一种方法。

在终端宽度处截断整个行

同样根据其他答案,可以将less -S配置为全局或每个存储库的core.pager选项。这将在终端宽度处修剪整个日志字符串,避免折行。

但它会对所有Git命令执行此操作!(至少会对所有生成分页输出的命令执行此操作)。

改进-仅针对特定命令进行截断

可以使用-c选项实现此目的,例如:git -c core.pager='less -S' log --graph --oneline

更好的做法是将其设置为别名,这样您就不必每次都输入它:

git config --global alias.graph "-c core.pager='less -S' \
 log --graph --oneline`

结合两种方法

您也可以将此与格式占位符相结合。这是一个使用 --graph 标志的示例,其中提交消息还会被填充/截断为50个字符,但由于 --graph 选项创建了一个变宽的提交图形绘制,因此需要结合两种方法。而且您不想每次都输一遍这个命令:

git config --global alias.graph "-c core.pager='less -S' \
log --pretty='tformat:%C(bold cyan)%h %C(blue)%<(10,trunc)%aN \
%<(50,trunc)%C(white)%s %C(auto)%d %C(dim green)%ar' --graph"

3

我将这个放到 ~/bin/git-mylog 中:

#!/bin/bash
COLS=$(tput cols)
git log --format="tformat:%>|(15)%C(auto)%h %Cgreen %<(20,trunc)%cn %C(auto) %<(15,trunc)%ar %<($((COLS-55)),trunc)%s" --graph

这里有些内容,但关键是使用tput cols来获取终端宽度,然后进行一些算术运算以将注释宽度截断为实际可用空间,而不是固定宽度。


它看起来很漂亮,具有自动调整列宽和颜色的功能... - FractalSpace
我在我的git配置文件中将其适配为别名:lg = !git log --format=\"tformat:%>|(15)%C(auto)%h %Cgreen %<(20,trunc)%cn %C(auto) %<(15,trunc)%ar %<($(($(tput cols)-55)),trunc)%s\" --graph - Bob

2
我似乎完全无法适当地格式化评论,所以将其发布为答案,但实际上是对@patthoyts的回复的评论。
trunc 的好处在于它会填充空格,所以你可以像这样使用它:
git log --pretty=format:"%ad %<(50,trunc)%s %h" --date=short --reverse
以产生一个更容易(至少对我的眼睛而言)浏览的概览。 $ git log --pretty=format:"%ad %<(50,trunc)%s %h" --date=short --reverse
2015-06-15 initial commit 5099ede 2015-06-16 Layout - Responsive grid added. 6534242 2015-06-17 HTML - H1 / Title updated <title>Testpage</title.. 88ea464 2015-06-18 Updating the Hotfix changes a8fbc47
提示 - 添加一个名为 alias 的别名(例如 trunc),这样会更方便。
git config --global alias.trunc 'log --pretty=format:"%ad %<(50,trunc)%s %h" --date=short --reverse'

(注:原文中的 "<" 在翻译时被编码为 "<",表示小于号)

1
git log --oneline

将显示已剥离的提交头(具有代码)。
git log --pretty=oneline

将会展示完整的提交头(包含代码)。

这适用于1.7 git,但不适用于2.2 git。我尝试过了。我认为@patthoyts建议的“--format”解决方案可能是你在git 2.x中唯一的选择。 - fbicknel

1

使用省略号的方式将在 Git 2.40(2023年第一季度)中得到澄清:

请查看提交记录 540e7bc, 提交记录 b5cd634, 提交记录 63792c5, 提交记录 8bcb8f8, 提交记录 d664a7a (2023年1月19日) 由Philip Oakley (PhilipOakley)提交。
(由Junio C Hamano -- gitster --合并于提交记录 4ac326f, 2023年1月30日)

文档: pretty-format描述了省略号截断的用法

签名作者:Philip Oakley

提交 a7f01c6pretty:支持在%>中截断,2013-04-19,Git v1.8.3-rc0 -- 合并)(pretty:支持在%>%<%><中截断,2013-04-19)添加了省略号在截断占位符值时的使用。 展示我们的“双点”省略号,并给出左、中、右截断的示例,以避免对调整字符串的哪一端产生任何困惑。(参见调整和子字符串)。

pretty-formats现在在其手册页面中包括:

如果输出超过N列,则在左侧(ltrunc) ..ft,中间(mtrunc) mi..le或结尾(trunc) rig..处截断(带省略号“..”)。

这就是%C(blue)%<(10,trunc)%aN %<(50,trunc)%C(white)%s的作用。


0
我想使用“引用”格式[1],但只带有截断的摘要。问题在于$<()和其他修饰符是用于“填充”,而我只想要截断。
请注意,我只想截断摘要,而不是整个输出行[2]。
我没有找到使用git(1)格式化实现这一点的方法,所以不得不使用通常的丑陋管道。
#/bin/sh
git log --date=short --pretty='format:%C(auto)%h (%<(50,trunc)%s, %ad)' $@ \
    | tr --squeeze-repeats ' ' | sed -e 's/ ,/,/g' | less --quit-if-one-screen
  • 将宽度截断为50个ASCII字符
  • tr --squeeze-repeats ' ' 用于去除连续的空白字符,即填充
    • 摘要行也可能包含连续的空白字符,但这种情况非常不常见,我不关心
  • sed -e 's/ ,/,/g' 用于去除剩余的单个空格,即分隔摘要和日期的逗号前的空格
  • less --quit-if-one-screen 旨在模拟默认的git(1)对输出的处理方式

作为Git别名(使用通常的位置参数的shell函数模式):

logrefshort = "!f() { git log --date=short --pretty='format:%C(auto)%h (%<(50,trunc)%s, %ad)' $@ | tr --squeeze-repeats ' ' | sed -e 's/ ,/,/g' | less --quit-if-one-screen; }; f"

例子

$ git logrefshort --no-merges -20 origin/master
d4a83d07b8c (The tenth batch, 2023-09-18)
bda494f4043 (The ninth batch, 2023-09-14)
d6c51973e4a (The eighth batch, 2023-09-13)
9f892830d69 (completion(switch/checkout): treat --track and -.., 2023-09-08)
94e83dcf5b5 (The seventh batch, 2023-09-07)
aae8558b103 (grep: reject --no-or, 2023-09-07)
203573b0246 (rebase -i: fix adding failed command to the todo.., 2023-09-06)
405509cbd66 (rebase --continue: refuse to commit after failed.., 2023-09-06)
e032abd5a0b (rebase: fix rewritten list for failed pick, 2023-09-06)
f2b5f41eda5 (sequencer: factor out part of pick_commits(), 2023-09-06)
9f67899b41e (sequencer: use rebase_path_message(), 2023-09-06)
206a78d7108 (rebase -i: remove patch file after conflict reso.., 2023-09-06)
36ac861a305 (rebase -i: move unlink() calls, 2023-09-06)
11422f23e3e (doc/diff-options: fix link to generating patch s.., 2023-09-06)
256a94ef6c8 (var: avoid a segmentation fault when `HOME` is u.., 2023-09-04)
82af2c639c4 (sequencer: fix error message on failure to copy .., 2023-09-03)
2a63c79dae7 (grep: use OPT_INTEGER_F for --max-depth, 2023-09-02)
078c42531e8 (name-rev: use OPT_HIDDEN_BOOL for --peel-tag, 2023-09-02)
6d79cd8474b (ref-filter: sort numerically when ":size" is used, 2023-09-02)
0058b3d5eed (parse-options: mark unused parameters in noop ca.., 2023-08-31)

注意事项

  1. git log --format=reference。例如:aae8558b103 (grep: reject --no-or, 2023-09-07)
  2. 但与其余的格式相比,它并不是非常动态(不像摘要)。唯一可能变化的事项(在公元10000年之前)是缩写哈希值,因为其长度取决于数据库/仓库中的对象数量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接