Estoy leyendo Pro Git, la primera y la segunda edición. Gracias a este libro, me dí cuenta de que no conocía ni la mitad de lo que puede ofrecer Git. Estoy utilizando Git desde hace tiempo pero en realidad, mi manera de usarlo lo hace totalmente inútil.
1. Estados de un archivo
Un archivo puede estar bajo seguimiento (tracked) o sin seguimiento (untracked). Git controla las versiones de los archivos que están bajo seguimiento. Los archivos que están bajo seguimiento pueden estar además en 3 estados:
- Sin modificaciones: Significa que está en el mismo estado que la última instantánea tomada por Git.
- Modificados: Significa que es diferente respecto a la última instantánea tomada por Git.
- Preparados: Significa que si haces commit ahora mismo, el estado actual de este archivo será el que se guarde.
Durante toda mi vida, he utilizado prácticamente sin pensarlo:
git commit -a
Esto significa que cada vez que confirmaba mi trabajo (commit), estaba enviando todo lo que había modificado. Esto puede ser útil en algunos casos, pero no siempre como verás más adelante.
2. Un commit para cada cosa
Como decía anteriormente, nunca presté atención a lo que confirmaba. A veces, programaba durante días sin confirmar nada, y al cabo de un tiempo, confirmaba todo junto. El mensaje de confirmación en ocasiones era tan escueto como:
Arreglados algunos bugs
Otras veces, escribía 10 o 15 líneas explicando todo lo que había hecho.
Estos dos tipos de confirmaciones con sus mensajes son malas y poco útiles, pero el mayor error está en confirmar muchos cambios que no guardan relación entre sí. Utilizar Git de esta manera no sirve de nada. El objetivo del control de versiones es facilitarte la vuelta a una versión anterior. Te permite almacenar un histórico de trabajo. Si tu histórico está hecho un desastre, tu control de versiones es inútil, es como si no tuvieras nada.
Cada commit debe contener sólo un bug o al menos debe ser coherente. Debes enviar confirmaciones más a menudo y con menos contenido. Esto te facilitará el trabajo cuando tengas que recuperar tu trabajo o volver atrás en el futuro. Te permitirá entender tu histórico de cambios ya que tus mensajes de confirmaciones serán claros y directos.
3. Formato de los mensajes
Utiliza la regla siguiente a la hora de redactar el mensaje: “Cada mensaje de commit debería ser capaz de completar la siguiente frase”:
Cuando sea aplicado, este commit … Arreglará el error al enviar un email
Cuando sea aplicado, este commit … Cambiará el css del formulario de contacto
Un buen mensaje de commit debería tener una primera línea con máximo 50 caracteres, luego una línea en blanco y después te puedes explayar todo lo que quieras. Esto te va a permitir tener un histórico de cambios mucho más claro y si sacas el histórico en una línea verás un histórico perfectamente entendible para cualquiera.
4. Si te equivocas, git commit –amend
Si te equivocas al enviar un commit, no envíes otro commit para arreglarlo.
Si te das cuenta de que tenías que haber enviado otro archivo además de lo que enviaste. Hazlo ahora con git add nombre_de_tu_archivo y después utiliza:
git commit –amend
Si quieres reescribir tu mensaje, reescríbelo. De esta forma, estás modificando lo que enviaste en tu último commit en vez de enviar uno nuevo. Mantén tu histórico limpio y claro.
Recuerda que sólo deberías hacer esto si todavía no has enviado tus cambios a un servidor remoto con git push. Si hicieras esto después de haber enviado tus cambios, podrías meter en problemas (infierno de conflictos) a otra persona que puede haber descargado tu trabajo y hecho cambios después del commit que tu quieres modificar. Si estás seguro de que no vas a meter a nadie en problemas, entonces git push -f forzará la sobreescritura de tu último commit.
5. git stash
Suelo trabajar casi siempre con al menos 3 ramas:
- master: La rama original creada por git que es la rama principal. Tiene todos los cambios que han sido probados y Aprobados.
- live: Esta rama contiene la versión que está en producción actualmente. Suele ir por detrás de master. Cuando el cliente da el visto bueno, hago un merge con master y si todo va bien, ya está el cambio en producción funcionando.
- nombre_de_la_rama_en_que_trabajo: Esta rama es la rama en la que estoy trabajando actualmente. Le doy un nombre que me ayude a entender de qué va.
Si trabajo en otra funcionalidad, suelo crear otra rama más por cada funcionalidad en general.
Hasta hace relativamente poco, cuando me llegaba algún imprevisto, o creaba una rama nueva, o lo solucionaba directamente en la rama en la que estaba trabajando. Lo que hacía era hacer commit con el estado actual de mi trabajo y me ponía a trabajar en el imprevisto. Al final, tenía un histórico desorganizado ya que enviaba confirmaciones con cosas sin acabar, cosas que fallaban o cosas que finalmente ni siquiera iban a ser parte de la solución.
git stash permite hacer un guardado de los archivos que tienes actualmente en tu directorio de trabajo. Esto significa que hace una copia de lo que tienes y limpia tu directorio de trabajo volviendo a tu último commit. Puedes resolver entonces el imprevisto, hacer el commit relacionado con ese imprevisto y volver a recuperar tu trabajo guardado con git stash pop.
Aprender no es perder el tiempo
Por muy poco tiempo del que dispongas, es importante dedicarle tiempo a estudiar tus herramientas y aplicaciones. Llevo años utilizando Git y por lo que he podido leer estos días, es como si no estuviera utilizándolo. Hasta hoy, he tenido suerte porque no he tenido que indagar en mi histórico de cambios o recuperar versiones antiguas, pero si hubiera tenido que hacerlo, posiblemente habría sido un desastre. Invertir tiempo en aprender a utilizar tus herramientas de trabajo no es perder el tiempo, es todo lo contrario.
Si quieres aprender más cosas sobre Git pero no el libro, leéte este artículo: 19 Tips For Everyday Git Use.