Finden Sie anhand der Hashes heraus, ob ein Git-Commit vor oder nach einem anderen Commit eingecheckt wurde
Lesezeit: 5 Minuten
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):
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:
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>
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.
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).
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.
11462000cookie-checkFinden Sie anhand der Hashes heraus, ob ein Git-Commit vor oder nach einem anderen Commit eingecheckt wurdeyes