1812 Stimmen

Wie kann ich in Git selektiv Änderungen aus einem anderen Zweig zusammenführen oder auswählen?

Ich verwende Git für ein neues Projekt, das zwei parallele - aber derzeit experimentelle - Entwicklungszweige hat:

  • master Import der bestehenden Codebasis plus einige Änderungen, bei denen ich mir im Allgemeinen sicher bin
  • exp1 : Versuchszweig #1
  • exp2 : Versuchszweig #2

exp1 y exp2 stehen für zwei sehr unterschiedliche Architekturansätze. Solange ich nicht weitergekommen bin, kann ich nicht wissen, welcher Ansatz (wenn überhaupt) funktionieren wird. Wenn ich in einem Zweig Fortschritte mache, habe ich manchmal Bearbeitungen, die im anderen Zweig nützlich wären, und möchte genau diese zusammenführen.

Was ist der beste Weg, um selektive Änderungen von einem Entwicklungszweig in einen anderen zusammenzuführen und dabei alles andere zurückzulassen?

Ansätze, die ich in Betracht gezogen habe:

  1. git merge --no-commit gefolgt von der manuellen Freigabe einer großen Anzahl von Bearbeitungen, die ich nicht zwischen den Zweigen austauschen möchte.

  2. Manuelles Kopieren von gemeinsamen Dateien in ein temporäres Verzeichnis, gefolgt von git checkout um in den anderen Zweig zu wechseln und dann mehr manuelles Kopieren aus dem temporären Verzeichnis in den Arbeitsbaum.

  3. Eine Abwandlung des obigen Beispiels. Verzichten Sie auf die exp Zweigen und verwenden Sie zwei zusätzliche lokale Repositories für Experimente. Dies macht das manuelle Kopieren von Dateien viel einfacher.

Alle drei Ansätze erscheinen mühsam und fehleranfällig. Ich hoffe, dass es einen besseren Ansatz gibt; so etwas wie einen Filterpfad-Parameter, der die git-merge wählerischer.

21voto

dsieczko Punkte 373

Am einfachsten ist es, wenn Sie Ihr Repository auf den Zweig setzen, mit dem Sie zusammenführen wollen, und dann Folgendes ausführen

git checkout [branch with file] [path to file you would like to merge]

Wenn Sie

git status

werden Sie sehen, dass die Datei bereits bereitgestellt wurde...

Dann laufen

git commit -m "Merge changes on '[branch]' to [file]"

Einfach.

20voto

Felix Punkte 970

Dies ist mein Arbeitsablauf für das Zusammenführen selektiver Dateien.

# Make a new branch (this will be temporary)
git checkout -b newbranch

# Grab the changes
git merge --no-commit  featurebranch

# Unstage those changes
git reset HEAD
(You can now see the files from the merge are unstaged)

# Now you can chose which files are to be merged.
git add -p

# Remember to "git add" any new files you wish to keep
git commit

17voto

JimStar Punkte 161

Es ist seltsam, dass Git immer noch nicht so ein praktisches Werkzeug "out of the box" hat. Ich benutze es häufig, wenn ich einen alten Versionszweig aktualisiere (der immer noch eine Menge Software-Benutzer hat), indem ich nur einige Fehlerbehebungen aus dem aktuellen Versionszweig. In diesem Fall wird es oft benötigt, um schnell zu nur einige Codezeilen aus der Datei im Stamm, wobei eine Menge anderer Änderungen (die nicht in die alte Version übernommen werden sollen) ignoriert werden... Und natürlich interaktives Dreiergespräch In diesem Fall ist eine Zusammenführung erforderlich, git checkout --patch <branch> <file path> ist für diesen Zweck der selektiven Zusammenführung nicht verwendbar.

Sie können es leicht tun:

Fügen Sie einfach diese Zeile hinzu [alias] Abschnitt in Ihrem globalen .gitconfig oder lokal .git/config Datei:

[alias]
    mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; /C/BCompare3/BCompare.exe $2.theirs $2 $2.base $2; rm -f $2.theirs; rm -f $2.base;' -"

Es setzt voraus, dass Sie Beyond Compare verwenden. Wechseln Sie bei Bedarf einfach zu einer Software Ihrer Wahl. Sie können auch die automatische Drei-Wege-Zusammenführung aktivieren, wenn Sie die interaktive selektive Zusammenführung nicht benötigen:

[alias]
    mergetool-file = "!sh -c 'git show $1:$2 > $2.theirs; git show $(git merge-base $1 $(git rev-parse HEAD)):$2 > $2.base; git merge-file $2 $2.base $2.theirs; rm -f $2.theirs; rm -f $2.base;' -"

Dann verwenden Sie so:

git mergetool-file <source branch> <file path>

So erhalten Sie das echte selektive Baumweg Zusammenführungsmöglichkeit einer beliebigen Datei in einem anderen Zweig.

14voto

Stunner Punkte 11509

Ich fand diese Stelle um die einfachste Antwort zu geben. Tun Sie es einfach:

git checkout <branch from which you want files> <file paths>

Ejemplo

Ziehen der .gitignore-Datei aus ZweigB in den aktuellen Zweig:

git checkout branchB .gitignore

Weitere Informationen finden Sie in diesem Beitrag.

10voto

Susheel Javadi Punkte 2874

Ich hatte genau das gleiche Problem, das Sie oben beschrieben haben. Aber ich fand dieses Git-Blog die Antwort deutlicher zu erläutern.

Befehl aus dem obigen Link:

# You are in the branch you want to merge to
git checkout <branch_you_want_to_merge_from> <file_paths...>

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