如何在 git add --patch 中使用 --color-words?
Posted
技术标签:
【中文标题】如何在 git add --patch 中使用 --color-words?【英文标题】:How to use --color-words with git add --patch? 【发布时间】:2012-06-08 02:06:46 【问题描述】:比较文件时,我更喜欢使用git diff --color-words
。有没有办法在使用git add --patch
或git add --interactive
时将其设为差异的默认格式?
【问题讨论】:
如果我编辑此问题以涵盖--word-diff
和--color-words
,是否可以?如果是这样,那么我的near 重复问题here 将能够作为该问题的exact 副本关闭。这将允许在此处合并答案,从而提高社区的效率。
可能与您可以在此处找到的内容重复:***.com/questions/49278577/…。请看看那里的答案。
【参考方案1】:
根据 VonC 所说的:
从 Git 2.9 开始,您可以在 add --patch
期间使用此命令为单词着色:
git -c interactive.diffFilter="git diff --color-words" add -p
这会将调用的interactive.diffFilter
变量设置为add -p
,而不影响进一步的调用。对我来说这是理想的,因为我通常想正常运行add -p
,但有时想用--color-words
运行它。
您可以像这样轻松地为此命令添加别名:
git config --global alias.addcw '-c interactive.diffFilter="git diff --color-words" add -p'
【讨论】:
很好地使用了add --patch
,还有很好的别名! +1
就像已经指出的那样,答案是(可悲的)错误,因为使用的命令git diff --color-words
不会使标准输入着色,但通常会执行。只需执行echo test | git diff
或git show <some-older-commit> | git diff
即可获取证据。
来自命令行工具的 macOS 上的 Git 2.17.2,我看到了 fatal: mismatched output from interactive.diffFilter hint: Your filter must maintain a one-to-one correspondence hint: between its input and output lines.
@VitalyZdanevich:我也看到了。
在带有 git 2.17.1 的 Ubuntu 上出现同样的错误 fatal: mismatched output
。【参考方案2】:
从VonC's answer 获得启发。下面是git 2.9中引入的--interactive
选项的详细使用步骤。
将diff-highlight 添加到您的路径中。
在 Ubuntu 上,diff-highlight
带有 git,可以在 /usr/share/git/diff-highlight/diff-highlight
中找到。
否则,您可以下载并手动设置。
cd ~/bin
curl -LO "https://raw.githubusercontent.com/git/git/master/contrib/diff-highlight/diff-highlight"
chmod u+x diff-highlight
如有必要,请重新启动您的 shell。
然后配置 Git 以在分页器中显示差异时过滤您的差异:
git config --global pager.log 'diff-highlight | less'
git config --global pager.show 'diff-highlight | less'
git config --global pager.diff 'diff-highlight | less'
git config --global interactive.diffFilter diff-highlight
这将额外强调一行的变化部分,这与--word-diff
几乎相同。
优势是您可以在任何地方获得单词差异,例如 git log --patch
或 git add -p
。
【讨论】:
这几乎对我有用,但 URL 不再有效,所以我不得不从源代码构建diff-highlight
(下载正确的 git 版本——不确定它有多重要——;cd <source directory>/contrib/diff-highlight
; 执行make
; 将新的diff-highlight
添加到您的PATH
) 然后从这个答案中的步骤chmod
开始。使用git version 2.17.2 (Apple Git-113)
为我工作。
你应该已经在你的 git 安装中安装了 diff-highlight。
在 Ubuntu Xenial 上,它以0644
模式安装。 Grrrr。
对于一个brew安装的git,路径是/usr/local/Cellar/git/2.27.0//share/git-core/contrib/diff-highlight/diff-highlight
你也可以通过“pip3 install --user diff-highlight”安装它,将“~/.local/bin”添加到$PATH【参考方案3】:
我最近解决了这个问题,但它需要在 git 中修改 Perl 脚本。不过,这很简单,不需要特殊技能。
此解决方案要求您的 git 配置对屏幕输出使用着色,因为这是 git 显示基于单词的差异的唯一情况。
-
将安装中的
git-add--interactive
复制到PATH
环境变量中的某个位置,并将其重命名为git-add--interactive-words
。
编辑一行大约一半以更改*
@colored = run_cmd_pipe("git", @diff_cmd, qw(--color --), $path);
到
@colored = run_cmd_pipe("git", @diff_cmd, qw(--color --color-words --), $path);
-
您现在可以运行
git add-interactive--words
来执行与 git add --interactive
等效的基于彩色单词的差异。
但是,将git add --patch
与它结合起来很尴尬,因为您需要向新脚本传递正确的参数。幸运的是,您可以为 .gitconfig
中的魔法词创建一个别名:
[alias]
iaddpw = add--interactive-words --patch=stage --
这意味着git iaddpw
运行与git add --interactive --patch
等效的基于彩色单词的差异。
*- 对于 Git 2.18,此命令为:
my @display_cmd = ("git", @diff_cmd, qw(--color --), $path);
【讨论】:
聪明。你应该向 Git 提交一个补丁。谢谢。 我的论文提交后;-) @mabraham 但我收到了这个警告:Use of uninitialized value $_ in print at /usr/local/Cellar/git/1.8.0/libexec/git-core/git-add--interactive-words line 1339
但使用 git add -p
并没有给我这个警告
@BPm @mabraham:您可以通过使用 if 语句将第 1339 行(即print;
)包围来压制该消息,以确保定义了$_
,即将第1339 行替换为if ($_) print;
行 1270-1340 中的现有着色代码假定“之前”和“之后”大块有内容,这不再一定是这种情况。 @Nevik 的修复在那里和第 1282 行有效。【参考方案4】:
使用 git 2.9(2016 年 6 月),您将拥有一个新选项:interactive.diffFilter
。
参见Jeff King (peff
)commit 0114384(2016 年 2 月 27 日)。(由 Junio C Hamano -- gitster
-- 合并于 commit 2052c52,2016 年 4 月 3 日)
add --interactive
: 允许自定义差异高亮程序
add--interactive的patch hunk selector知道怎么问 git 获取彩色差异,并将它们与 我们应用的无色差异。但是没有办法 使用诸如 contrib 之类的差异过滤器工具的人 diff-highlight 以查看它们的正常突出显示。
此补丁允许用户定义任意 shell 命令以 通过管道传输彩色差异。确切的输出不应该 问题(因为我们只是向人类展示结果)只要 它与原始 diff 行兼容(因此 hunk-splitting 也可以拆分彩色版本)。
然后您可以将该差异通过管道传输到 diff --color-words
。
作为Andrew Dufresne的commented,GitHub blog post指的是contrib脚本contrib/diff-highlight
:
您可以使用“
--color-words
”仅突出显示更改的部分 线。然而,这对于代码来说通常很难阅读,因为它会丢失 行结构,你最终会得到格式奇怪的位。相反,此脚本对面向行的差异进行后处理,查找对 行,并突出显示不同的段。
结果特别强调了一行的变化部分:
关于这些差异,“diff-highlight
”过滤器(在contrib/
)学会了更好地理解“git log --graph
”输出。
参见commit 4551fbb、commit 009a81e、commit fbcf99e、commit 7ce2f4c、commit e28ae50、commit 53ab9f0、commit 5013acc(2018 年 3 月 21 日)Jeff King (peff
)。(合并Junio C Hamano -- gitster
--commit d19e556,2018 年 4 月 10 日)
在“diff-highlight
: detect --graph
by indent”中查看更多信息
注意:在 Git 2.17(Q2 2018)之前,“git add -i
”使用的“interactive.diffFilter
”必须保持其输入和输出的一一对应关系,但并未强制执行,导致最终用户混乱。
我们现在至少要确保过滤结果的行数与其输入的行数相同,以检测损坏的过滤器。
见commit 42f7d45、commit af3570e(2018 年 3 月 3 日)Jeff King (peff
)。(由 Junio C Hamano -- gitster
-- 合并到 commit c5e2df0,2018 年 3 月 14 日)
在 Git 2.30(2021 年第一季度)中,“git add -i
”(man) 无法使用配置为显示补丁的自定义颜色,这一问题已得到纠正。
见commit 96386fa、commit 890b68b、commit 0cb8939、commit afae3cb、commit 6681e36(2020 年 11 月 16 日)、commit 25d9e5c、commit c62cd17、commit 6f1a5ca、commit decc9ee(11 月 11 日)、2和commit cb581b1、commit d34e450(2020 年 11 月 10 日)Johannes Schindelin (dscho
)。(由 Junio C Hamano -- gitster
-- 合并到 commit e0d2568,2020 年 12 月 8 日)
add -p
:比color.diff.plain
更喜欢color.diff.context
签字人:约翰内斯·辛德林
Git 的差异机制允许用户覆盖在差异中使用的颜色,甚至是纯色的上下文行。截至8dbf3eb6850(
diff.h
:将DIFF_PLAIN
颜色槽重命名为DIFF_CONTEXT,
2015-05-27,Git v2.4.5),配置设置的首选名称是color.diff.context
,尽管Git仍然允许@987654407 @。在
git add -p
(man) 的上下文中,这个逻辑有点难以复制:git_diff_basic_config()
按顺序读取所有配置值,如果它看到 any em>color.diff.context
或color.diff.plain
,它接受新颜色。 不过,git add -p
(man) 的 Perl 版本需要通过git config --get-color
(man),它只允许指定一个键。git add -p
(man)的内置版本也是如此,必须经过repo_config_get_value()
。我们可以在这里做的最好的事情是寻找
.context
,如果没有找到,则回退到寻找.plain
,如果仍然没有找到,则回退到硬编码的默认值(在这种情况下只是一个空字符串,因为上下文行通常没有着色)。当使用两个配置名称时,这仍然会导致不一致:初始差异将由差异机制着色。 但是,一旦被用户编辑,大块必须由
git add -p
(man) 重新着色,然后它将使用其他设置为上下文行着色。在实践中,这并不是所有那么糟糕。
git config
(man) 手册在color.diff.<slot>
中这么说:`context` (context text - `plain` is a historical synonym)
因此,我们应该假设用户使用其中一个名称,而不是两个名称。 此外,编辑后查看大块的情况相对较少,因为默认情况下它会立即上演。
【讨论】:
这个github tutorial 对如何使用这个新选项有更好的描述。 @Andrew-Dufresne 我同意。我已经包含了对博客文章引用的 contrib 脚本的引用。 执行git config interactive.diffFilter diff-highlight
- 现在在 git commit -p
中完全没有颜色。 git version 2.17.1 (Apple Git-112)
@VitalyZdanevich 尝试使用git add -p
而不是git commit -p
。
@VonC 不同的行。【参考方案5】:
解决方案
使用diff-highlight | less -FRX --tabs=4
作为您的diffFilter
:
git -c interactive.diffFilter="diff-highlight | less -FRX --tabs=4" add --patch
更多关于diff-highlight
:source,a quick primer
自制
如果您使用 Homebrew (OS X),您可以将以下内容放入您的 .gitconfig
(以使用已安装的 diff-highlight
):
[interactive]
diffFilter = "$(git --exec-path | sed 's/libexec/share/')/contrib/diff-highlight/diff-highlight | less -FRX --tabs=4"
输入输出1-1对应
从 git 2.17 开始,单词 diff 解决方案必须保持输入和输出行之间的 1-1 对应关系以避免:
$ git -c interactive.diffFilter="git diff --word-diff --color" add --patch
fatal: mismatched output from interactive.diffFilter
hint: Your filter must maintain a one-to-one correspondence
hint: between its input and output lines.
diff-so-fancy
现在支持此功能(从 v1.4.0 开始),因为 https://github.com/so-fancy/diff-so-fancy/issues/35 已关闭。见this。
【讨论】:
很好地使用了interactive.diffFilter
,我描述了in my own answer。 +1
macOS Mojave - No such file or directory
默认预装 git。
我只在 OS X 上测试了 Homebrew 的安装,确实如此。以下是来自git
自己的一些说明:git-scm.com/book/en/v1/…【参考方案6】:
如前所述,将diff-highlight
添加到interactive.diffFilter
配置键是最简单的选择(从Git 2.9 开始)。以下命令可以在 Debian/Ubuntu 上完成此操作,而无需复制脚本、更改权限或修改 $PATH:
git config interactive.diffFilter "perl /usr/share/doc/git/contrib/diff-highlight/diff-highlight"
git -c interactive.diffFilter="git diff --color-words" add -p
或 git config interactive.diffFilter "git diff --color-words"
之类的东西不能正常工作:add -p
总是提示第一个修改的文件。
【讨论】:
【参考方案7】:这个工具做得很好https://github.com/mookid/diffr
[core]
pager = diffr | less -R
[interactive]
diffFilter = diffr
【讨论】:
【参考方案8】:这也可以通过delta:
[interactive]
diffFilter = delta --color-only --features=interactive
通过diff-so-fancy:
[interactive]
diffFilter = diff-so-fancy --patch
【讨论】:
【参考方案9】:在你的 $(HOME)/.gitconfig 文件中添加这个
[color]
diff = auto
interactive = auto
应该这样做。
【讨论】:
谢谢,但这不是我要说的。这不是 color,而是我正在寻找的逐字差异。 没有。我说的是逐个字符的差异,而不是逐行的差异。试试git diff --color-words
,你就会明白我的意思了。以上是关于如何在 git add --patch 中使用 --color-words?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用寻呼机进行长 git add --patch hunks?
使用 git add --patch <filename> 手动编辑
`Git add --patch` 多个文件:从上一个文件转到大块
[Git] Use git add --patch for better commit history and mitigating bugs