如何防止'git diff'使用分页器?

895

有没有一种命令行开关可以传递给 git diff 和默认使用 less 分页器的其他命令呢?我知道存在以下方法:

  • git diff | cat... 去除所有语法高亮
  • git config --global core.pager cat 将全局 .gitconfig 中的分页器设置为cat
  • export GIT_PAGER=cat

但我更喜欢一种命令行开关。


19
注意:core.pager 'less -+F -+X' 是一种更近期的方法来去除这些选项。请参考我的回答 - VonC
1
"less -+F -+X" 是一个神奇的设置,可以在长日志中删除令人讨厌的“...跳过...”标记。非常感谢这些选项,你救了我的一天! - Guillaume Perrot
请始终使用Git Diff的分页器。 - Trevor Boyd Smith
请参考与git一起使用less的相关问题(这取决于less版本):https://unix.stackexchange.com/questions/107315/less-quit-if-one-screen-without-no-init - Pierz
寻找Windows的解决方案?@Jaredcheeda的答案https://dev59.com/lHI95IYBdhLWcg3wtwb4#57399465可行。 - Jarmos
20个回答

1012

--no-pager告诉Git不要使用分页器。将选项-F传递给less将告诉它如果输出适合单个屏幕,则不要分页。

确保在命令之前添加--no-pager-P,例如git --no-pager log...

用法:

git --no-pager diff

其他评论中的选项包括:
# Set an evaporating environment variable to use 'cat' for your pager
GIT_PAGER=cat git diff

# Tells 'less' not to paginate if less than a page
export LESS="-F -X $LESS"
# ...then Git as usual
git diff

# short option alternative
git -P diff

49
或者使用GIT_PAGER或PAGER环境变量,或core.pager git配置变量。 - Jakub Narębski
99
请记住,在您的命令之前必须添加--add-pager,例如“git --no-pager log --format=blah”。 - Ana Betts
7
另外,如果您的终端在退出“less”后清除屏幕,则需要在“less”选项中添加“-E”以使“-F”可用。 - mgalgs
15
请注意,如果您想在别名中包含--no-pager,则需要在命令前面加上它。为了避免错误,您需要像这样创建别名:git config alias.foo '!git --no-pager foo'。有点令人困惑。简单地将别名设置为'--no-pager foo'是行不通的。 - Jim Stewart
2
--no-pager can also be shortened to -P - Alex Jasmin
显示剩余14条评论

380

如先前的回答所提到的,将-F选项传递给less会在内容少于一个屏幕时退出。然而,在这样做后,屏幕会被重置,导致无法看到内容。

-X选项可以取消这种行为。因此,我使用以下命令根据内容量启用条件分页:

git config --global --replace-all core.pager "less -F -X"

52
注意:在 git 1.8.0.2 中,我不得不使用 git config --global --add core.pager "less -F -X",上面那个命令不起作用。 - Dogbert
13
好的!为了让它不仅在Git上表现良好,而且在所有程序中都能这样做,请在您的.bashrc.zshrc文件中添加类似于export LESS="-RFX"的内容。 - defhlt
1
是的,正如我在回答中所解释的那样,我更喜欢在分页程序启动和退出之前不重置屏幕,特别是如果所有内容都适合一个屏幕,这正是“-X”所做的。如果您不喜欢,请不要使用它。我喜欢它,因为这样我可以通过查看历史记录中以前的git命令的结果来引用诸如git SHAs之类的东西,而无需再次输入命令。各有所好。 - ishaaq
5
截至2017年12月,如果您使用的是版本号为530或更高的less,那么您不需要使用“-X”,这里有一篇Unix SE的文章解释了这个问题。使用“less -F”将产生所需的行为。 - Captain Man
1
我认为如果没有使用分页器,重置功能就不应该被应用,否则应该被应用。 - Kamil Dziedzic
显示剩余6条评论

239

使用

git config --global core.pager cat
为了在所有仓库的所有命令中摆脱分页,您可以使用core.pager而不是使用单个Git子命令禁用分页,并且您可以按Git存储库更改设置(省略--global)。有关详细信息,请参见man git-config并搜索pager.<cmd>

问题不是如何完全禁用分页,而是如何禁用grep子命令的分页。 mtahmed的答案是完美的。 - TilmanBaumann
15
可能这不是详细解释所要求的,但这正是我在寻找的内容,而且它是谷歌搜索结果中排名靠前的,因此感谢@geekQ。 - Brian F Leighty
如果你在一个有大量提交的代码库中执行 git log,那将是非常糟糕的。更糟糕的是,如果执行 git log -p,你会看到所有提交的差异被倒入到你的终端中。 - Ether

