Sistema de ramificaciones
Hasta ahora sólo se ha mencionado cómo trabajar en Git de una forma lineal o plana; es decir, un commit le sigue a otro directamente. A continuación se muestra un diagrama de cómo se representa en Git un historial lineal:
Gran parte de la eficiencia de Git es que guarda un identificador para cada objeto que almacena. Para ello emplea el método para generar valores hash llamado SHA1; entonces el diagrama anterior queda como sigue:
Ahora bien, git tiene una forma de saber que versión del proyecto se está editando. El mecanismo que Git utiliza se basa en referencias a los commits. Estas referencias son en si mismas un objeto Git y por lo tanto, también se pueden referenciar. La referencia que indíca qué versión se está utilizando en el directorio de trabajo se llama HEAD. Continuando con el ejemplo anterior, el diagrama queda como sigue:
Es decir, si queremos trabajar una versión distinta del proyecto, basta con mover el apuntador HEAD al objeto que queramos. Ésto se hace con el siguiente comando:
$ git checkout <ref>
Donde ref es una referencia al objeto sobre el que se quiere trabajar.
Si se ejecuta la instrucción git status
en la primer línea de la pantalla aparecerá un texto "On branch master"; ésto es porque al crear un repositorio git, automáticamente se crea una rama llamada master, que es sobre la que se ha estado trabajando. Una rama es análoga a una línea del tiempo para la historia del repositorio. Entonces HEAD en realidad apunta hacia master, no directamente a un commit, y el diagrama queda como sigue:
Las ramas pueden utilizarse como referencia usando directamente su nombre; es decir, el comando:
$ git checkout master
Mueve HEAD a la rama master (de ser necesario). El nombre de rama se debe a que se pueden crear ramas a partir de otras. Por ejemplo, suponga que en un programa se requiere experimentar con nuevas características; entonces mantenemos la rama principal intacta y creamos una especial para experimentar.
Para crear una rama se utiliza el siguiente comando:
$ git branch cool-feature
$ git checkout cool-feature # Trabajar sobre la nueva rama
# O bien, puede usarse el siguiente atajo
$ git checkout -b cool-feature
Los commits subsecuentes a este comando tendrán efecto sólo sobre la rama cool-feature.
Para ver todas las ramas que existen y saber en cuál estamos se utiliza:
$ git branch # La rama actual aparece resaltada
Para borrar una rama sin commits propios se usa:
$ git branch -d rama
Por lo mencionado anteriormente, si la rama a borrar tiene commits propios, éstos serán eliminados por completo de Git. Si ésto es lo que se desea, el comando a utilizar es el siguiente:
$ git branch -D rama
En ambos casos, se debe hacer checkout en una rama distinta primero; es decir, no se puede borrar la rama actual.
Como ejemplo de cuando usar ramas en git suponga que tiene a su disposición dos bibliotecas de código, pero no sabe cuál de ellos se adapta mejor a sus necesidades (Foundation y Bootstrap, por ejemplo). Lo que se puede hacer en estos casos es lo siguiente:
$ git branch frontend-bootstrap
$ git branch frontend-foundation
$ git checkout frontend-bootstrap
# Probar bootstrap
$ git checkout frontend-foundation
# Probar foundation
Ésto funciona desde cualquier rama, pero para mantener el ejemplo simple suponga que la rama inicial era master. A continuación se muestra un diagrama de esta serie de operaciones:
Al inicio de éste capítulo se mencionó que se había estado trabajando de forma lineal. Otra forma de decir ésto es que un commit sólo tiene un hijo. En este caso, el commit en master tiene dos (para probar Foundation y Bootstrap).