Git Diff mit Zeilennummern (Git Log mit Zeilennummern)

92

Wie erhalte ich bei a git diffoder a git log -pdie Zeilennummern der Quelldatei (en), die in die Ausgabe eingebettet sind?

Ich habe versucht, es man git-diff | grep "line numbers"nachzuschlagen und habe versucht zu googeln, aber nichts schnell bekommen.

Drew LeSueur
quelle

Antworten:

89

Sie können keine für Menschen lesbaren Zeilennummern erhalten git diff

Derzeit gibt es keine Optionen, um Zeilennummern vertikal nebeneinander anzuzeigen git diff.

Unified-Diff-Format

Diese Informationen sind in den (c) Hunk-Headern für jede Änderung im Diff verfügbar, sie sind jedoch nur im Unified-Diff-Format :

@@ -start,count +start,count @@

Der ursprüngliche Status der Datei wird mit -und der neue Status mit dargestellt +(dies bedeutet nicht, dass der Hunk-Header hinzugefügt und gelöscht wird. Stellt startdie Startzeilennummer jeder Version der Datei dar und gibt an count, wie viele Zeilen enthalten sind ab dem Startpunkt.

Beispiel

diff --git a/osx/.gitconfig b/osx/.gitconfig
index 4fd8f04..fcd220c 100644
--- a/osx/.gitconfig
+++ b/osx/.gitconfig
@@ -11,7 +11,7 @@ <== HERE!
 [color "branch"]
        upstream = cyan
 [color "diff"]
-       meta = yellow
+       meta = cyan
        plain = white dim
        old = red bold
        new = green bold

Der Hunk-Header

@@ -11,7 +11,7 @@

sagt, dass die vorherige Version der Datei in Zeile 11 beginnt und 7 Zeilen enthält:

11  [color "branch"]
12         upstream = cyan
13  [color "diff"]
14 -       meta = yellow
14 +       meta = cyan
15         plain = white dim
16         old = red bold
17         new = green bold

Die nächste Version der Datei beginnt ebenfalls in Zeile 11 und enthält ebenfalls 7 Zeilen.

Das Unified-Diff-Format ist nicht wirklich für den menschlichen Verzehr bestimmt

Wie Sie wahrscheinlich sehen können, macht es das Unified-Diff-Format nicht einfach, Zeilennummern herauszufinden (zumindest, wenn Sie keine Maschine sind). Wenn Sie wirklich Zeilennummern möchten, die Sie lesen können, müssen Sie ein unterschiedliches Werkzeug verwenden, das sie für Sie anzeigt.

Zusätzliche Lektüre

Khalid
quelle
3
Hier ist ein Grep, um nur Zeilennummern in geänderten Dateien zu extrahieren, z. B. um einen Checkstyle-Bericht zu filterngit diff --unified=0 | grep -Po '^\+\+\+ ./\K.*|^@@ -[0-9]+(,[0-9]+)? \+\K[0-9]+(,[0-9]+)?(?= @@)'
Jakub Bochenski
1
@ JakubBochenskis Kommentar hat mein Problem ganz gut gelöst.
0xbe5077ed
Dies ist nur dann wirklich nützlich, wenn Sie --unified=0oder angeben -U0.
Caw
Ich bin gerade fertig git diffn, ein Drop-In-Ersatz (Wrapper), für git diffden Zeilennummern angezeigt werden und der mit allen Verwendungsmöglichkeiten und Optionen kompatibel ist git diff: stackoverflow.com/questions/24455377/…
Gabriel Staples
22

Hier sind zwei weitere Lösungen, die den Code von Andy Talkowski erweitern.

Klartext:

  git diff | gawk 'match($0,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
   /^(---|\+\+\+|[^-+ ])/{print;next};\
   {line=substr($0,2)};\
   /^-/{print "-" left++ ":" line;next};\
   /^[+]/{print "+" right++ ":" line;next};\
   {print "(" left++ "," right++ "):"line}'

Farbiger Text, vorausgesetzt \033[66mdas Format für Farbcodes:

  git diff --color=always | \
    gawk '{bare=$0;gsub("\033[[][0-9]*m","",bare)};\
      match(bare,"^@@ -([0-9]+),[0-9]+ [+]([0-9]+),[0-9]+ @@",a){left=a[1];right=a[2];next};\
      bare ~ /^(---|\+\+\+|[^-+ ])/{print;next};\
      {line=gensub("^(\033[[][0-9]*m)?(.)","\\2\\1",1,$0)};\
      bare~/^-/{print "-"left++ ":" line;next};\
      bare~/^[+]/{print "+"right++ ":" line;next};\
      {print "("left++","right++"):"line;next}'

Der Code ändert Zeilen , die mit Start -und +auf -1:-und +1:+sind, und Zeilen , die mit nichts anfangen zu (5,6):. Die Nummern sind die Zeilennummern aus der jeweiligen Datei.

PFudd
quelle
Ich stelle fest, dass die Ausrichtung (Einrückung) des Codes unterbrochen wird, während native git diffdie Ausrichtung sorgfältig beibehält. Dieser Code ist momentan über meinem Kopf. Wären Sie also bereit, ihn zu beheben? Mit anderen Worten, wenn in einer Zeile +240:+und in der nächsten Zeile steht (241,257):, müssen Sie der oberen Zeile einige zusätzliche Leerzeichen hinzufügen, damit der Code die richtige Ausrichtung und Einrückung mit dem Code aus der unteren Zeile beibehält. Vielleicht könnte dies leicht mit Druck gemacht werden?
Gabriel Staples
... ich meine mit printf.
Gabriel Staples
Keine Ursache; Ich habe es verstanden! Ich bin gerade fertig geworden git diffn. Siehe hier: stackoverflow.com/a/61997003/4561887 . Danke @PFudd, für deine Antwort. Ich habe es studiert und zum Lernen verwendet, dann von vorne angefangen und geschrieben git diffn. Einmal formatiert, damit ich Ihren Code lesen konnte (danke @EdMorton), konnte ich einige großartige Dinge daraus lernen, die mir geholfen haben.
Gabriel Staples
6

Hier ist ein Skript, das versucht, dies zu beheben - es wurde nicht im Zorn getestet, aber es scheint in Ordnung zu sein. Es basiert auf den Datensätzen, die git diff erstellt, und verwendet awk, um die Zeilenanzahl aufrechtzuerhalten.

# Massage the @@ counts so they are usable
function prep1() {
   cat | awk -F',' 'BEGIN { convert = 0; }
       /^@@ / { convert=1; }
       /^/  { if ( convert == 1 ) { print $1,$2,$3;
              } else { print $0;
              }
              convert=0;
             }'
}

# Extract all new changes added with the line count
function prep2() {
  cat | awk 'BEGIN { display=0; line=0; left=0; out=1;}
     /^@@ / { out=0; inc=0; line=$4; line--; display=line; left=line;        }
     /^[-]/   { left++; display=left; inc=0; }
     /^[+]/   { line++; display=line; inc=0; }
     /^[-+][-+][-+] / { out=0; inc=0; }
     /^/    { 
               line += inc;
               left += inc;
               display += inc;
               if ( out == 1 ) {
                   print display,$0;
               } else {
                   print $0;
               }
               out = 1;
               inc = 1;
               display = line;
            }'
} 

git diff $1 | prep1 | prep2 
Andy Talkowski
quelle
4

Sie können git difftoolden Diff mit einem externen Editor ausführen, der Zeilennummern anzeigt. So geht's mit vim / vimdiff:

  1. Setze vimdiff als Git's Difftool:

    git config --global diff.tool vimdiff
    
  2. Konfigurieren Sie ~/.vimrc, dass Zeilennummern bei Verwendung von vimdiff automatisch angezeigt werden:

    if &diff
        set number
    endif
    
  3. Führen Sie git difftool aus, das vimdiff mit Zeilennummern verwendet:

    git difftool
    
wisbucky
quelle
Indem ich nur git difftool mache, öffnet es für mich das tkdiff-Tool, das selbst die Zeilennummernfunktion hat. Danke wisbucky
Richardd
3

Ein schneller Weg ist zu bedienen git diff -U0. Dadurch werden die Kontextzeilen auf 0 gesetzt, wodurch die @ @ -Werte mit den tatsächlich geänderten Zeilen übereinstimmen. Standardmäßig enthalten die @@ -Werte 3 Zeilen Vorher / Nachher-Kontext, was für Menschen nicht geeignet ist.

Beispiel:

git diff # default
@@ -10,8 +10,8 @@

Dies ist schwierig, die Zeilennummern der geänderten Zeilen zu berechnen, da sich Zeile 10 auf die erste Zeile des vorherigen Kontexts bezieht. Die tatsächliche Zeilennummer der ersten geänderten Zeile beträgt 10 + 3 = 13. Um die Anzahl der geänderten Zeilen zu berechnen, müssen Sie auch den Vorher- und Nachher-Kontext subtrahieren: 8-3-3 = 2.

git diff -U0
@@ -13,2 +13,2 @@

Wie Sie sehen können, erleichtert das Setzen von context = 0 das Lesen der @@ -Werte für Menschen. Sie können sehen, dass die geänderten Zeilen bei Zeile 13 beginnen und es 2 geänderte Zeilen gibt.

Dies ist nicht perfekt, da nur die Zeilennummer für jeden Block angezeigt wird. Wenn Sie Zeilennummern für jede Zeile anzeigen möchten, verwenden Sie difftool für einen externen Editor. Siehe https://stackoverflow.com/a/50049752

wisbucky
quelle
3

Ich benutze es gerne git difftoolmit meld als Difftool. Es ist einfacher zu betrachten als git diff, hat einen schönen Side-by-Side-GUI-Vergleich und zeigt Zeilennummern auf jeder Seite.

Konfiguration:

  1. Anweisungen zum Einrichten von meld als Difftool für Windows oder Linux

Beispiel-Screenshot:

Geben Sie hier die Bildbeschreibung ein

Update 24. Mai 2020:

Ich habe gerade git diffnin den letzten Tagen geschrieben, um ein Ersatz für git diffdie Kommandozeile zu sein. Versuch es einmal. Siehe meine andere Antwort hier .

Gabriel Staples
quelle
2

Ab dem 24. Mai 2020 können Sie jetzt das Drittanbieter-Tool git diffn(vollständige Offenlegung: Ich habe es geschrieben) für diesen Zweck verwenden. Es ist ein leichter Wrapper git diff, der in der awkmuster- / aktionsbasierten Programmiersprache geschrieben ist. Hier ist eine Beispielausgabe von running git diffn:

Geben Sie hier die Bildbeschreibung ein

Hier ist eine Demo:

1/3: Demo von git diffn:

Erstellen Sie diese Datei:

hello_world.c:

#include <stdio.h>

int main()
{
    printf("Hello World\n");

    return 0;
}

Verpflichte es:

git add hello_world.c
git commit -m "add hello_world.c"

Ändern Sie es in dieses und speichern Sie die Datei:

hello_world.c:

// Basic hello world example

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello Gabriel\n");
    
    int i = 700;
    printf("i = %i\n", i);
    return 0;
}

Führen Sie jetzt aus:

git diff

Hier ist die Ausgabe von git difffirst zu Vergleichszwecken:

$ git diff
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+// Basic hello world example
+
 #include <stdio.h>
 
-int main()
+int main(int argc, char *argv[])
 {
-    printf("Hello World\n");
-
+    printf("Hello Gabriel\n");
+    
+    int i = 700;
+    printf("i = %i\n", i);
     return 0;
-}
\ No newline at end of file
+}

