web-dev-qa-db-ja.com

git diffを使用して、行番号を追加および変更するにはどうすればよいですか?

テキストファイルがあると仮定します

alex
bob
matrix
will be removed
git repo

そして私はそれを更新しました

alex
new line here
another new line
bob
matrix
git

ここで、行番号(2,3)を追加し、行番号(6)を更新しました

Git diffまたは他のgitコマンドを使用してこれらの行番号情報を取得するにはどうすればよいですか?

71
Mahmoud Khaled

git diff --statは、私が推測しているものをコミットするときに得られる出力を表示します。

git diff --stat

変更された行番号を正確に表示するには、使用できます

git blame -p <file> | grep "Not Committed Yet"

そして、変更された行は、結果の終了括弧の前の最後の番号になります。しかし、きれいな解決策ではありません:(

65
Sedrik

Diffから結果の行番号を計算する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
http-fetch.c:1: #include "cache.h"
http-fetch.c:2: #include "walker.h"
http-fetch.c:3: 
http-fetch.c:4:-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
http-fetch.c:4:+int main(int argc, const char **argv)
http-fetch.c:5: {
http-fetch.c:6:+       const char *prefix;
http-fetch.c:7:        struct walker *walker;
http-fetch.c:8:        int commits_on_stdin = 0;
http-fetch.c:9:        int commits;
http-fetch.c:19:        int get_verbosely = 0;
http-fetch.c:20:        int get_recover = 0;
http-fetch.c:21: 
http-fetch.c:22:+       prefix = setup_git_directory();
http-fetch.c:23:+
http-fetch.c:24:        git_config(git_default_config, NULL);
http-fetch.c:25: 
http-fetch.c:26:        while (arg < argc && argv[arg][0] == '-') {
fetch.h:1: #include "config.h"
fetch.h:2: #include "http.h"
fetch.h:3: 
fetch.h:4:-int cmd_http_fetch(int argc, const char **argv, const char *prefix);
fetch.h:4:+int main(int argc, const char **argv);
fetch.h:5: 
fetch.h:6: void start_fetch(const char* uri);
fetch.h:7: bool fetch_succeeded(int status_code);

このような差分から:

$ git diff
diff --git a/builtin-http-fetch.c b/http-fetch.c
similarity index 95%
rename from builtin-http-fetch.c
rename to http-fetch.c
index f3e63d7..e8f44ba 100644
--- a/builtin-http-fetch.c
+++ b/http-fetch.c
@@ -1,8 +1,9 @@
 #include "cache.h"
 #include "walker.h"

-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
+int main(int argc, const char **argv)
 {
+       const char *prefix;
        struct walker *walker;
        int commits_on_stdin = 0;
        int commits;
@@ -18,6 +19,8 @@ int cmd_http_fetch(int argc, const char **argv, const char *prefix)
        int get_verbosely = 0;
        int get_recover = 0;

+       prefix = setup_git_directory();
+
        git_config(git_default_config, NULL);

        while (arg < argc && argv[arg][0] == '-') {
diff --git a/fetch.h b/fetch.h
index 5fd3e65..d43e0ca 100644
--- a/fetch.h
+++ b/fetch.h
@@ -1,7 +1,7 @@
 #include "config.h"
 #include "http.h"

-int cmd_http_fetch(int argc, const char **argv, const char *prefix);
+int main(int argc, const char **argv);

 void start_fetch(const char* uri);
 bool fetch_succeeded(int status_code);

周囲のコンテキストではなく、追加/削除/変更された行のみを表示する場合は、-U0 git diffへ:

$ git diff -U0 | diff-lines
http-fetch.c:4:-int cmd_http_fetch(int argc, const char **argv, const char *prefix)
http-fetch.c:4:+int main(int argc, const char **argv)
http-fetch.c:6:+       const char *prefix;
http-fetch.c:22:+       prefix = setup_git_directory();
http-fetch.c:23:+
fetch.h:4:-int cmd_http_fetch(int argc, const char **argv, const char *prefix);
fetch.h:4:+int main(int argc, const char **argv);

ANSIカラーコードに対して堅牢であるため、--color=always git diffに追加して、追加/削除された行の通常の色分けを取得します。

出力は簡単にgrepできます:

$ git diff -U0 | diff-lines | grep 'main'
http-fetch.c:4:+int main(int argc, const char **argv)
fetch.h:4:+int main(int argc, const char **argv);

あなたの場合git diff -U0は以下を与えます:

$ git diff -U0 | diff-lines
test.txt:2:+new line here
test.txt:3:+another new line
test.txt:6:-will be removed
test.txt:6:-git repo
test.txt:6:+git

行番号だけが必要な場合は、echo "$path:$line:$REPLY"だけecho "$line"と出力をuniqにパイプします。

27
John Mellor

--unified=0git diffオプションを使用します。

たとえば、git diff --unified=0 commit1 commit2は差分を出力します。

*enter image description here*

--unified=0オプションのため、diff出力には0コンテキスト行が表示されます。つまり、正確に変更された行を示しています。

これで、「@@」で始まる行を識別し、パターンに基づいて解析できます。

@@ -startline1,count1 +startline2,count2 @@

上記の例に戻って、ファイルWildcardBinding.Javaの場合、行910から開始して、0行が削除されます。 911行目から始まり、4行追加されます。

16
Ida

同じ問題があったので、git diffの出力を変更して各行の行番号を追加するgawkスクリプトを作成しました。作業ツリーを比較する必要がある場合に役立つことがありますが、それに限定されません。たぶんそれはここの誰かに役立つでしょうか?

$ git diff HEAD~1 |showlinenum.awk
diff --git a/doc.txt b/doc.txt
index fae6176..6ca8c26 100644
--- a/doc.txt
+++ b/doc.txt
@@ -1,3 +1,3 @@
1: red
2: blue
 :-green
3:+yellow

ここからダウンロードできます:
https://github.com/jay/showlinenum

6
Jay

コミットされていないすべての行の行番号(追加/変更):

git blame <file> | grep -n '^0\{8\} ' | cut -f1 -d:

出力例:

1
2
8
12
13
14
3
Rich

行番号を表示する外部差分ツールを構成します。たとえば、これは私のgitグローバル設定にあるものです:

diff.guitool=kdiff3
difftool.kdiff3.path=c:/Program Files (x86)/KDiff3/kdiff3.exe
difftool.kdiff3.cmd="c:/Program Files (x86)/KDiff3/kdiff3.exe" "$LOCAL" "$REMOTE"

詳細については、この回答を参照してください: https://stackoverflow.com/q/949242/526535

2
manojlds

これは、一緒にまとめたbash関数です。

echo ${f}:
for n in $(git --no-pager blame --line-porcelain $1 |
        awk '/author Not Committed Yet/{if (a && a !~ /author Not Committed Yet/) print a} {a=$0}' |
        awk '{print $3}') ; do
    if (( prev_line > -1 )) ; then
        if (( "$n" > (prev_line + 1) )) ; then
            if (( (prev_line - range_start) > 1 )) ; then
                echo -n "$range_start-$prev_line,"
            else
                echo -n "$range_start,$prev_line,"
            fi
            range_start=$n
        fi
    else
        range_start=$n
    fi
    prev_line=$n
done
if (( "$range_start" != "$prev_line" )) ; then
    echo "$range_start-$prev_line"
else
    echo "$range_start"
fi

そして、最終的には次のようになります。

views.py:
403,404,533-538,546-548,550-552,554-559,565-567,580-582
1
forivall

git diffshortstatパラメーターと組み合わせて使用​​すると、変更されたno of行のみを表示できます。

最後のコミット以降に変更された行数(既にリポジトリにあるファイル内)

git diff HEAD --shortstat

次のようなものが出力されます

1 file changed, 4 insertions(+)
1
shahalpk

これはおそらく、変更された行のかなり正確なカウントです。

git diff --Word-diff <commit> |egrep '(?:\[-)|(?:\{\+)' |wc -l

また、diffの行番号の解決策は次のとおりです。 https://github.com/jay/showlinenum

0
Jay Carroll

まさにあなたが求めていたものではありませんが、git blame TEXTFILEが役立つ場合があります。

0
u-punkt