1

我从Using git diff 中找到了一个很好的 shell 函数diff-lines() ,如何获得添加和修改的行号?

我在我的文件中添加了函数.bashrc,它在我的命令行中工作:

[marslo@mppdev ~/Tools/Git/LinuxStuff]
$ git diff -U0 | diff-lines
Scripts/.marslorc:29:-# Inspired from https://stackoverflow.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers
Scripts/.marslorc:29:+# Inspired from https://stackoverflow.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers/12179492#12179492

但是,当我尝试将命令添加为 git 别名时,这里出了点问题:

[marslo@mppdev ~/Tools/Git/LinuxStuff]
$ cat ~/.gitconfig | grep "ldiff ="
    ldiff = "!bash -c 'git diff -U0' | diff-lines"
[marslo@mppdev ~/Tools/Git/LinuxStuff]
$ git ldiff
sh: diff-lines: command not found
fatal: Failed to run 'bash -c 'git diff -U0' | diff-lines' when expanding alias 'ldiff'

而且,bash -c 'git diff -U0' | diff-lines仍然有效

[marslo@mppdev ~/Tools/Git/LinuxStuff]
$ bash -c 'git diff -U0' | diff-lines
Scripts/.marslorc:29:-# Inspired from https://stackoverflow.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers
Scripts/.marslorc:29:+# Inspired from https://stackoverflow.com/questions/8259851/using-git-diff-how-can-i-get-added-and-modified-lines-numbers/12179492#12179492

这里有详细信息: 低密度脂蛋白

4

2 回答 2

2

问题是这diff-lines是一个 shell 函数,而不是一个实际的可执行文件。当您运行时,"!bash -c 'git diff -U0' | diff-lines"您会收到一个错误,因为 shell 没有为您提供资源~/.bashrc,因此它不知道diff-lines. 这是 shell 的正常行为——它们只在特定情况下获取这些设置,而运行命令不是其中之一。

所以这里有一些建议。首先,如果行号功能在 git 之外很好,请考虑将 diff-lines 制作为脚本,而不仅仅是一个 shell 函数:

#!/bin/bash

diff-lines() {
    local path=
    local line=
    while read; do
        esc=$'\033'
        if [[ $REPLY =~ ---\ (a/)?.* ]]; then
            continue
        elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then
            path=${BASH_REMATCH[2]}
        elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then
            line=${BASH_REMATCH[2]}
        elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then
            echo "$path:$line:$REPLY"
            if [[ ${BASH_REMATCH[2]} != - ]]; then
                ((line++))
            fi
        fi
    done
}

diff-lines

然后,您可以将别名设置为:

ldiff = !sh -c 'git diff "$@" | diff-lines' -

这也将允许您将参数传递给git ldiff,就像真正的 diff 命令一样。您还可以diff-lines通过在您的 中执行以下操作来用作您的寻呼机~/.gitconfig

[pager]
    diff = diff-lines | less

然后,常规git diff命令将通过您的diff-lines脚本传递,最后通过 less 来获取分页。我使用相同的技巧来突出显示行中的单词变化。

另一种选择是亚当提到的:创建一个名为git-ldiff运行您的 diff 命令并通过 diff-lines 管道它的脚本

#!/bin/bash

diff-lines() {
    local path=
    local line=
    while read; do
        esc=$'\033'
        if [[ $REPLY =~ ---\ (a/)?.* ]]; then
            continue
        elif [[ $REPLY =~ \+\+\+\ (b/)?([^[:blank:]$esc]+).* ]]; then
            path=${BASH_REMATCH[2]}
        elif [[ $REPLY =~ @@\ -[0-9]+(,[0-9]+)?\ \+([0-9]+)(,[0-9]+)?\ @@.* ]]; then
            line=${BASH_REMATCH[2]}
        elif [[ $REPLY =~ ^($esc\[[0-9;]+m)*([\ +-]) ]]; then
            echo "$path:$line:$REPLY"
            if [[ ${BASH_REMATCH[2]} != - ]]; then
                ((line++))
            fi
        fi
    done
}

git diff "$@" | diff-lines

注意:这与上面的脚本完全相同,只是对最后一行进行了少量修改。

于 2013-11-07T13:43:54.937 回答
1

而不是使用别名:

  1. 将您的代码放入脚本中,
  2. 命名脚本git-ldiff
  3. 用于使其可执行,并且chmod +x script
  4. 将脚本放在 PATH 中的目录中。

现在,当你输入 时git ldiff,git 会找到并运行你的 scipt。

于 2013-11-07T12:37:11.167 回答