Cómo combinar archivos específicos de ramas de Git


Tengo 2 ramas de git branch1 y branch2 y quiero fusionar file.py en rama2 hacia file.py en la rama 1 y solo ese archivo.

En esencia, solo quiero trabajar en el file.py en branch1 pero queremos aprovechar el comando merge. ¿Cuál es la mejor manera de hacer esto?

 121
Author: rwolst, 2013-08-08

6 answers

La respuesta aceptada ya menciona el uso de git checkout. Ahora, podría haber contenido en file.py de branch2 que ya no es aplicable en branch1. Tal situación requerirá escoger algunos cambios y dejar otros. Por lo tanto, para tener un control total haga una fusión interactiva usando el interruptor --patch:

$ git checkout --patch branch2 file.py

La sección modo interactivo en la página de manual de git-add(1) explica las claves que se deben usar:

y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk nor any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk nor any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

El comando split es particularmente útil.

 134
Author: pdp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-16 10:21:45

Como se señala en los comentarios, esto técnicamente no es una "fusión", por lo que el enlace a continuación utiliza comillas. Sin embargo, rara vez necesito algo tan complicado como otros carteles describen, así que creo que es útil, si no una solución adecuada, para la pregunta de la OP.

Echa un vistazo a esta página: Git Tip: Cómo "Combinar" Archivos Específicos de Otra rama Proporciona la forma más sencilla de hacer esto, en Mi humilde opinión.

Básicamente, para aplicarlo a su situación:

$ git checkout branch1 # i.e. make sure you're in branch1
$ git checkout branch2 file.py

Fácil peasy, file.py ahora está en la rama 1.

 85
Author: Мати Тернер,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-27 17:52:18

¿Están todas las modificaciones a file.py en branch2 en sus propias confirmaciones, separadas de las modificaciones a otros archivos? Si es así, puede simplemente cherry-pick los cambios sobre:

git checkout branch1
git cherry-pick <commit-with-changes-to-file.py>

De lo contrario, merge no opera sobre rutas individuales...también podría crear un parche git diff de file.py cambios de branch2 y git apply a branch1:

git checkout branch2
git diff <base-commit-before-changes-to-file.py> -- file.py > my.patch
git checkout branch1
git apply my.patch
 13
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-07 23:45:50

Ninguna de las otras respuestas realidad "combinar" los archivos, como si estuviera usando el comando merge. (En el mejor de los casos, requerirán que selecciones manualmente las diferencias.) Si realmente desea aprovechar la fusión utilizando la información de un ancestro común, puede seguir un procedimiento basado en uno que se encuentra en la sección "Fusión avanzada" del Manual de Referencia de git.

Para este protocolo, asumo que quieres fusionar la ruta / al / archivo del archivo.txt ' de origen / maestro en la CABEZA-modificar según corresponda. (Usted no tiene que estar en el directorio superior de su repositorio, pero ayuda.)

# Find the merge base SHA1 (the common ancestor) for the two commits:
git merge-base HEAD origin/master

# Get the contents of the files at each stage
git show <merge-base SHA1>:path/to/file.txt > ./file.common.txt
git show HEAD:path/to/file.txt > ./file.ours.txt
git show origin/master:path/to/file.txt > ./file.theirs.txt

# You can pre-edit any of the files (e.g. run a formatter on it), if you want.

# Merge the files
git merge-file -p ./file.ours.txt ./file.common.txt ./file.theirs.txt > ./file.merged.txt

# Resolve merge conflicts in ./file.merged.txt
# Copy the merged version to the destination
# Clean up the intermediate files

Git merge-file debe usar todos los ajustes de fusión predeterminados para formatear y similares.

También tenga en cuenta que si su "nuestra" es la versión de la copia de trabajo y no desea ser demasiado cauteloso, puede operar directamente en el archivo:

git merge-base HEAD origin/master
git show <merge-base SHA1>:path/to/file.txt > ./file.common.txt
git show origin/master:path/to/file.txt > ./file.theirs.txt
git merge-file path/to/file.txt ./file.common.txt ./file.theirs.txt
 6
Author: R.M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-08 23:02:59

Puedes stash y stash pop el archivo:

git checkout branch1
git checkout branch2 file.py
git stash
git checkout branch1
git stash pop
 5
Author: Martin G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-05 19:07:14

Para combinar solo los cambios de file.py de branch2, haga que los otros cambios desaparezcan.

git checkout -B wip branch2
git read-tree branch1
git checkout branch2 file.py
git commit -m'merging only file.py history from branch2 into branch1'
git checkout branch1
git merge wip

Merge nunca mirará ningún otro archivo. Es posible que necesite '- f ' las cajas si los árboles son lo suficientemente diferentes.

Tenga en cuenta que esto dejará a branch1 como si todo en la historia de branch2 hasta ese punto se hubiera fusionado, lo que puede no ser lo que desea. Una mejor versión de la primera comprobación de arriba es probablemente

git checkout -B wip `git merge-base branch1 branch2`

En cuyo caso el mensaje de confirmación debe probablemente también sea

git commit -m"merging only $(git rev-parse branch2):file.py into branch1"
 2
Author: jthill,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-08 02:42:31