# Convención Git Al igual que otras guías de estilo de programación, los temas tratados abarcan no sólo cuestiones estéticas de formato, sino también otros tipos de convenciones o estándares de codificación. Sin embargo, este documento se centra principalmente en las reglas estrictas y rápidas que seguimos universalmente y evita dar consejos que no sean claramente aplicables (ya sea por humanos o herramientas). ![Histórico Git](https://images.unsplash.com/photo-1556075798-4825dfaaf498?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&ixlib=rb-1.2.1&auto=format&fit=cover&w=720&h=480&q=10) Este documento sirve como la definición completa de los estándares de GIT para El Tiempo ADS. Un Repositorio se podrá describir como _**Estilo CEET**_ si y sólo si se adhiere a las reglas en este documento. ## Tabla de contenido [Toc] ## Branches * Usa nombres cortos y descriptivos. * El nombre descriptivo de la rama debe ser imperativo. * Los identificadores de problemas, bugs, Historias de Usuario o tickets podrán ser referenciadas en el nombre de sus ramas. * Nombra tus ramas en minúscula, a excepción de identificadores externos. * Usa guiones para separar las palabras. ```bash # bien git checkout -b ADP15-migración-del-api git checkout -b ADP15-mejorar-performance-componente-x git checkout -b ADP15-refactor-redux-of-auth-module # mal - Poco descriptivo git checkout -b arreglo_sencillo git checkout -b ADP15-solucionar-bug ``` * En caso de que varios desarrolladores colaboren en una misma característica, es conveniente tener ramas personales para cada miembro del equipo y una para el equipo entero. en tales casos usar la siguiente convención. ```bash git checkout -b ADP15-feature-x/master # Branch del equipo entero git checkout -b ADP15-feature-x/maria # Branch personal de María git checkout -b ADP15-feature-x/nick # Branch personal de Nick ``` Se pueden hacer integraciones o `merges` desde las `branches` personales al `branch` del equipo ( ver ["Merging"](#Merging)). Eventualmente, el `branch` del equipo será integrado a "master". Elimina tú `branch` del repositorio remoto después de haber sido integrado a menos que haya una razón especifica de no hacerlo. _Consejo: Usa el comando a continuación desde "master" para mostrar branches integrados:_ ```bash git branch --merged | grep -v "\*" ``` ## Commits * **Cada commit debe de estar compuesto por un sólo cambio lógico** No debes de tener varios cambios lógicos en un commit. Por ejemplo, si un cambio corrige un error y, a la vez, optimiza el rendimiento de un aspecto de la aplicación, debes separarlo en dos commits. _Consejo: Usa `git add-p` para interactivamente montar/stage partes específicas de los archivos modificados._ * **No separes un sólo cambio lógico en varios commits** Por ejemplo, una nueva implementación junto con sus pruebas o tests correspondientes deben de estar en el mismo commit. * **Realiza commits temprano y frecuentemente** Commits que son pequeños y autónomos son más fáciles de entender y revertir si algo sale mal. * **Los commits deben de ser ordenados lógicamente** Por ejemplo, si el commit A depende de los cambios hechos en commit B, entonces, el commit B debe de realizarse antes del commit A. _Nota: En caso de estar trabajando sólo en un branch local que (no se ha integrado*, es totalmente aceptable de usar commits para capturar el estado de tu trabajo. Sin embargo, sigue siendo cierto que los reglas descritas previamente aplican antes de su integración.)_ ### Mensajes * **Usa tu editor y no tu terminal cuando escribes un mensaje para el commit** Realizar commits desde la terminal fomenta la mentalidad de que es necesario hacer que quepa todo en una sola linea lo cual usualmente resulta en mensajes ambiguos y poco informativos. ```bash # bien git commit # mal git commit -m "Corrección rápida" ``` #### Estructura del mensaje Tenemos reglas muy precisas sobre cómo se pueden formatear nuestros mensajes de confirmación de git. Esto conduce a mensajes más legibles que son fáciles de seguir al revisar el historial del proyecto . Pero también, usamos los mensajes de confirmación de git para generar el registro de cambios. > La especificación de [Conventional Commits][Conventional-Commits] es una convención liviana que se aplica a los mensajes de los commits. Esta especificación proporciona un conjunto fácil de reglas para crear un historial de commits explícito ajustada a [SemVer](http://semver.org/), al describir las características, correcciones y cambios que rompen la compatibilidad en los mensajes de los commits. > > [Conventional Commits v1.0.0][Conventional-Commits] ##### Formato de mensaje de confirmación Cada mensaje de confirmación consta de un encabezado , un cuerpo y un pie de página. El encabezado tiene un formato especial que incluye un tipo , un alcance y un asunto: ```tex= <type>(<scope>): <subject> <BLANK LINE> <body> <BLANK LINE> <footer> ``` Ejemplos: * [Ejemplos Conventional Commits][Conventional-Commits-Examples] * [Ejemplos Angular Commits][Angular-Commits] ##### Revert Si el commit revierte un commit anterior, debe comenzar con `revert:`, seguido del asunto del commit revertido. En el cuerpo deberá decir: `Esto revierte el commit <hash>` donde el hash es el `SHA` del commit que se revierte. ##### Tipos Dependiendo del contexto de las aplicaciones pueden haber más o menos que los señalados a continuación: * **fix:** DEBE ser usado cuando el commit soluciona un error en el código de la aplicación. * **feat:** DEBE ser usado cuando un commit agrega una nueva característica a la aplicación. * **build:** DEBE ser usado cuando los cambios afecta el sistema de compilación o dependencias de la aplicación. * **ci:** DEBE ser usado cuando los cambios afectan los archivos de configuración relacionados con sistema de **integración continua**. * **docs:** DEBE ser usado cuando los cambios afectan únicamente a la documentación. * **perf:** DEBE ser usado cuando los cambios mejoran el rendimiento. * **refactor:** DEBE ser usado cuando el código **no** corrige un error, **ni** agrega una característica. * **style:** DEBE ser usado cuando los cambios no afectan el significado del código (espacios en blanco, puntos y comas, formato... etc). * **test:** DEBE ser usado para agregar pruebas unitarias adicionales, o corregir pruebas existentes. Todos los tipos antes mencionados PUEDEN ser acompañados de un alcance para su mejor comprensión. ###### Alcance Es el nombre del Módulo afectado (cómo lo percibe la persona que lee el registro de cambios a partir de los commits) A continuación, se muestra una lista de posibles alcances: * Authentication * Authorization * Utils * Commons * Core * Users * Permissions * Roles * Lang * Campaigns * Advertisers * Advertisements * Docs: Se puede usar para cambios relacionados con la documentación oficial dentro del directorio del proyecto o librería. ###### Asunto La primera linea del mensaje de commit, debe ser descriptiva y concisa. Idealmente, esta línea no debe de tener más de 50 caracteres. Debe de ser capitalizada y escrita en el imperativo. No es necesario que termine en punto final, puesto que sirve como el título del commit. ```tex= # bien - modo imperativo, usa mayúsculas y tiene menos de 50 caracteres Marcar registros como obsoletos tras falla # malo arreglé ActiveModel::Mensajes de error cuando AR fue usado correctamente ``` ###### Cuerpo Después del título debe ir una línea en blanco seguida por una descripción más completa del commit. Cada línea debe de tener 72 caracteres o menos y debe de explicar la razón por la cual el cambio es necesario, cómo rectifica el problema y qué efectos secundarios puede tener. También debe proporcionar cualquier recurso relacionado (por ejemplo, un enlace al issue correspondiente en el bug tracker): Al final cuando escribes el mensaje de un commit, piensa sobre qué necesitarías saber si te encuentras con este commit después de un año. ###### Dependencias Si un commit A depende de commit B, la dependencia debe de ser escrita en el mensaje de commit A refiriéndote a commit B por su respectivo hash de SHA1. Del mismo modo, si un commit A corrige un error introducido por commit B, este también se debe de indicar en el mensaje de commit A. Si un commit ha de entrar al proceso de squash con respecto a otro commit, usa --squash y --fixup respectivamente, con el fin que la intención sea clara: _Consejo: Usa `--autosquash` al realizar un rebase.(Los commits marcados entrarán al proceso de squash automáticamente.)*_ ##### Ejemplo ```tex= docs: Resumen corto de no más de 50 caracteres. Texto opcional detallando aspectos del cambio en el commit donde cada linea debe tener un máximo de 72 caracteres. En ciertas situaciones, la primera linea del mensaje se trata como el asunto de un correo electrónico y el resto del mensaje como su cuerpo. La línea en blanco que separa el resumen del cuerpo es crítica (a menos que se omita el cuerpo en su totalidad), ya que herramientas como rebase se pueden llegar a confundir si ambas partes están juntas. Párrafos adicionales vienen después de líneas en blanco. - Se pueden crear listas las cuales consisten de un guión o un asterisco seguido por un sólo espacio y con lineas en blanco entre sí. Vínculos a recursos relacionados pueden ser agregados al final del mensaje: Corrige: #APD56, #78 Véase también: #ADP12, #34 Fuente http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html ``` ## Merging * **No reescribas el historial ya publicado** El historial de un repositorio es muy valioso, ya que muy importante poder saber qué ocurrió exactamente en un momento dado. Alteraciones al historial es una fuente común de errores para todos aquellos trabajando en el proyecto. Sin embargo, existen casos legítimos en los cuales reescribir el historial es aceptable. Estos casos son cuando: * Tú eres el único trabajando en la branch y la branch no será revisada. * Tú quieres reorganizar tu branch (p. ej. squash commits) y/o hacer un rebase de tu branch con respecto a "master". Dicho esto, nunca reescribas la historia del branch "master" o de cualquier otro branch especial como aquellos usados en producción o en los servidores de control de calidad. * **Mantén el historial limpio y simple** Antes de someter tu branch a un merge: * Asegúrate que se acomoda a la guía de estilo escogida para el proyecto y realiza las acciones necesarias en caso de que no se acomode. * Haz un rebase con respecto al branch que ha de recibir el merge: ```bash [mi-branch] $ git fetch [mi-branch] $ git rebase origin/master # Ahora haz el merge ``` Esto resulta en un branch que puede ser directamente aplicado al final del branch "master" lo cual simplifica el historial del proyecto. _Nota: Esta estrategia es más adecuada para proyectos con branches de corta duración. Si no es así, es posible que sea mejor ocasionalmente hacer un merge en vez de un rebase con la branch "master"._ * Si tu branch incluye más de un commit, no hagas un merge con fast-forward: ```bash # bien - asegura que un commit del merge sea creado git merge --no-ff mi-branch # mal git merge mi-branch ``` ## Notas adicionales * Existen varios estilos, flujos de trabajo o workflows y cada uno tiene sus fortalezas y debilidades. El hecho de que un workflow encaje con un proyecto en específico depende del equipo, de aspectos del proyecto en sí y de tus procesos de desarrollo. Dicho esto, es importante elegir y mantener un workflow específico. * El tener un estilo constante en el repositorio hace que sea fácil entender lo que está pasando a través del log o registro. * Prueba/crea tests antes del push. No hagas un push con un trabajo no terminado. * Usa Tags Anotadas para marcar lanzamientos/releases u otros puntos importantes en el historial. * Usa Tags Ligeras para uso personal, como para marcar commits y facilitar su búsqueda en el futuro. * Mantén tus repositorios en buenas condiciones al hacerles mantenimiento ocasionalmente: * [git-gc(1)](http://git-scm.com/docs/git-gc) * [git-prune(1)](http://git-scm.com/docs/git-prune) * [git-fsck(1)](http://git-scm.com/docs/git-fsck) ## Referencias * [Conventional Commits][Conventional-Commits] * [Guía de contribución de Angular][Conventional-Commits] * [Guia de estilos GIT por jeko2000][Jeko2000] * [Guia de estilos GIT Reaction Commerce][Reaction Commerce] * [Palabras clave para usar en RFC para indicar niveles de requisitos][RFC2119] [Conventional-Commits]: https://www.conventionalcommits.org "Conventional commits" [Conventional-Commits-Examples]: https://www.conventionalcommits.org/es/v1.0.0-beta.3/#ejemplos "Conventional commits example" [Angular-contributing-guide]: https://github.com/angular/angular/blob/22b96b9/CONTRIBUTING.md "Guía de contribución de Angular" [Angular-Commits]: https://github.com/angular/angular/commits/master "Commits Angular" [Jeko2000]: https://github.com/jeko2000/git-style-guide/#mensajes "git-style-guide" [RFC2119]: https://www.ietf.org/rfc/rfc2119.txt "Palabras clave para usar en RFC para indicar niveles de requisitos" [Udacity]: https://udacity.github.io/git-styleguide/ "Udacity Git Style guide" [Reaction Commerce]: https://docs.reactioncommerce.com/docs/git-style-guide