Wenn ich in Git ein Ahnen-Commit-Objekt anführe, verwechsle ich zwischen HEAD^
und HEAD~
.
Beide haben eine "nummerierte" Version wie HEAD^3
und HEAD~2
.
Sie scheinen mir sehr ähnlich oder gleich zu sein, aber gibt es Unterschiede zwischen der Tilde und dem Caret?
Antworten:
Faustregeln
~
meiste Zeit - um eine Reihe von Generationen zurück zu gehen, normalerweise was Sie wollen^
Zusammenführungs-Commits verwenden - weil sie zwei oder mehr (unmittelbare) Eltern habenMnemonik:
~
fast linear aus und möchte in einer geraden Linie rückwärts gehen^
schlägt ein interessantes Segment eines Baumes oder einer Weggabelung vorTilde
Der Abschnitt "Festlegen von Revisionen" in der
git rev-parse
Dokumentation definiert~
alsSie können Eltern von jedem Commit erreichen, nicht nur
HEAD
. Sie können auch über Generationen zurückgehen: Diesmaster~2
bedeutet beispielsweise, dass der Großelternteil der Spitze des Hauptzweigs den ersten Elternteil bei Zusammenführungs-Commits bevorzugt.Caret
Der Git-Verlauf ist nichtlinear: ein gerichteter azyklischer Graph (DAG) oder Baum. Für ein Commit mit nur einem Elternteil
rev~
undrev^
bedeuten dasselbe. Der Caret-Selektor wird bei Merge-Commits nützlich, da jeder das Kind von zwei oder mehr Elternteilen ist - und die aus der Biologie entliehene Sprache belastet.HEAD^
bedeutet das erste unmittelbare Elternteil der Spitze des aktuellen Zweigs.HEAD^
ist die Abkürzung fürHEAD^1
, und Sie können auch adressierenHEAD^2
und so weiter nach Bedarf. Der gleiche Abschnitt dergit rev-parse
Dokumentation definiert es alsBeispiele
Diese Spezifizierer oder Selektoren können beliebig verkettet werden, z. B. ist
topic~3^2
in Englisch das zweite übergeordnete Element des Zusammenführungs-Commits das Urgroßelternteil (vor drei Generationen) der aktuellen Spitze des Zweigstopic
.Der oben erwähnte Abschnitt der
git rev-parse
Dokumentation zeichnet viele Pfade durch eine fiktive Git-Geschichte nach. Die Zeit fließt im Allgemeinen nach unten. Commits D, F, B und A sind Merge-Commits.Führen Sie den folgenden Code aus, um ein Git-Repository zu erstellen, dessen Verlauf mit der angegebenen Abbildung übereinstimmt.
Sie fügt hinzu , Aliase in der neuen Wegwerf - Repo nur für
git lol
undgit lola
schauen Sie sich die Geschichte sehen können , wie inBeachten Sie, dass sich die SHA-1-Objektnamen auf Ihrem Computer von den oben genannten unterscheiden. Mit den Tags können Sie jedoch Commits nach Namen adressieren und Ihr Verständnis überprüfen.
Die „Spezifikation von Revisionen“ in der
git rev-parse
Dokumentation enthält viele nützliche Informationen und ist eine eingehende Lektüre wert. Siehe auch Git Tools - Revisionsauswahl aus dem Buch Pro Git .Reihenfolge der übergeordneten Commits
Das Commit 89e4fcb0dd aus dem eigenen Verlauf von git ist ein Merge-Commit, wie
git show 89e4fcb0dd
in der Kopfzeile Merge angegeben, in der die Objektnamen der unmittelbaren Vorfahren angezeigt werden.Wir können die Bestellung bestätigen, indem wir darum bitten
git rev-parse
, die unmittelbaren Eltern von 89e4fcb0dd nacheinander anzuzeigen.Das Abfragen des nicht vorhandenen vierten übergeordneten Elements führt zu einem Fehler.
Wenn Sie nur die Eltern extrahieren möchten, verwenden Sie ein hübsches Format
%P
für die vollständigen Hashesoder
%p
für abgekürzte Eltern.quelle
^^^^^^^
anstatt~7
, oder ? Deshalb~
ist nützlichDer Unterschied zwischen
HEAD^
undHEAD~
wird durch die Abbildung (von Jon Loeliger) auf http://www.kernel.org/pub/software/scm/git/docs/git-rev-parse.html gut beschrieben .Diese Dokumentation kann für Anfänger etwas dunkel sein, daher habe ich die folgende Abbildung wiedergegeben:
quelle
F = A^2^
.^ == ^1 == LEFTMOST PARENT
,^2 == SECOND LEFTMOST PARENT
und so weiter. Und~ == ~1 == LEFTMOST PARENT
,~2 == LEFTMOST PARENTS LEFTMOST PARENT == LEFTMOST GRANDPARENT
. Im weiteren~2^2 == LEFTMOST GRANDPARENTS SECOND LEFTMOST PARENT
Beide
~
und^
für sich beziehen sich auf das übergeordnete Element des Commits (~~
und^^
beide beziehen sich auf das Commit der Großeltern usw.). Sie unterscheiden sich jedoch in ihrer Bedeutung, wenn sie mit Zahlen verwendet werden:~2
bedeutet zwei Ebenen in der Hierarchie über das erste übergeordnete Element, wenn ein Commit mehr als ein übergeordnetes Element hat^2
bedeutet das zweite übergeordnete Element, bei dem ein Commit mehr als ein übergeordnetes Element hat (dh weil es sich um eine Zusammenführung handelt).Diese können kombiniert werden, so dass
HEAD~2^3
MittelHEAD
‚s Großeltern verpflichten dritt Eltern zu begehen.quelle
^^
war das gleiche wie^2
aber es ist nicht.Meine zwei Cent...
quelle
H=A~2^2
nichtH=A~2^1
?A
,B
,D
,G
sind auf dem gleichen Zweig und der CommitD
ist eine ZusammenführungG
undH
daher mit zwei Eltern. Das commit (H
) aus einem anderen Zweig wird also von referenziert^2
.Hier ist eine sehr gute Erklärung, die wörtlich von http://www.paulboxley.com/blog/2011/06/git-caret-and-tilde stammt :
quelle
Mit dem
^<n>
Format können Sie das n-te übergeordnete Element des Commits auswählen (relevant für Zusammenführungen). Mit diesem~<n>
Format können Sie das n-te Vorgänger-Commit auswählen, immer nach dem ersten übergeordneten Element. Siehe git-rev-parse ‚s Dokumentation für einige Beispiele.quelle
Es ist erwähnenswert, dass git auch eine Syntax zum Verfolgen von "von wo Sie gekommen sind" / "von jetzt zurück wollen" hat - zum Beispiel
HEAD@{1}
verweist es auf den Ort, von dem aus Sie zu einem neuen Festschreibungsort gesprungen sind.Grundsätzlich
HEAD@{}
erfassen Variablen den Verlauf der HEAD-Bewegung, und Sie können sich für die Verwendung eines bestimmten Kopfes entscheiden, indem Sie mit dem Befehl die Reflogs von Git untersuchengit reflog
.Beispiel:
Ein Beispiel könnte sein, dass ich lokale Commits a-> b-> c-> d ausgeführt habe und dann 2 Commits verworfen habe, um meinen Code zu überprüfen -
git reset HEAD~2
- und danach möchte ich meinen HEAD wieder auf d - verschiebengit reset HEAD@{1}
.quelle
Einfach ausgedrückt :
~
gibt Vorfahren an^
gibt Eltern anSie können beim Zusammenführen einen oder mehrere Zweige angeben. Dann hat ein Commit zwei oder mehr Eltern und ist dann
^
nützlich, um Eltern anzuzeigen.Angenommen , Sie sind auf dem Zweig A und Sie haben zwei weitere Filialen: B und C .
In jedem Zweig sind die drei letzten Commits:
Wenn Sie jetzt in Zweig A den folgenden Befehl ausführen:
dann kombinieren Sie drei Zweige miteinander (hier hat Ihr Zusammenführungs- Commit drei Eltern)
und
~
gibt den n-ten Vorfahren im ersten Zweig an, alsoHEAD~
zeigt A3 anHEAD~2
zeigt A2 anHEAD~3
zeigt A1 an^
gibt den n-ten Elternteil an, alsoHEAD^
zeigt A3 anHEAD^2
zeigt B3 anHEAD^3
zeigt C3 anDie nächste Verwendung von
~
oder^
nebeneinander erfolgt im Kontext des durch vorherige Zeichen festgelegten Commits.Hinweis 1 :
HEAD~3
ist immer gleich:HEAD~~~
und zu:HEAD^^^
(jedes zeigt A1 an ),und allgemein :
HEAD~n
ist immer gleich:HEAD~...~
( n- mal~
) und:HEAD^...^
( n- mal^
).Hinweis 2 :
HEAD^3
ist nicht dasselbe wieHEAD^^^
(das erste zeigt C3 an und das zweite zeigt A1 an ),und allgemein :
HEAD^1
ist das gleiche wieHEAD^
,HEAD^n
ist immer nicht dasselbe wieHEAD^...^
( n- mal~
).quelle
TLDR
~ ist das, was Sie die meiste Zeit wollen, es verweist auf vergangene Commits auf den aktuellen Zweig
^ verweist auf Eltern (git-merge erstellt einen zweiten Elternteil oder mehr)
A ~ ist immer dasselbe wie A ^
A ~~ ist immer dasselbe wie A ^^, und so weiter ist
A ~ 2 jedoch nicht dasselbe wie A ^ 2,
da ~ 2 eine Abkürzung für ~~ ist,
während ^ 2 dies nicht ist Abkürzung für alles, es bedeutet das 2. Elternteil
quelle
HEAD ^^^ ist dasselbe wie HEAD ~ 3, wobei das dritte Commit vor HEAD ausgewählt wird
HEAD ^ 2 gibt den zweiten Kopf in einem Merge-Commit an
quelle
HEAD ~ gibt das erste übergeordnete Element in einem "Zweig" an.
Mit HEAD ^ können Sie ein bestimmtes übergeordnetes Element des Commits auswählen
Ein Beispiel:
Wenn Sie einem Seitenzweig folgen möchten, müssen Sie etwas wie angeben
quelle
aktuelles Beispiel für den Unterschied zwischen HEAD ~ und HEAD ^
quelle
Einfach ausgedrückt, für die erste Ebene der Abstammung (Abstammung, Vererbung, Abstammung usw.) zeigen HEAD ^ und HEAD ~ beide auf dasselbe Commit, das sich über dem HEAD (Commit) befindet.
Weiterhin ist HEAD ^ = HEAD ^ 1 = HEAD ~ = HEAD ~ 1. Aber HEAD ^^! = HEAD ^ 2! = HEAD ~ 2. Doch HEAD ^^ = HEAD ~ 2. Weiter lesen.
Über die erste Ebene der Abstammung hinaus werden die Dinge schwieriger, insbesondere wenn der Arbeitszweig / Hauptzweig Zusammenschlüsse hatte (von anderen Zweigen). Es gibt auch die Frage der Syntax mit dem Caret, HEAD ^^ = HEAD ~ 2 (sie sind gleichwertig) ABER HEAD ^^! = HEAD ^ 2 (sie sind zwei völlig verschiedene Dinge).
Jedes Caret bezieht sich auf das erste Elternteil des HEAD, weshalb Carets, die aneinandergereiht sind, Tilde-Ausdrücken entsprechen, da sie sich auf die ersten Eltern des ersten Elternteils (des ersten Elternteils) usw. usw. beziehen, die ausschließlich auf der Anzahl der verbundenen Carets basieren oder auf der Zahl nach der Tilde (so oder so bedeuten beide dasselbe), dh beim ersten Elternteil bleiben und x Generationen aufsteigen.
HEAD ~ 2 (oder HEAD ^^) bezieht sich auf das Commit, das zwei Abstammungsstufen über dem aktuellen Commit (HEAD) in der Hierarchie liegt, dh das Commit der Großeltern des HEAD.
HEAD ^ 2 bezieht sich dagegen NICHT auf das Commit des zweiten Elternteils des ersten Elternteils, sondern einfach auf das Commit des zweiten Elternteils. Dies liegt daran, dass das Caret das übergeordnete Element des Commits bedeutet und die folgende Nummer angibt, auf welches / welches übergeordnete Commit Bezug genommen wird (das erste übergeordnete Element, wenn dem Caret keine Nummer folgt [weil es eine Abkürzung für die Nummer ist 1 sein, was den ersten Elternteil bedeutet]). Im Gegensatz zum Caret impliziert die Zahl, die danach folgt, keine weitere Hierarchieebene nach oben, sondern impliziert, wie viele Ebenen seitwärts in der Hierarchie das richtige übergeordnete Element (Commit) gefunden werden muss. Im Gegensatz zur Zahl in einem Tilde-Ausdruck ist es nur ein Elternteil in der Hierarchie, unabhängig von der Zahl, mit der das Caret (sofort) ausgeführt wird. Anstatt nach oben, das Caret '
HEAD ^ 3 ist also gleich dem dritten Elternteil des HEAD-Commits (NICHT der Urgroßelternteil, wie HEAD ^^^ AND HEAD ~ 3 wäre ...).
quelle
~
das bedeutet Eltern.^
Wenn es Eltern von zwei oder mehr hat, wie z. B. Merge Commit, können wir den zweiten Elternteil oder einen anderen auswählen.Wenn also nur eines wie (HEAD ~ oder HEAD ^) ist, hat es die gleichen Ergebnisse.
quelle