Und ein Screenshot, um die Farbe zu zeigen. Beachten Sie, dass der rot hervorgehobene Bereich lediglich leere Leerzeichen (in diesem Fall Leerzeichen) anzeigt, die gelöscht werden könnten:

Geben Sie hier die Bildbeschreibung ein

Hier ist die Ausgabe von git diffn. Beachten Sie, dass alle Zeilennummern perfekt angezeigt werden!

  • Die Zeilennummern für gelöschte Zeilen befinden sich links und zeigen -links und rechts ein Zeichen :, damit Sie besser sehen können - unabhängig davon, ob Ihre Augen rechts vom Doppelpunkt oder ganz unten scannen möchten links vom Bildschirm.
  • Die Zeilennummern für hinzugefügte Zeilen befinden sich weiter rechts und zeigen ein +Zeichen sowohl ganz links als auch rechts von :.
  • Zeilennummern für unveränderte Zeilen , die für den Kontext angezeigt werden, werden sowohl für die linke (alte Datei) als auch für die rechte (neue Datei) angezeigt, getrennt durch a ,.

Ausgabe von git diffn:

$ git diffn
diff --git a/hello_world.c b/hello_world.c
index e01704a..e971b73 100644
--- a/hello_world.c
+++ b/hello_world.c
@@ -1,8 +1,12 @@
+        1:+// Basic hello world example
+        2:+
    1,   3: #include <stdio.h>
    2,   4: 
