Finden Sie anhand der Hashes heraus, ob ein Git-Commit vor oder nach einem anderen Commit eingecheckt wurde

Lesezeit: 5 Minuten

Benutzer-Avatar
Gleiten

Eine Sache, die ich bei der Verwendung von svn vermisse, war die einfache Nummerierung von Revisionsnummern. Ich kann leicht erkennen, ob die in der Testumgebung bereitgestellte Version vor oder nach einem bestimmten Commit liegt.

Wenn Git Hashes für seine Commits verwendet, wie kann man feststellen, ob ein Commit vor oder nach einem anderen Commit durchgeführt wurde?

Wie Sie bemerkt haben, sind die Dinge in Git nicht so einfach. Insbesondere die Definition von „vorher“ und „nachher“ bedarf einer weiteren Klärung.

Wenn Sie darauf vertrauen, dass die Leute, die sich in Ihr Repository einschreiben, nicht mit Zeitstempeln herumspielen, und Sie bereits wissen, dass sich beide Commits auf demselben Zweig befinden, können Sie die Zeitstempel der Commits vergleichen und einfach sehen, welcher früher ist. Verwenden Sie den folgenden Befehl für jeden Commit und vergleichen Sie das Ergebnis.

git log -1 --format="%ci" <commit>

Bei Git können Sie den Zeitstempeln jedoch nicht unbedingt vertrauen, da es im Gegensatz zu Subversion kein zentrales Repository gibt, das diese erstellen soll. Sie können auch nicht sicher sein, dass sich zwei Commits auf demselben Zweig befinden (obwohl dieses Problem auch bei Subversion besteht).

Um diese Probleme zu vermeiden, sprechen Sie darüber, ob ein Commit ein Vorfahre eines anderen ist, anstatt ob es davor oder danach kommt. Im folgenden Commit-Diagramm sind B und C Vorfahren von A, während B kein Vorfahr von C ist, noch umgekehrt:

B    (master)
| C  (branch)
|/
A    (root)

Um festzustellen, ob Commit A ein Vorfahre von Commit B ist, verwenden Sie den folgenden Befehl (basierend auf ein Artikel bei git bereit):

git rev-list <commitA> | grep $(git rev-parse <commitB>)

Der erste Teil listet alle Commits auf, die Vorfahren von Commit A sind; Der zweite Teil ruft den vollständigen Hash von Commit B ab und durchsucht dann die Ancestor-Liste nach diesem Commit. Wenn Sie eine Ausgabe sehen, ist Commit A ein Vorfahr von Commit B. Tauschen Sie die Argumente aus, um herauszufinden, ob Commit A stattdessen ein Vorfahr von Commit B ist.

Diese zweite Form ist langsamer, gibt Ihnen aber absolute Gewissheit, dass ein Commit ein Vorfahre eines anderen ist.

  • Was stellt also der Zeitstempel dar, wenn ich git log -1 –format=’%ci’ mache? Ich versuche nur, ein Szenario zu verstehen, in dem ich dem Zeitstempel nicht vertrauen kann.

    – Gleiten

    9. Januar 2013 um 21:49 Uhr


  • @Glide: Dieser Zeitstempel stellt die Zeit dar, zu der der Commit durchgeführt wurde. Da der Commit jedoch zunächst im lokalen Repository des Entwicklers durchgeführt wird, wenn die Uhr auf seinem Computer falsch ist oder er einen Trick wie das Spielen mit verwendet GIT_COMMITTER_DATEkönnte dieser Zeitstempel falsch sein.

    – ich und

    10. Januar 2013 um 11:33 Uhr

  • Hey, der Befehl funktioniert, aber was Sie darüber gesagt haben, wie es funktioniert, ist falsch. Der Befehl git rev-list bestimmt tatsächlich, ob Commit B ein Vorfahre von Commit A ist. Sie sagen: „Der erste Teil listet alle Commits auf, die Vorfahren von Commit A sind“. Was es anscheinend tut, nach einigen Tests, die ich gerade gemacht habe. Wenn Sie also diese Liste nach einem Commit-SHA durchsuchen, wird grep erfolgreich sein, wenn sich Commit B in dieser Ancestor-Liste befindet, dh ein Vorfahre von Commit A ist – das Gegenteil von dem, was Sie geschrieben haben.

    – eeeeaaii

    1. Mai 2017 um 19:51 Uhr


  • git rev-list <commitA> | grep <commitB> gibt 0 (wahr) zurück, wenn commitA nach B liegt, gibt 1 (falsch) zurück, wenn commitA vor B liegt. Dies liegt daran, dass git rev-list gibt alle “Vorfahren-Commits” von commitA zurück.

    – CMCDragonkai

    27. April 2018 um 3:25 Uhr

