git – Überspringt bestimmte Commits beim Zusammenführen

Ich benutze Git seit ungefähr einem Jahr und denke, es ist fantastisch, aber ich habe gerade mit einer zweiten Version des Projekts begonnen und eine neue Zweigstelle dafür gegründet. Ich kämpfe ein wenig mit dem besten Weg, um die Dinge zu bewältigen.

Ich habe zwei Zweige namens Master10 (für v1) und Master20 (für v2). Ich habe in der Version 1 auf Branch Master10 Fehlerbehebungen gemacht und neue Sachen von Master20 entwickelt. Immer wenn ich einen Bugfix mache, füge ich ihn in v2 ein, indem ich master20 auschecke und git merge master10 . So weit, ist es gut.

Jetzt habe ich jedoch eine Änderung in v1 vorgenommen, die ich in v2 nicht möchte, aber ich möchte weitere Fehlerkorrekturen fortsetzen. Wie kann ich Git mitteilen, dass er diesen bestimmten Commit (oder eine Reihe von Commits) überspringen soll, aber dass ich in Zukunft weitere Fehlerbehebungen zusammenführen möchte?

Ich dachte, git rebase könnte git rebase sein, aber ich las den Doc und mein Kopf explodierte fast.

Ich denke, was ich will, ist etwas wie ein “git sync” -Befehl, der Git sagt, dass zwei Zweige jetzt synchron sind und in Zukunft nur die Commits von diesem Sync-Punkt zusammenführen.

Jede Hilfe wird geschätzt.

Wenn Sie die meisten, aber nicht alle Commits auf dem Zweig “maint” zum Beispiel in “master” zusammenführen möchten, können Sie dies tun. Es erfordert etwas Arbeit —- wie oben erwähnt, ist der übliche Anwendungsfall, alles aus einem Zweig zu merge — aber manchmal passiert es, dass Sie eine Version geändert haben, die nicht zurück integriert werden sollte (vielleicht der Code) schon im Master überholt), wie stellst du das dar? Hier geht…

Nehmen wir an, dass maint 5 Änderungen angewendet hat und eine davon (maint ~ 3) nicht in den Master zurückgemischt werden soll, obwohl alle anderen auch sein sollten. Sie tun dies in drei Phasen: eigentlich alles vor dem einen zusammenführen, sagen git, um maint ~ 3 als verschmolzen zu markieren, auch wenn es nicht ist, und dann den Rest zusammenführen. Die Magie ist:

 bash $ git merge maint~4 bash $ git merge -s ours maint~3 bash $ git merge maint 

Der erste Befehl führt alles zusammen, bevor Sie sich auf den Master festlegen. In der Standardnachricht für das Zusammenführungsprotokoll wird erläutert, dass Sie “branch ‘maint’ (früher Teil)” zusammenführen.

Der zweite Befehl führt das lästige Mainten ~ 3 Commit zusammen, aber die Option “-s ours” sagt Git, eine spezielle “Merge-Strategie” zu verwenden, die einfach dadurch funktioniert, dass der Baum, in den Sie merge, nicht ignoriert wird ) Sie merge vollständig. Aber es macht immer noch einen neuen Zusammenführungs-Commit mit HEAD und maint ~ 3 als Eltern, so dass der Revisionsgraph jetzt sagt, dass maint ~ 3 zusammengeführt ist. In der Tat wollen Sie wahrscheinlich auch die Option -m verwenden, um ‘merge merge’ zu erklären, dass das Mainten ~ 3 Commit tatsächlich ignoriert wird!

Der letzte Befehl fügt einfach den Rest von maint (maint ~ 2..maint) in den Master ein, so dass Sie alle wieder synchronisiert werden.

IMHO, die logischste Sache zu tun ist, alles zusammenzufassen, und dann git revert (commit_you_dont_want), um es zu entfernen .

Beispiel:

 git merge master git revert 12345678 

Wenn Sie mehrere Commits “to-ignore” haben oder die Rückmeldungsnachricht bearbeiten möchten:

 git merge master git revert -n 123456 git revert -n abcdef git commit -m "... Except commits 123456 and abcdef" 

Dann könnte Ihre Geschichte wie folgt aussehen:

 | ... Except 123456 and abcdef |\ Merge branch 'master' into 'your_branch' 

Wenn Sie Konflikte haben, die NUR diese “zu ignorieren” Commits beinhalten, können Sie Folgendes verwenden:

 git merge master -X ours 

Ihre Version wird also gegenüber der anderen bestehen bleiben. Selbst ohne Fehlermeldungen können Sie diese unerwünschten Commits dennoch “rückgängig machen”, da sie möglicherweise andere Änderungen enthalten, die nicht in Konflikt stehen, und Sie wollen sie trotzdem nicht.

Wenn Sie Konflikte haben, die NICHT NUR die “to-ignore” -Zulassungen betreffen, sollten Sie sie manuell lösen, und Sie müssen sie wahrscheinlich beim Zurücksetzen erneut lösen.

Commits enthalten Vorfahren. Sie können ein Commit nicht zusammenführen, ohne vorherige Commits zusammenzuführen.

Sie können sie natürlich pflücken. Das ist ein guter Fluss, wenn Sie einen Zweig im Wartungsmodus haben.

Eine Art Werbung für mein Projekt, die den von @araqnid beschriebenen process grundlegend umschließt.

Es ist eine Art Helfer, der folgenden GIT-Fluss einführt:

  • Es gibt eine tägliche / wöchentliche Benachrichtigung über anstehende Zusammenführungen von Wartungszweigen in den Zweig dev / master
  • Branch Maintainer überprüft den Status und entscheidet selbst, ob alle Commits benötigt werden und blockiert sie entweder oder fordert Entwickler auf, sich selbst zu blockieren. Am Ende wird der Wartungszweig in das Upsteam eingebunden.

Ein Zitat von der Projektseite:

Abhängig vom Workflow ist es möglich, neben dem Master-Zweig auch Wartungs- oder kundenspezifische Filialen zu haben. Diese Zweige werden auch LTS-Zweige genannt.

Oft gehen die Hotfixes in die Zweige, in denen der Fehler gemeldet wurde, und dann wird das Commit zurück in den Master-Zweig zusammengeführt.

Allgemein üblich ist, dass alle Zweige perfekt mit dem Master synchronisiert sind, dh Sie möchten ein klares Delta zwischen einem bestimmten Zweig und Master sehen, um zu verstehen, ob der Master alle Features und Bugfixes enthält.

Manchmal möchten Sie jedoch keine bestimmten Commits, da sie kundenspezifisch sind und für andere Benutzer nicht sichtbar sein sollen. Oder Ihr Master-Zweig divergierte so sehr, dass es einen völlig anderen Ansatz erfordert, um das Problem zu beheben, oder besser, das Problem ist dort nicht mehr vorhanden.

Auch im Falle von cherry-pick vom Master in den Wartungszweig soll das resultierende Commit im Master gesperrt werden.

Klingt wie ein klassischer Fall für ‘git cherry-pick’ https://git-scm.com/docs/git-cherry-pick es macht genau das, wie es sich anhört

Erstellen Sie eine dritte Verzweigung für die gewünschten Änderungen in master10, aber nicht in master20. Betrachte Master10 immer als deinen “Master”, den stabilsten Zweig von allen. Die Branche, in der alle anderen Zweige ständig mithalten wollen.