98
您可以在全局配置中禁用/启用特定输出的分页器:
git config --global pager.diff false

或者设置core.pager选项,只需提供一个空字符串:

git config --global core.pager ''

在我看来,这比你说的设置为cat要好。


这是对我有效的版本 git version 2.5.4 (Apple Git-61) - Ashley Coolman
1
这正是我想要的,因为其他命令会完全禁用分页器,但这是唯一一个只禁用 git diff 的答案,同时让它在其他命令中继续工作。 - SingleNegationElimination
截至本文撰写时,在 Windows / PowerShell 上,我不得不手动编辑 code "$($env:UserProfile)\.gitconfig" 并在 [core] 设置下添加 pager = 。这个答案对于我的当前 powershell 会话起作用,但似乎没有将设置保存在任何地方,因此在下次启动时仍然有效。 - No Refunds No Returns
1
要选择性地分页其他选项,请使用 git config --global pager.log "less -F -X" 或类似命令。 - Clucking Turtle
注意:在Windows上,最后一个命令中使用单引号无法正常工作,但双引号可以:git config --global core.pager "" - wovano
显示剩余2条评论

79
最近文档中提到了一种不同的方法来移除less的默认选项(“默认选项”是FRSX)。
对于这个问题,可以使用以下方法(git 1.8+)。
git config --global --replace-all core.pager 'less -+F -+X'

例如,Dirk Bester在评论中建议:
export LESS="$LESS -FRXK" 

所以我可以使用Ctrl-C退出less并获得有颜色的差异。 Wilson F评论中和他的问题中提到,less支持水平滚动,因此当行被截断时,less会禁用“如果只有一页则退出”,使用户仍然可以向左滚动文本以查看被截断的内容。
这些修改已在 Git 1.8.x 中可见,如 "始终使用分页器进行 git diff" 所示(请参见评论)。但是文档刚刚重新措辞(适用于 Git 1.8.5 或 1.9,Q4 2013)。

用于 Git 命令(如 'less')的文本查看器。
这个值旨在由 shell 解释。

优先顺序是:

  • $GIT_PAGER 环境变量,
  • 然后是 core.pager 配置,
  • 再是 $PAGER
  • 最后是编译时选择的默认设置(通常是 'less')。

当未设置 LESS 环境变量时,Git 会将其设置为 FRSX
(如果已设置 LESS 环境变量,则 Git 不会对其进行更改)。

如果您想有选择地覆盖 Git 的 LESS 默认设置,则可以将 core.pager 设置为例如 less -+S
Git 将把此设置传递给 shell,shell 将其转换为 LESS=FRSX less -+S。环境告诉命令将 S 选项设置为截断长行,但命令行将其重置为默认值以折叠长行。


请参阅提交 97d01f2a,了解新文档措辞背后的原因:

配置:重写core.pager文档

文本提到了core.pagerGIT_PAGER,但没有给出其优先级的整体概述。借鉴git var(1)文档中更好的描述。

使用机制允许全局、全局和每个仓库的配置文件,并不仅限于特定变量。删除它以澄清段落。

重写部分,解释环境变量LESS如何设置为Git的默认值,以及如何选择性地自定义它。


注意:提交 b327583Matthieu Moy moy,2014年4月,适用于git 2.0.x/2.1,2014年第三季度)将默认删除 $LESS 中的 'S':

pager: 默认情况下从 $LESS 中删除 'S'

By default, Git used to set $LESS to -FRSX if $LESS was not set by the user.
The FRX flags actually make sense for Git (F and X because sometimes the output Git pipes to less is short, and R because Git pipes colored output).
The S flag (chop long lines), on the other hand, is not related to Git and is a matter of user preference. Git should not decide for the user to change LESS's default.

More specifically, the S flag harms users who review untrusted code within a pager, since a patch looking like:

-old code;
+new good code; [... lots of tabs ...] malicious code;

would appear identical to:

-old code;
+new good code;

Users who prefer the old behavior can still set the $LESS environment variable to -FRSX explicitly, or set core.pager to 'less -S'.

文档将会这样说明:

