Gibt es in git eine Möglichkeit, ein Push-Datum für ein bestimmtes Commit zu erhalten?

90

Ich frage mich, ob es eine Möglichkeit gibt, ein Push-Datum für jedes Commit im Git-Protokoll anzuzeigen. Wenn dies nicht möglich ist, gibt es eine Möglichkeit, alle Commits unter einem bestimmten Push anzuzeigen.

Ich schreibe ein Programm, das die Commits verfolgen muss, wenn sie gepusht werden. Da das Git-Protokoll nach dem Festschreibungsdatum und nicht nach dem Push-Datum sortiert ist, kann ich die letzten übertragenen Commits nicht sehen. Wenn ein Benutzer beispielsweise 2 Tage vor dem Push an den Master ein Commit für sein lokales Repository durchführt, wird dieses Commit hinter 2 Tage anderer Commits im Master-Repository-Protokoll platziert.

justkikuchi
quelle

Antworten:

76

Ich habe wahnsinnig lange gebraucht, um verstreute Informationen zu sammeln und endlich die beste Antwort auf diese Frage zu finden, aber jetzt weiß ich, dass ich sie habe. In nur zwei Zeilen kein Code und keine Hooks:

# required for a bare repo
git config core.logAllRefUpdates true

git reflog --date=local master

Endlich einfach.

Warnung: Sie möchten wahrscheinlich die Standardwerte von gc.reflogExpireund überschreiben gc.reflogExpireUnreachable. Überprüfen Sie, ob git help reflogDetails vorliegen und wie und warum dies funktioniert.

Die beiden obigen Befehle müssen in dem Klon ausgeführt werden, auf den Sie drücken . Wenn dies nicht möglich ist, muss eine Annäherung in einem anderen permanenten Klon ausgeführt werden:

git fetch               origin        # often and *regularly*
git reflog --date=local origin/master

Löschen Sie niemals diesen permanenten Klon, sonst verlieren Sie die Daten.

März
quelle
2
Ich möchte hinzufügen, dass ich in meinem Fall tun musste git reflog --date=local origin/master(Notiz origin/), um die Liste der Pushs zu sehen. Ansonsten waren nur Commits, Checkout und Pulls in der Liste (was auch nützlich ist). Eigentlich wurde ich durch die Antwort von @ JonathanDay darauf hingewiesen .
NIA
@NIA: origin / master gibt dir nur eine Annäherung. Ich habe meine Antwort nach Ihrem Kommentar aktualisiert. Klärt dies?
MarcH
37

Git ist ein verteiltes Versionskontrollsystem, daher müssen Sie sorgfältig definieren, was Sie unter "Push-Datum" verstehen. Angenommen, Benutzer A überträgt einige Commits an das Repository von Benutzer B. Einige Zeit später überträgt Benutzer B dieselben Commits an ein drittes Repository. An welchem ​​Datum interessieren Sie sich?

Ich spekuliere, dass Sie ein freigegebenes Repository haben und möchten, dass die Benutzer dieses freigegebenen Repositorys feststellen können, wann etwas im Repository veröffentlicht wurde. Wenn dies zutrifft, müssen Sie diese Informationen im freigegebenen Repository sammeln.

Die schlechten Nachrichten

Leider gibt es keine Möglichkeit, das Datum an die Festschreibungsnachrichten anzuhängen. Dies würde die Festschreibungs-ID (die ein SHA1-Hash des Inhalts ist) ändern und alle möglichen Probleme verursachen.

Die guten Nachrichten

Glücklicherweise hat Git eine (relativ neue) Funktion namens Notizen . Mit dieser Funktion können Sie Commits beliebigen Text anhängen, der git logangezeigt werden kann. Notizen können bearbeitet und mit anderen geteilt werden.

Mit der Notizenfunktion können Sie jedem Commit die Nachricht "Dieses Commit wurde am [Datum] empfangen" hinzufügen, sobald es vom freigegebenen Repository empfangen wird.

Siehe git help notesfür Details.

