Si quiero fusionarme en una rama de Git, los cambios realizados solo en algunos de los archivos cambiaron en una confirmación particular que incluye cambios en varios archivos, ¿cómo se puede lograr esto?
Supongamos que el git commit llamada stuff
tiene cambios en los archivos A
, B
, C
, y D
pero quiero fusionar sólo stuff
cambios 's a archivos A
y B
. Suena como un trabajo para, git cherry-pick
pero cherry-pick
solo sabe cómo combinar confirmaciones completas, no un subconjunto de los archivos.
fuente
git checkout .
, también recomendaríagit clean -f
eliminar cualquier archivo nuevo pero no deseado introducido por el commit seleccionado.git add -p
que le permite decidir de forma interactiva qué cambios desea agregar al índice por archivogit reset -p HEAD
. Es el equivalenteadd -p
pero muy pocos saben que existe.Los otros métodos no funcionaron para mí, ya que la confirmación tuvo muchos cambios y conflictos con muchos otros archivos. Lo que se me ocurrió fue simplemente
En realidad, no contiene
add
los archivos ni realiza una confirmación por usted, por lo que es posible que deba seguir conO si desea omitir el complemento, puede usar el
--cached
argumento paragit apply
También puede hacer lo mismo para directorios completos
fuente
show SHA -- file | apply
básicamente lo mismocheckout SHA -- file
que en la respuesta de Mark Longair ?checkout SHA -- file
pagará exactamente la versión en SHA, mientrasshow SHA -- file | apply
que solo aplicará los cambios en SHA (al igual que cherry-pick). Importa si (a) hay más de una confirmación que cambia el archivo dado en la rama de origen, o (b) hay una confirmación que cambia el archivo en su rama de destino actual.git revert
deshace todo el commit). En ese caso, solo usegit show -R SHA -- file1.txt file2.txt | git apply -
git diff SHA -- file1.txt file2.txt | git apply -
significa aplicar todas las diferencias entre la versión actual del archivo y la versión en SHA a la versión actual. En esencia es lo mismo quegit checkout SHA -- file1.txt file2.txt
. Vea mi comentario anterior de por qué eso es diferente a cuál es lagit show
versión.git apply -3 -
lugar de sologit apply -
, luego, si ocurre un conflicto, puede usar su técnica estándar de resolución de conflictos, incluido el usogit mergetool
.Por lo general, uso la
-p
bandera con un pago git de la otra rama, que me parece más fácil y más detallado que la mayoría de los otros métodos que he encontrado.En principio:
ejemplo:
Luego, aparece un cuadro de diálogo que le pregunta qué cambios desea en los "blobs", esto prácticamente funciona para cada fragmento de cambio continuo de código que luego puede señalar
y
(Sí)n
(No), etc. para cada fragmento de código.La opción
-p
opatch
funciona para una variedad de comandos en git, incluido elgit stash save -p
que le permite elegir qué desea guardar de su trabajo actualA veces uso esta técnica cuando he hecho mucho trabajo y me gustaría separarla y comprometerme en más confirmaciones basadas en temas usando
git add -p
y eligiendo lo que quiero para cada confirmación :)fuente
git-add -p
, pero no sabía quegit-checkout
también tiene una-p
bandera: ¿eso soluciona los problemas de fusión que tiene la no-p
respuesta ?-p
permitiría una edición manual para una sección tan conflictiva, quecherry-pick
probablemente también cedería de todos modos.git reset -p HEAD
también permite-p
que se pueda dejar de usar cuando solo desea eliminar algunos parches del índice.Quizás la ventaja de este método sobre la respuesta de Jefromi es que no tienes que recordar qué comportamiento de git reset es el correcto :)
fuente
cherry-pick
y usar directamentegit checkout stuff -- A B
? Y congit commit -C stuff
el mensaje de confirmación seguiría siendo el mismo tambiénstuff
no se han modificado en su rama actual o en cualquier lugar entre el ancestro común deHEAD
ystuff
y la punta destuff
. Si lo han hecho,cherry-pick
crea el resultado correcto (esencialmente el resultado de una fusión), mientras que su método descartaría los cambios en la rama actual y mantendría todos los cambios del ancestro común hastastuff
, no solo los que están en ese Compromiso único.stuff
que el resultado de la selección de cereza se iríaA
yB
con un contenido diferente de su contenido en el compromisostuff
. Sin embargo, si fuera lo mismo, tienes razón: podrías hacer lo que dices.La selección de cereza es elegir cambios de un "compromiso" específico. La solución más simple es elegir todos los cambios de ciertos archivos es usar
Por ejemplo:
Fuentes y explicación completa http://jasonrudolph.com/blog/2009/02/25/git-tip-how-to-merge-specific-files-from-another-branch/
ACTUALIZAR:
Con este método, git no FUSIONARÁ el archivo, simplemente anulará cualquier otro cambio realizado en la rama de destino. Deberá fusionar los cambios manualmente:
fuente
La situación:
Estás en tu rama, digamos
master
y tienes tu compromiso en cualquier otra rama. Debe elegir solo un archivo de esa confirmación en particular.El enfoque:
Paso 1: Pago en la sucursal requerida.
Paso 2: asegúrese de haber copiado el hash de confirmación requerido.
Paso 3: Ahora tiene los cambios del archivo requerido en la rama deseada. Solo necesita agregarlos y confirmarlos.
fuente
Simplemente elegiría todo, luego haría esto:
Luego revertiría los cambios que no quiero y luego realizaría una nueva confirmación.
fuente
Use
git merge --squash branch_name
esto para obtener todos los cambios de la otra rama y preparará una confirmación para usted. Ahora elimine todos los cambios innecesarios y deje el que desee. Y git no sabrá que hubo una fusión.fuente
Encontré otra forma que evita cualquier fusión conflictiva en la selección de cerezas, que en mi opinión es algo fácil de recordar y entender. Dado que en realidad no está seleccionando una confirmación, sino parte de ella, primero debe dividirla y luego crear una confirmación que se adapte a sus necesidades y seleccionarla.
Primero cree una rama desde el commit que desea dividir y pruébela:
Luego revierte el commit anterior:
Luego agregue los archivos / cambios que desea seleccionar:
y comprometerlo:
tenga en cuenta el hash de confirmación, llamémoslo PICK-SHA y regresemos a su rama principal, master, por ejemplo, forzando el pago:
y escoge el commit:
ahora puedes eliminar la rama temporal:
fuente
Combine una rama en una nueva (squash) y elimine los archivos que no necesita:
fuente
En aras de la integridad, lo que funciona mejor para mí es:
Hace exactamente lo que OP quiere. Resuelve conflictos cuando es necesario, de manera similar, ¿cómo lo
merge
hace? Lo haceadd
pero nocommit
tus nuevos cambios.fuente
Puedes usar:
La notación
<commit>^
especifica el (primer) padre de<commit>
. Por lo tanto, este comando diff selecciona los cambios realizados<path>
en el commit<commit>
.Tenga en cuenta que esto todavía no confirmará nada (como lo
git cherry-pick
hace). Entonces, si quieres eso, tendrás que hacer:fuente