post thumbnail

Git desde Cero: Rebase y Stash.

Publicado Por: Alberto Grespan, El 01/08/2013


Detalles del Curso:

Dificultad: Intermedio

Duración: 30 min


Hemos habilitado un repo en GitHub para que puedas descargar el código de esta entrada:

Échale un vistazo aquí.

Bienvenidos a un nuevo capítulo de Git desde cero en este curso hablaremos de otra forma para realizar la unión de ramas llamada "rebase", de como almacenar cambios sin tener que consolidarlos y cuales son las mejores prácticas a la hora de utilizar estas herramientas. Los comandos a utilizar esta semana serán los siguientes:

  • git rebase.
  • git stash (múltiples comandos).

¿Qué es git rebase ?

Si recordamos en capítulos anteriores, específicamente en el capítulo 5 hablamos sobre la herramienta merge, dicha herramienta es utilizada para unión de ramas. En Git existen dos estrategias "principales" para realizar la unión de ramas, la primera es la conocida merge y la segunda es rebase. Esta herramienta al igual que todas tiene sus pro y sus contra, pero en general una vez que aprendamos su flujo de trabajo se darán cuenta que posiblemente la mejor manera de realizar la unión de ramas en git.

¿Qué hace rebase de especial?

Cuando nosotros utilizamos esta herramienta para unir ramas, git sencillamente reproduce los cambios que consolidamos uno a uno en nuestra rama de trabajo y los lleva a la rama a donde queremos unirlos, es decir, genera una especie archivos virtuales que vienen siendo nuevas consolidaciones en la rama a la que se le unirán los cambios y los ubica uno detrás del otro en el mismo orden que se realizaron. Utilizando la estrategia de "rebase" al unir ramas, nos puede ayudar a evitar conflictos, siempre y cuando se realice con commits que no se hayan hecho públicos, es decir, que no se encuentren en un servidor remoto. Si dichos cambios se encontraran abiertos al público y existiera gente trabajando sobre ellos y a nosotros se nos ocurre aplicar un rebase, puede que los compañeros que están compartiendo el repositorio nos lleguen a odiar, ya que estamos modificando todos los commits y posiblemente el conflicto posterior al rebase sea más difícil de reparar de lo que piensan. Por lo tanto como regla de oro jamas utilicen "rebase" posterior a la realización de un "git push" o sobre "commits" que ya se encuentren en el repositorio remoto.

Pongámonos en marcha y probemos como funciona el rebase!

$ git checkout master

# Creamos una nueva rama llamada readme-branch
$ git checkout -b readme-branch

# Con un editor de texto editamos y escribimos lo siguiente.
$ nano README.md

# pegamos el siguiente texto

# Repositorio git para el curso Git desde cero

Este repositorio conserva absolutamente todo el historial del curso.
Se encuentra clasificado por capítulos almacenados en etiquetas (tags), para
poder observar estos cambios debes revisar el log.

Para bajar el repositorio completo con todos los capítulos de la serie Git
desde Cero, debes clonar el mismo en tú equipo con el siguiente comando:

    $ git clone https://github.com/codeheroco/tutorial-git.git

Luego para ir a un capítulo en específico utilizamos el comando:

    $ git tag -l # listamos los capítulos
    $ git checkout Capitulo-X  # Donde X es el número del capítulo.

De esta manera estamos cambiando al final del capítulo con toda la "solución"
o texto del mismo.

Consolidamos los cambios realizados y posteriormente realizamos el rebase de la rama readme-branch a la rama master de la siguiente manera:

$ git status
$ git add README.md
$ git commit -m "Mejor archivo README"

# aplicamos el rebase.

$ git rebase master
Current branch readme-branch is up to date.

# para que los "commits" virtuales se consoliden en master tenemos que
# unirlos con el merge.

$ git checkout master
Switched to branch 'master'

$ git merge readme-branch
Updating c99705e..48eb2db # en este punto esta consolidando en master.
Fast-forward
 README.md | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

Pudiésemos también aplicar el rebase a una rama sin necesidad de estar ubicados en ella como por ejemplo, estando parados sobre una nueva rama llamada a-v creada a partir de master. Vamos a rebasar la rama readme-branch a master. hagamos la prueba!

$ git chechout -b a-v
$ git rebase master readme-branch
Switched to branch 'readme-branch' # git nos cambia a la rama readme-branch
Current branch readme-branch is up to date. # Actualiza virtualmente master