So zeichnen Sie das Datum auf

Hier ist der Ansatz, den ich empfehle:

  1. Ändern Sie den post-receiveHook in Ihrem freigegebenen Repository, um jedes neu erreichbare Commit für jede aktualisierte Referenz zu durchlaufen.
  2. Fügen Sie für jedes Commit etwas wie "[Benutzer] von [repository_url] fügte dieses Commit zu [ref] am [Datum] hinzu" an die Notiz des Commits an.

    Möglicherweise möchten Sie refs/notes/received-onanstelle der Standardeinstellung eine Notizenreferenz verwenden, die diesem Zweck (wie ) gewidmet ist refs/notes/commits. Dies verhindert Konflikte mit Notizen, die für andere Zwecke erstellt wurden.

  3. Ändern Sie Ihren receiveHook, um Aktualisierungen Ihrer Notizenreferenz zu verweigern (damit Benutzer nicht versehentlich oder absichtlich mit den Notizen herumspielen).
  4. Bitten Sie alle Benutzer, die folgenden Befehle in ihrem Arbeitsbaum auszuführen:

    # Fetch all notes from the shared repository.
    # Assumes the shared repository remote is named 'origin'.
    git config --add remote.origin.fetch '+refs/notes/*:refs/remote-notes/origin/*'
    
    # Show all notes from the shared repository when running 'git log'
    git config --add notes.displayRef 'refs/remote-notes/origin/*'
    

    Dieser Schritt ist erforderlich, da Git standardmäßig nicht verzweigte Verweise ohne Tags in Upstream-Repositorys ignoriert.

Das oben Gesagte setzt voraus, dass Verweise nur erweitert, niemals gelöscht oder zwangsweise aktualisiert werden. Sie möchten wahrscheinlich, dass der post-receiveHook auch Notizen zum Entfernen am [Datum] anfügt, um diese Fälle zu behandeln.

Richard Hansen
quelle
Ich habe Ihre Idee in meinem Blog mnaoumov.wordpress.com/2013/01/31/git-get-push-date
mnaoumov
7
git reflog show origin/master --pretty='%h %gd %gs %s' --date=iso

Das scheint für mich ziemlich gut zu funktionieren. Das Committer-Datum (% cd) ist irreführend, da es nicht unbedingt mit dem Push-Datum übereinstimmt. Die Option --date = iso gibt jedoch das Push / Fetch-Datum aus .

Beachten Sie, dass beim Abrufen vom Ursprung / Master das Datum gedruckt wird, an dem Sie es abgerufen haben. NICHT das Datum, an dem jemand anderes das Commit gedrückt hat.

 - %h:  abrev. hash
 - %gd: human readable reflog selector
 - %gs: reflog subject
 - %s:  subject/commit message

Bonus: Sie können natürlich hübscher formatieren. Bisher gefällt mir diese Farbcodierung. Es ist allerdings ein bisschen viel zu tippen. Dadurch wird der SHA auf Rot, der Reflog-Selektor auf Cyan und der Reflog auf Grün gesetzt.

git reflog show origin/master --pretty='format:%C(red)%h%Creset %C(cyan)%gd%Creset %C(green)%gs%Creset: %s' --date=iso
VC
quelle
Hallo VC, bedeutet das, dass wenn die Ausgabe des Befehls "reflog show origin / master --pretty = '% Cred% h% Creset -% C (gelb)% gd% Creset% Cblue (% gs)% Creset% s' - -date = iso "ist" da4c192cd -origin / master @ {2019-02-07 08:13:40 +0100} (Pull: Schnellvorlauf) JIRA-2542 Testbericht verbessern ", bedeutet dann Inhalt meines Zweigs JIRA -2542 wurde am Origin / Master durch ein Fast-Froward am 2019-02-07 08:13:40 zusammengeführt?
Simon
Hallo Simon, ja. Sie haben einen Git-Pull an Ihrem Zweig durchgeführt und dieser wurde zu diesem Zeitpunkt über den Schnellvorlauf auf Origin / Master zusammengeführt.
VC
Es funktioniert nur im Repository des Autors. Wenn ich ein Repository klone, ist der Wert leer. Sie können die Push-Zeit anderer Leute nicht sehen.
Ramwin
6

