Introducción


Progamación en equipo

La programación en equipo de proyectos hoy en día es fundamental, y los beneficios son múltiples tanto para los desarrolladores como para el proyecto. Si vamos a trabajar en un proyecto en equipo con git deberemos saber:

Commits documentados


Cada commit al repositorio debe estar bien documentado, es una recomendación de buenas prácticas de desarrollo a la que si nos acostumbramos ayudaremos mucho a la evolución de los proyectos en los que participemos.


Los commits que realizamos en principio se almacenan únicamente en nuestro repositorio, pero trabajando en equipo lo normal es mandarlos a un repositorio padre en el que participan varias personas.

Commit roñoso

Veamos un ejemplo de un commit mal documentado. Puede que nuestras modificaciones sean perfectas, pero el comentario asociado al commit debe acompañarlas. Ejemplo:

Commit con sustancia

Veamos un ejemplo de un commit bien documentado. La primera línea debe ser un resumen de todos los cambios. En las líneas siguientes podemos explicarlo con detalle, separando los párrafos adecuadamente.

git log


Necesitamos una herramienta con la que poder examinar cuáles han sido los últimos commits al repositorio. Al trabajar en equipo los cambios que hacen los compañeros pueden afectar a nuestro desarrollo. git log es la utilidad que necesitamos para ello.


Veamos algunos ejemplos, aunque git log es muy potente y nos permite parametrizar la consulta en función de lo que queramos obtener, el uso más común es el que vamos a ver en las próximas pantallas.

git log --oneline


Si ejecutamos este comando dentro de un directorio de trabajo veremos un resumen de los últimos commits al repositorio. Muy útil para echar un vistazo rápido a las últimas modificaciones.

git log


Veamos el resultado de ejecutar un git log sin parámetros dentro de un directorio de trabajo clonado del propio repositorio del código fuente de git.

git log --oneline --graph --decorate


Podemos navegar con este comando un proyecto tan complejo como git y ver cómo desarrollan los gurús.

tig


Una herramienta muy útil para examinar el log de un proyecto es tig (website). Utilizando ncurses visualizaremos de forma estructurada los últimos commits permitiendo una navegación cómoda.


Arrancamos tig desde el propio directorio del proyecto para visualizar todo el histórico.
[~/git-puesto-en-practica]$ tig

tig

Atención: necesito vuestra concentración 5 minutos

Trabajando con ramas


Las ramas son bifurcaciones del proyecto, que permiten desarrollar diferentes partes de un software en paralelo.

Facilitan el aislar los cambios sin afectar al resto del desarrollo, para posteriormente fusionar la rama con la master branch (si así lo deseamos).


Una rama nueva se crea con el comando git branch, cambiaremos al contexto de una rama con el comando git checkout, y fusionaremos ramas con git merge.

git branch


Para listar las ramas creadas en el repositorio:

[~/git-puesto-en-practica]$ git branch
* master

La rama principal que siempre tendremos creada se denomina master.


Creamos una rama nueva con el siguiente comando:

[~/git-puesto-en-practica]$ git branch testing
[~/git-puesto-en-practica]$ git branch
* master
  testing

Borramos una rama utilizando el parámetro -d.

[~/git-puesto-en-practica]$ git branch
* master
  testing
[~/git-puesto-en-practica]$ git branch -d testing
[~/git-puesto-en-practica]$ git branch
* master

La facilidad de uso de las ramas nos permite bifurcar una versión concreta del proyecto para empezar a trabajar en una nueva característica, o un bug que haya que solucionar.

git checkout


Podemos cambiar el contexto y comenzar a trabajar con otra rama mediante el comando checkout.

[~/git-puesto-en-practica]$ git branch
* master
  devel
[~/git-puesto-en-practica]$ ls
a.txt
[~/git-puesto-en-practica]$ git checkout devel
Switched to branch 'devel'
[~/git-puesto-en-practica]$ git branch
  master
* devel
[~/git-puesto-en-practica]$ ls
a.txt  b.txt

git merge


Si queremos fusionar una rama con la que actualmente estamos trabajando, utilizaremos git merge:

[~/git-puesto-en-practica]$ git branch
* master
  devel
[~/git-puesto-en-practica]$ git merge devel
Updating 211141d..26b8cd6
Fast-forward
 b.txt |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 b.txt

Git es capaz de resolver conflictos en los cambios de manera automática (y de manera muy inteligente), salvo aquellos que no haya más remedio que resolverlos a mano.

Trabajando con repositorios remotos


Un proyecto git no tiene un repositorio central al que enviar los cambios, pero para colaborar en un proyecto integrado por varios desarrolladores, necesitaremos enviar nuestros cambios a un repositorio común.


Es habitual tener definido un repositorio remoto con el cual interactuaremos enviando nuestros cambios (si tenemos permisos de escritura), o del cual nos traeremos las actualizaciones que se vayan produciendo.

Los repositorios git son todos iguales (no hay diferencia entre cliente y servidor). En algunos tendremos permisos de lectura y en otros permisos de lectura/escritura.

Podemos definirnos todos los repositorios remotos que queramos asociados a nuestro repositorio, de los que obtendremos (y tal vez enviemos) actualizaciones.


El comando que nos permite gestionar los repositorios remotos es git remote.

git remote


Si hemos clonado (con git clone) nuestro proyecto, ya tendremos definido un repositorio remoto, que por defecto se identifica con el alias origin.

El comando git remote -v nos mostrará todos los repositorios remotos que tengamos definidos:

[~/git-puesto-en-practica]$ git remote -v
origin  git@github.com:tombatossals/git-puesto-en-practica.git (fetch)
origin  git@github.com:tombatossals/git-puesto-en-practica.git (push)

git remote add/rm


Añadimos o eliminamos repositorios remotos con estos dos comandos. El nombre (alias) que le damos al repositorio es a nuestro gusto, aunque como convenio se pone el repositorio base como origin.

Añadir un repositorio:

git remote add octopress git://github.com/imathis/octopress.git

Borrar un repositorio:

git remote rm octopress

¡No os durmáis todavía! Viene algo interesante.

Recibir/enviar cambios a los repositorios


Ya sabemos cómo enlazar nuestro repositorio con otros repositorios asociados. Veamos cómo obtener (o enviar) los cambios de un repositorio de nivel superior.

Esta operación es muy útil para estar siempre en sincronía con los cambios que van realizando en el proyecto principal.


git pull


Este comando obtiene los últimos cambios del repositorio remoto, y realiza un merge con el directorio de trabajo.

[~/git-puesto-en-practica]$ git pull
remote: Counting objects: 10, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 3), reused 6 (delta 3)
Unpacking objects: 100% (6/6), done.
From github.com:tombatossals/git-puesto-en-practica
   7d8ccd7..9c0a361  master     -> origin/master
Updating 7d8ccd7..9c0a361
Fast-forward
 acerca-de/index.html                 |   52 ++++++++++++++++++++++++++
 trabajando-en-equipo/images/pull.jpg |  Bin 0 -> 65507 bytes
 trabajando-en-equipo/index.html      |   66 +++++++++++++++++++++++++++++++--
 3 files changed, 114 insertions(+), 4 deletions(-)
 create mode 100644 acerca-de/index.html

git fetch


Tal vez pull sea un comando "demasiado automático". git fetch es una alternativa más controlada, ya que al traerse los cambios del repositorio remoto no los aplica directamente sobre nuestro directorio de trabajo, sino que espera que nosotros lo hagamos manualmente.

Despues de un git fetch es conveniente hacer un diff, comparando las ramas de trabajo local con la del repositorio remoto.

Finalmente, si estamos de acuerdo con los cambios, ejecutaremos un merge.

git push


Enviamos todos los cambios que hemos realizados sobre nuestro repositorio local al repositorio/s remoto/s que tengamos definido/s.

[~/git-puesto-en-practica]$ git push
Counting objects: 10, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 60.16 KiB, done.
Total 6 (delta 3), reused 0 (delta 0)
To git@github.com:tombatossals/git-puesto-en-practica.git
   7d8ccd7..9c0a361  master -> master

Flujo de información en Git (simplificado)

Imagen de Wikipedia