如何让 diff 像 git-diff 一样工作?

Posted

技术标签:

【中文标题】如何让 diff 像 git-diff 一样工作?【英文标题】:How to get diff working like git-diff? 【发布时间】:2011-06-18 22:38:09 【问题描述】:

我喜欢git diff 的输出格式。行间变化的颜色和+/- 表示比 GNU diff 更容易阅读。

我可以在 git repo 之外使用--no-index 标志运行git diff,它工作正常。但是,它似乎缺少用于从递归 diff 中排除文件或子目录的 --exclude 选项。

有没有办法两全其美? (颜色选项和- 格式的git diff--exclude GNU diff 选项)。

我尝试过colordiff,但我还是更喜欢git diff的输出格式

【问题讨论】:

要将添加的蓝色变为绿色,请将 newtext 更改为 /etc/colordiff。我认为 git 使用绿色? 直到现在我才听说过 --no-index 标志。我刚刚用它来比较 git show 的输出和两个文件的差异 - 谢谢! 【参考方案1】:

这将执行+/- 而不是<>

diff -u file1 file2

从 GNU diffutils 3.4 开始,添加了标志 --color。将两者结合起来会产生以下效果:

diff --color -u file1 file2

标志--color 也接受一个参数,有效选项为neveralwaysauto。当您想更明确地说明需要做什么时很有用。

【讨论】:

酷,这结合 colordiff 让我足够接近我想要的。我想我下次需要进一步向下滚动手册页...谢谢! 使用 diff -u 进行着色的一种简单方法是将输出通过管道传输到 tig,命令行 git repo 查看器:diff -u file1 file2 | tig 从您的 apt/yum/pacman 存储库中安装 colordiff 并使用它。 需要在 Amazon Linux 上启用 Extra Packages for Enterprise Linux (EPEL) 才能安装 colordiff: docs.aws.amazon.com/AWSEC2/latest/UserGuide/… 除了colordiff,你还可以通过定义cdiff() diff -u $@ | vim -R -; 来获取vim的颜色。【参考方案2】:

您也可以使用git diff --no-index -- A B(通过manpage)。

【讨论】:

+1,但遗憾的是,如果其中一个文件是符号链接,这将不起作用。 +1 这非常有用,因为它展示了如何让 git 报告两个跟踪文件 AB彼此 相比不同的地方,而不是每个文件已相对于它们各自的上一个修订版进行了修改。 @EmilLundberg:在 Linux 上使用 git 1.9.1 中的符号链接为我工作。不知道之前的版本是不是坏了。 git diff --no-index 很棒,但正如 OP 指出的那样,它缺少 --exclude 标志,因此它的用处通常非常有限。【参考方案3】:

    安装colordiff。

    更新您的 ~/.colordiffrc(如有必要,首先复制 /etc/colordiffrc):

    # be more git-like:
    plain=off
    newtext=darkgreen
    oldtext=darkred
    diffstuff=darkcyan
    

    colordiff -u file1 file2 用于两个文件或colordiff -ruN path1 path2 用于递归比较路径。

不完全一样,但很接近。

【讨论】:

【参考方案4】:

这是我的建议,而且非常接近

diff -u FILE1 FILE2 | colordiff | less -R
colordiff: 你必须安装这个 brew install colordiff 在我的 Mac 上。 port install colordiff 在某些 Mac 上。 sudo apt-get install colordiff 在 Debian 或 Ubuntu 上 其他平台请从the main page或GitHub下载源码并关注the installation instructions -R:这告诉 Less 显示颜色而不是原始代码。

我最终使用了-w,因为我不想看到空格差异。

diff -w -u FILE1 FILE2 | colordiff | less -R

编辑:正如@Ciprian Tomoiaga 在评论中所建议的那样,您可以将其设为一个函数并将其放入您的~/.bashrc 文件中。

function gdiff ()  diff -u $@ | colordiff | less -R; 

【讨论】:

为此添加一个 bash 函数到 .bashrc:function gdiff () diff -u $@ | colordiff | less -R; 【参考方案5】:

根据 Unix SE 上的 this answer,GNU diff 自 2016 年末的 3.4 版以来具有 --color 选项。这与-u 一起应该足以模仿git diff 的输出:

diff -u --color=always file1 file2 | less -r

--color 在管道中使用时必须为 alwaysauto 将关闭管道中的颜色。

我只在 Windows 上使用 Git Bash 进行过尝试,less -R 只会为大块的第一行着色。 less -r 在这种情况下为我修复了它。

【讨论】:

【参考方案6】:

仅使用bashdifftputless,我们可以非常接近git diff 的输出。不过,由于diff 程序员的短视,会有一些显着差异。

将以下 Bash 函数定义放入由您的用户帐户自动获取的某个文件中,您将能够从命令行访问该函数:

