Usando GIT, ¿cómo puedo fusionar selectivamente los cambios de una confirmación en otra 'bifurcación'?

81

Toma este escenario:

  1. Decido 'bifurcar' una base de código en github.com, y empiezo a hacer mi rutina: Editar - Confirmar - Empujar; también conocido como hack hack hack.
  2. Después de hacer algunos cambios, veo algunos cambios que otra persona ha hecho en el mismo proyecto, ¡y me gustan!
  3. Decido que quiero fusionarlos con los míos. El problema es que solo quiero una 'porción' de una confirmación en particular, de varias confirmaciones que ha realizado.

¿Cuál sería el método más eficiente para obtener esta cantidad selecta de cambios, fusionados en mi 'bifurcación'?

Tim
fuente

Respuestas:

119

Después de trollear las olas del mundo IRC, alguien dio una gran solución:

git cherry-pick SHA1 --no-commit
git add --patch

¡Ojalá ayude a cualquiera con la misma pregunta!

EDITAR: OK, tal vez no sea tan simple. Estos son los pasos completos:

  1. Primero tienes que estar en tu repositorio, hacer los cd-ing necesarios para llegar a tu directorio de trabajo.

  2. Ahora debe agregar la rama remota y luego buscarla. Haz esto por:

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. Ahora puede ejecutar comandos como git log someUser/masterpara encontrar la confirmación SHA1 que desea fusionar 'parcialmente'.

  4. Una vez que tenga el SHA, ahora puede ejecutar:

    git cherry-pick -n SHA1

    ¿Dónde SHA1está el compromiso SHA, duh!

  5. Es muy posible que haya conflictos, según la antigüedad del compromiso y la frecuencia con la que cambia esa área particular del proyecto. Lo sentimos, pero debe resolverlos manualmente con su editor de confianza. Así que saque VIM, o cualquier otra cosa que use, y elimine los conflictos hasta que llegue a la etapa en la que le gustan los cambios.

  6. Ahora debe restablecer el índice a la revisión HEAD, luego puede usar el confiable add --patchcomando GIT para elegir qué cambios desea:

    git reset HEAD

    git add --patch o git add -p

  7. ¡Hurra! Comprometer tiempo:

    git commit -m "I merged a select amount of changes"

  8. Para limpiar el desorden (las cosas a las que dijo que no git add --patch) y solo mantener los cambios seleccionados en su repositorio de trabajo, ejecute:

    git reset --hard HEAD

    Aparentemente también git checkout -fes otra opción.

Tim
fuente
Me alegro de que lo hayas encontrado git add -p; es extremadamente poderoso. Si ya tiene la confirmación en cuestión (por ejemplo, no la usó --no-commiten la selección de cereza, o es una de sus confirmaciones), puede usarla git reset HEAD^para rebobinar el índice y luego volver a agregar los cambios con git add -p, confirmando en pasos . Si la confirmación no está en la punta de la rama, puede usar git rebase -iy elegir editar la confirmación en cuestión.
Cascabel
3
agradable recorrido. recuerde que si solo desea la confirmación completa , solo emite el -nen el paso 4. Así:git cherry-pick SHA1
Hulvej
La clave aquí es git remote add <user> <fork-url>: entonces puede git cherry-pickhacerlo como de costumbre.
Tom
2

No tengo claro lo que quieres. Si desea traer solo ciertas confirmaciones de las otras bifurcaciones, puede usar git cherry-pick SHA. Explicación completa sobre gitready .

hgmnz
fuente
Solo busco una 'porción' / 'sección' / 'unas pocas líneas' de una confirmación en particular, fusionada en mi repositorio. No es un archivo particularmente específico.
Tim
En ese caso, git format-patch SHA, git apply <patch> es una opción
hgmnz
2

Realmente me gusta la solución de Tim, sin embargo, a veces me gusta jugar en vimdiff. Mi solución a este problema es cruda, pero me funciona porque me gusta vim.

He configurado vimdiff como mi difftool, y luego, para fusionar selectivamente, difiero la rama:

git difftool <branch> <file>

Luego voy al panel con la versión de la rama actual y edito el original en vim (a veces esto no es necesario, pero a veces vimdiff abre una versión en / tmp) y deshabilito el modo de solo lectura:

:e <file>
:set readonly!

Ahora puedo usar las herramientas de parche de vim, como doy dppara aplicar lo que quiero, y hacer otras pequeñas ediciones sobre la marcha. Cuando termino, guardo el archivo, salgo de vim y luego presento y confirmo el archivo en git como una edición normal.

Como dije, esto no es particularmente sofisticado, pero es muy poderoso y aún está puramente en la línea de comandos. Solo asegúrese de agregar un mensaje de confirmación claro, ya que git no incluirá automáticamente un mensaje de combinación para usted.

Ejemplo de vimdiff http://j.mp/1dZVllt

Mike Dacre
fuente
No creo que esta respuesta califique completamente como digna de ser una respuesta independiente en toda regla. Información útil, pero no particularmente relevante. (¿Por qué está en la parte superior de las respuestas?)
Mike Kormendy
1

Si solo desea un puerto de una confirmación, probablemente sea mejor seleccionar la confirmación que desea y restablecer los archivos que no desea que se toquen.

git cherry-pick SHA1
git checkout HEAD file1 file2 ... fileN

Por supuesto, si tiene varias partes modificadas en un archivo y solo desea conservar algunas de ellas, no tiene más remedio que editar el archivo manualmente, eliminando los cambios.

Bombe
fuente
2
¿Es necesario el pago aquí? ¿No pone el comando cherry pick los cambios en su directorio de trabajo?
Casey Watson