Dies ist vielleicht eine einfache Frage (vielleicht schon einmal gestellt?), aber ich konnte keine Antwort finden (ich habe es wirklich versucht, ich bin nicht nur faul :)).
Ich arbeite an einem Git-Zweig, der auf einem anderen Zweig basiert. Allerdings weiß ich nicht, auf welchem Zweig es basiert.
Gibt es einen Befehl oder eine Möglichkeit herauszufinden, aus welchem Zweig mein aktueller Zweig stammt?
Ich habe versucht, in SourceTree und auch mit zu suchen git log --graph --all
aber irgendwie kann ich nicht wirklich herausfinden, woher der Zweig stammt.
Danke!
In Git gibt es eine solche Vorstellung überhaupt nicht.
Dies lässt sich vielleicht am besten anhand eines Beispiels erkennen. Betrachten Sie das folgende Commit-Diagrammfragment:
o <-- branchA
/
o--o--o
\
o--o <-- branchB
Hier „offensichtlich“ branchB
kommt von branchA
. Aber Moment, da ist noch mehr, da ist ein bisschen, das ich ausgelassen habe:
o <-- branchA
/
o--o--o--o <-- branchC
\
o--o <-- branchB
Nun, das tut es branchB
geht runter branchA
oder löst es sich branchC
?
Das Schwierigste daran ist, dass jeder dieser Zweige in erstellt werden kann beliebig Befehl;1 Darüber hinaus können die Beschriftungen – die Filialnamen – auch verschoben oder entfernt werden jederzeit.2 Also, wenn Sie sich dafür entscheiden branchB
basiert auf branchA
aber dann löscht jemand branchA
Alles in allem bleibt Ihnen Folgendes übrig:
o--o--o--o <-- branchC
\
o--o <-- branchB
und nun branchB
basiert eindeutig darauf branchC
nicht branchA
.
[Edit: if you want to identify the specific commit where two branches first “split apart”, use git merge-base
. Having found that commit, you can see what other branch names might also be interesting with git branch --contains
, and so on. The general rule here is that the commit graph is all you really have: labels like branch names are only good until you or someone else changes them later. Tag labels should generally stay where they are but even those can be moved, it’s just generally more of a pain.]
1Nun, fast alle: Die übergeordneten Commits eines neuen Commits müssen vorhanden sein, bevor Sie die untergeordneten Commits erstellen können, es sei denn, Sie haben eine Möglichkeit, den kryptografischen SHA-1-Hash zu knacken.
2Das Entfernen einer Bezeichnung bedeutet, dass die Commits, die man findet, indem man bei dieser Bezeichnung beginnt und in diesen Zeichnungen „rückwärts“ arbeitet (nach links und vielleicht nach oben oder unten, sowie solange man sich weiter nach links bewegt), „unerreichbar“ werden, es sei denn, sie sind nicht erreichbar. Sie werden gefunden, wenn Sie von einem anderen Label ausgehen. Nicht erreichbare Commits im Commit-Graph sind schließlich3 vollständig entfernt, aber normalerweise haben Sie etwa 30 Tage Zeit, um sie zurückzubekommen.
3Dies wird mit Gits „Reflogs“ erreicht. Jeder Reflog-Eintrag funktioniert wie ein normales Label, da er einen Commit „erreichbar“ macht und ihn daher behält. Tatsächlich sind die Reflog-Einträge abgelaufen.
Wenn git-gc(1) die Informationen nicht aktiviert und entfernt hat, erstellen Sie ein Shell-Skript in Ihrem $PATH und benennen Sie es git-fork-point
mit den folgenden:
#!/bin/sh
if [ $# -gt 0 ]
then
target="$1"
else
target=$(git branch|sed -ne 's,^\* ,,p')
fi
git reflog |sed -nE \
"s,^([a-f0-9]+).*: checkout: moving from ([^[:space:]]+) to ${target}\$,Forked on commit \1 from \2.,p" |tail -1
Es kann jetzt als Git-Fork-Point verwendet werden und verwendet standardmäßig den aktuellen Zweig.
Dies basiert auf der Annahme, dass das erste Auftreten eines Zweignamens, der mit einem Checkout verknüpft ist, einen neuen Zweig erstellt (Reflog erfolgt in umgekehrter chronologischer Reihenfolge, daher das Ende -1).
Daran sind zwei Dinge falsch:
- Wiederverwendung des Zweignamens, nachdem festgestellt wurde, dass einer den falschen übergeordneten Zweig verwendet hat, listet tatsächlich den falschen übergeordneten Zweig auf
- Wenn der Verlauf fehlt, wird nur der Zeitpunkt aufgeführt, zu dem der Wechsel zum ersten Mal vorgenommen wurde.
Es funktioniert jedoch in 80 % der Fälle, weshalb ich es verwende.
Zur Verdeutlichung: Ich habe den Zweig, an dem ich arbeite, nicht selbst erstellt, sondern möchte Änderungen vom „übergeordneten“ Zweig in meinen Zweig zusammenführen
– Sebastian
31. Okt. 2014 um 17:01 Uhr
Wie würden Sie diesen Zweig manuell identifizieren? Sie sollten den Fall in Betracht ziehen, dass der ursprüngliche Zweig über zusätzliche Commits verfügt, nachdem Sie von ihm abgezweigt haben.
– Thorbjørn Ravn Andersen
31. Okt. 2014 um 17:17 Uhr
@ThorbjørnRavnAndersen Entschuldigung, ich habe mich wahrscheinlich nicht ganz klar ausgedrückt. Ich meinte, dass. Ich befinde mich beispielsweise in einem Feature-Zweig „f1“, der von z. B. Master abgezweigt ist, und möchte Änderungen vom Master kontinuierlich einbinden. Außer in meinem Fall weiß ich nicht, woher „f1“ stammt. Leider scheint mir Toreks Antwort vieles aufzuklären. Danke!
– Sebastian
31. Okt. 2014 um 20:26
Sie müssen sich genau darüber im Klaren sein, was Sie wissen wollen, sonst können Sie die Maschine nicht bitten, das für Sie zu erledigen.
– Thorbjørn Ravn Andersen
31. Okt. 2014 um 21:29