379 Stimmen

Git-Schnellvorlauf VS kein Schnellvorlauf Zusammenführung

Mit Git merge können wir die Zusammenführung von Zweigen im Schnelldurchlauf und ohne Schnelldurchlauf durchführen. Irgendwelche Ideen, wann man Fast-Forward-Merge und wann No-Fast-Forward-Merge verwenden sollte?

435voto

Ivan Danilov Punkte 13636

En --no-ff ist nützlich, wenn Sie eine klare Vorstellung von Ihrem Feature-Zweig haben wollen. Selbst wenn in der Zwischenzeit keine Commits gemacht wurden - FF ist möglich - wollen Sie manchmal immer noch, dass jeder Commit in der Mainline einem Feature entspricht. Also behandeln Sie einen Feature-Zweig mit einer Reihe von Commits als eine Einheit, und führen sie als eine Einheit zusammen. Es ist aus Ihrer Geschichte ersichtlich, wenn Sie Feature-Branch-Merging mit --no-ff .

Wenn Ihnen so etwas egal ist, können Sie wahrscheinlich mit FF auskommen, wann immer es möglich ist. So werden Sie mehr svn-ähnliches Gefühl des Arbeitsablaufs haben.

Der Autor dieses Artikels zum Beispiel Artikel meint, dass --no-ff Option standardmäßig sein sollte, und seine Argumentation ist ähnlich wie die, die ich oben dargelegt habe:

Stellen Sie sich die Situation vor, dass eine Reihe kleinerer Übertragungen im "Feature"-Zweig zusammen ein neues Feature ergeben: Wenn Sie einfach "git merge feature_branch" ausführen, ohne --no-ff Es ist unmöglich, in der Git-Historie zu sehen, welche der Commit-Objekte zusammen ein Feature implementiert haben - man müsste alle Protokollmeldungen manuell lesen. Ein ganzes Feature (d.h. eine Gruppe von Commits) rückgängig zu machen, ist ein wahres Kopfzerbrechen [wenn --no-ff nicht verwendet wird], während es leicht möglich ist, wenn die --no-ff Flagge verwendet wurde [weil es sich nur um eine Übergabe handelt]."

Graphic showing how --no-ff groups together all commits from feature branch into one commit on master branch

23voto

themefield Punkte 3022

Ich kann ein Beispiel nennen, das häufig in Projekten vorkommt.

Hier, Option --no-ff (d.h. echte Zusammenführung ) erstellt eine neue Übergabe mit mehreren Eltern und ermöglicht eine bessere Verfolgung des Verlaufs. Andernfalls, --ff (d.h. Vorwärtsverflechtung ) ist standardmäßig.

$ git checkout master
$ git checkout -b newFeature
$ ...
$ git commit -m 'work from day 1'
$ ...
$ git commit -m 'work from day 2'
$ ...
$ git commit -m 'finish the feature'
$ git checkout master
$ git merge --no-ff newFeature -m 'add new feature'
$ git log
// something like below
commit 'add new feature'         // => commit created at merge with proper message
commit 'finish the feature'
commit 'work from day 2'
commit 'work from day 1'
$ gitk                           // => see details with graph

$ git checkout -b anotherFeature        // => create a new branch (*)
$ ...
$ git commit -m 'work from day 3'
$ ...
$ git commit -m 'work from day 4'
$ ...
$ git commit -m 'finish another feature'
$ git checkout master
$ git merge anotherFeature       // --ff is by default, message will be ignored
$ git log
// something like below
commit 'work from day 4'
commit 'work from day 3'
commit 'add new feature'
commit 'finish the feature'
commit ...
$ gitk                           // => see details with graph

(*) Beachten Sie, dass hier, wenn die newFeature Zweig wiederverwendet wird, muss git, anstatt einen neuen Zweig zu erstellen, einen --no-ff trotzdem zusammenführen. Das bedeutet, dass eine schnelle Vorwärtszusammenführung nicht immer möglich ist.

13voto

Pritom Nandy Punkte 1215

