Wenn ich in einem Git-Zweig die Änderungen zusammenführen möchte, die nur an einigen der Dateien vorgenommen wurden, die in einem bestimmten Commit geändert wurden, einschließlich Änderungen an mehreren Dateien, wie kann dies erreicht werden?
Angenommen , die Git commit genannt stuff
hat Änderungen an Dateien A
, B
, C
, und , D
aber ich möchte nur verschmelzen stuff
‚s Änderungen an Dateien A
und B
. Es klingt wie ein Job für, kann git cherry-pick
aber cherry-pick
nur ganze Commits zusammenführen, nicht eine Teilmenge der Dateien.
quelle
git checkout .
würde ich empfehlen, auchgit clean -f
alle neuen, aber unerwünschten Dateien zu entfernen, die durch das von Cherry ausgewählte Commit eingeführt wurden.git add -p
der Sie interaktiv entscheiden können, welche Änderungen Sie dem Index pro Dateigit reset -p HEAD
. Es ist das Äquivalent von,add -p
aber nur sehr wenige wissen, dass es existiert.Die anderen Methoden haben bei mir nicht funktioniert, da das Commit viele Änderungen und Konflikte mit vielen anderen Dateien aufwies. Was ich mir ausgedacht habe, war einfach
Es werden nicht
add
die Dateien oder ein Commit für Sie ausgeführt, sodass Sie möglicherweise nachverfolgen müssenOder wenn Sie das Hinzufügen überspringen möchten, können Sie das
--cached
Argument verwenden, umgit apply
Sie können dasselbe auch für ganze Verzeichnisse tun
quelle
show SHA -- file | apply
Grunde das Gleichecheckout SHA -- file
wie in Mark Longairs Antwort ?checkout SHA -- file
wird genau die Version bei SHA auschecken, währendshow SHA -- file | apply
nur die Änderungen in SHA angewendet werden (genau wie bei Cherry-Pick). Es ist wichtig, ob (a) mehr als ein Commit die angegebene Datei im Quellzweig ändert oder (b) ein Commit die Datei in Ihrem aktuellen Zielzweig ändert.git revert
zurücksetzen möchten (da das gesamte Commit rückgängig gemacht wird). In diesem Fall verwenden Sie einfachgit show -R SHA -- file1.txt file2.txt | git apply -
git diff SHA -- file1.txt file2.txt | git apply -
bedeutet, alle Unterschiede zwischen der aktuellen Version der Datei und der Version bei SHA auf die aktuelle Version anzuwenden. Im Wesentlichen ist es das gleiche wiegit checkout SHA -- file1.txt file2.txt
. In meinem früheren Kommentar erfahren Sie, warum sich das von dergit show
Version unterscheidet.git apply -3 -
statt nurgit apply -
. Wenn ein Konflikt auftritt, können Sie Ihre Standardtechnik zur Konfliktlösung verwenden, einschließlich der Verwendunggit mergetool
.Normalerweise verwende ich das
-p
Flag mit einer Git-Kasse aus dem anderen Zweig, die ich einfacher und detaillierter finde als die meisten anderen Methoden, auf die ich gestoßen bin.Allgemein gesagt:
Beispiel:
Sie erhalten dann einen Dialog, in dem Sie gefragt werden, welche Änderungen in "Blobs" gewünscht werden. Dies funktioniert so ziemlich für jeden Teil der kontinuierlichen Codeänderung, den Sie dann für jeden Teil des Codes signalisieren können
y
(Ja)n
(Nein) usw.Die Option
-p
oderpatch
funktioniert für eine Vielzahl von Befehlen in git, einschließlichgit stash save -p
der Option , mit der Sie auswählen können, was Sie aus Ihrer aktuellen Arbeit speichern möchtenIch verwende diese Technik manchmal, wenn ich viel Arbeit geleistet habe und sie trennen und in mehr themenbasierten Commits
git add -p
festschreiben möchte, indem ich für jedes Commit wähle und auswähle, was ich will :)quelle
git-add -p
, aber ich weiß nicht,git-checkout
hat auch eine-p
Fahne - das tut fix die fusionierenden Probleme die Nicht --p
Antwort hat?-p
würde eine manuelle Bearbeitung für einen solchen widersprüchlichen Abschnitt möglich sein, wascherry-pick
wahrscheinlich auch ohnehin nachgeben würde. Ich werde dies das nächste Mal testen, wenn ich es brauche, definitiv ein interessanter Ansatzgit reset -p HEAD
ermöglicht auch das,-p
was praktisch sein kann, wenn Sie nur einige Patches aus dem Index entfernen möchten.Vielleicht ist der Vorteil dieser Methode gegenüber Jefromis Antwort, dass Sie sich nicht daran erinnern müssen, welches Verhalten beim Zurücksetzen von Git das richtige ist :)
quelle
cherry-pick
und direkt verwendengit checkout stuff -- A B
? Und mitgit commit -C stuff
der Commit-Nachricht würde auch die gleiche bleibenstuff
in Ihrem aktuellen Zweig oder irgendwo zwischen dem gemeinsamen Vorfahren vonHEAD
undstuff
und der Spitze von nicht geändert wurdenstuff
. Wenn dies der Fall ist,cherry-pick
wird das richtige Ergebnis erstellt (im Wesentlichen das Ergebnis einer Zusammenführung), während Ihre Methode die Änderungen im aktuellen Zweig wegwirft und alle Änderungen vom gemeinsamen Vorfahren bis zustuff
- nicht nur den darin enthaltenen - beibehält Single Commit.stuff
, den das Ergebnis der Kirschauswahl verlassen würde,A
undB
mit einem anderen Inhalt als dem Inhalt des Commitsstuff
. Wenn es jedoch genauso wäre, haben Sie Recht - Sie könnten einfach tun, was Sie sagen.Cherry Pick ist das Auswählen von Änderungen aus einem bestimmten "Commit". Die einfachste Lösung besteht darin, alle Änderungen bestimmter zu verwendender Dateien auszuwählen
Zum Beispiel:
Quellen und vollständige Erklärung http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
AKTUALISIEREN:
Mit dieser Methode verschmilzt git die Datei nicht, sondern überschreibt lediglich alle anderen Änderungen, die am Zielzweig vorgenommen wurden. Sie müssen die Änderungen manuell zusammenführen:
quelle
Die Situation:
Sie befinden sich in Ihrer Niederlassung, sagen wir,
master
und Sie haben Ihr Commit in einer anderen Niederlassung. Sie müssen nur eine Datei aus diesem bestimmten Commit auswählen.Die Vorgehensweise:
Schritt 1: Kasse in der gewünschten Filiale.
Schritt 2: Stellen Sie sicher, dass Sie den erforderlichen Commit-Hash kopiert haben.
Schritt 3: Sie haben jetzt die Änderungen der erforderlichen Datei in Ihrem gewünschten Zweig. Sie müssen sie nur hinzufügen und festschreiben.
quelle
Ich würde einfach alles auswählen und dann Folgendes tun:
Dann würde ich die Änderungen, die ich nicht möchte, zurücksetzen und dann ein neues Commit durchführen.
quelle
Mit
git merge --squash branch_name
dieser Option erhalten Sie alle Änderungen aus dem anderen Zweig und bereiten ein Commit für Sie vor. Entfernen Sie nun alle nicht benötigten Änderungen und belassen Sie die gewünschte. Und Git wird nicht wissen, dass es eine Fusion gab.quelle
Ich habe einen anderen Weg gefunden, der jede widersprüchliche Verschmelzung beim Kirschpflücken verhindert, die IMO leicht zu merken und zu verstehen ist. Da Sie eigentlich kein Commit auswählen, sondern einen Teil davon, müssen Sie es zuerst aufteilen und dann ein Commit erstellen, das Ihren Anforderungen entspricht, und es auswählen.
Erstellen Sie zunächst einen Zweig aus dem Commit, den Sie teilen möchten, und checken Sie ihn aus:
Setzen Sie dann das vorherige Commit zurück:
Fügen Sie dann die Dateien / Änderungen hinzu, die Sie auswählen möchten:
und begebe es:
Beachten Sie den Commit-Hash. Nennen wir ihn PICK-SHA und kehren Sie zu Ihrem Hauptzweig zurück. Master erzwingt beispielsweise das Auschecken:
und wählen Sie das Commit aus:
Jetzt können Sie den temporären Zweig löschen:
quelle
Füge einen Zweig zu einem neuen zusammen (Squash) und entferne die nicht benötigten Dateien:
quelle
Der Vollständigkeit halber funktioniert für mich am besten:
Es macht genau das, was OP will. Es löst Konflikte bei Bedarf, ähnlich wie
merge
. Es tutadd
aber nichtcommit
Ihre neuen Änderungen.quelle
Sie können verwenden:
Die Notation
<commit>^
gibt das (erste) Elternteil von an<commit>
. Daher wählt dieser diff-Befehl die Änderungen aus, die<path>
im Commit vorgenommen wurden<commit>
.Beachten Sie, dass dies noch nichts festlegt (wie
git cherry-pick
auch). Wenn Sie das wollen, müssen Sie Folgendes tun:quelle