如何改进 git 的差异突出显示?

How to improve git's diff highlighting?

git diff 的输出针对往往每行一个语句的代码进行了优化,而文本可能(如果像我这样的作者懒得使用换行符)会导致难以阅读的差异输出比读取差异输出

更多的是"Where's Wally?"搜索

而在 GitLab 或 GitHub 的 Web 前端上突出显示会立即显示差异

我知道我正在比较 HTML 和纯文本(苹果和橘子),但是应该可以通过使用不同的颜色或添加标记字符来改进 git diff 输出围绕一个变化(JUnit 使用 [] 围绕插入,这不是很好读,但是我的意思的一个例子)这将是第一次我希望在 [=28= 中的某个地方可用的东西] 其实不是。

您可以使用 --word-diff[=<mode>] 选项来更轻松地查看一行中哪些词发生了变化。这在手册页中描述为

Show a word diff, using the <mode> to delimit changed words. By default, words are delimited by whitespace; see --word-diff-regex below. The <mode> defaults to plain, and must be one of:

  • color – Highlight changed words using only colors. Implies --color.

  • plain – Show words as [-removed-] and {+added+}. Makes no attempts to escape the delimiters if they appear in the input, so the output may be ambiguous.

  • porcelain – Use a special line-based format intended for script consumption. Added/removed/unchanged runs are printed in the usual unified diff format, starting with a +/-/` ` character at the beginning of the line and extending to the end of the line. Newlines in the input are represented by a tilde ~ on a line of its own.

  • none – Disable word diff again.

Note that despite the name of the first mode, color is used to highlight the changed parts in all modes if enabled.

另一个答案中建议的 word-diff 并不完全是 gitlab/github 所做的。要获得相同的效果,您可以使用 diff-highlight 脚本,即 distributed with git.

  1. 首先找到 diff-highlight 脚本的路径。它因系统而异,通常不在 $PATH 中。您可以通过您的包管理器找到它,例如:

    1. 软呢帽:rpm -ql git | grep diff-highlight
    2. Debian/Ubuntu/Mint: dpkg -L git | grep diff-highlight
    3. Archlinux:pacman -Ql git | grep diff-highlight
  2. 编辑 ~/.gitconfig,并在 [pager] 部分添加以下 (替换路径):

    [pager]
        # diff-highlight is script provided by git that shows word-by-word diff
        log  = perl /usr/share/git/diff-highlight/diff-highlight | less
        show = perl /usr/share/git/diff-highlight/diff-highlight | less
        diff = perl /usr/share/git/diff-highlight/diff-highlight | less
    

    我在这里使用 perl 而不是直接调用脚本,因为某些发行版似乎没有在脚本上设置可执行位。 IMO 这是一个应该报告的包错误。无论如何,这个答案应该无视那个。

现在 logdiffshow 命令应该逐字显示差异。截图:

另外值得一提的是diffr。它是用 Rust 编写的,并使用 Myers 最长公共子序列算法。与 git 的 diff-highlight 相比,它给出了更好的结果,参见:

git的diff-highlight:

diffr:

安装后,使用方式与diff-highlight类似,即编辑~/.gitconfig,在[pager]部分添加如下:

[pager]
    log  = diffr | less
    show = diffr | less
    diff = diffr | less

Delta 是其他答案中后处理工具的现代替代品。

高度可配置emulation modes for diff-highlight and diff-so-fancy) and includes many features 在其他工具中找不到:side-by-side 视图,语法高亮显示,以及合并冲突git blame输出的着色

Delta 文档还有一个 overview of related projects,其中提到了更多 ad-hoc 可以产生类似输出的工具。