¡TRANSOLUTIONS AHORA ES PARTE DE BAUFEST!
Ingresa a baufest.com para conocer más sobre nuestros servicios.

BLOG

Viernes, 16 Febrero 2018 08:13

5 cosas que no debes hacer con Git

En esta ocasión Jesus Angulo, Software Architect de Trans Solutions Systems, nos dará cinco consejos bastante útilies para desarrolladores que recién estan empezando a utilizar Git. Estas recomendaciones facilitarán la transición que haga un desarrollador cuando cambie de un sistema de control de versiones a Git. Tendrá una experiencia mejor y evitará algunos errores comunes que se pueden dar.

Creado y distribuido por Linus Torvalds, Git es un sistema de control de versiones, concebido inicialmente para el desarrollo del kernel Linux. Desde su lanzamiento en 2005, Git ha evolucionado convirtiéndose en el sistema de control de versiones por excelencia para el desarrollo de proyectos Open-Source. En los últimos años su popularidad se ha extendido a desarrollos empresariales en adición a proyectos privados.

 

proyecto open source

Al haberse vuelto ubicuo en la industria de Software, muchos desarrolladores que estaban acostumbrados a utilizar un sistema de control de versiones centralizado como TFVC se están obligando a cambiar hacia Git. Por ello, hoy quiero contarles 5 cosas que nunca deben hacer con Git.

1. NUNCA hacer commit directamente a 'master'

Esto sobretodo aplica cuando trabajas colaborativamente usando un repositorio central principal, pero también es válido si uno trabaja sólo. Debemos evitar la mala costumbre de trabajar directamente sobre la rama master. No debemos trabajar nuestros cambios directamente porque estaremos perdiendo una de las características que más aprecio de Git: la capacidad de crear ramas instantáneamente (pues son sólo la referencia a un commit).

flechas turquesas apuntando a la derecha

 

No usar una rama aislada para trabajar en nuevas características sobre nuestro código nos hará mucho más difícil y peligroso el sincronizar nuestras ramas. Esto no nos permitirá subir commits para sub-tareas de una feature más grande sin desestabilizar nuestra rama.

Mi costumbre es crear una nueva rama para cada cosa nueva en la que trabajaré. De esta manera master (o develop) siempre estará listo para cambios rápidos menores o hotfixes.

2. NUNCA hacer git push –force

Normalmente, cuando hacemos push a nuestro repositorio central, los commits que hemos realizado son enviados y colocados "tal cual" encima del estado actual de nuestra rama en el repositorio central. Sin embargo, cuando nuestro repositorio local no está sincronizado con el repositorio central, este último no podrá hacer merge y nos devolverá un mensaje de error.

colisión de ejercitos

Lo correcto en estos casos es que sincronicemos nuestro repositorio local, ya sea con un  git pull o cualquier otra técnica similar. Una vez sincronizado nuestro repositorio local y asegurado de que todo funcione bien proceder a hacer push. Lo peor que podríamos hacer en este escenario es el terrible git push --force. Un push force sobrescribe toda la estructura y secuencia de commits en el repositorio central, tirando a la basura los commits de las demás personas.

La configuración por defecto en Git nos permite hacer esto, pero en la mayoría (por no decir todos) de los casos no deberíamos poder hacerlo. ¿Y cómo puedo evitar que alguien haga un push --force? Depende del servicio que utilices como repo central. De ser el estándar podemos configurarlo con el siguiente comando:

git config --system receive.denyNonFastForwards true

3. NUNCA subir archivos binarios

Los archivos de texto son un punto clave aquí. Los cambios en esta clase de archivos son fácilmente detectables, pero es casi imposible para datos binarios. Los datos acerca de cambios en archivos binarios hacen imposible leer los commits. Sin embargo, hay otra muy buena razón para dejarlos fuera de nuestro repositorio. Generalmente estos archivos como imágenes, binarios compilados o incluso videos son mucho más grandes que los archivos de texto de nuestro código. Entonces si hacemos commit de ellos a nuestro repositorio, el tamaño de este se volverá muy grande.

Hay que aclarar que esto es muy importante. No porque el almacenamiento sea un problema, sino que el punto de tener un VCS distribuido es que sea rápido para clonar y navegar entre las ramas. Siempre querremos coger una nueva máquina y clonar el repositorio tan rápido como sea posible. Queremos ser capaces de cambiar de ramas tan rápido como sea posible, pero si haces commit de un número significativo de archivos binarios te darás cuenta de lo lento que estas tareas se vuelven.

4. NUNCA usar git pull

Ok esto podría sonar un tanto jalado de los pelos, pero es que si hacemos git pull no tendremos oportunidad de ver qué clase de cambios estamos tratando de incorporar. Los cambios podrían ser grandes refactorizaciones con un alto impacto o cambios sencillos de los que no hay que preocuparnos. La recomendación es usar git fetch periódicamente para actualizar solo la referencia a las ramas remotas, darle una inspección rápida y decidir qué hacer.

Para mantener el repositorio limpio, tus commits deberían estar encima de los cambios que los demás han subido al repositorio central hasta que tu hagas push. Para esto en lugar de git pull deberemos usar git pull --rebase. Así los conflictos serán resueltos commit por commit y no todo en uno.

NOTA: No estamos recomendando hacer rebase de un repositorio remoto. Hacer rebase de la historia local está bien, de hecho, es necesario para mantener limpia la historia, pero cambiar la historia de los commits de otras personas es una mala práctica.

5. NUNCA Usar Fast Forward

Si nosotros hacemos git merge directamente, no estamos asegurándonos de crear un merge commit. Los merge commit solo son necesarios cuando ambas ramas que queremos mezclar (merge) tienen nuevos commits.

¿Por qué son importantes los merge commits? Pues bien, sin un merge commit yo no puedo saber que commits representan una "feature" sobre la que se ha trabajado sin inspeccionar uno por uno los commits y sus mensajes.

Veámoslo en acción para no olvidarlo.

Con los siguientes comandos tendremos nuestro repositorio con nuestro primer commit:

git init test

cd test

echo "content" > file.txt

git add *

git commit -m "init"

Creamos una rama, modificamos el archivo file.txt y hacemos commit (hacemos 2 commits para que se vea mejor en la historia): 

git checkout -b branch1

echo "modification" >> file.txt

git commit -am "branch1 modification 1"

echo "modification" >> file.txt

git commit -am "branch1 modif"

merge git

A continuación, hacemos merge sin la opción de fast forward.

git checkout master

git merge --no-ff --log --no-edit branch1

creando una rama git

Ahora, otra vez creamos una rama, modificamos los archivos y hacemos commit.

git checkout -b branch2

echo "modif" >> file.txt

git commit -am "branch2 modif"

echo "modif" >> file.txt

git commit -am "branch2 modif"
creando una rama en git

Finalmente, hacemos merge usando fast-forward:

git checkout master

git merge --ff-only branch2

merge en git usando fast-forward

Como pueden observar, no tenemos forma alguna de determinar en base a la historia la existencia de una rama y saber que commits fueron parte de esa feature. Así que, no olviden usar merge con la opción de --no-ff.