-   3     :-int main()
+        5:+int main(int argc, char *argv[])
    4,   6: {
-   5     :-    printf("Hello World\n");
-   6     :-
+        7:+    printf("Hello Gabriel\n");
+        8:+    
+        9:+    int i = 700;
+       10:+    printf("i = %i\n", i);
    7,  11:     return 0;
-   8     :-}
\ No newline at end of file
+       12:+}

Und ein Screenshot, um die Farbe zu zeigen. Beachten Sie, dass die Doppelpunkte NICHT farbig oder stilisiert sind, um mit dem umgebenden Text links und rechts übereinzustimmen. Dies ist ein beabsichtigtes und entworfenes Verhalten, das als visuelles Trennzeichen zwischen den links hinzugefügten Zeilennummern und der ursprünglichen git diffAusgabe rechts fungiert.

Geben Sie hier die Bildbeschreibung ein

2/3: Was ist das?

Von obengit-diffn.sh :

BESCHREIBUNG:

git-diffn.sh

  1. ein Ersatz, für git diffden auch Zeile 'n'Nummern angezeigt werden! Verwenden Sie es genau so git diff, außer dass Sie auch diese schönen Zeilennummern sehen, damit Sie Ihre Änderungen besser verstehen.

  2. Da es sich nur um einen leichten, auf awk-Sprache basierenden Wrapper handelt git diff, werden ALLE Optionen und Parameter git diffakzeptiert , die akzeptiert werden. Beispiele:

  3. git diffn HEAD~

  4. git diffn HEAD~3..HEAD~2

  5. funktioniert mit jeder Ihrer git diffFarbeinstellungen, auch wenn Sie benutzerdefinierte Farben verwenden

  6. In meiner Antwort hier erfahren Sie, wie Sie benutzerdefinierte Diff-Farben festlegen und einen Screenshot der Ausgabe von benutzerdefinierten Farben anzeigen von git diffn: Wie passen Sie die Farbe des Diff-Headers in Git Diff an?

  7. Hier sind einige Beispielbefehle git configaus meiner obigen Antwort zum Festlegen benutzerdefinierter git diffFarben und Attribute (Textformatierung):

       git config --global color.diff.meta "blue"
       git config --global color.diff.old "black red strike"
       git config --global color.diff.new "black green italic"
       git config --global color.diff.context "yellow bold"
    
  8. in git diffnist die Farbausgabe standardmäßig eingeschaltet; Wenn Sie die Ausgabefarbe deaktivieren möchten, müssen Sie --no-coloroder verwenden --color=never. Siehe man git difffür Details. Beispiele:

     git diffn --color=never HEAD~
     git diffn --no-color HEAD~3..HEAD~2
    

