Wie kann ich die Anzahl der Zeilen berechnen, die zwischen zwei Commits in Git geändert wurden?

748

Gibt es eine einfache Möglichkeit, die Anzahl der Zeilen zu berechnen, die zwischen zwei Commits in Git geändert wurden?

Ich weiß, dass ich a machen git diffund die Zeilen zählen kann, aber das scheint langweilig. Ich würde auch gerne wissen, wie ich das machen kann, einschließlich nur meiner eigenen Commits in den Linecounts.

Mike
quelle
3
Sie sehen sich BitBucket an.
Alex78191

Antworten:

1114

Sie möchten die --statOption git diffoder, wenn Sie dies in einem Skript analysieren möchten , die --numstatOption.

git diff --stat <commit-ish> <commit-ish>

--statErzeugt die für Menschen lesbare Ausgabe, die Sie nach dem Zusammenführen gewohnt sind. --numstaterzeugt ein schönes Tabellenlayout, das Skripte leicht interpretieren können.

Ich habe irgendwie übersehen, dass Sie dies bei mehreren Commits gleichzeitig tun wollten - das ist eine Aufgabe für git log. Ron DeVera geht darauf ein, aber Sie können tatsächlich viel mehr tun, als er erwähnt. Da git logdie Diff-Maschinerie intern aufgerufen wird, um die angeforderten Informationen zu drucken, können Sie ihr eine der Diff-Stat-Optionen geben - nicht nur --shortstat. Was Sie wahrscheinlich verwenden möchten, ist:

git log --author="Your name" --stat <commit1>..<commit2>

aber du kannst --numstatoder --shortstatauch verwenden. git logSie können Commits auch auf verschiedene andere Arten auswählen - sehen Sie sich die Dokumentation an . Möglicherweise interessieren Sie sich für Dinge wie --since(anstatt Festschreibungsbereiche anzugeben, wählen Sie einfach Festschreibungen seit letzter Woche aus) und --no-merges(Festschreibungsübertragungen führen keine Änderungen ein) sowie für die hübschen Ausgabeoptionen ( --pretty=oneline, short, medium, full...).

Hier ist ein Einzeiler, um Gesamtänderungen anstelle von Änderungen pro Festschreibung aus dem Git-Protokoll zu erhalten (ändern Sie die Auswahloptionen für die Festschreibung wie gewünscht - dies wird von Ihnen festgeschrieben, von Festschreibung1 zu Festschreibung2):

git log --numstat --pretty="%H" --author="Your Name" commit1..commit2 | awk 'NF==3 {plus+=$1; minus+=$2} END {printf("+%d, -%d\n", plus, minus)}'

(Sie müssen das Git-Protokoll einige identifizierende Informationen über das Commit drucken lassen. Ich habe den Hash willkürlich ausgewählt und dann mit awk nur die Zeilen mit drei Feldern ausgewählt, die die stat-Informationen enthalten.)

Cascabel
quelle
2
Dies beantwortet nicht die ursprüngliche Frage zu "geänderten Zeilen". Eine Zeilenänderung wird sowohl als eingefügte als auch als gelöschte Zeile berechnet. Die Berechnung der Anzahl geänderter Zeilen erfordert mehr Arbeit als hier beschrieben.
Ville Laitila
12
@VilleLaitila: Dies ist so nah wie möglich ohne absurden Aufwand und es war gut genug für das OP und 15 andere. (Wie definieren Sie, wann eine geänderte Zeile zu einer hinzugefügten und einer gelöschten Zeile wird? Durch Bearbeiten des Abstands zwischen der Zeile - und + als Bruchteil der Zeilenlänge?) Wir alle wissen, dass Änderungen verdoppelt werden. Wir können das einfach als nützliche Metrik für das Ausmaß der Veränderung bezeichnen und mit unserem Leben weitermachen.
Cascabel
188
git diff --shortstat <commit1> <commit2>war derjenige, den ich wollte.
Kim
9
Als Referenz für das Datumsformat --sinceund --untilist so etwas wie: yesterday, 1 month 2 weeks 3 days 1 hour 1 second ago, oder1979-02-26 18:30:00
juanmirocks
4
@Bryson Ja, deshalb heißt <commit-ish>es in dieser Zeile: Sie funktioniert mit allem, was ein Commit darstellt, einschließlich wörtlicher Commits, Zweige, Tags und Refs im Allgemeinen. Siehe auch stackoverflow.com/questions/23303549/…
Cascabel
193

