Wenn ich mit Git in einem Team mit Feature-Zweigen arbeite, finde ich es oft schwierig, die Zweigstruktur in der Geschichte zu verstehen.
Beispiel:
Nehmen wir an, es gab ein Feature-Branch- Feature / einen Kaffee zum Zubereiten und die Fehlerbehebung auf dem Master wurde parallel zum Feature-Branch fortgesetzt .
Die Geschichte könnte so aussehen:
* merge feature/make-coffee
|\
| * small bugfix
| |
* | fix bug #1234
| |
| * add milk and sugar
| |
* | improve comments
| |
* | fix bug #9434
| |
| * make coffe (without milk or sugar)
| |
* | improve comments
|/
*
Problem
Auf den ersten Blick fällt es mir schwer zu sagen, auf welcher Seite sich der Feature-Zweig befindet. Normalerweise muss ich auf beiden Seiten mehrere Kommentare durchsuchen, um eine Vorstellung davon zu bekommen, welche welche ist. Dies wird noch komplizierter, wenn mehrere Feature-Zweige parallel vorhanden sind (insbesondere wenn es sich um eng verwandte Features handelt) oder wenn Feature-Zweige und Master in beide Richtungen zusammengeführt wurden.
Im Gegensatz dazu ist dies in Subversion erheblich einfacher, da der Filialname Teil des Verlaufs ist. So kann ich sofort feststellen, dass ursprünglich ein Commit für "feature / make-coffee" ausgeführt wurde.
Git könnte dies vereinfachen, indem der Name des aktuellen Zweigs in die Commit-Metadaten aufgenommen wird, wenn ein Commit erstellt wird (zusammen mit Autor, Datum usw.). Git tut dies jedoch nicht.
Gibt es einen fundamentalen Grund, warum dies nicht getan wird? Oder wollte nur niemand die Funktion? Wenn es das letztere ist, gibt es andere Möglichkeiten, den Zweck historischer Zweige zu verstehen, ohne den Namen zu sehen?
Antworten:
Wahrscheinlich, weil Filialnamen nur innerhalb eines Repositorys von Bedeutung sind. Wenn ich im
make-coffee
Team bin und alle meine Änderungen über einen Gatekeeper einreiche, wird meinmaster
Zweig möglicherweise in denmake-coffee-gui
Zweig des Gatekeepers gezogen , den er mit seinemmake-coffee-backend
Zweig zusammenführt, bevor er zu einemmake-coffee
Zweig zurückkehrt, der in den zentralenmaster
Zweig eingegliedert wird.Sogar innerhalb eines Repositorys können sich die Filialnamen ändern, während sich Ihr Workflow entwickelt.
master
könnte sich später änderndevelopment
, um beispielsweise aufgerufen zu werden .Wie CodeGnome angedeutet hat, hat git eine starke Designphilosophie, etwas nicht in die Daten zu backen, wenn es nicht benötigt wird. Die Benutzer werden voraussichtlich Optionen verwenden , in
git log
und fürgit diff
die Ausgabe der Daten an ihre nach der Tat mögen. Ich empfehle, einige davon auszuprobieren, bis Sie ein Format gefunden haben, das für Sie besser funktioniert.git log --first-parent
Beispielsweise werden die Commits aus einem Zweig, in dem die Zusammenführung stattfindet, nicht angezeigt.quelle
Filialverlauf verfolgen mit
--no-ff
In Git hat ein Commit Vorfahren, aber ein "Zweig" ist eigentlich nur der aktuelle Kopf einer Entwicklungslinie. Mit anderen Worten, ein Commit ist eine Momentaufnahme des Arbeitsbaums zu einem bestimmten Zeitpunkt und kann zu einer beliebigen Anzahl von Zweigen gleichzeitig gehören. Dies ist ein Teil dessen, was Git Branching im Vergleich zu anderen DVCS so leicht macht.
Git-Commits enthalten keine Verzweigungsinformationen, da sie für den Git-Verlauf nicht erforderlich sind. Zusammenführungen, die nicht schnell vorwärts gehen, können jedoch sicherlich zusätzliche Informationen darüber enthalten, welcher Zweig zusammengeführt wurde. Sie können sicherstellen, dass Ihr Verlauf diese Informationen enthält, indem Sie die
--no-ff
Markierung immer an Ihre Zusammenführungen übergeben. git-merge (1) sagt:Dadurch wird im Allgemeinen eine Zusammenführungsnachricht ähnlich der erstellt
Merge branch 'foo'
, sodass Sie normalerweise Informationen zu "Ahnenzweigen" mit einer Zeile ähnlich der folgenden finden:quelle
git log --merges
.Die einfachste Antwort ist, dass die Namen der Zweige vergänglich sind. Was wäre, wenn Sie beispielsweise einen Zweig umbenennen würden (
git branch -m <oldname> <newname>
)? Was würde mit all den Verpflichtungen gegen diesen Zweig passieren? Oder was ist, wenn zwei Personen Zweigniederlassungen mit demselben Namen in verschiedenen lokalen Repositorys haben?Das einzige, was in git Bedeutung hat, ist die Prüfsumme des Commits. Dies ist die Grundeinheit für die Verfolgung.
Die Informationen sind da, Sie fragen einfach nicht danach und sie sind nicht genau da.
Git speichert die Prüfsumme des Kopfes jeder Verzweigung in
.git/refs/heads
. Beispielsweise:(Ja, ich überhäufte meine Git-Prüfsummen, es ist nichts Besonderes, aber es sind private Speicher, die ich in dem Moment betrachte, in dem nichts versehentlich durchgesickert sein muss).
Wenn Sie sich dies ansehen und jedes Commit, das dies als übergeordnetes Element enthält, oder das übergeordnete Element oder das übergeordnete Element des übergeordneten Elements nachverfolgen, können Sie herausfinden, in welchen Zweigen sich ein bestimmtes Commit befindet.
Das Speichern des Namens eines Zweigs (der sich wie oben erwähnt ändern kann), in dem sich ein Commit befindet, ist ein zusätzlicher Aufwand für das Commit, der nicht hilft. Speichern Sie die übergeordneten Elemente des Commits und dessen Gut.
Sie können die Zweige anzeigen, indem Sie den Befehl git log mit dem entsprechenden Flag ausführen.
Es gibt viele verschiedene Möglichkeiten, um auszuwählen, was Sie dafür wollen - schauen Sie sich die Git-Log- Dokumentation an - den
-all
Abschnitt und die wenigen Optionen, die folgen.Diese Zweige wurden mit 'test', 'test1' und 'test2' belegt.
Beachten Sie, dass die Git-Log-Dokumentation sehr umfangreich ist und es durchaus möglich ist, fast alles herauszuholen, was Sie wollen.
quelle
Warum enthalten Git-Commits nicht den Namen des Zweigs, in dem sie erstellt wurden?
Nur eine Designentscheidung. Wenn Sie diese Informationen benötigen, können Sie einen Prepare-Commit-msg- oder Commit-msg-Hook hinzufügen, um dies für ein einzelnes Repository zu erzwingen.
Nach der BitKeeper-Katastrophe entwickelte Linus Torvalds git passend zum Linux-Kernel-Entwicklungsprozess. Dort wird ein Patch, bis er akzeptiert wird, überarbeitet, bearbeitet, mehrmals poliert (alles per E-Mail), abgemeldet (= Commit bearbeiten), von Kirschen gepflückt und zu Zweigen des Leutnants gewandert -Picks und so weiter, bis sie schließlich von Linus flussaufwärts zusammengeführt werden.
In einem solchen Workflow gibt es möglicherweise keinen bestimmten Ursprung eines Commits, und oft wird ein Commit nur in einem temporären Debugging-Zweig in einem unwichtigen privaten Zufalls-Repository mit lustigen Zweignamen erstellt, während Git verteilt wird.
Vielleicht ist diese Designentscheidung nur zufällig getroffen worden, aber sie passt genau zum Linux-Kernel-Entwicklungsprozess.
quelle
Denn in Git werden Commits wie "Kaffee machen" als Teil beider Zweige betrachtet, wenn der Feature-Zweig zusammengeführt wird. Es gibt sogar einen Befehl, um das zu überprüfen:
Auch sind Niederlassungen billig, lokal und ätherisch; Sie können problemlos auf dem Server hinzugefügt, entfernt, umbenannt, verschoben und gelöscht werden.
Git folgt dem Prinzip, dass alles möglich ist, weshalb Sie einen Zweig einfach von einem Remote-Server entfernen und den Verlauf einfach umschreiben können.
Nehmen wir an, ich war in der 'Master'-Branche und habe zwei Commits gemacht:' Kaffee kochen 'und' Milch und Zucker hinzufügen '. Dann entscheide ich mich, eine neue Branche zu verwenden, und setze' Master 'wieder auf' Ursprung 'zurück /Meister'. Kein Problem, die ganze Geschichte ist noch sauber: "Kaffee kochen" und "Milch und Zucker hinzufügen" gehören nicht zum Master, sondern nur zu Feature / Kaffee kochen.
Mercurial ist das Gegenteil; es will nichts ändern. Zweige sind permanent, das Umschreiben des Verlaufs ist verpönt. Sie können einen Zweig nicht einfach vom Server löschen.
Kurz gesagt: Git ermöglicht es Ihnen, alles zu tun, Mercurial möchte die Dinge vereinfachen (und macht es wirklich schwierig, Sie tun zu lassen, was Sie wollen).
quelle