Git-Branches: Intuition und Realität
(jvns.ca)- Viele Menschen finden die Funktionsweise von Git-Branches nicht intuitiv.
- Es wird der Unterschied zwischen dem üblichen intuitiven Modell von Git-Branches und der tatsächlichen internen Darstellung von Branches in Git erklärt.
- Es wird gezeigt, dass das intuitive Modell und die tatsächliche Funktionsweise von Git in Wirklichkeit sehr eng miteinander verbunden sind.
- Es wird diskutiert, welche Grenzen das intuitive Modell hat und warum es Probleme verursachen kann.
Das intuitive Branch-Modell
- Viele Menschen stellen sich Branches als „Äste eines Apfelbaums“ vor.
- In Git haben Branches kein Konzept von „Eltern“, was sich von der Vorstellung unterscheidet, dass sie von
mainabzweigen.
In Git ist ein Branch die gesamte Historie
- In Git ist ein Branch nicht einfach nur ein abgezweigter Commit, sondern umfasst die vollständige Historie aller vorherigen Commits.
- Anhand eines Beispiel-Repositorys wird gezeigt, dass sowohl
mainals auchmybranchjeweils 4 Commits haben.
Branches werden als Commit-ID gespeichert
- Intern werden Branches in Git als kleine Textdateien gespeichert, die eine Commit-ID enthalten.
- Der neueste Commit jedes Branches ist in dieser Datei verzeichnet.
- Da es zwischen Commits keine Eltern-Kind-Beziehung gibt, kennt Git keine Beziehungen zwischen Branches.
Die Intuition der Menschen ist meistens nicht so falsch
- Es ist etwas töricht zu sagen, die Intuition der Menschen über Git sei „falsch“.
- Auch ein „falsches“ Modell kann in der Praxis nützlich sein.
Rebase verwendet das „intuitive“ Branch-Konzept
- Rebase wendet nur die Commits des „intuitiven“ Branches erneut auf
mainan. - Das Ergebnis eines Rebase stimmt mit dem intuitiven Modell überein.
Auch Merge verwendet das „intuitive“ Branch-Konzept
- Merge kopiert keine Commits, benötigt aber einen gemeinsamen Basis-Commit.
- Die Merge-Base findet den Commit, an dem der im intuitiven Modell betrachtete Branch abgezweigt ist.
Auch GitHub-Pull-Requests verwenden die intuitive Idee
- Wenn man auf GitHub einen Pull Request erstellt, um
mybranchinmainzu mergen, werden nur die Commits des intuitiven Branches angezeigt.
Intuition ist gut, hat aber Grenzen
- Die intuitive Definition eines Branches passt gut zur tatsächlichen Arbeit mit Git, aber Git erkennt einen von
mainabgezweigten Branch nicht als etwas grundsätzlich anderes.
Trunk und abgezweigte Branches
- Menschen nehmen
mainundmybranchunterschiedlich wahr, und das beeinflusst die Art, wie sie Git verwenden. - Git unterscheidet nicht, ob ein Branch ein „Abzweig“ eines anderen Branches ist.
Git kann Rebase auch „rückwärts“ ausführen
- Da Git nicht mitteilt, ob ein Branch ein „Abzweig“ eines anderen Branches ist, müssen Nutzer selbst wissen, wann welcher Branch rebased werden sollte.
- Sowohl
git rebase mainals auch das umgekehrte Rebasegit rebase mybranchsind möglich. Dasselbe gilt für Merge.
Das Fehlen einer Hierarchie zwischen Git-Branches ist etwas seltsam
- Die Aussage, dass der
main-Branch nichts Besonderes ist, kommt daher, dass Git die Beziehungen zwischen Branches nicht erkennt. - Zwischen den Branches bestehen Beziehungen, aber Git weiß nichts davon.
Auch die Git-Branch-UI ist seltsam
- Wenn man nur die „abgezweigten“ Commits sehen möchte, unterscheiden sich die Vorgehensweisen mit
git logundgit diff.
Auf GitHub ist der Standard-Branch etwas Besonderes
- GitHub hat einen „Standard-Branch“, der eine besondere Rolle spielt.
Meinung von GN⁺
Das Wichtigste an diesem Artikel ist, den Unterschied zwischen dem intuitiven Verständnis der Menschen von Git-Branches und der tatsächlichen Funktionsweise von Git zu verstehen. Der Artikel wird Einsteigerinnen und Einsteigern im Software Engineering helfen, das Konzept von Git-Branches besser zu verstehen und effektiver zu nutzen. Es ist interessant und lehrreich zu sehen, wie das intuitive Modell von Git-Branches mit der praktischen Arbeit übereinstimmt und wie Git die Beziehungen zwischen Branches gerade nicht behandelt.
1 Kommentare
Hacker-News-Kommentare
git reset --hardundgit stashÄnderungen und Branch-Zeiger manipuliere. Um einen falschen Merge rückgängig zu machen, verwende ichgit reset --hard <letzter Commit vor dem Merge>, und um kleine Änderungen aus einem lokalen Branch auf den Main-Branch anzuwenden, nutze ichgit stash, checke dann den Main-Branch aus und verwendegit stash apply.git addundgit commitverwendet. Dieses Tutorial visualisiert Branches und hilft dabei, sie lesend zu verstehen.git merge my-branchmy-branch in den aktuellen Branch, undgit rebase my-branchrebased den aktuellen Branch auf my-branch.maingehört.git range-diffmuss man die Basis im Kopf behalten. Dieses Tool vergleicht zwei Bereiche wiemain..previousundmain..current.