Ich habe das folgende Repository-Layout:
- Hauptniederlassung (Produktion)
- Integration
- Arbeiten
Was ich erreichen möchte, ist, eine Reihe von Commits aus dem Arbeitszweig auszuwählen und in den Integrationszweig zusammenzuführen. Ich bin ziemlich neu in Git und ich kann nicht herausfinden, wie ich das genau machen soll (das Kirschpflücken von Festschreibungsbereichen in einem Vorgang, nicht das Zusammenführen), ohne das Repository durcheinander zu bringen. Irgendwelche Hinweise oder Gedanken dazu? Vielen Dank!
git
git-merge
git-cherry-pick
verrücktbyte
quelle
quelle
Antworten:
Wenn es um eine Reihe von Commits geht, Kirschernte
istwar nicht praktisch.Wie unten von Keith Kim erwähnt , hat Git 1.7.2+ die Möglichkeit eingeführt, eine Reihe von Commits auszuwählen (aber Sie müssen sich immer noch der Konsequenzen der Auswahl von Kirschen für zukünftige Zusammenführungen bewusst sein ).
damian kommentiert und warnt uns:
Wenn Sie den Bereich
B
durchD
(einschließlich) auswählen möchten , wäre diesB^..D
.Siehe " Git Zweig aus Bereich früherer Commits erstellen? " Zur Veranschaulichung.
Wie Jubobs erwähnt in den Kommentaren :
Hinweis: Ab Git 2.9.x / 2.10 (Q3 2016) können Sie einen Bereich von Commits direkt für einen verwaisten Zweig (leerer Kopf) auswählen: siehe " So machen Sie einen vorhandenen Zweig zu einem verwaisten Zweig in Git ".
Ursprüngliche Antwort (Januar 2010)
A
rebase --onto
wäre besser, wenn Sie den angegebenen Commit-Bereich zusätzlich zu Ihrem Integrationszweig wiedergeben, wie Charles Bailey hier beschrieben hat .( Suchen Sie auch in der git rebase-Manpage nach "So würden Sie einen Themenzweig basierend auf einem Zweig in einen anderen transplantieren" , um ein praktisches Beispiel dafür zu sehen.
git rebase --onto
)Wenn Ihre aktuelle Niederlassung Integration ist:
Das wird alles zwischen:
first_SHA-1_of_working_branch_range
(daher das~1
): das erste Commit, das Sie wiederholen möchtenintegration
" (was auf das letzte Commit zeigt, das Sie aus demworking
Zweig wiedergeben möchten )zu "
tmp
" (was zeigt, wohinintegration
vorher gezeigt wurde)Wenn bei der Wiedergabe eines dieser Commits ein Konflikt auftritt:
git rebase --continue
" ausführen .git rebase --skip
"git rebase --abort
" (und setzen Sie denintegration
Zweig wieder auf dentmp
Zweig)Danach
rebase --onto
,integration
wird in der letzten wieder commit der Integration Zweig (das „isttmp
“ branch + alle wieder Commits)rebase --onto
Vergessen Sie nicht, beim Kirschpflücken oder , wie hier beschrieben, Konsequenzen für spätere Zusammenführungen zu haben .Eine reine "
cherry-pick
" Lösung wird hier diskutiert und würde Folgendes beinhalten:Wenn Sie jedoch eine Reihe von Commits "wiedergeben" müssen, sollte das Wort "Wiedergabe" Sie dazu bringen, die "
rebase
" -Funktion von Git zu verwenden.quelle
-m
Wie gehen Sie mit diesen Commits um, wenn Sie Commits haben, deren Eltern diese Option benötigen ? Oder gibt es eine Möglichkeit, diese Commits herauszufiltern?-m
soll sie für Sie erledigen, indem Sie die Hauptzeile auswählen, auf die sich der-m
Parameter bezieht, den Sie für diese Kirschernte ausgewählt haben.-m
Option nur dann bestehen lässt, wenn sie ein übergeordnetes Commit trifft, wenn eine Reihe von Commits ausgewählt wird. Gerade jetzt , wenn ich gehe ,-m
wiegit cherry-pick a87afaaf..asfa789 -m 1
es gilt für alle Commits im Bereich.error: Commit 8fcaf3b61823c14674c841ea88c6067dfda3af48 is a merge but no -m option was given.
ich Sie gerade tatsächlich realisiert könntegit cherry-pick --continue
und es wäre schön (aber es würde auch nicht die Eltern begehen)Ab Git v1.7.2 kann Cherry Pick eine Reihe von Commits akzeptieren:
quelle
cherry-pick A..B
Commit A nicht erhalten wird (das würden Sie dafür benötigenA~1..B
), und wenn es Konflikte gibt, wird Git nicht automatisch fortgesetzt, wie es Rebase tut (zumindest ab 1.7.3.1)git cherry-pick A..B C
es nicht so funktioniert, wie man es naiv erwarten würde. Es wird nicht alles im Bereich auswählenA..B
und festschreibenC
! Dazu müssen Sie zuerstgit cherry-pick A..B
und dann in zwei Zeilen aufteilengit cherry-pick C
. Wenn Sie also einen Bereich haben, müssen Sie ihn separat ausführen.Angenommen, Sie haben 2 Zweige,
"branchA": Enthält Commits, die Sie kopieren möchten (von "commitA" nach "commitB").
"branchB": Der Zweig, in den die Commits von "branchA" übertragen werden sollen.
1)
2) Holen Sie sich die IDs von "commitA" und "commitB"
3)
4)
5) Wenn Sie einen Konflikt haben, lösen Sie ihn und geben Sie ein
um den Kirschpflückprozess fortzusetzen.
quelle
Sind Sie sicher, dass Sie die Zweige nicht zusammenführen möchten? Wenn der Arbeitszweig einige kürzlich festgeschriebene Commits enthält, die Sie nicht möchten, können Sie einfach an der gewünschten Stelle einen neuen Zweig mit einem HEAD erstellen.
Wenn Sie aus irgendeinem Grund wirklich eine Reihe von Commits auswählen möchten, können Sie dies elegant tun, indem Sie einfach ein Patchset abrufen und es auf Ihren neuen Integrationszweig anwenden:
Dies ist im Wesentlichen das, was git-rebase sowieso tut, aber ohne dass Spiele gespielt werden müssen. Sie können hinzufügen
--3way
,git-am
wenn Sie zusammenführen müssen. Stellen Sie sicher, dass sich noch keine anderen * .patch-Dateien in dem Verzeichnis befinden, in dem Sie dies tun, wenn Sie die Anweisungen wörtlich befolgen ...quelle
A^
einschließen mussA
.Ich habe den Code von VonC in ein kurzes Bash-Skript eingewickelt
git-multi-cherry-pick
, damit es einfach ausgeführt werden kann:Ich verwende dies derzeit, um den Verlauf eines Projekts neu zu erstellen, bei dem sowohl Code von Drittanbietern als auch Anpassungen im selben SVN-Trunk gemischt wurden. Ich teile jetzt den Kerncode von Drittanbietern, Module von Drittanbietern und Anpassungen in ihre eigenen Git-Zweige auf, um die zukünftigen Anpassungen besser zu verstehen.
git-cherry-pick
ist in dieser Situation hilfreich, da ich zwei Bäume im selben Repository habe, aber ohne einen gemeinsamen Vorfahren.quelle
Alle oben genannten Optionen fordern Sie auf, Zusammenführungskonflikte zu lösen. Wenn Sie für ein Team festgeschriebene Änderungen zusammenführen, ist es schwierig, die Zusammenführungskonflikte von Entwicklern zu lösen und fortzufahren. "Git Merge" führt die Zusammenführung jedoch in einem Schuss durch, aber Sie können eine Reihe von Revisionen nicht als Argument übergeben. Wir müssen die Befehle "git diff" und "git apply" verwenden, um den Zusammenführungsbereich der Umdrehungen durchzuführen. Ich habe festgestellt, dass "git apply" fehlschlägt, wenn die Patch-Datei für zu viele Dateien unterschiedlich ist. Daher müssen wir einen Patch pro Datei erstellen und dann anwenden. Beachten Sie, dass das Skript die im Quellzweig gelöschten Dateien nicht löschen kann. Dies ist ein seltener Fall. Sie können solche Dateien manuell aus dem Zielzweig löschen. Der Exit-Status von "git apply" ist nicht Null, wenn der Patch nicht angewendet werden kann.
Unten ist das Skript.
quelle
Ich habe das vor einigen Tagen getestet, nachdem ich die sehr klare Erklärung von Vonc gelesen hatte.
Meine Schritte
Start
dev
: ABCDEFGHIJtarget
: ABCDE
noch nichtH
Schritte zum Kopieren von Features ohne die Schritte E und H in der Verzweigung
dev_feature_wo_E_H
git checkout dev
git checkout -b dev_feature_wo_E_H
git rebase --interactive --rebase-merges --no-ff D
wo ichdrop
vorE
undH
in den Rebase-Editor stellecommit
Schritte zum Kopieren des Zweigs
dev_feature_wo_E_H
auf das Ziel.git checkout target
git merge --no-ff --no-commit dev_feature_wo_E_H
commit
Einige Bemerkungen
cherry-pick
in den Tagen zuvor getangit cherry-pick
ist mächtig und einfach abermerge
ich Konflikte der anfänglichen Commits lösen und Commits duplizieren. Für ein oder zweicherry-pick
ist es also in Ordnung, "Kirschen zu pflücken", aber für mehr ist es zu ausführlich und der Zweig wird zu komplexgit rebase --onto
quelle
Eine andere Möglichkeit könnte darin bestehen, mit unserer Strategie zum Commit vor dem Bereich zusammenzuführen und dann eine "normale" Zusammenführung mit dem letzten Commit dieses Bereichs (oder einem Zweig, wenn es der letzte ist). Angenommen, nur 2345 und 3456 Commits des Masters werden in den Feature-Zweig eingefügt:
im Feature-Zweig:
quelle