[git] 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 명령을 사용하여 이러한 줄 번호 정보를 어떻게 얻을 수 있습니까?



답변

git diff --stat 내가 생각하기에 당신이 언급하는 것을 커밋 할 때 얻는 출력을 보여줄 것입니다.

git diff --stat

변경된 줄 번호를 정확하게 표시하려면 다음을 사용할 수 있습니다.

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

그리고 변경된 줄은 결과에서 끝 괄호 앞의 마지막 숫자가됩니다. 그래도 깨끗한 해결책은 아닙니다 🙁


답변

다음은 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);

다음과 같은 diff에서 :

$ 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에 전달 하여 추가 / 제거 된 행에 대한 일반적인 색상 코딩을 얻을 수 있습니다.

출력은 쉽게 그릴 수 있습니다.

$ 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.


답변

--unified=0옵션을 사용합니다 git diff.

예를 들어, git diff --unified=0 commit1 commit2diff를 출력합니다.

* 여기에 이미지 설명 입력 *

--unified=0옵션 때문에 diff 출력은 0 개의 컨텍스트 행을 표시합니다. 즉, 변경된 라인을 정확하게 보여줍니다 .

이제 ‘@@’로 시작하는 줄을 식별하고 패턴을 기반으로 구문 분석 할 수 있습니다.

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

위의 예로 돌아가서 WildcardBinding.java 파일의 경우 910 행에서 시작하면 0 행이 삭제됩니다. 911 번 줄부터 시작하여 4 줄이 추가됩니다.


답변

나는 이와 같은 문제가 있었기 때문에 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


답변

커밋되지 않은 모든 라인의 라인 번호 (추가 / 수정) :

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

출력 예 :

1
2
8
12
13
14


답변

줄 번호를 표시하는 외부 비교 도구를 구성하십시오. 예를 들어, 이것은 내 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


답변

다음은 내가 함께 만든 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