git merge-base hat dafür ein Flag. Es gibt einfach einen 0/1-Exit-Code zurück.

git merge-base --is-ancestor <commit> <commit>

  • Oder machen Sie eine Ebene merge-basewenn das Ergebnis einer der beiden Commits ist, der zuerst kam, oder es könnte ein dritter Commit sein, der sie zu Cousins ​​oder Geschwistern macht, oder es könnte nichts sein, in diesem Fall stammen sie aus nicht verwandten Geschichten.

    – jthill

    20. Dezember 2018 um 0:51 Uhr

git rev-list --count kann helfen. Angenommen 110a187 kommt 4 Commits davor 5d41af1dann:

 $ git rev-list --count 110a187..5d41af1
4
 $ git rev-list --count 5d41af1..110a187
0

Also sowas wie:

test $(git rev-list --count $a..$b) == 0 && \
       echo "$a is not an ancestor of $b"

  • Wenn @Glide eher Elternteil/Nachkomme als Zeit bedeutet, dann ist diese Antwort genauer in dem Fall, in dem die Commits über Zusammenführungen aus verschiedenen Zweigen in einen Zweig kamen.

    – Chrys Cheng

    28. August 2015 um 11:32 Uhr

Verwenden git show bei jedem Commit, um das Datum des Commit zu finden. Es gibt keine Möglichkeit, nur auf den Hash zu schauen, um die Reihenfolge zu bestimmen, da es nichts als ein Hash ist.

Sie können benutzerdefinierte Formatzeichenfolgen verwenden, um genau das anzuzeigen, was Sie möchten Manpages Für mehr Information.

git show --format="%ci" <commit>

Benutzer-Avatar
Michal

Sie können alle Commit-Informationen aus dem Protokoll abrufen, das den Hash, den Autor, das Datum und den Kommentar anzeigt:

git log

Sie können die Uhrzeit/das Datum eines bestimmten Commits aus dem Commit-Log abrufen. Etwas wie:

git log -1 --format="%cd" <commit>

Das ‘%cd’ gibt Ihnen das Datum im Protokollformat, Sie können auch Folgendes tun:

  • %cD: RFC2822-Stil
  • %cr: relativ
  • %ct: UNIX-Zeitstempel
  • %ci: ISO 8601-Format

Von dort aus könnten Sie einige Vergleiche mit Skripten durchführen, wenn Sie automatisieren müssen.

Benutzer-Avatar
petee

Mit all den von @me_and erwähnten Bemerkungen können Sie auch Folgendes versuchen:

git rev-list --no-walk commitA commitB

In der Ausgabe werden bereitgestellte Commits in umgekehrter chronologischer Reihenfolge nach Commit-Zeit angezeigt. Die Reihenfolge der bereitgestellten Commits spielt also keine Rolle (im Gegensatz zu der von @Douglas Bagnall vorgeschlagenen Idee).

Benutzer-Avatar
Zombo

Wenn Sie Tags verwenden, können Sie tun

git describe --tags

Dadurch erfahren Sie, wie viele Commits seit dem letzten Tag ausgeführt wurden.

1146200cookie-checkFinden Sie anhand der Hashes heraus, ob ein Git-Commit vor oder nach einem anderen Commit eingecheckt wurde

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy