2009-10-26 11 views
74

Supongamos que tengo esta rama de función "foo". Ahora quiero fusionarlo de nuevo en el maestro, pero he agregado un código de depuración que no quiero en el maestro.¿Cómo puedo fusionar muchas confirmaciones, pero dejar una?

El código de depuración está en su propia confirmación, por lo que podría usar git cherry-pick en cada confirmación y omitir este compromiso. Pero eso va a ser bastante tedioso.

¿Hay algo de "inversión inversa" que hace esto, o una combinación interactiva?

Respuesta

54

Uso rebase interactivo:

git rebase -i SHA-OF-FIRST-COMMIT-IN-BRANCH 

que abrirá algo como esto en $ EDITOR:

pick 8ac4783 folders and folders 
    pick cf8b1f5 minor refactor 
    pick 762b37a Lots of improvement. Folders adn shit. 
    pick 3fae6e1 Be ready to tableview 
    pick b174dc0 replace folder collection view w/ table view 
    pick ef1b65b more finish 
    pick ecc407f responder chain and whatnot 
    pick 080a847 play/pause video 
    pick 6719000 wip: movie fader 
    pick c5f2933 presentation window fade transition 

    # Rebase e6f77c8..c5f2933 onto e6f77c8 
    # 
    # Commands: 
    # p, pick = use commit 
    # e, edit = use commit, but stop for amending 
    # s, squash = use commit, but meld into previous commit 
    # 
    # If you remove a line here THAT COMMIT WILL BE LOST. 
    # However, if you remove everything, the rebase will be aborted. 
    # 

Así que lo que hace es simplemente para eliminar la línea que contiene la depuración cometen, se el archive y cierre su editor, y git le dirá algo como:

Successfully rebased and updated refs/heads/master. 

Ahora yo puedes simplemente fusionarte en esa rama para dominar.

ACTUALIZACIÓN: Cabe señalar que la alteración de la historia con rebase debería solo ocurrir en las ramas privadas. Si esta rama ha estado expuesta al público, use git revert según lo propuesto por otro respondedor.

+0

agradable .. y no es una buena manera de llegar al PRIMER-COMPROMISO-EN-RAMA SHA-DE-? –

+0

@DaveVogt sí! Ver http://stackoverflow.com/questions/1527234/finding-a-branch-point-with-git – boycy

67

A pesar de lo que otros SCMs lo usan para significar, en git, git revert es una selección de cereza inversa.

+9

'git revert' registra una nueva confirmación con los cambios apropiados eliminados. –

+11

@mikem: que es, creo, lo que intuitivamente significa una selección inversa de cereza. Ambos 'revert' y' cherry-pick' también tienen una opción '-n' que no realiza un commit pero deja los cambios en el área de caché/index/staging para que los comandos sean muy similares. –

+0

corto y dulce: te alienta a probarlo, pensando que '¡no hay manera de que sea así de simple! ¡Le mostraré! '... y entonces es así de simple. parece funcionar incluso para el código que comencé a seleccionar cuidadosamente pero luego me comprometí normalmente (¿oops?), lo cual creo que tiene sentido, ya que finalmente 'git' se trata de diferencias entre instantáneas, no eventos dependientes. no se. sigo aprendiendo sobre características como esta y esperando que haya una trampa, ¡pero parecen funcionar, todo el tiempo! –

2

Use rebase interactivo para eliminar las confirmaciones que no desea.

En una nueva rama "foo-merge" creado a partir de "foo":

git rebase -i master 

Una vez que esté en la modalidad de confirmación editar, eliminar las líneas que contienen la depuración se compromete, guardar y salir del editor.

Después de cambio de base, sólo tiene que tirar de foo-funden en master:

git checkout master 
git pull . foo-merge 
+0

¿Repitiendo mucho? –

+1

Un poco difícil de contribuir a través de comentarios cuando no está permitido. FWIW, voté su respuesta antes de decidir que la mía sería lo suficientemente diferente como para ser una entrada separada, y luego archivarla. –

7

Otra idea es añadir el revirtió confirmar sobre el uno con código de depuración y para fusionarlo en su rama principal. Luego eliminamos ese compromiso extra en la rama foo.

git checkout foo 
git revert COMMIT_REF_WITH_DEBUG_CODE 

git checkout master 
git merge foo 

git checkout foo 
git reset --hard HEAD~1 

Asegúrate de que tu árbol de trabajo esté limpio. Primero crea la confirmación revertida. Luego, combínalo en maestro. Luego reinicie el puntero de rama de la rama foo al padre de la confirmación revertida, por lo que vuelve a estar en su estado original.

Si no le gusta usar git reset, puede crear una bifurcación temporal donde crea la confirmación revertida. Al final, eliminas la rama temporal.

Cuestiones relacionadas