wake-up-neo.com

Wie kann ich mit git diff Zeilennummern hinzufügen und ändern?

Angenommen, ich habe eine Textdatei

alex
bob
matrix
will be removed
git repo

und ich habe es aktualisiert

alex
new line here
another new line
bob
matrix
git

Hier habe ich die Zeilennummer (2,3) und die aktualisierte Zeilennummer (6) hinzugefügt.

Wie kann ich diese Zeilennummern mit git diff oder einem anderen git-Befehl erhalten?

65
Mahmoud Khaled

git diff --stat zeigt Ihnen die Ausgabe an, die Sie erhalten, wenn Sie Sachen begehen, auf die Sie sich beziehen.

git diff --stat

Um genau die Zeilennummern anzuzeigen, die geändert wurden, können Sie verwenden

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

Die geänderte Zeile ist die letzte Zahl vor den schließenden Klammern im Ergebnis. Keine saubere Lösung :(

59
Sedrik

Hier ist eine Bash-Funktion, um die resultierenden Zeilennummern aus einem Diff zu berechnen:

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
}

Es kann folgende Ausgaben erzeugen:

$ 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);

von einem diff wie folgt:

$ 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);

Wenn Sie nur hinzugefügte/entfernte/modifizierte Zeilen und nicht den umgebenden Kontext anzeigen möchten, können Sie -U0 an git diff übergeben:

$ 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);

Es ist robust gegenüber ANSI-Farbcodes, sodass Sie --color=always an git diff übergeben können, um die üblichen Farbkodierungen für hinzugefügte/entfernte Zeilen zu erhalten.

Die Ausgabe kann einfach abgerufen werden:

$ 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);

In Ihrem Fall würde git diff -U0 folgendes ergeben:

$ 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

Wenn Sie nur die Zeilennummern wünschen, ändern Sie echo "$path:$line:$REPLY" in echo "$line" und leiten Sie die Ausgabe durch uniq.

26
John Mellor

Ich benutze die --unified=0-Option von git diff.

Zum Beispiel gibt git diff --unified=0 commit1 commit2 das diff aus:

*enter image description here*

Aufgrund der Option --unified=0 werden in der Diff-Ausgabe 0 Kontextzeilen angezeigt. mit anderen Worten, es zeigt genau die geänderten Zeilen .

Jetzt können Sie die Zeilen identifizieren, die mit '@@' beginnen, und sie anhand des Musters analysieren: 

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

Zurück zum obigen Beispiel: Beginnen Sie für die Datei WildcardBinding.Java ab Zeile 910: 0 Zeilen werden gelöscht. Ab Zeile 911 werden 4 Zeilen hinzugefügt.

15
Ida

Ich hatte das gleiche Problem, also schrieb ich ein gawk-Skript, das die Ausgabe von git diff ändert, um die Zeilennummer jeder Zeile voranzustellen. Ich finde es manchmal nützlich, wenn ich den Arbeitsbaum differenzieren muss, obwohl er nicht darauf beschränkt ist. Vielleicht ist es jemandem hier nützlich?

$ 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

Sie können es hier herunterladen:
https://github.com/jay/showlinenum

6
Jay

Zeilennummern aller nicht festgeschriebenen Zeilen (hinzugefügt/geändert):

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

Beispielausgabe:

1
2
8
12
13
14
3
Rich

Konfigurieren Sie ein externes Vergleichstool, das Ihnen die Zeilennummern anzeigt. Zum Beispiel habe ich dies in meiner git global config:

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"

Weitere Informationen finden Sie in dieser Antwort: https://stackoverflow.com/q/949242/526535

2
manojlds

Sie können git diff in Verbindung mit dem Parameter shortstat verwenden, um nur die geänderten Zeilen no von anzuzeigen. 

Die Anzahl der Zeilen wurde geändert (in einer Datei, die sich bereits im Repo befindet) seit Ihrem letzten Commit 

git diff HEAD --shortstat

Es wird etwas Ähnliches ausgegeben 

1 file changed, 4 insertions(+)
2
shahalpk

Hier ist eine bash-Funktion, die ich zusammengeschustert habe:

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

Und es sieht so aus:

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

Dies ist wahrscheinlich eine ziemlich genaue Anzahl geänderter Zeilen:

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

Hier ist auch eine Lösung für Zeilennummern in Ihrem diff: https://github.com/jay/showlinenum

0
Jay Carroll

Nicht genau das, wonach Sie gefragt haben, aber git blame TEXTFILE kann helfen.

0
u-punkt