Git rebase –interactive en Git
Lección 31 / 53
Git Guía Git Guía Git español
Una aclaración: el uso del comando git rebase en Git que veremos en esta sección se centrará únicamente en la posibilidad que ofrece de modificar uno o más commit más antiguos que el último guardado, es decir, la ejecución en modo interactive.
Veremos el modo estándar de git rebase (y lo que realmente significa) en otro capítulo.
Como sugiere el nombre, el modo interactive requiere que interactúes con el comando durante su ejecución, para indicarle qué hacer.
En primer lugar, es necesario identificar el commit o el grupo de commit para modificar en el historial, en particular, "cuántos commit atrás" es el primer compromiso que se desea cambiar. En el ejemplo de historial que se muestra al comienzo de esta sección, nos gustaría poder cambiar las commit comenzando con la quinta más antigua (35dec0e trying adding profile page). En este caso se utilizará el comando:
git rebase --interactive HEAD~5
Donde HEAD~5 indica a Git que se prepare para modificar cualquiera o todas las últimas 5 commit.
Cuando se inicia el proceso interactivo de git rebase, el editor predeterminado se abre con un contenido similar al siguiente:
pick b2b95ad wip - unfinished
pick edb709f profile mostly works, missing phone number
pick af75ac9 update indentation for checks from linter
pick 35dec0e increase version
pick 5dd0865 make variable names more clear
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
[...]
La primera parte contiene la lista de commit seleccionadas, desde la más antigua a la más reciente, por lo tanto, en orden inverso con respecto al git log, cada una de las cuales está precedida por un comando de rebase, de default pick. Cada fila se compone de la siguiente manera:
<COMANDO> <COMMIT_ID> <COMMIT_MESSAGE>.
Solo los dos primeros son necesarios para git rebase, el mensaje de commit es para aquellos que preguntarán qué cambios hacer para tener una referencia del contenido de la commit.
La segunda parte contiene la explicación de los diversos comandos de rebase en forma de comentario.
Al guardar y cerrar este texto de la misma manera que cuando se escribe el mensaje de commit, git rebase intentará aplicar el comando proporcionado a cada una de las 5 commit seleccionadas. Si no se aplican cambios, git rebase simplemente volverá a aplicar los mismos cambios. Así que básicamente no hará nada.
En el caso de nuestro ejemplo, nuestra intención era obtener dos commit: uno con todos los cambios necesarios para implementar una característica determinada y otro con solo los cambios que guardan la nueva versión en el proyecto. Según nuestra intención y el contenido de las commit realmente disponibles, las indicaciones para dar a git rebase cambiarán de vez en cuando.
Intentemos esbozar cómo proceder. En nuestro caso, queremos reunir todas las commit que cambian el código fuente para implementar una determinada función y cambiar el mensaje de commit a la commit que solo cambia la versión del proyecto, dejando esto como la commit final. En ese caso, podemos indicarle a git rebase que aplique los siguientes comandos:
pick b2b95ad wip - unfinished
squash edb709f profile mostly works, missing phone number
squash af75ac9 update indentation for checks from linter
squash 5dd0865 make variable names more clear
edit 35dec0e increase version
Para fusionar commit , es necesario tomar la más antigua (pick) e indicar a git rebase que "aplaste" (squash) la inmediatamente siguiente.
Las primeras 4 líneas anteriores le indican a git rebase que fusione cuatro en una sola commit.
La última línea dice que se mantenga el contenido de la commit como está, pero que se cambie el mensaje (edit).
Una cosa importante a tener en cuenta: para fusionar todas las commit que iban a realizar cambios, cambiamos el orden en que aparecían las commit iniciales en el historial del proyecto (las commit 5dd0865 y 35dec0e se invirtieron en el orden de aplicación de los comandos). No siempre es posible invertir el orden de aplicación de las commit, pero en nuestro caso hipotético fue posible hacerlo porque las dos commit iniciales realizaron cambios en archivos diferentes. Nosotros volveremos al problema más tarde.
Al guardar y cerrar el archivo, git rebase procederá a aplicar los comandos recibidos hasta que se requiera la intervención del usuario.
La primera solicitud será proporcionar un nuevo mensaje de commit para las commit "fusionadas".
# This is a combination of 4 commits.
# This is the 1st commit message:
wip - unfinished
# This is the commit message #2:
profile mostly works, missing phone number
# This is the commit message #3:
update indentation for checks from linter
# This is the commit message #4:
make variable names more clear
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
Se reportan los mensajes de los commits que se van fusionando, por conveniencia, pero es posible borrar todo y escribir uno nuevo desde cero. Una vez que se haya escrito el mensaje deseado, simplemente guarda y sal del editor para continuar.
La segunda solicitud de intervención vendrá en el manejo de la última commit que fue parte del rebase.
En este caso, habiendo elegido editar, git rebase no solo te pedirá que ingreses el nuevo mensaje de commit, sino que se mantendrá a un lado temporalmente, dejando espacio para la ejecución de otros comandos.
$ git rebase --interactive HEAD~5
Stopped at 35dec0e... increase version
You can amend the commit now, with
git commit --amend
Once you're satisfied with your changes, run
git rebase --continue
$
En este caso, las instrucciones provistas dicen exactamente qué hacer: ejecutar un git commit --amend que nos permite cambiar el mensaje de commit, seguido de un git rebase --continue para continuar con la ejecución de rebase.
Si todo va bien, git rebase os recompensará con un mensaje alentador de rebase successful.
Si algo sale mal, cuando el proceso se detiene para avisar de la imposibilidad de continuar, podrían volver a aparecer en pantalla las instrucciones para solucionar el problema. En estas situaciones, aún es posible ejecutar git rebase --abort para cancelar la ejecución de rebase.
Cuando la ejecución de rebase es exitosa, las commit modificadas se pierden y se reemplazan por las nuevas en el historial.
Para comenzar a familiarizarse con git rebase y su modo interactive, el consejo es intentar crear pequeños commit "independientes", en los que luego poder volver a basarlos para fusionarlos, cambiar su orden y cosas por el estilo.
git rebase es uno de los comandos Git más "poderosos", porque te permite modificar el historial del repositorio. Dominar su uso puede no ser inmediato, pero convertir las cosas más simples o difíciles también aporta el contenido exacto de la historia de los commits para cambiar/reorganizar/rehacer/…
Siempre es importante prestar atención a qué cambios formarán parte de un commit (y en qué orden), porque de esto también depende la posibilidad futura de reorganizar el historial de tus cambios antes de hacerlos públicos.
Anterior
30 La opción Git commi..Siguiente
32 Atajos para comandos..