3/3: Installation

  1. Windows (nicht getestet): Dies funktioniert möglicherweise im Bash-Terminal, das mit Git für Windows geliefert wird, ist jedoch nicht getestet. Installieren Sie Git für Windows. Öffnen Sie das mitgelieferte Bash-Terminal und befolgen Sie die nachstehenden Anweisungen. Ich brauche einige Tester, die dies in Git für Windows testen. Bitte sehen und beantworten Sie hier: https://github.com/git-for-windows/git/issues/2635 .
  2. Mac (ungetestet): Verwenden Sie das Terminal und befolgen Sie die nachstehenden Anweisungen. Möglicherweise müssen Sie installieren gawk. Wenn ja, versuchen Sie Folgendes : brew install gawk.
  3. Linux (unter Ubuntu 18.04 getestet und funktioniert einwandfrei): Befolgen Sie die nachstehenden Anweisungen für das Terminal.

Option 1 (meine Empfehlung): Laden Sie das gesamte Repo herunter und erstellen Sie dann einen Symlink zum Programm, damit Sie jederzeit Updates erhalten können, indem Sie eine git pullvom Repo ausführen.

Erstens, cdwohin Sie dies installieren möchten. Dann renne:

git clone https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.git
cd eRCaGuy_dotfiles/useful_scripts
mkdir -p ~/bin
ln -si "${PWD}/git-diffn.sh" ~/bin/git-diffn

Getan! Jetzt mach einfach den letzten Schritt unten!

Option 2 (für diejenigen, die nur die 1-Datei möchten): Laden Sie nur die eine Datei einmal herunter.

mkdir -p ~/bin
cd ~/bin
wget https://raw.githubusercontent.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles/master/useful_scripts/git-diffn.sh
chmod +x git-diffn.sh
mv git-diffn.sh git-diffn

Getan! Jetzt mach einfach den letzten Schritt unten!

Letzter Schritt:

Schließen Sie nun Ihr Terminal und öffnen Sie es erneut oder geben Sie es erneut ein . ~/.bashrc, und Sie sind fertig!

git diffnfunktioniert jetzt als exakter Drop-In-Ersatz für git diff!

Gabriel Staples
quelle
1

Du kannst es versuchen

git blame

auf der Datei. Es zeigt Ihnen den Committer, die Commit-ID und die Zeilennummer für jede Zeile in der Datei.

Juan
quelle
4
Das Problem dabei ist, dass es Ihnen keinen Unterschied zeigt , was das Originalplakat verlangte. git blamezeigt nur den aktuellen Status der Datei mit Zeilennummern an.
5
Ich wusste von Git-Schuld, aber jemand, der googelt, hat es vielleicht nicht. Es könnte jemandem helfen. Danke für die Antwort.
Drew LeSueur
git blamebeantwortet in keiner Weise die Frage; Ich bin ziemlich verblüfft über die positiven Stimmen hier
Michael Mrozek
Bitte spammen Sie den Stackoverflow nicht mit Antworten, die nicht mit den Fragen zusammenhängen.
Ahmed
0

Konfigurieren Sie zuerst Ihr Git Diff-Tool, z. B. Meld

git config --global diff.tool meld

Dann ziehen Sie Ihr Difftool an einer Datei:

git difftool -y config.rb

Denken Sie daran, die Zeilennummer in den Einstellungen Ihres Diff-Tools festzulegen.

HaxtraZ
quelle