Git es un software de control de versiones diseñado por Linus Torvalds, pensando en la eficiencia y la confiabilidad del mantenimiento de versiones de aplicaciones cuando éstas tienen un gran número de archivos de código fuente. Su propósito es llevar registro de los cambios en archivos de computadora y coordinar el trabajo que varias personas realizan sobre archivos compartidos (Git - Wikipedia).

Fundamentos GIT

Los tres estados

Git tiene tres estados principales en los que se pueden encontrar tus archivos:

  • Confirmado (committed)
  • Modificado (modified)
  • Preparado (staged)

Confirmado (committed) significa que los datos están almacenados de manera segura en la base de datos local.

Modificado (modified) significa que se ha modificado el archivo pero todavía no se ha confirmado en la base de datos local.

Preparado (staged) significa que se ha marcado un archivo modificado en su versión actual para que vaya en la próxima confirmación.

Esto nos lleva a las tres áreas principales de un proyecto de Git:

  • El directorio de Git (Git directory)
  • El directorio de trabajo (working directory)
  • El área de preparación (staging area)
Git's areas
Figura 1: Areas de git.

El directorio de Git (Git directory) es donde se almacenan los metadatos y la base de datos de objetos para el proyecto. Es la parte más importante de Git, y es lo que se copia cuando se clona un repositorio desde otra computadora.

El directorio de trabajo (working directory) es una copia de una versión del proyecto. Estos archivos se sacan de la base de datos comprimida en el directorio de Git, y se colocan en disco para que se pueda usar o modificar.

El área de preparación (staging area) es un archivo, generalmente contenido en el directorio de Git, que almacena información acerca de lo que va a ir en la próxima confirmación. A veces se le denomina índice (“index”), pero se está convirtiendo en estándar el referirse a ella como el área de preparación.

El flujo de trabajo básico en Git es algo así:

  • Se modifican una serie de archivos en el directorio de trabajo.
  • Se preparan los archivos, añadiéndolos al área de preparación.
  • Se confirman los cambios, lo que toma los archivos tal y como están en el área de preparación y almacena esa copia instantánea de manera permanente en el directorio de Git.

Si una versión concreta de un archivo está en el directorio de Git, se considera confirmada (committed). Si ha sufrido cambios desde que se obtuvo del repositorio, pero ha sido añadida al área de preparación, está preparada (staged). Y si ha sufrido cambios desde que se obtuvo del repositorio, pero no se ha preparado, está modificada (modified).

Ciclo de vida del estado de los archivos

Cada archivo de un repositorio puede tener dos estados:

  • Rastreados (Tracked files)
  • Sin Rastrear (Untracked files)