Für die Faulen verwenden git log --stat.

Thomas
quelle
14
Ich fand das nützlich und fügte ein hinzu -10, um die vorherigen zehn Commits anzuzeigen.
Choylton B. Higginbottom
2
Wenn Sie mit dem Anzeigen des Commit-Verlaufs fertig sind, geben Sie Folgendes ein, Qum zum Terminal zurückzukehren.
Stevoisiak
180
git diff --shortstat

gibt Ihnen nur die Anzahl der Zeilen, die geändert und hinzugefügt wurden. Dies funktioniert nur bei nicht bereitgestellten Änderungen. So vergleichen Sie mit einem Zweig:

git diff --shortstat some-branch
Orkoden
quelle
3
Cool! aber .. beachten Sie, dass dies nur mit nicht bereitgestellten Änderungen
funktioniert
3
Wenn Sie Änderungen mit inszeniert haben git add, stellen Sie sicher, dass Sie dies tungit diff --shortstat --cached
TomNash
2463 Dateien geändert, 39745 Einfügungen (+), 21383 Löschungen (-) Ich habe im letzten Monat tatsächlich etwa 5.000 bis 10.000 gelöscht. Es ist fast alles, was ich getan habe, außer Dinge zu bewegen. Irgendwas stimmt nicht. Es enthält keine entfernten Dateien oder so?
jgmjgm
46
git diff --stat commit1 commit2

BEARBEITEN: Sie müssen auch die Commits angeben (ohne Parameter wird das Arbeitsverzeichnis mit dem Index verglichen). Z.B

git diff --stat HEAD^ HEAD

um die Eltern von HEADmit zu vergleichen HEAD.

Matthew Flaschen
quelle
1
Es gibt nie wirklich eine Notwendigkeit zu verwenden diff-index- das diffFrontend kann alles handhaben; Ich glaube, der Fall von diff-indexwird von der abgedeckt --cached/--staged. (Und es gibt keine Möglichkeit, diff-indexzwei willkürliche Commits zu vergleichen, wie vom OP verlangt.)
Cascabel
Die Ausgabe davon ist nichts für mich.
Mike
@ Mike: Hast du ein Karat weggelassen? War Ihr letztes Commit ein Merge-Commit? Wenn Git sagt, dass es keinen Unterschied gibt, dann deshalb, weil es keinen Unterschied gibt.
Cascabel
6
oder wenn nicht git diff --stat HEAD
festgeschrieben
1
Sie können auch weiter zurück vergleichen als nur das übergeordnete Element HEAD~n, indem nSie angeben, wie weit Sie zurückgehen möchten. git diff --stat HEAD~5 HEADzeigt kombinierte Statistiken für die letzten 5 Commits in Bezug auf HEAD an.
Nathan Beck
18

Angenommen, Sie möchten alle Ihre Commits zwischen abcd123 (dem ersten Commit) und wxyz789 (dem letzten Commit) vergleichen, einschließlich:

git log wxyz789^..abcd123 --oneline --shortstat --author="Mike Surname"

Dies ergibt eine prägnante Ausgabe wie:

abcd123 Made things better
 3 files changed, 14 insertions(+), 159 deletions(-)
wxyz789 Made things more betterer
 26 files changed, 53 insertions(+), 58 deletions(-)