Schau es dir an git reflog show master . Wahrscheinlich nicht das genaue Format, das Sie möchten, aber Sie sollten in die richtige Richtung weisen.

Eine andere Idee ist das Ausführen eines Skripts in einem Push-Hook.

Karl Bielefeldt
quelle
Ich dachte darüber nach, einen Schubhaken zu laufen, aber es scheint, dass dies eine letzte Anstrengung sein sollte. Mit einem Hook scheint es, als müsste jeder Benutzer diesen Hook in jedem seiner Repositorys haben. Können Sie das genauer beschreiben git reflog show master? Ich möchte das Push-Datum der einzelnen Commits jedes Benutzers anzeigen können.
Justkikuchi
git reflog zeigt die Reihenfolge der Änderungen in dem Repo, in dem Sie es ausführen. Ich bin mir nicht sicher, ob es einen direkten Weg gibt, um das Datum zu erhalten, aber .git/logs/refs/heads/masterdarin wird ein Zeitstempel angezeigt.
Karl Bielefeldt
3
Wie für Haken, dort erhalten Haken , die auf der Maschine laufen Sie drücken auf . Da Pushing nur in Bezug auf ein bestimmtes Repo relevant ist, gehe ich davon aus, dass Sie ein bestimmtes "gesegnetes" Repo haben, auf dem Sie es ausführen möchten. Gleiches gilt git reflogfür diese Angelegenheit.
Karl Bielefeldt
5

Diese Antwort bezüglich der Überprüfung des Reflogs auf der Fernbedienung kann hilfreich sein ( https://stackoverflow.com/a/8791295/336905 ), indem sie Ihnen Informationen darüber gibt, welcher Zweig durchgeschoben wurde, auch wenn er nicht anzeigt , welche Commits übertragen wurden, aber Sie könnte sich gegenseitig korrelieren, indem der nächste Push nach dem lokalen Festschreibungsdatum gefunden wird. Nicht narrensicher, aber praktisch, wenn Sie den ausgezeichneten Notizenvorschlag von @RichardHansen, der zuvor veröffentlicht wurde, noch nicht implementiert haben

Jonathan Day
quelle
1
Mit einem Hinweis, dass beim Reflog von origin/branchnur die auf dem aktuellen Computer vorgenommenen Änderungen angezeigt werden , ist dies äußerst nützlich! Für den täglichen Gebrauch möchte ich keine Hooks implementieren, also für eine einfache Frage: "Hmmm, als ich das Commit letzte Woche gepusht habe?" - Es funktioniert großartig.
NIA
4

Sie können auch die Änderungszeit der Datei für die Festschreibungsobjektdatei im Verzeichnis "Objekte" im Git-Repository auf dem Server selbst anzeigen.

Reich
quelle
2

Warum unterscheidet sich git AuthorDate von CommitDate?

  • AuthorDate Dies ist der Zeitpunkt, an dem das Commit zum ersten Mal erstellt wurde.
  • CommitDate Dies ist der Zeitpunkt, an dem das Commit zuletzt geändert wurde (z. B. Rebase).

Sie können diese mit den --prettyFormatierungsoptionen erhalten:

       o    %cd: committer date
       o    %cD: committer date, RFC2822 style
       o    %cr: committer date, relative
       o    %ct: committer date, UNIX timestamp
       o    %ci: committer date, ISO 8601 format

Also, wenn Sie und andere Entwickler tun werden , git rebasebevor git push, werden Sie mit einem Ende begehen Zeitpunkt , der später als der ist Autor Datum .

Dieser Befehl zeigt das Festschreibungsdatum an: git log --pretty=fuller

dnozay
quelle
1

Ich denke, Sie können die nächste Notation verwenden, um das Push-Datum zu erhalten: git log -g --date = local

Pashh PGH
quelle