git cometer las mejores prácticas

Estoy usando git para administrar un proyecto de C ++. Cuando estoy trabajando en los proyectos, me resulta difícil organizar los cambios en compromisos cuando se cambian cosas que están relacionadas con muchos lugares.

Por ejemplo, puedo cambiar una interfaz de class en un file .h , que afectará al file .cpp correspondiente, y también a otros files que lo utilicen. No estoy seguro de si es razonable poner todas las cosas en un gran compromiso.

Intuitivamente, creo que los commits deben ser modulares, cada uno de ellos corresponde a una actualización / cambio funcional, para que los queueboradores puedan elegir cosas en consecuencia. Pero parece que a veces es inevitable include muchos files y cambios para que un cambio funcional realmente funcione.

La búsqueda no me proporcionó ninguna buena sugerencia o consejos. Por lo tanto, me pregunto si alguien podría darme algunas buenas prácticas al hacer commits.

PD. He estado usando git por un time y sé cómo agregar / rebase / dividir / modificar de forma interactiva / … Lo que estoy pidiendo es la parte de FILOSOFÍA.

Actualización: gracias por todos los consejos. Tal vez esto debería aprenderse de la práctica. Mantendré el problema abierto durante un time para ver si hay más sugerencias.

Tiendo a comprometerme como propones: una confirmación es un set de cambios lógicamente conectado. Mis compromisos pueden ser desde un único linaje hasta un cambio en todos los files (por ejemplo, agregar / cambiar un aviso de copyright en los files fuente). El motivo del cambio no tiene que ser una tarea completa que estoy implementando, pero generalmente es un hito en la tarea.

Si he modificado algo que no está relacionado con mi compromiso actual, tiendo a hacer un complemento interactivo para separar también los cambios no relacionados, incluso cuando se trata de un espacio en blanco orderado.

He encontrado que confirma que simplemente volcar el estado de trabajo al repository los hace mucho less útiles: no puedo respaldar una corrección de errores en una versión anterior o include una funcionalidad de utilidad en otra twig fácilmente si las confirmaciones están por todas partes.

Una alternativa a este enfoque es utilizar una gran cantidad de pequeños commits dentro de una twig de características, y una vez que se haya completado toda la function, realice una reescritura de historial pesado para orderar las confirmaciones en una estructura lógica. Pero encuentro que este enfoque es una pérdida de time.

Este es exactamente el caso de uso, para el cual el index , el área de ensayo, se introdujo en git.

Puede sentirse libre de hacer tantos cambios no relacionados entre sí como sea posible. Luego, elige lo que todos están relacionados y luego haces varios commits atómicos de una vez.

Lo hago todo el time. Si usa git-gui o cualquiera de los otros clientes de GUI, puede elegir no solo el file que desea comprometer, sino también hunks within the files , para que sus confirmaciones sean lo más atómicas posible.

Intento y sigo estas prácticas en el order …

  1. Un compromiso no debe fallar una compilation. ¡Lo más importante!

  2. Debe estar formado por una unidad lógica de cambio, ya sea una sola línea / carácter o un file / class completo con los cambios correspondientes en otras partes del código, aún siguiendo el # 1.

    ¿Cuál es una unidad lógica de cambio? En términos de git , si puede especificar los cambios en el post de confirmación en el menor número de caracteres, en una oración (sin AND de curso), y no puede dividir esa descripción en unidades más pequeñas, que llamo una unidad.

  3. El post de confirmación debe especificar claramente la esencia del compromiso.

  4. El post de confirmación debe ser pequeño, generalmente no más de 80 caracteres. Cualquier otra elaboración debería ser parte de la description .

Descargo de responsabilidad: Yo también estoy en el process de tratar de determinar qué debe hacer la confirmación y cómo debe terminar buscando la historia final. Sin embargo, quería compartir algunos de los resources con los que me he encontrado durante mi propia investigación.

En primer lugar, el proyecto Kernel de Linux tiene una excelente página en Merge Strategies para fusionar el código en sentido ascendente. Hablan sobre hacer commits del tamaño de un bocado; haciendo una o más confirmaciones de refactorización antes de las adiciones reales que desee (se supone que las refactorizaciones harán que su function sea más limpia, por supuesto;) y otras cosas.

Mi otra página favorita es Git Best Practices de Seth Robertson. Esta no es solo una página sobre muchas de las mejores prácticas para usar git, sino que también es un recurso tremendo que contiene suficiente información sobre una amplia variedad de temas de git para hacer que la información en profundidad sea trivial.

A veces, cuando realizas grandes refacciones, es inevitable que cambies muchos files en una confirmación. Cuando cambia la interfaz de una class, debe cambiar el encabezado, la implementación y todos los lugares que usan la interfaz en una confirmación, porque ningún estado intermedio funcionaría.

Sin embargo, la práctica recomendada es cambiar la interfaz sin introducir en realidad ninguna funcionalidad nueva primero, probar que no se rompió la funcionalidad existente y confirmarla. Luego implementar la característica real que necesitaba la interfaz actualizada y confirmarla por separado. Es probable que termine haciendo algunos ajustes en la refactorización en el process que aplastará a la primera confirmación mediante una rebase interactiva.

De esta forma hay un gran compromiso, pero no hace nada difícil, simplemente mezcla el código, por lo que debería ser más fácil de entender a pesar de que es grande y de que el segundo compromiso (o más, si la function es grande) no lo es. demasiado grande.

Lo que estoy preguntando es la parte de FILOSOFÍA.

Creo que puedo responder esto porque he estado involucrado en una investigación personal recientemente.

Uno debe enfocarse en crear un compromiso atómico . Lo que significa que es necesario tener un cuidado adicional en algunas cosas para una confirmación:

  • No debería tener ningún valor si se hace parcialmente
  • No debería romper la construcción
  • Debe contener un buen post y cuerpo para la trazabilidad (con references de boletos siempre que sea posible)
  • No debe contener mucho ruido difuso (espacios en blanco y cambios de estilo, a less que el compromiso sea específico para eso)

Los compromisos deben enfocarse en un cambio y un solo cambio . Cualquier cosa más que eso puede tener malos efectos secundarios.

Algunas personas podrían argumentar que esto es demasiado, que no es práctico. Pero el mejor argumento a favor, incluso para las pequeñas empresas, es el hecho de que las consolidaciones atómicas obligarán a su layout a estar más desacoplado y consistente, porque un requisito para lograr compromisos atómicos óptimos completos es tener una base de código saludable que no sea un desastre.

Si fuerza sistemáticamente las buenas prácticas de compromiso, podrá impulsar la cultura de la ingeniería y el código en sí mismo a un mejor estado.

Algo que me ayudó mucho a resolver lo que estaba cometiendo, y por qué, fue mover nuestra organización de repository al model de "twig de características", popularizado por la extensión de Git Flow .

Al tener twigs que describen cada function (o actualización, corrección de errores, etc.) en las que se está trabajando, las confirmaciones se vuelven less sobre la function y más sobre cómo se está implementando esa function. Por ejemplo, recientemente estaba solucionando un error de zona horaria dentro de su propia twig de corrección de errores (correcciones de errores / gh-87 por ejemplo), y las confirmaciones se dividieron en lo que se hizo o en el server y la interfaz, y dentro de las testings. Debido a que todo esto sucedía en una twig dedicada a ese error ( con un número de problema de GitHub también, para mayor claridad y cierre automático ), mis compromisos fueron vistos como pasos incrementales para resolver ese problema, y ​​por lo tanto requirieron less explicación de por qué Yo los estaba haciendo.