Ron DeVera
quelle
Die Ausgabe davon ist nichts für mich (ich habe Commits gemacht und überprüft - der Autor ist korrekt, indem er sie mit dem Git-Protokoll und ohne andere Argumente verwendet).
Mike
Das ist mir auch passiert. Die beiden Commits waren in der falschen Reihenfolge und wurden durch Vertauschen behoben.
Bob Esponja
1
Die Festschreibungsreihenfolge wurde aktualisiert und klargestellt, was die beiden SHAs darstellen. Danke, dass
du
3
Die --shortstatFlagge ist fantastisch, sie funktioniert git diffjedoch (nicht git log).
Glück 84
Wie fasse ich sie zusammen?
Bis zum
13

Eine andere Möglichkeit, alle Änderungsprotokolle in einem bestimmten Zeitraum abzurufen

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10"

Ausgabe:

2637cc736 Revert changed code
 1 file changed, 5 insertions(+), 5 deletions(-)
ba8d29402 Fix review
 2 files changed, 4 insertions(+), 11 deletions(-)

Mit einem langen Ausgabeinhalt können Sie zur besseren Lesbarkeit in eine Datei exportieren

git log --author="Tri Nguyen" --oneline --shortstat --before="2017-03-20" --after="2017-03-10" > /mnt/MyChangeLog.txt
nmtri
quelle
2

Obwohl alle oben genannten Antworten korrekt sind, ist die folgende nützlich, wenn Sie die Anzahl der letzten Commits benötigen

Unter eins wird die Anzahl der letzten 5 Commits angezeigt

git diff $(git log -5 --pretty=format:"%h" | tail -1) --shortstat

um die letzten 10 Commits zu zählen

git diff $(git log -10 --pretty=format:"%h" | tail -1) --shortstat

generisch - Ändern Sie N mit der Anzahl der letzten Commits, die Sie benötigen

git diff $(git log -N --pretty=format:"%h" | tail -1) --shortstat

um alle Commits seit dem Start zu zählen

git diff $(git log --pretty=format:"%h" | tail -1) --shortstat


quelle
Dies ergibt, dass "'tail' nicht als interner oder externer Befehl, bedienbares Programm oder Batch-Datei erkannt wird."
Charles Roddie
2

git log --numstat gibt Ihnen nur die Zahlen

Nibinbhaskar
quelle
1

Ich habe dieses Problem nur für mich selbst gelöst, also werde ich mitteilen, was ich mir ausgedacht habe. Hier ist das Endergebnis:

> git summary --since=yesterday
total: 114 file changes, 13800 insertions(+) 638 deletions(-)

Der zugrunde liegende Befehl sieht folgendermaßen aus:

git log --numstat --format="" "$@" | awk '{files += 1}{ins += $1}{del += $2} END{print "total: "files" files, "ins" insertions(+) "del" deletions(-)"}'

Beachten Sie den $@Befehl im Protokoll, um Ihre Argumente wie --author="Brian"oder weiterzugeben --since=yesterday.

Es war chaotisch, dem awk zu entkommen, um es in einen Git-Alias ​​zu setzen. Stattdessen habe ich es in ein ausführbares Skript auf meinem Pfad ( ~/bin/git-stat-sum) eingefügt und dann das Skript im Alias ​​in meinem .gitconfig:

[alias]
    summary = !git-stat-sum \"$@\"

Und es funktioniert wirklich gut. Eine letzte Sache, die zu beachten ist, file changesist die Anzahl der Änderungen an Dateien, nicht die Anzahl der eindeutigen Dateien, die geändert wurden. Das habe ich gesucht, aber es ist möglicherweise nicht das, was Sie erwarten.

Hier ist ein weiteres Beispiel oder zwei

git summary --author=brian
git summary master..dev
# combine them as you like
git summary --author=brian master..dev
git summary --all

Wirklich, Sie sollten in der Lage sein, jeden git logBefehl durch zu ersetzen git summary.

nicht definiert
quelle