Rebase de una única confirmación de Git

116

¿Hay alguna forma de reajustar una única confirmación de una rama a otra rama?

Tengo esta estructura de rama:

-- -- -- -- -- (Master)
            \
              -- -- -- -- -- XX (Feature-branch)

Todo lo que quiero hacer es volver a basar la última confirmación Feature-branchen master y deshacer Feature-branchuna confirmación.

-- -- -- -- -- XX (Master)
            \
              -- -- -- -- -- (Feature-branch)

¿Cómo puedo hacer eso?

Kevin Meyer
fuente
3
Si puede reajustar cualquier número de confirmaciones, ¿por qué pregunta por reajustar una sola? Si pudiera hacer preguntas en SO, preguntaría cuál es la diferencia entre rebasar (una única confirmación) y elegir.
Val
9
Porque no sabía que existía la selección selectiva, y hago "Faff about on branch", "Get request for fix on different branch", "fix it", "Commit to wrong branch", "D'OH!" lo suficiente como para que hacer la pregunta fuera útil.
Kevin Meyer

Respuestas:

116

Puede elegir XX para dominar.

git checkout master
git cherry-pick <commit ID of XX>

Y elimine la última confirmación de la rama de características con git reset.

git checkout Feature-branch
git reset --hard HEAD^
tewe
fuente
64
¿Cómo puede una pregunta específicamente llamada 'git rebase ...' tener la respuesta aceptada que contiene una selección, que es un concepto totalmente diferente y, a veces, per se se considera impuro?
Bondax
1
No estoy seguro de si esto es relevante, pero la confirmación que quería cambiar de base tenía algunos archivos que se movieron y los cherry-pickhizo aparecer como si se hubieran eliminado de la ubicación anterior y se hayan creado en la nueva ubicación. Supongo que rebase se habría encargado de eso, pero a estas alturas he empujado corriente arriba, así que no puedo probar eso. En cualquier caso, tenga cuidado si se encuentra en una situación similar.
waldyrious
Nota: para enviar los cambios Feature-branchal origen, deberá hacerlo, git push -f origin Feature-branchya Feature-branchque ahora se considera que está 1 confirmación detrás de origin/Feature-branch.
jojo
1
¿Cuál es la diferencia práctica entre esta solución y la de CharlesB ?
Lii
96
git rebase --onto master branch~1 branch 

Esto dice "reajustar el rango de confirmaciones entre la última antes de la rama y la rama (es decir, la confirmación XX) en la punta de la rama maestra"

Después de que esta branchsugerencia de operación se mueva en la confirmación XX, entonces desea volver a establecerla con

git checkout branch
git reset --hard branch@{1}^

Que dice "restablecer la sugerencia de la rama a la confirmación antes de su estado anterior"

Entonces, una selección de cerezas es una solución más simple ...

CharlesB
fuente
5
Esto no parece funcionar para mí, pierdo las confirmaciones antes de XX y la rama se vuelve a basar en maestra con una única confirmación, pero nunca las usé --ontoantes, por lo que es posible que esté haciendo algo mal. Por cierto, el OP dijo rebase, pero parece que quiere hacer una selección.
tewe
1
mi error, rebase de hecho mueve la rama en el maestro, debe reiniciarse
CharlesB
1
¿Cuál es la diferencia práctica entre esta solución y la de tewe ?
Lii
1
@Lii, lo único que puedo ver es que usa 3 pasos en lugar de 4
CharlesB
52

En realidad, es bastante sencillo de hacer. La solución es hacer una rebase interactiva y "eliminar" todas las confirmaciones que no desea incluir en la rebase.

git rebase -i <target_branch>¿Dónde target_branchestá la rama en la que desea volver a basarse?

Luego editará el archivo que se abre y picklas confirmaciones que desea y drop(o dpara abreviar) todas las confirmaciones que no desea traer.

hrdwdmrbl
fuente
6
En mi opinión, una solución mucho mejor, y en realidad aborda la pregunta.
GabrielOshiro
Esta debería ser la solución aceptada dado lo general, intuitiva y breve que es.
Pablo Arias
1

La respuesta de @Charles es correcta. De todos modos terminé usando esto tantas veces, sobre todo para reajustar una configuración específica en un proyecto

  * configuración de producción a8f9182 (HEAD -> producción)
  | * configuración de preproducción (pre) daa18b7
  | /  
  | * d365f5f (local) configuración local
  | /  
  * 27d2835 (dev) nueva característica asombrosa que salvará el mundo
* | 56d2467 (maestro) aburrido estado del arte para el proyecto
| /

que creo un nuevo comando para ello:

$ gato ~ / bin / git-rebaseshot 
COMPROMISO = $ 1
DEST = $ {2: -HEAD}
git rebase $ {COMMIT} ^ $ {COMMIT} --en $ DEST

normalmente desea autocompletar los nombres de las ramas para ese comando, así que agréguelo obteniendo esta función (agregando a .bashrc o .profile):

_git_rebaseshot () 
{ 
    __gitcomp_nl "$ (__ git_refs)"
}

git autocomplete lo buscará

puedes usar este comando así:

# rebase config on prepro on actual HEAD
$ git rebaseshot prepro 
# rebase config on local onto dev
$ git rebaseshot local dev
# rebase production config on master
$ git rebaseshot pro master

Cuando divide las características correctamente, las posibilidades son infinitas.

* a8f9182 (HEAD -> postgres) configuración BBDD
* configuración local a8f9182 (local)
* a8f9182 (debug) configuración de nivel de registro
* a8f9182 (dev) nueva característica
|

Supongo que esto es lo que le gusta hacer a la gente de las colchas .

este comando funcionará de todos modos con cualquier sha / ref que proporciones:

$ git rebaseshot <Feature branch> master
$ git rebaseshot <commit of XX> master
albfan
fuente
//, ¿Puedes vincular a algún proyecto donde podamos ver esto en acción?
Nathan Basanese
Por su naturaleza, las sucursales disponibles para rebaseshot no se comprometen fuera del repositorio local. Simplemente cree varias ramas en la parte superior del maestro (nivel de registro, conexión de base de datos, configuración) y use el comando entre ellas. Es fácil ver el efecto.
albfan
//, encontré algunos problemas. Lo intentaré de nuevo.
Nathan Basanese
0

Aquí tienes otra opción:

  1. Asegúrese de tener un control remoto con una copia de la rama de funciones
  2. Eliminar la rama de función local
  3. Cree y realice el pago de una nueva rama con el mismo nombre que la rama de función anterior que acaba de eliminar del maestro
  4. Elija la confirmación de la copia remota de la rama de características que desee.

Los comandos se ven así:

git checkout Feature-branch
git push -u origin HEAD
git checkout master
git branch -D Feature-branch
git checkout -b Feature-branch
git cherry-pick HASH-OF-XX

No es un comando de rebase, no, pero es un rebase en espíritu.

cdmo
fuente