function gdiff()

    local REG=`tput op`
    local GRP=`tput setaf 6`
    local ADD=`tput setaf 2`
    local REM=`tput setaf 1`

    local NL=$'\n'
    local GRP_LABEL="$GRP@@ %df,%dn +%dF,%dN @@$REG"

    local UNCH_GRP_FMT=''

    [[ "$1" == '@full' ]] && 

        UNCH_GRP_FMT="$GRP_LABEL$NL%="
        shift
    

    diff \
        --new-line-format="$ADD+%L$REG" \
        --old-line-format="$REM-%L$REG" \
        --unchanged-line-format=" %L$REG" \
        --new-group-format="$GRP_LABEL$NL%>" \
        --old-group-format="$GRP_LABEL$NL%<" \
        --changed-group-format="$GRP_LABEL$NL%<%>" \
        --unchanged-group-format="$UNCH_GRP_FMT" \
            "$@" | less -FXR

这个函数的工作原理如下:

    最终,diff 会被调用并使用各种格式选项来指定如何显示文件中的更改。 tput 用于将 ANSI 颜色代码插入到这些格式选项中。请注意,使用非 ANSI 终端时,您可能需要将 tput setaf 替换为 tput setfdiff 的输出通过管道传送到less-R 允许保留 ANSI 颜色。 -X 防止 less 在退出时清除屏幕。如果输出适合一个屏幕,-F 会阻止 less 作为寻呼机运行。 如果第一个参数是@full,该函数将显示除添加和删除的行之外的所有未更改的行。

请注意此方法与git diff 之间的以下区别:

    git diff 报告围绕每个更改的三行上下文。不幸的是,diff 似乎会抱怨并退出,如果您想指定上下文行数,同时还要指定格式选项。 (至少在 Mac OS X Yosemite 中是这样)。感谢diff 程序员。因此,您既可以不请求围绕每个更改的上下文行(这是默认行为),也可以通过将 @full 指定为第一个参数来请求同时报告文件中所有未更改的行。 由于上下文的行数与git diff不同,因此该函数报告的行号也会与git diff报告的行数不同。 您可能会看到报告存在单行更改,这是正确的行为,但当您更改的文件包含单个空行的插入时会很烦人。我认为git diff 可以通过其上下文更好地处理这个问题。如果您愿意,可以尝试将不同的选项传递给 diff 以更好地处理空格。

【讨论】:

【参考方案7】:

将它放在你的 rc 文件中,最常见的是 .bashrc.zshrc

diff() git diff --no-index "$1" "$2" | colordiff;

要求:gitcolordiff 应该已经安装。

用法:diff file1 file2

【讨论】:

【参考方案8】:

您正在寻找colordiff:

sudo apt-get install colordiff

【讨论】:

【参考方案9】:

由于bat 有很好的着色效果,我已经测试过它是否也适用于diff,令人惊讶的是它开箱即用的效果非常好。

$ diff file1 file2 | bat$ diff -u file1 file2 | bat

所以我想你可以让下面这样的函数更高效:

function bdiff ()  diff -u $@ | bat;

【讨论】:

【参考方案10】:

在 debian 9 中测试 diff -u --color=always file1 file2

【讨论】:

【参考方案11】:

另一种选择是从存储库外部执行此操作,以便 git 知道文件之间的差异。例如。一个 shell 函数,例如:

gdiff() 
    (
        dir=`pwd`
        cd ./$(git rev-parse --show-cdup)/..
        git diff  $dir/$1 $dir/$2
    )

【讨论】:

【参考方案12】:

使用colordiff:

安装:

sudo apt-get install colordiff

用法:

colordiff -u file_one file_two

给出与git diff 所示完全相同的差异。

【讨论】:

【参考方案13】:

如果没有colordiffgit diff,可以通过vim获取颜色。

cdiff()  diff -u $@ | vim -R -; 

或者干脆

cdiff()  diff -u $@ | view -; 

【讨论】:

【参考方案14】:

添加

alias diff="git diff --no-index --"

到 ~/.zshrc 或 ~/.bashrc

这使用 git diff 来做两个文件之间的普通差异

【讨论】:

【参考方案15】:

我认为配置设置:

[color]
     ui = true

结合“diff”命令的--relative=&lt;path&gt; 选项可以满足您的需求。你试过了吗?

【讨论】:

这是git 中的差异。他要求diff 程序选项

以上是关于如何让 diff 像 git-diff 一样工作?的主要内容,如果未能解决你的问题,请参考以下文章

git-diff 忽略 ^M

在 git-diff 的输出中着色空白

在提交之间使用 git-diff 忽略 *all* 空格更改

Git内部原理之深入解析环境变量

如何从 git diff 读取输出?

如何从 git diff 读取输出?