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.


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


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.


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

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.


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(-)

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

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


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


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.