Diff只改变了部分线条

时间:2014-09-02 09:39:09

标签: git bash diff

是否可以使用git diff

仅显示旧行和新行之间的差异

以下是文件a.txt的内容:

  

123456789

这是文件b.txt的内容

  

123455789

这是正常git diff输出:

normal output

这就是我想要完成的事情: wanted output

我更喜欢使用git diff执行此操作,但如果无法完成,我可以使用任何其他应用。

1 个答案:

答案 0 :(得分:14)

这是git diff--word-diff选项。虽然默认情况下没有达到该级别的粒度。

要获得像这样的单字符差异,也需要自定义--word-diff-regex。 (我在这里的git别名中有'([^[:alnum:]]|[^[:space:]])',但这似乎是这样做的。虽然这不是我编写时的重点。)

顺便说一下,您也可以将--word-diff=color --word-diff-regex='...'缩写为--color-words='...'

查看this是否符合您的要求:

$ cat worddiff.awk
BEGIN {
    RS="\n?~\n"
    FS="\n"
}

# Special case the diff header/chunk header lines.
/^diff --git/ {
    print
    next
}

{
    delete outs
    for (i=1; i<=NF; i++) {
        if ($i ~ /^[-+]/) {
            mode = substr($i, 1, 1)
            $i = ((mode=="-")?red:green) substr($i, 2) reset
            outs[mode] = outs[mode] $i reset
            outs["set" mode]++
        } else {
            gsub(/^ /, "", $i)
            outs["-"] = outs["-"] $i
            outs["+"] = outs["+"] $i
        }
    }

    # If we didn't have any changes then this is a context line and we need to
    # print it out.
    if (!outs["set-"] && !outs["set+"]) {
        print " " outs["-"]
        next
    }

    if (outs["set-"]) {
        print red "-" reset outs["-"]
    }

    if (outs["set+"]) {
        print green "+" reset outs["+"]
    }
}

用作:

git diff --word-diff=porcelain | awk -v red="$(tput setaf 1)" -v green="$(tput setaf 2)" -v reset="$(tput sgr0)" -f worddiff.awk

git diff --word-diff-regex='([^[:alnum:]]|[^[:space:]])' --word-diff=porcelain | awk -v red="$(tput setaf 1)" -v green="$(tput setaf 2)" -v reset="$(tput sgr0)" -f worddiff.awk

awk可能更干净,并且有一个非GNU awk split成语来清除一个我无法在delete a出现问题时无法回忆的数组。

编辑:更新了上面的代码,以匹配gist的最新版本。最初的特殊情况模式过于宽松。原始代码未正确处理添加的空行。更新后的代码并不是最好的,但我认为在--word-diff=porcelain {{1}} known limitations的情况下我可以做到最好。