Ich verwende git für ein neues Projekt, das zwei parallele - aber derzeit experimentelle - Entwicklungszweige hat:
master
: Import der vorhandenen Codebasis plus ein paar Mods, deren ich mir allgemein sicher binexp1
: experimenteller Zweig # 1exp2
: experimenteller Zweig # 2
exp1
und exp2
repräsentieren zwei sehr unterschiedliche architektonische Ansätze. Bis ich weiter komme, kann ich nicht wissen, welches (wenn überhaupt) funktionieren wird. Wenn ich in einem Zweig Fortschritte mache, habe ich manchmal Änderungen, die im anderen Zweig nützlich sind, und möchte nur diese zusammenführen.
Was ist der beste Weg, um selektive Änderungen von einem Entwicklungszweig zum anderen zusammenzuführen und alles andere hinter sich zu lassen?
Ansätze, die ich in Betracht gezogen habe:
git merge --no-commit
gefolgt von der manuellen Deaktivierung einer großen Anzahl von Änderungen, die ich nicht zwischen den Zweigen gemeinsam machen möchte.Manuelles Kopieren gängiger Dateien in ein temporäres Verzeichnis, gefolgt von
git checkout
einem Wechsel in den anderen Zweig und anschließendem manuellen Kopieren aus dem temporären Verzeichnis in den Arbeitsbaum.Eine Variation des oben genannten. Verlassen Sie die
exp
Zweige vorerst und verwenden Sie zwei zusätzliche lokale Repositories zum Experimentieren. Dies macht das manuelle Kopieren von Dateien viel einfacher.
Alle drei Ansätze scheinen mühsam und fehleranfällig zu sein. Ich hoffe, es gibt einen besseren Ansatz. so etwas wie ein Filterpfadparameter, der git-merge
selektiver machen würde .
quelle
git merge -s ours --no-commit
gefolgt von einigengit read-tree
nicht eine gute Lösung dafür? Siehe stackoverflow.com/questions/1214906/…Antworten:
Sie verwenden den Befehl cherry-pick , um einzelne Commits von einem Zweig abzurufen.
Wenn sich die gewünschten Änderungen nicht in einzelnen Commits befinden, verwenden Sie die hier gezeigte Methode, um das Commit in einzelne Commits aufzuteilen . Grob gesagt verwenden Sie diese Option
git rebase -i
, um das ursprüngliche Commit zu bearbeiten,git reset HEAD^
Änderungen selektiv zurückzusetzen undgit commit
dieses Bit dann als neues Commit im Verlauf festzuschreiben.Es gibt eine andere nette Methode hier im Red Hat Magazine, bei der Sie nur Teile eines Hunks hinzufügen
git add --patch
oder möglicherweisegit add --interactive
hinzufügen können, wenn Sie verschiedene Änderungen an einer einzelnen Datei aufteilen möchten (suchen Sie auf dieser Seite nach "split").Nachdem Sie die Änderungen aufgeteilt haben, können Sie jetzt nur die gewünschten auswählen.
quelle
Ich hatte genau das gleiche Problem wie oben von Ihnen erwähnt. Aber ich fand das klarer, als ich die Antwort erklärte.
Zusammenfassung:
Überprüfen Sie die Pfade des Zweigs, den Sie zusammenführen möchten.
Hinweis: Es funktioniert auch ohne
--
wie im verlinkten Beitrag zu sehen.oder um selektiv Hunks zusammenzuführen
Alternativ können Sie Reset verwenden und dann mit der Option hinzufügen
-p
.Schließlich begehen
quelle
foo.c
müssengit reset HEAD foo.c
Sie diese Datei entfernen, und Sie können sie dann unterscheiden. Ich fand das heraus, nachdem ich es ausprobiert hatte und hierher zurückgekommen war, um nach einer Antwort darauf zu suchengit diff --cached
git checkout -p <revision> -- <path>
wird das gleiche sein wie die ersten drei Befehle, die Sie beschrieben haben :)Führen Sie aus, um Dateien von einem Zweig selektiv in einen anderen Zweig zusammenzuführen
Wo
branchX
ist der Zweig, von dem Sie in den aktuellen Zweig zusammenführen möchten?Mit dieser
--no-commit
Option werden die von Git zusammengeführten Dateien bereitgestellt, ohne sie tatsächlich festzuschreiben. Dies gibt Ihnen die Möglichkeit, die zusammengeführten Dateien nach Belieben zu ändern und sie dann selbst festzuschreiben.Je nachdem, wie Sie Dateien zusammenführen möchten, gibt es vier Fälle:
1) Sie möchten eine echte Zusammenführung.
In diesem Fall akzeptieren Sie die zusammengeführten Dateien so, wie Git sie automatisch zusammengeführt hat, und schreiben sie dann fest.
2) Es gibt einige Dateien, die Sie nicht zusammenführen möchten.
Sie möchten beispielsweise die Version im aktuellen Zweig beibehalten und die Version in dem Zweig, aus dem Sie zusammenführen, ignorieren.
Führen Sie Folgendes aus, um die Version im aktuellen Zweig auszuwählen:
Dadurch wird die Version von
file1
im aktuellen Zweig abgerufen und diefile1
von Git zusammengestellte Version überschrieben .3) Wenn Sie die Version in branchX möchten (und keine echte Zusammenführung).
Lauf:
Dadurch wird die von Git automatisch zusammengeführte Version von
file1
in abgerufenbranchX
und überschriebenfile1
.4) Der letzte Fall ist, wenn Sie nur bestimmte Zusammenführungen auswählen möchten
file1
.In diesem Fall können Sie die geänderte
file1
Version direkt bearbeiten, auf die gewünschte Version aktualisierenfile1
und dann festschreiben.Wenn Git eine Datei nicht automatisch zusammenführen kann, wird die Datei als "nicht zusammengeführt" gemeldet und eine Kopie erstellt, in der Sie die Konflikte manuell lösen müssen.
Um dies anhand eines Beispiels weiter zu erläutern, nehmen wir an, Sie möchten
branchX
in den aktuellen Zweig einbinden:Anschließend führen Sie den
git status
Befehl aus, um den Status geänderter Dateien anzuzeigen.Zum Beispiel:
Wo
file1
,file2
undfile3
sind die Dateien, die git erfolgreich automatisch zusammengeführt hat.Dies bedeutet, dass Änderungen in
master
undbranchX
für alle drei Dateien ohne Konflikte miteinander kombiniert wurden.Sie können prüfen , wie die Zusammenführung , indem Sie das getan wurde
git diff --cached
;Wenn Sie eine Zusammenführung als unerwünscht empfinden, können Sie dies tun
git commit
Wenn Sie nicht zusammenführen
file1
und die Version im aktuellen Zweig beibehalten möchtenLauf
Wenn Sie nicht zusammenführen möchten
file2
und nur die Version in möchtenbranchX
Lauf
Wenn Sie
file3
automatisch zusammengeführt werden möchten , tun Sie nichts.Git hat es zu diesem Zeitpunkt bereits zusammengeführt.
file4
oben ist eine fehlgeschlagene Zusammenführung von Git. Dies bedeutet, dass in beiden Zweigen Änderungen in derselben Zeile auftreten. Hier müssen Sie die Konflikte manuell lösen. Sie können die Zusammenführung verwerfen, indem Sie die Datei direkt bearbeiten oder den Befehl checkout für die Version in dem Zweig ausführenfile4
, der Sie werden möchten .Schließlich nicht vergessen
git commit
.quelle
git merge --no-commit branchX
es sich nur um einen Schnellvorlauf handelt, wird der Zeiger aktualisiert und das --no-commit wird daher stillschweigend ignoriert--no-ff
, um dieses Verhalten zu verhindern?Ich mag die obigen Ansätze nicht. Die Verwendung von Cherry-Pick ist ideal, um eine einzelne Änderung auszuwählen, aber es ist schmerzhaft, wenn Sie alle Änderungen mit Ausnahme einiger schlechter Änderungen vornehmen möchten. Hier ist mein Ansatz.
Es gibt kein
--interactive
Argument, das Sie an git merge übergeben können.Hier ist die Alternative:
Sie haben einige Änderungen an der Zweigfunktion vorgenommen und möchten einige, aber nicht alle auf nicht schlampige Weise an den Master übergeben (dh Sie möchten nicht jede einzelne auswählen und festschreiben).
Wickeln Sie das einfach in ein Shell-Skript ein, ändern Sie den Master in $ in und ändern Sie das Feature in $ from, und schon kann es losgehen:
quelle
git rebase -i $to
zugit rebase -i $to || $SHELL
, so dass der Benutzer aufrufen kanngit --skip
usw., wie erforderlich , wenn die Fütterungsmaterial ausfällt. Es lohnt sich auch, die Zeilen mit&&
anstelle von Zeilenumbrüchen zu verketten.Es gibt noch einen anderen Weg:
Es ist eine Mischung aus
git checkout
undgit add -p
könnte genau das sein, wonach Sie suchen:quelle
Während einige dieser Antworten ziemlich gut sind, habe ich das Gefühl, dass keine die ursprüngliche Einschränkung von OP tatsächlich beantwortet hat: Auswahl bestimmter Dateien aus bestimmten Zweigen. Diese Lösung macht das, kann aber mühsam sein, wenn es viele Dateien gibt.
Können sagen , Sie haben
master
,exp1
undexp2
Zweige. Sie möchten eine Datei aus jedem der experimentellen Zweige in Master zusammenführen. Ich würde so etwas machen:Auf diese Weise erhalten Sie Unterschiede in der Datei für jede der gewünschten Dateien. Nichts mehr. Nicht weniger. Es ist nützlich, dass Sie zwischen den Versionen radikal unterschiedliche Dateiänderungen haben - in meinem Fall, wenn Sie eine App von Rails 2 auf Rails 3 ändern.
BEARBEITEN : Dadurch werden Dateien zusammengeführt, es wird jedoch eine intelligente Zusammenführung durchgeführt. Ich konnte nicht herausfinden, wie ich diese Methode verwenden kann, um Diff-Informationen in der Datei abzurufen (möglicherweise wird dies immer noch zu extremen Unterschieden führen. Ärgerliche kleine Dinge wie Leerzeichen werden wieder zusammengeführt, es sei denn, Sie verwenden die
-s recursive -X ignore-all-space
Option).quelle
git checkout exp1 path/to/file_a path/to/file_x
git checkout feature <path>/*
Gruppen von Dateien bekommen.Die Antwort von 1800 INFORMATION ist völlig richtig. Als Git-Noob reichte mir "Use Cherry Cherry-Pick" jedoch nicht aus, um dies herauszufinden, ohne ein bisschen mehr im Internet zu stöbern. Deshalb dachte ich, ich würde einen detaillierteren Leitfaden veröffentlichen, falls sich jemand in einem befindet ähnliches Boot.
Mein Anwendungsfall war es, selektiv Änderungen aus dem Github-Zweig eines anderen in meinen eigenen zu ziehen. Wenn Sie bereits eine lokale Niederlassung mit den Änderungen haben, müssen Sie nur die Schritte 2 und 5-7 ausführen.
Erstellen Sie (falls nicht erstellt) einen lokalen Zweig mit den Änderungen, die Sie vornehmen möchten.
$ git branch mybranch <base branch>
Wechseln Sie hinein.
$ git checkout mybranch
Ziehen Sie die gewünschten Änderungen aus dem Konto der anderen Person. Wenn Sie dies noch nicht getan haben, möchten Sie sie als Fernbedienung hinzufügen.
$ git remote add repos-w-changes <git url>
Ziehen Sie alles von ihrem Ast herunter.
$ git pull repos-w-changes branch-i-want
Zeigen Sie die Festschreibungsprotokolle an, um zu sehen, welche Änderungen Sie möchten:
$ git log
Wechseln Sie zurück zu dem Zweig, in den Sie die Änderungen übernehmen möchten.
$ git checkout originalbranch
Cherry wählt Ihre Commits nacheinander mit den Hashes aus.
$ git cherry-pick -x hash-of-commit
Hutspitze: http://www.sourcemage.org/Git_Guide
quelle
git cherry
Befehl (siehe Handbuch zuerst), um Commits zu identifizieren, die Sie noch nicht zusammengeführt haben.Hier erfahren Sie, wie Sie eine
Myclass.java
Datei in einemmaster
Zweig durch einenMyclass.java
in einemfeature1
Zweig ersetzen können . Es wird funktionieren, auch wennMyclass.java
es nicht existiertmaster
.Beachten Sie, dass dies überschreibt - nicht zusammenführt - und lokale Änderungen im Hauptzweig ignoriert.
quelle
theirs
überschreibenours
=> +1 Cheers;)2. Manual copying of common files into a temp directory followed by ...copying out of the temp directory into the working tree.
Der einfache Weg, um tatsächlich fusioniert bestimmte Dateien aus zwei Zweigen, nicht nur bestimmte Dateien mit denen aus einem anderen Zweig ersetzen.
Schritt eins: Diff die Zweige
git diff branch_b > my_patch_file.patch
Erstellt eine Patch-Datei mit dem Unterschied zwischen dem aktuellen Zweig und branch_b
Schritt zwei: Wenden Sie den Patch auf Dateien an, die einem Muster entsprechen
git apply -p1 --include=pattern/matching/the/path/to/file/or/folder my_patch_file.patch
nützliche Hinweise zu den Optionen
Sie können das Platzierungsmuster
*
als Platzhalter verwenden.Schrägstriche müssen nicht entkommen.
Sie können stattdessen auch --exclude verwenden und es auf alles außer den Dateien anwenden, die dem Muster entsprechen, oder den Patch mit -R umkehren
Die Option -p1 ist ein Überbleibsel des Befehls * unix patch und der Tatsache, dass der Inhalt der Patch-Datei jedem Dateinamen
a/
oderb/
(oder mehr, je nachdem, wie die Patch-Datei generiert wurde) vorangestellt wird, die Sie entfernen müssen, damit er herausgefunden werden kann Die reale Datei zum Pfad zu der Datei, auf die der Patch angewendet werden muss.Weitere Optionen finden Sie in der Manpage für git-apply.
Schritt drei: Es gibt keinen Schritt drei
Natürlich möchten Sie Ihre Änderungen festschreiben, aber wer soll sagen, dass Sie keine anderen verwandten Optimierungen haben, die Sie vornehmen möchten, bevor Sie Ihre Festschreibung vornehmen?
quelle
Hier erfahren Sie, wie Sie den Verlauf dazu bringen können, mit minimalem Aufwand nur ein paar Dateien aus einem anderen Zweig zu verfolgen, selbst wenn eine "einfachere" Zusammenführung viel mehr Änderungen mit sich gebracht hätte, die Sie nicht möchten.
Zunächst machen Sie den ungewöhnlichen Schritt, im Voraus zu erklären, dass das, was Sie festschreiben möchten, eine Zusammenführung ist, ohne dass git irgendetwas mit den Dateien in Ihrem Arbeitsverzeichnis tut:
. . . Dabei ist "Filialname" das, von dem Sie behaupten, dass es zusammengeführt wird. Wenn Sie sich sofort festlegen würden, würde dies keine Änderungen vornehmen, aber es würde immer noch die Abstammung des anderen Zweigs anzeigen. Sie können weitere Zweige / Tags / etc. Hinzufügen. bei Bedarf auch zur Befehlszeile. Zu diesem Zeitpunkt müssen jedoch keine Änderungen festgeschrieben werden. Holen Sie sich daher als Nächstes die Dateien aus den anderen Revisionen.
Wenn Sie aus mehr als einem anderen Zweig zusammengeführt haben, wiederholen Sie den Vorgang nach Bedarf.
Jetzt befinden sich die Dateien aus dem anderen Zweig im Index und können mit dem Verlauf festgeschrieben werden.
In dieser Commit-Nachricht müssen Sie viel erklären.
Bitte beachten Sie jedoch, falls dies nicht klar war, dass dies eine durcheinandergebrachte Sache ist. Es ist nicht im Sinne dessen, wofür ein "Zweig" ist, und Kirschpflücken ist eine ehrlichere Art, das zu tun, was Sie hier tun würden. Wenn Sie eine weitere "Zusammenführung" für andere Dateien in demselben Zweig durchführen möchten, den Sie beim letzten Mal nicht übernommen haben, wird eine Meldung "bereits aktuell" angezeigt. Es ist ein Symptom, nicht zu verzweigen, wenn wir sollten, in der "von" -Zweig sollte mehr als eine andere Verzweigung sein.
quelle
git merge --no-ff --no-commit -s outs branchname1
) ist genau das, wonach ich gesucht habe! Vielen Dank!Ich weiß, dass ich etwas spät dran bin, aber dies ist mein Workflow zum Zusammenführen ausgewählter Dateien.
quelle
Am einfachsten ist es, Ihr Repo auf den Zweig einzustellen, mit dem Sie zusammenführen möchten, und dann auszuführen.
Wenn du läufst
Sie sehen die bereits bereitgestellte Datei ...
Dann renne
Einfach.
quelle
Ich fand, dass dieser Beitrag die einfachste Antwort enthält. Nur tun:
Beispiel:
Weitere Informationen finden Sie im Beitrag.
quelle
Es ist seltsam, dass Git immer noch kein so praktisches Tool "out of the box" hat. Ich benutze es häufig, wenn ich einen alten Versionszweig (der immer noch viele Software-Benutzer hat) durch nur einige Bugfixes aus dem aktuellen Versionszweig aktualisiere . In diesem Fall ist es oft erforderlich, schnell nur einige Codezeilen aus der Datei im Trunk abzurufen und viele andere Änderungen zu ignorieren (die nicht in die alte Version übernommen werden sollen) ... und natürlich die interaktive Drei-Wege- Zusammenführung wird in diesem Fall benötigt,
git checkout --patch <branch> <file path>
ist für diesen selektiven Zusammenführungszweck nicht verwendbar.Sie können es leicht tun:
Fügen Sie diese Zeile einfach zu einem
[alias]
Abschnitt in Ihrer globalen.gitconfig
oder lokalen.git/config
Datei hinzu:Dies bedeutet, dass Sie Beyond Compare verwenden. Wechseln Sie bei Bedarf einfach zu einer Software Ihrer Wahl. Sie können es auch in die automatische Drei-Wege-Zusammenführung ändern, wenn Sie die interaktive selektive Zusammenführung nicht benötigen:
Dann verwenden Sie wie folgt:
Dies gibt Ihnen die echte Möglichkeit zum selektiven Zusammenführen von Bäumen für jede Datei in einem anderen Zweig.
quelle
Es ist nicht genau das, wonach Sie gesucht haben, aber es war nützlich für mich:
Es ist eine Mischung aus einigen Antworten.
quelle
git checkout HEAD file1
Folgendes tun: Um die aktuelle Version beizubehalten und die Dateifile1
zu entfernen , können Sie mit der-p
Option einen Teil der Datei auswählen , die zusammengeführt werden soll. Danke für den Trick!Ich würde eine machen
Auf diese Weise können Sie den Bereich der Festschreibungen für ein Dateimuster aus einem Zweig begrenzen.
Gestohlen von: http://www.gelato.unsw.edu.au/archives/git/0701/37964.html
quelle
Ich hatte genau das gleiche Problem wie oben von Ihnen erwähnt. Aber ich fand diesen Git-Blog klarer, als ich die Antwort erklärte.
Befehl über den obigen Link:
quelle
Ich mag die Antwort "Git-Interactive-Merge" oben, aber es gibt eine einfachere. Lassen Sie git dies für Sie tun, indem Sie eine Rebase-Kombination aus interaktiv und auf:
Der Fall ist also, dass Sie C1 und C2 von der 'Feature'-Verzweigung (Verzweigungspunkt' A ') wollen, aber im Moment keine der anderen.
Wie oben, gelangen Sie in den interaktiven Editor, in dem Sie die Auswahlzeilen für C1 und C2 auswählen (wie oben). Speichern und beenden, und dann wird mit der Rebase fortgefahren und Sie erhalten Zweig 'Temp' und auch HEAD bei Master + C1 + C2:
Dann können Sie einfach den Master auf HEAD aktualisieren und den temporären Zweig löschen, und schon kann es losgehen:
quelle
Was ist mit
git reset --soft branch
? Ich bin überrascht, dass es noch niemand erwähnt hat.Für mich ist es der einfachste Weg, die Änderungen selektiv aus einem anderen Zweig auszuwählen, da dieser Befehl in meinen Arbeitsbaum alle Diff-Änderungen einfügt und ich einfach auswählen kann, welche ich benötige. Auf diese Weise habe ich die volle Kontrolle über die festgeschriebenen Dateien.
quelle
Ich weiß, dass diese Frage alt ist und es viele andere Antworten gibt, aber ich habe mein eigenes Skript namens "pmerge" geschrieben, um Verzeichnisse teilweise zusammenzuführen. Es ist in Arbeit und ich lerne immer noch sowohl Git- als auch Bash-Scripting.
Dieser Befehl verwendet
git merge --no-commit
und wendet dann Änderungen an, die nicht mit dem angegebenen Pfad übereinstimmen.Verwendung:
git pmerge branch path
Beispiel:
git merge develop src/
Ich habe es nicht ausgiebig getestet. Das Arbeitsverzeichnis sollte frei von nicht festgeschriebenen Änderungen und nicht verfolgten Dateien sein.
quelle
Sie können
read-tree
einen bestimmten Remote-Baum lesen oder in den aktuellen Index einfügen, zum Beispiel:Verwenden Sie
-m
stattdessen "Zusammenführen".Siehe auch: Wie füge ich ein Unterverzeichnis in git zusammen?
quelle
Ein einfacher Ansatz zum selektiven Zusammenführen / Festschreiben nach Datei:
git checkout dstBranch git merge srcBranch // make changes, including resolving conflicts to single files git add singleFile1 singleFile2 git commit -m "message specific to a few files" git reset --hard # blow away uncommitted changes
quelle
Wenn Sie nicht zu viele Dateien haben, die geändert wurden, bleiben Ihnen keine zusätzlichen Commits.
1. Zweig vorübergehend duplizieren
$ git checkout -b temp_branch
2. Auf das letzte gewünschte Commit zurücksetzen
$ git reset --hard HEAD~n
, wobein
die Anzahl der Commits angegeben ist, die Sie zurückgehen müssen3. Überprüfen Sie jede Datei aus dem ursprünglichen Zweig
$ git checkout origin/original_branch filename.ext
Jetzt können Sie bei Bedarf einen Commit ausführen und Push erzwingen (um Remote zu überschreiben).
quelle
Wenn Sie nur ein bestimmtes Verzeichnis und lassen alles andere intakt und noch bewahren Geschichte verschmelzen müssen, könnten Sie vielleicht versuchen , diese ... ein neues erstellen
target-branch
weg von der ,master
bevor Sie experimentieren.Bei den folgenden Schritten wird davon ausgegangen, dass Sie zwei Zweige
target-branch
undsource-branch
haben und sich das Verzeichnisdir-to-merge
, das Sie zusammenführen möchten , im Verzeichnis befindetsource-branch
. Angenommen, Sie haben andere Verzeichnisse wiedir-to-retain
im Ziel, die Sie nicht ändern und den Verlauf beibehalten möchten. Es wird auch davon ausgegangen, dass es Zusammenführungskonflikte in der gibtdir-to-merge
.quelle
Wenn sich zwischen den aktuellen Commits der beiden Zweige nur wenige Dateien geändert haben, füge ich die Änderungen manuell zusammen, indem ich die verschiedenen Dateien durchlaufe.
git difftoll <branch-1>..<branch-2>
quelle