# cambiamos de rama
$ git co master
Switched to branch 'master'

$ git merge readme-branch
Updating c99705e..48eb2db
Fast-forward
 README.md | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

Listo ya hemos realizado un merge utilizando primero rebase. Recuerden que como buena práctica debemos o deberíamos eliminar las ramas que han sido unidas y por último sino quieren que sus compañeros los odien no vayan a realizar un rebase de una rama pública!.

$ git branch -d readme-branch
Deleted branch readme-branch (was 48eb2db).

Stash

Muchas veces nos encontramos trabajando en una funcionalidad y nos llama un compañero de trabajo pidiendo ayuda o diciéndonos que debemos modificar algo inmediatamente y que abandonemos lo que hacemos por un momento. Cuando esto ocurre sabemos que si nos cambiamos de rama los archivos modificados se vienen a la nueva rama y no queremos eso; por otra parte sería una locura realizar un "commit" incompleto o con código defectuoso ya que esto nos puede traer problemas futuros, es aquí cuando entra en juego nuestro comando "git stash".

¿Qué realiza git stash?

Simplemente almacena todos nuestras modificaciones y restaura nuestra rama al estado original para que cuando nos cambiemos de rama no nos llevemos los cambios incompletos, posteriormente podemos reaplicar estas modificaciones incompletas o borrar las mismas.

¿Cómo lo utilizamos?

Pues muy sencillo, vamos a agregar unos cambios a una nueva rama llamada rama-stash. Para probar como funciona, haremos stash de unos cambios y luego los volveremos a aplicar.

$ git checkout -b rama-stash
Switched to a new branch 'rama-stash'

$ nano README.md

# Agregamos al final del archivo el siguiente párrafo y guardamos.

Recuerden que para la explicación completa de este curso se pueden dirigir a
[codehero.co](http://codehero.co) o directamente a [codehero.co/series/git-desde-cero](http://codehero.co/series/git-desde-cero/)

# Si llegamos a mirar el status podemos apreciar los cambios

$ git status
# On branch rama-stash
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#    modified:   README.md
#
no changes added to commit (use "git add" and/or "git commit -a")

Ahora guardaremos los cambios y posteriormente los volveremos a aplicar.

$ git stash
Saved working directory and index state WIP on rama-stash: 48eb2db Mejor archivo README
HEAD is now at 48eb2db Mejor archivo README

# Miramos el status y vemos que se encuentra limpio

$ git status
# On branch rama-stash
nothing to commit, working directory clean

# Podemos ver los cambios que se encuentran guardados en stash

$ git stash list
Saved working directory and index state WIP on rama-stash: 48eb2db Mejor archivo README
stash@{0}: WIP on rama-stash: 48eb2db Mejor archivo README

Ahora nos toca escoger si queremos reaplicar los cambios o simplemente borrarlos, cualquiera de las dos opciones es posible en este momento.

# Para aplicar los cambios
$ git stash pop
# On branch rama-stash
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#    modified:   README.md
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (f511b3332361558cff180717868ac208132bb2bf)

# para borrarlos
$ git stash drop

Si existiera más de un stash disponible, se tiene que decir explícitamente si queremos reaplicar los cambios o borrarlos de la siguiente manera:

$ git stash pop stash@{0} # Para reaplicar
$ git stash drop stash@{0} # Para borrarlos

El comando stash es uno de los más utilizados cuando requerimos cambiarnos de rama para "arreglar" otro problema o simplemente requerimos un cambio de rama para realizar una prueba. Mi consejo es que siempre que puedan aplicarlo lo hagan y por favor no realicen commits con código con errores.


Conclusión

En este último capítulo y en conjunto con los cursos anteriores hemos adquirido el conocimiento para realizar la unión de ramas de una mejor manera y de como guardar cambios sin realizar un commit en los proyectos que desarrollemos, estos atributos son fundamentales en el flujo de trabajo de git. Profundizaremos un poco más sobre rebase en capítulos posteriores. Si te surge algún tipo de duda no te detengas y déjanos un comentario, que gustosamente lo responderemos.

¡Hasta la próxima semana!


¿Te ha gustado esta publicación?

Compártela:

Por Alberto Grespan

Conoce más sobre este autor aquí


comments powered by Disqus