Ramas y uniones en git

Guía con los principales comandos para ramas, una de las grandes características del sistema de control de versiones git

Antes de leer este artículo conviene haber leído el anterior: uso básico de git.

Una rama representa una línea independiente de desarrollo, es como crear un nuevo área de trabajo con su área de ensayo y su historial. Los nuevos commits se registrarán de forma independiente en el historial la rama, lo que se conoce como forks en el historial del proyecto (término muy empleado en github).

Listar, crear y manejar ramas, git branch

git branch

Este comando lista las ramas locales que existen. La rama en la que estás trabajando actualmente se señala con un asterisco *. La rama master es la rama con la que se comienza en cualquier proyecto, y es la que se utiliza como rama principal donde se encuentra el proyecto en su estado final.

git branch [rama]

Este comando crea una rama con el nombre que elijas.

git checkout experimento

Si hemos nombrado a la rama "experimento", este comando nos sitúa en esa rama.

Si estábamos en la rama master, teníamos archivos modificados sin añadir o añadidos en el área de ensayo, y nos situamos en la rama experimento con git checkout, éstos cambios se verán en la rama experimento. Hasta que no se haga un commit, los cambios no pertenecerán a ninguna rama.

git branch -v

Este comando muestra el último commit en cada rama.

git checkout -b [rama]

Este código crea una rama y hace checkout directamente en la misma. Es el código que se suele usar ya que cuando se crea una rama normalmente se suele hacer checkout en ella.

Es bastante frecuente crear una rama, hacer los cambios que sean necesarios, unirla a una rama principal y después eliminar la rama que se había creado. De esta forma si has estado haciendo cambios que realmente no han resultado ser buenos puedes deshacerte de la rama con facilidad.

git branch -d [rama]

Este código elimina una rama.

Unir una rama a la rama actual, git merge

Una vez que has trabajado en una rama, lo normal es querer incorporar los cambios a la rama principal. Para unir una rama a la actual se utiliza el siguiente comando:

git merge

Cuando sólo se han añadido o eliminado archivos en una rama, es fácil unirla a la principal. El resultado simplemente será la suma o resta de esos archivos en la principal. Cuando se hacen modificaciones en archivos, incluyendo cambios en los nombres de los archivos, git detecta esos cambios y los adapta automáticamente, pero a veces surgen conflictos.

Solucionar conflictos entre las ramas

Los conflictos aparecen cuando se ha modificado la misma parte de código en dos ramas diferentes.

Pongamos que tenemos un proyecto con un archivo de texto llamado hola.txt, donde sólo aparece una línea de texto que dice "Hola que tal". Estamos en la rama master.

Creamos y hacemos checkout en una rama llamada cambios:

git checkout -b cambios

Abrimos el archivo hola.txt y cambiamos "Hola que tal" por "Hola como estás".

Volvemos a la rama master con git checkout master. Cuando intentamos unir la rama cambios con git merge cambios, aparece lo siguiente:

Auto-merging hola.txt
CONFLICT (content): Merge conflict in hola.txt
​Automatic merge failed; fix conflicts and then commit the result.

Abrimos el archivo hola.txt (seguimos en la rama master) y ahora el texto aparece así:

<<<<<<< HEAD
Hola que tal
=======
Hola como estás
>>>>>>> cambios

Removemos las partes que ha añadido git en el código, solucionamos el conflito creado y añadimos el resultado al área de ensayo con git add .

Si ya no queremos hacer más cambios podemos hacer commit directamente: git commit -m "Nuevo saludo implementado".

Ahora la rama master tendrá los cambios que queríamos de la rama cambios, y ésta tendrá el código que tenía antes. Puedes comprobarlo con git checkout cambios. Si ya no se va a utilizar la rama, procedemos a eliminarla con git branch -d cambios.

Mostrar el historial de instantáneas de una rama, git log

Git posee un comando que muestra todos los commits que han llevado a la instantánea en la que te encuentras:

git log

Cuando se hace un git commit, git almacena los archivos de la instantánea, el mensaje e información de la persona que lo realizó (nombre y email). Pero git también almacena la instantánea en la que se basa. Cuando se clona un proyecto, se guarda la instantánea inicial y eso permite registrar quién y cómo se han efectuado los cambios posteriores. El commit en el que se basa un nuevo commit se llama padre (parent).

Para ver por orden cronológico la lista de padres de una rama se usa el comando git log. Para verlo de forma más reducida se emplea:

git log --oneline

Y de forma esquematizada:

git log --oneline --graph

Si se añade el nombre de la rama se ven sólo los cambios realizados en esa rama. Por ejemplo en la rama experimento:

git log --oneline --graph experimento

Marcar la importancia de una instantánea con una etiqueta, git tag

Cuando se llega a una instantánea en el desarrollo de un proyecto en el que se cree conveniente marcar como importante, se utilizan las etiquetas. Las tags actúan como un marcador en un commit específico, normalmente para marcar diferentes versiones de un proyecto:

git tag -a v2.0

La -a permite añadir un mensaje, además de registrar quien lo añadió y cuándo. Se abre el editor vim y se escribe una descripción de la versión.

Para ver el historial git log con los tags, se añade decorate:

git log --oneline --decorate --graph

Fuentes: gitref.org, git-scm.com