环境变量没有设置 S 选项,但是命令行设置了该选项,指示 less 截断长行。
同样地,将 core.pager 设置为 less -+F 将会禁用来自命令行的环境中指定的 F 选项,禁用了 less 的 "一屏退出" 行为。
可以针对特定的命令明确激活某些标志:例如,将 pager.blame 设置为 less -S 仅为 git blame 启用行截断。


2
谢谢。这让我明白我想要的是将LESS变量设置为"$LESS -FRXK",以便在使用ctrl-c退出less时得到有颜色的差异显示。 - Dirk Bester
这里有一个谜题(对我来说是):当我将less设置为<1屏幕退出并且不剪切行(即less -F -+S)时,运行日志命令后我会回到命令提示符。然而,如果我剪切行(即删除-+S),并且任何行被剪切,则在结束时,它不会立即退出,而是打印“END”并等待我按q键。是否有一种方法可以剪切行并仍然在不到一屏幕的时间内自动退出less - Wilson F
1
@WilsonF 我不知道,但那听起来像是一个好问题:为什么不把它变成一个问题,而不是让它埋在评论里呢? - VonC
是的,我应该这样做。所以,我做了,谢谢! - Wilson F
对于任何对此感兴趣但不想跟随链接的人;-):事实证明,less支持水平滚动(也许每个人都知道这一点,但我不知道),因此当行被截断时,less禁用了quit-if-one-screen,以便用户仍然可以向左滚动文本以查看被截断的内容。 - Wilson F
显示剩余2条评论

20

我在Linux上使用的Git版本为2.1.4,以下方法对我有效:

git config --global --replace-all core.pager cat

这会使Git使用cat代替lesscat只是将diff的输出直接显示在屏幕上,而没有分页。


通常情况下,如果答案包含代码意图以及解释解决问题的原因而不引入其他问题,那么这样的答案会更有帮助。某些用户将没有解释的答案标记为删除。 - Nathan Tuggy
5
@NathanTuggy 我认为我已经很清楚地回答了问题。看起来一些用户喜欢为了好玩而标记短回答。我会添加一些文字。 - jcoffland

12

关于管道时禁用颜色:

使用 --color 以避免颜色被禁用。

git diff --color | less -R

或者强制配置(例如在 .gitconfig 文件中):

[color]
        ui = on

git diff | less -R

对于非彩色工具,请使用:

git diff --no-color | 某些基本工具

将环境变量 LESS=-R 导出(例如在 .bashrc 中)默认在"less"中打开颜色支持:

git diff | less


2
请注意,如果未设置LESS环境变量,则在调用分页器时,git将其设置为FRSX - tobbez

11

有时候我想禁用分页,特别是当我知道输出内容不是很长的时候。为此,我发现使用Git别名是一个不错的技巧:

git config --global --add alias.n '!git --no-pager'

或者将以下内容添加到 ~/.gitconfig 文件的 [alias] 部分:

n = !git --no-pager

这意味着您可以使用前缀n来关闭任何Git命令的分页功能,例如:
git n diff # Show the diff without pager
git n log -n 3 # Show the last three commits without pager
git n show v1.1 # Show information about a tag

8
-P 也表示不使用分页功能。 - luckyguy73

10

您可以使用 pager.alias 为 diff 添加别名,并与其自己的分页器一起使用,如下所示:

[alias]
  dc = diff
  dsc = diff --staged
[pager]
  dc = cat
  dsc = cat

这将保持颜色并在 'git dc' 被调用时使用 'cat' 作为分页器。

此外,不要做以下事情:

  • 在别名中使用 --no-pager。Git(1.8.5.2,Apple Git-48)会抱怨您试图修改环境。
  • 使用带有 !sh!git 的 shell。这将绕过上述环境错误,但它将重置您的工作目录(对于此命令而言)到顶级 Git 目录,因此如果您已经在存储库的子目录中,则任何对本地文件的引用都将无法正常工作。

1
+1 当您想要通过“git log”而不是“git log --oneline”进行提交导航时,此技术非常有用。使用“pager.log = less -FXR + / ^ commit .*”,同时将“--oneline”选项与“alias.l1 = log --oneline”和“pager.l1 = less -FXR”特殊处理。 - Claudio

9

正如“man git”所述,您可以在任何命令中使用--no-pager

我在以下命令中使用它:

git --no-pager diff
git --no-pager log --oneline --graph --decorate --all -n 10

然后使用别名来避免使用(和记忆)长命令。


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