Este es el primer post sobre git de una serie que llamaré Git World en la que iremos descubriendo cómo trabajamos dentro del equipo de desarrollo con git y qué herramientas os pueden resultar útiles para sacar el máximo partido a vuestro control de versiones.
En Visualtis S.L. llevamos muchos años haciendo uso de git como herramienta de control de versiones y hemos probado distintos flujos de trabajo. Es fundamental definir en vuestro equipo cómo interactuar con git para que todos los miembros del equipo sepan que deben hacer en cada instante.
Como he comentado se pueden usar distintos flujos de trabajo dependiendo sobre todo del tamaño del proyecto y el número de desarrolladores implicados en el mismo. Para un proyecto medio con dos o tres desarrolladores proponemos este flujo de trabajo.
- Nos bajamos el proyecto del repositorio central con git clone.
git clone ssh://servidor/rutaproyecto proyecto
- Esto nos crea una rama master en nuestro repositorio local que está sincronizado con el central.
- Creamos una rama local para desarrollo. Ésta se puede llamar work, develop o el nombre que más os guste. Esta rama será local y nunca deberá ser publicada en el servidor.
git checkout -b work
- En esta rama desarrollaremos nuevas funcionalidades y arreglaremos bugs haciendo commits unitarios para conservar la trazabilidad. Nosotros añadimos una referencia a la petición de Redmine a la que pertenece ese cambio o fix.
git add . // añadimos todos los archivos al índice
git commit -m "refs #xxx Fix del bug xxx" // consolidamos los cambios en los archivos en nuestra rama local
- Cuando estemos seguros de que nuestra funcionalidad está ok, iremos a nuestra rama master (local) y nos traeremos los cambios de otros miembros del equipo hayan podido hacer. Como hemos dicho al principio, al hacer el git clone, la rama master local estaba sincronizada con la rama master remota en aquel momento. La idea de nuestro flujo es que siempre nuestra rama master local esté siempre libre de conflictos.
git checkout master //cambio de rama
git pull origin master // nos traemos cambios de otros miembros del equipo
- Al traernos cambios de la rama master remota veremos commits de otros miembros del equipo. Estos commits los podemos ver con
git log
- Nunca habrá conflictos en este paso puesto que nuestro flujo evitará hacer mezclas de código en esta rama.
- Volvemos a nuestra rama local y hacemos la mezcla de código con un
git rebase master
. En posteriores entradas explicaremos la diferencia de hacer merges o rebases.
git checkout work // cambio de rama
git rebase master // mezclamos nuestros cambios con los recuperados en el paso anterior
- En este paso nos podemos encontrar conflictos si nuestro equipo ha tocado los mismos archivos que nosotros. Si se da el caso, debemos resolver los conflictos (adaptando el código que git no ha podido mezclar correctamente), añadiremos esos archivos conflictivos al índice y continuaremos el rebase.
// arreglamos archivo_en_conflicto
git add archivo_en_conflicto // añadimos al índice el archivo en conflicto arreglado
git rebase --continue
- Una vez hayamos terminado el rebase nos falta publicar nuestros cambios en el repositorio central. Para ello primero debemos mezclar los cambios de nuestra rama local de desarrollo con nuestra rama master local, y luego hacer push para copiar esos cambios en el repositorio central.
git checkout master // cambio de rama
git merge work // mezclamos nuestra rama master local con nuestra rama de desarrollo
git push origin master // publicamos en la rama master remota
- Por último siempre debemos volver a nuestra rama de desarrollo para evitar hacer cambios en nuestra rama master local
git checkout work
Este flujo de trabajo funciona realmente bien si todos los miembros del equipo lo conocen y si lo aplican rigurosamente los conflictos y problemas que se puedan derivar serán controlables y fácilmente solucionables.
En próximas entregas seguiremos viendo aspectos y funcionalidades sobre git.
Un saludo
Jose A. Ródenas «rodio»
CTO en Visualtis S.L.