Los archivos rastreados (Tracked files) son todos aquellos archivos que estaban en la última instantánea del proyecto; pueden ser archivos sin modificar, modificados o preparados (//staged//).

Los archivos no rastreados (Untracked files) son los demás --cualquier otro archivo del directorio de trabajo que no estaba en la última instantánea y que no están en el área de preparación (//staging area//).

Cuando se clona por primera vez un repositorio, todos los archivos estarán rastreados y sin modificar pues se acaba de sacar y aun no han sido editados.

Mientras se editan archivos, Git los ve como modificados, pues han sido cambiados desde su último commit. Luego se prepara estos archivos modificados y finalmente se confirma todos los cambios preparados, y se repite el ciclo.

Git's lifecycle
Figura 1: Ciclo de vida del estado de los archivos en git.

Comandos básicos

Iniciando un repositorio en un directorio existente

git init

Clonando un repositorio existente

git clone git://gitlab.com/Diavolo/gru.git

Clonar un repositorio a un directorio con nombre diferente del repo remoto

git clone git://gitlab.com/Diavolo/gru.git amapola

Revisando el estado de los archivos

git status

status abreviado

git status -s
  M README
 MM Rakefile
 A  lib/git.py
 M  lib/simplegit.py
 ?? LICENSE.txt

Los archivos nuevos que no están rastreados tienen un ?? a su lado, los archivos que están preparados tienen una A y los modificados una M. El estado aparece en dos columnas - la columna de la izquierda indica el estado preparado (//staged//) y la columna de la derecha indica el estado sin preparar. Por ejemplo, en esa salida, el archivo README está modificado en el directorio de trabajo pero no está preparado, mientras que lib/simplegit.py está modificado y preparado. El archivo Rakefile fue modificado, preparado y modificado otra vez por lo que existen cambios preparados y sin preparar.

Ver los cambios preparados (staged) y no preparados (unstaged)

Ver cambios no preparados (unstaged)
git diff
Ver cambios preparados (staged)
git diff --staged

O también

git diff --cached

Branch

Cada proyecto debe tener un branch principal (usualmente master).

También un branch secundario (usualmente develop) usado para guardar los cambios que serán liberados en la próxima versión.

Para aplicaciones web, las ramas //staging// y //production// pueden ser usados para sus lanzamientos respectivos. En estos casos, el branch //production// será el branch principal

Creación branches

Cuando creamos cambios en el código, se debe de crear un nuevo branch a partir de la rama principal.

git checkout -b feature/feature_name

Nombrando branches

El nombre de una rama debería de seguir alguna de las siguientes categorías:

  • bug: Corrección de un bug. p. ej. bug/sign-in
  • config: A cambiado una configuración. p. ej. config/amazon-settings
  • design: Modificación en el artwork, HTML o CSS para incorporar un nuevo diseño. p. ej. design/sign-up-button
  • dev: El código esta siendo mejorado para mejorar el desarrollo. p. ej. dev/upgrading-django. Esto incluye: actualización de versiones, remplazo de librerías y añadir herramientas de desarrollo como por ejemplo frameworks para realizar testing.
  • documentation: Actualización en la documentación.
  • feature: Una característica de la aplicación que será desarrollada. p. ej. feature/comments
  • hotfix: Corrección de un bug en caliente (que no puede esperar a que sea corregido en la siguiente versión).
  • refactor: Factorización de un fichero fuente. p. ej. refactor/user.py

Renombrando branches

Local y remotamente

git branch -m new_branch                    # Rename current local branch
git branch -m old_branch new_branch         # Rename branch locally    

git push origin :old_branch                 # Delete the old branch    
git push --set-upstream origin new_branch   # Push the new branch, set local branch to track the new remote

Commit

El mensaje de un commit consiste en 3 diferentes partes separadas con una línea en blanco:

  • Título
  • Cuerpo [Opcional]
  • Pie [Opcional]
type: subject

body

footer

El título consiste en el tipo y asunto del mensaje.

Type / Tipo

El tipo es contenido en el título y puede ser de alguno de los siguientes casos:

  • build: Cambios que afectan el sistema de compilación o las dependencias externas. Sin cambios en el código.
  • ci: Cambios en los archivos configuración y scripts de CI (jenkins, Travis, Circle, etc.).
  • docs: Se realizaron cambios en la documentación.
  • feat: Una nueva característica.
  • fix: Se solucionó un bug.
  • perf: Un cambio en el código que mejora el rendimiento.
  • refactor: Un cambio de código que no corrige un error ni agrega una característica/función.
  • style: Cambios que no afectan el significado del código (espacios en blanco, formato, punto y coma que faltan, etc).
  • test: Se añadieron pruebas, refactorización de pruebas. Sin cambios en el código.
  • chore: Cambios en archivos no relacionados a codigo fuente y/o casos no descritos en los tipos anteriormente mencionados. p. ej. Actualización del .gitignore.

Subject / Asunto

El asunto no debe contener mas de 50 caracteres, debe iniciar con una letra mayúscula y no terminar con un punto. Debemos ser imperativos al momento de redactar nuestro commit, es decir hay que ser objetivos y muy importante tenemos que acostumbrarnos a escribirlos en Inglés esto es una de las mejores prácticas que podemos tener en nuestros commits.

Con ser imperativos se hace referencia a este sencillo ejemplo: usar change en lugar de "changed" o "changes".

Body / Cuerpo

No todos los commits son lo suficientemente complejos como para necesitar de un cuerpo, sin embargo es opcional y se usan en caso de que el commit requiera una explicación y contexto. Utilizamos el cuerpo para explicar el ¿Qué y Por qué? de un commit y no el ¿Cómo? Al escribir el cuerpo, requerimos de una línea en blanco entre el título y el cuerpo, ademas debemos limitar la longitud de cada línea a no más de 72 caracteres.

Footer / Pie

El pie es opcional al igual que el cuerpo, pero este es usado para el seguimiento de los IDs con incidencias.

Ejemplo de commit

feat: Summarize changes in around 50 characters or less

More detailed explanatory text, if necessary. Wrap it to about 72 
characters or so. In some contexts, the first line is treated as the 
subject of the commit and the rest of the text as the body. 

The blank line separating the summary from the body is 
critical (unless you omit the body entirely); 
various tools like `log`, `shortlog` and `rebase` can get 
confused if you run the two together. 

Explain the problem that this commit is solving. 
Focus on why you are making this change as oppose
to how (the code explains that). 

Are there side effects or other unintuitive consequenses of this change?
Here's the place to explain them.
Further paragraphs come after blank lines.

- Bullet points are okay, too 
- Typically a hyphen or asterisk is used for the bullet, preceded by a single space,
  with blank lines in between, but conventions vary here

If you use an issue tracker, put references to them at the bottom, like this:

Resolves: #123 
See also: #456, #789

Referencias