Wenn wir in einer Entwicklungsumgebung arbeiten und unseren Code in den Staging-/Produktionszweig einbringen, kann Git no fast forward eine bessere Option sein. Wenn wir im Entwicklungszweig an einer einzelnen Funktion arbeiten, haben wir in der Regel mehrere Commits. Die Nachverfolgung von Änderungen mit mehreren Commits kann später unpraktisch sein. Wenn wir mit dem Staging-/Produktionszweig mit Git no fast forward zusammenführen, gibt es dort nur 1 Commit. Wenn wir nun die Funktion rückgängig machen wollen, müssen wir nur diesen Commit rückgängig machen. Das Leben ist einfach.

4voto

JDG Punkte 387

Git-Visualisierung

Hier sind die Git-Log-Visualisierungen mit den Unterschieden. So sahen die Bäume aus, als ich drei Zweige von dev mit der Bezeichnung 1 2 3 erstellte und dann mit und ohne Schnellvorlauf zusammenführte. Ich füge den Einrichtungscode am Ende ein. Sie können einen Absatz mit Befehlen in Ihr Terminal einfügen, um verschiedene Git-Szenarien schnell einzurichten und zurückzusetzen, was beim Lernen von Git sehr hilfreich war.

Beachten Sie, dass Git bei Fast-Forward nicht einmal eine Zusammenführung anzeigt.

--no-ff         --ff (default)

* Merge 3
| * 3
* | Merge 2     * Merge 3
| | * 2         | * 3
| |/            * | Merge 2
* / Merge 1     | | * 2
|/              | |/
| * 1           * / 1
|/              |/
* main          * main

Es lohnt sich, diesen Ansatz mit der Umbasierung zu vergleichen.

Einrichtung/Abbau

Sie können dies wiederholt ausführen, um das Projektarchiv zu löschen und neu zu initialisieren. Es ist für Windows, also denke ich, Sie müssen nur den Dateipfad und die rd Verzeichnisbefehle entfernen, wenn Sie unter *nix arbeiten.

Um das Verhalten beim schnellen Vorlauf zu sehen, entfernen Sie --no-ff aus den Zusammenführungsbefehlen am Ende. Entfernen Sie die --pretty Stück, wenn Sie die Commit-IDs sehen wollen.

cd \user\docs\code\learning\github\sandbox
rd /s /q 0.git 1 2 3
git init --bare 0.git
git clone 0.git 1
cd 1
git config user.name "user"
git config user.email "user@email.com"
git commit --allow-empty -m main
git switch -c 1 main
git commit --allow-empty -m 1
git switch -c 2 main
git commit --allow-empty -m 2
git switch -c 3 main
git commit --allow-empty -m 3
git switch main
git merge --no-ff 1
git merge --no-ff 2
git merge --no-ff 3
git log --graph --oneline --first-parent --all --pretty=%s

1voto

beibichunai Punkte 82

Neben den genannten Gründen für die Verwendung --no-ff Die Einhaltung einer korrekten übergeordneten Reihenfolge im Zielzweig ist ein weiterer Aspekt.

Verwendung von --no-ff Die Reihenfolge der Eltern in der letzten Übergabe im resultierenden Zweig ist unabhängig von der Reihenfolge der Eltern in der letzten Übergabe des Zweigs, den Sie zusammenführen, die erste Elternschaft befindet sich im Zielzweig, nicht im Zweig, den Sie zusammengeführt haben. Wenn Sie ein ff durchführen, wird der letzte Commit des Zweiges, den Sie zusammenführen, als letzter in den Zielzweig aufgenommen, so dass der erste Parent des letzten Commits im Zielzweig auf einen Commit außerhalb der Mainline verweist. Das ist wahrscheinlich nicht das, was Sie wollen.

Sie könnten zum Beispiel verwenden --first-parent einen Zweigverlauf filtern möchten, um nur die wichtigsten Änderungen an einem Zweig zu sehen, oder andere Operationen durchführen möchten, bei denen standardmäßig der erste übergeordnete Zweig verwendet wird, wie revert . Wenn Ihr Zweig keine korrekte übergeordnete Referenzierung beibehält, würden die Ergebnisse anders ausfallen als erwartet.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X