So rufen Sie das letzte Änderungsdatum aller Dateien in einem Git-Repository ab

64

Ich kann das letzte Änderungsdatum einer einzelnen Datei in einem Git-Repository abrufen:

git log -1 --format="%ad" -- path/to/file

Gibt es eine einfache und effiziente Möglichkeit, dasselbe für alle derzeit im Repository vorhandenen Dateien zu tun?

Eric Bréchemier
quelle

Antworten:

74

Eine einfache Antwort wäre, durch jede Datei zu iterieren und ihre Änderungszeit anzuzeigen, dh:

git ls-tree -r --name-only HEAD | while read filename; do
  echo "$(git log -1 --format="%ad" -- $filename) $filename"
done

Dies ergibt eine Ausgabe wie folgt:

Fri Dec 23 19:01:01 2011 +0000 Config
Fri Dec 23 19:01:01 2011 +0000 Makefile

Natürlich können Sie dies steuern, da es sich an dieser Stelle nur um ein Bash-Skript handelt. Sie können es also nach Herzenslust anpassen!

Andrew M.
quelle
2
Ich hatte gehofft, dass es eine Option gibt, eine kombinierte Ausgabe in einem einzigen Durchlauf des Git-Protokolls zu erhalten, aber Ihre Antwort ist besser als die, die ich mit find im Sinn hatte. Ich kannte git-ls-tree nicht, was den Vorteil hat, nur die im Repository gespeicherten Dateien aufzulisten, den .git-Ordner zu überspringen und die Dateien zu ignorieren. Vielen Dank.
Eric Bréchemier
Kein Problem, Eric. Sie folgen der gleichen Route wie ich - dh Sie suchen und ignorieren das .git-Verzeichnis! :) Es kann einige Optionen geben, die die git-Installationsbefehle verwenden, aber ehrlich gesagt funktioniert dies ziemlich gut. Wenn Sie eine Möglichkeit finden könnten, die Informationen auf Dateibasis auf einmal abzurufen, funktioniert dies am besten. Denken Sie jedoch daran, dass git den Status von Commits verwendet und nicht den Status einzelner Dateien.
Andrew M.
11
Ich empfehle die Verwendung von --format = "% ai", wenn Sie sortierbare Zeitstempel anstelle von lesbaren Datumsangaben wünschen.
ThorSummoner
2
Da "HEAD" nur eine Referenz ist, können Sie jede gewünschte Referenz verwenden, sei es ein Tag, ein Zweig, ein Commit-Hash usw.
Andrew M.
1
Verwenden Sie, wie @ThorSummoner sagte, das% ai-Format für das Datum und führen Sie dann eine Pipe aus, um die Ergebnisse zu sortieren:git ls-tree -r --name-only HEAD | while read filename; do echo "$(git log -1 --format="%ai" -- $filename) $filename"; done | sort
John Hunt,
21

Dieser Ansatz funktioniert auch mit Dateinamen, die Leerzeichen enthalten:

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {}

Beispielausgabe:

2015-11-03 10:51:16 -0500 .gitignore
2016-03-30 11:50:05 -0400 .htaccess
2015-02-18 12:20:26 -0500 .travis.yml
2016-04-29 09:19:24 +0800 2016-01-13-Atlanta.md
2016-04-29 09:29:10 +0800 2016-03-03-Elmherst.md
2016-04-29 09:41:20 +0800 2016-03-03-Milford.md
2016-04-29 08:15:19 +0800 2016-03-06-Clayton.md
2016-04-29 01:20:01 +0800 2016-03-14-Richmond.md
2016-04-29 09:49:06 +0800 3/8/2016-Clayton.md
2015-08-26 16:19:56 -0400 404.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-bradycardia-algorithm.htm
2015-12-23 17:03:51 -0500 _algorithms/acls-pulseless-arrest-algorithm-asystole.htm
2016-04-11 15:00:42 -0400 _algorithms/acls-pulseless-arrest-algorithm-pea.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-secondary-survey.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-suspected-stroke-algorithm.htm
2016-03-31 11:54:19 -0400 _algorithms/acls-tachycardia-algorithm-stable.htm
...

Die Ausgabe kann nach Änderungszeitstempel sortiert werden, indem | sortam Ende Folgendes hinzugefügt wird :

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {} | sort
William Entriken
quelle
Gibt es eine Möglichkeit, dies nach Änderungszeitstempel zu sortieren?
Amelio Vazquez-Reina
1
@ AmelioVazquez-Reina: Füge einfach `| hinzu bis zum Ende des Befehls sortieren.
Dotancohen
2
Dies funktioniert, dauert aber noch lange ...
Guillochon
5

Dies ist eine kleine Änderung von Andrew M.'s Antwort. (Ich konnte seine Antwort nicht kommentieren.)

Setzen Sie den ersten Dateinamen in doppelte Anführungszeichen , um Dateinamen mit eingebetteten Leerzeichen zu unterstützen.

git ls-tree -r --name-only HEAD | while read filename; do
    echo "$(git log -1 --format="%ad" -- "$filename") $filename"
done

Beispielausgabe:

Tue Jun 21 11:38:43 2016 -0600 subdir/this is a filename with spaces.txt

Ich schätze, dass Andrews Lösung (basierend auf ls-tree ) mit nackten Repositorys funktioniert! (Dies gilt nicht für Lösungen mit ls-Dateien.)

Kevin G.
quelle
Sie können das Echo auch überspringen: git log -1 --format = "% ad $ filename"
Kevin Lyda
0

Hier ist die Fischmuschel-Version von Andrew Ms Antwort für diejenigen, die Fisch verwenden.

git ls-tree -r --name-only HEAD | while read -l filename
    printf '%s %s\n' (git log -1 --format="%ai" -- $filename) $filename
end

Ich speichere dies als Fischfunktion für den einfachen Zugriff.

Kevin Cherepski
quelle
0

Für diejenigen von uns, die Windows und PowerShell verwenden, die Antwort von Andrew M mit dem computerlesbaren Tweak:

git ls-tree -r --name-only HEAD | ForEach-Object { "$(git log -1 --format="%ai" -- "$_")`t$_" }

Beispielausgabe:

2019-05-07 12:00:37 -0500   .editorconfig
2016-07-13 14:03:49 -0500   .gitattributes
2019-05-07 12:00:37 -0500   .gitignore
2018-02-03 22:01:17 -0600   .mailmap
James Skemp
quelle