Actualmente estoy trabajando en un proyecto más grande que desafortunadamente tiene algunos archivos donde no siempre se siguen las pautas de calidad del software. Esto incluye archivos grandes (leer líneas 2000-4000) que claramente contienen múltiples funcionalidades distintas.
Ahora quiero refactorizar estos archivos grandes en varios pequeños. El problema es que, dado que son tan grandes, varias personas (incluido yo) en diferentes ramas están trabajando en estos archivos. Por lo tanto, realmente no puedo pasar de desarrollar y refactorizar, ya que fusionar estas refactorizaciones con los cambios de otras personas se volverá difícil.
Por supuesto, podríamos requerir que todos se fusionen para desarrollar, "congelar" los archivos (es decir, no permitir que nadie los edite más), refactorizar y luego "descongelar". Pero esto tampoco es realmente bueno, ya que esto requeriría que todos básicamente detuvieran su trabajo en estos archivos hasta que se complete la refactorización.
Entonces, ¿hay alguna forma de refactorizar, no exigir a nadie que deje de trabajar (por mucho tiempo) o fusionar sus ramas de características para desarrollar?
fuente
Respuestas:
Ha entendido correctamente que esto no es tanto un problema técnico como social: si desea evitar conflictos de fusión excesivos, el equipo debe colaborar de una manera que evite estos conflictos.
Esto es parte de un problema mayor con Git, ya que la ramificación es muy fácil, pero la fusión aún puede requerir mucho esfuerzo. Los equipos de desarrollo tienden a lanzar muchas sucursales y luego se sorprenden de que fusionarlas sea difícil, posiblemente porque están tratando de emular Git Flow sin comprender su contexto.
La regla general para las fusiones rápidas y fáciles es evitar que se acumulen grandes diferencias, en particular que las ramas de características deben tener una vida muy corta (horas o días, no meses). Un equipo de desarrollo que pueda integrar rápidamente sus cambios verá menos conflictos de fusión. Si algún código aún no está listo para la producción, podría ser posible integrarlo pero desactivarlo mediante un indicador de función. Tan pronto como el código se haya integrado en su rama maestra, será accesible para el tipo de refactorización que está tratando de hacer.
Eso podría ser demasiado para su problema inmediato. Pero puede ser factible pedirles a los colegas que combinen sus cambios que afectan este archivo hasta el final de la semana para que pueda realizar la refactorización. Si esperan más tiempo, tendrán que lidiar con los conflictos de fusión ellos mismos. Eso no es imposible, es solo un trabajo evitable.
También es posible que desee evitar romper grandes extensiones de código dependiente y solo realizar cambios compatibles con API. Por ejemplo, si desea extraer alguna funcionalidad en un módulo separado:
Este proceso de varios pasos puede evitar muchos conflictos de fusión. En particular, solo habrá conflictos si otra persona también está cambiando la funcionalidad que extrajo. El costo de este enfoque es que es mucho más lento que cambiar todo a la vez, y que tiene temporalmente dos API duplicadas. Esto no es tan malo hasta que algo urgente interrumpe esta refactorización, la duplicación se olvida o se prioriza, y terminas con un montón de deudas tecnológicas.
Pero al final, cualquier solución requerirá que coordines con tu equipo.
fuente
Realice la refactorización en pasos más pequeños. Digamos que su archivo grande tiene el nombre
Foo
:Agregue un nuevo archivo vacío
Bar
, y confírmelo en "trunk".Encuentre una pequeña porción del código en la
Foo
que se pueda moverBar
. Aplique el movimiento, actualice desde troncal, cree y pruebe el código y comprométase a "troncal".Repita el paso 2 hasta
Foo
yBar
tienen igual tamaño (o cualquier tamaño que prefiera)De esa manera, la próxima vez que tus compañeros de equipo actualicen sus ramas desde el tronco, obtendrán tus cambios en "porciones pequeñas" y podrán fusionarlos uno por uno, lo cual es mucho más fácil que tener que fusionar una división completa en un solo paso. Lo mismo ocurre cuando en el paso 2 obtienes un conflicto de fusión porque alguien más actualizó el enlace intermedio.
Esto no eliminará los conflictos de fusión ni la necesidad de resolverlos manualmente, pero restringe cada conflicto a un área pequeña de código, que es mucho más manejable.
Y, por supuesto, comunicar la refactorización en el equipo. Informe a sus compañeros lo que está haciendo, para que sepan por qué tienen que esperar conflictos de fusión para el archivo en particular.
fuente
rerere
opción gits habilitadaEstá pensando en dividir el archivo como una operación atómica, pero puede realizar cambios intermedios. El archivo gradualmente se volvió enorme con el tiempo, y gradualmente puede volverse pequeño con el tiempo.
Elija una parte que no haya tenido que cambiar en mucho tiempo (
git blame
puede ayudar con esto) y divídala primero. Combina ese cambio en las ramas de todos, luego elige la siguiente parte más fácil de dividir. Tal vez incluso dividir una parte es un paso demasiado grande y primero debe reorganizar el archivo grande.Si las personas no se fusionan con frecuencia para desarrollarse, debe alentarlo, luego, después de fusionarse, aproveche la oportunidad para separar las partes que acaban de cambiar. O pídales que hagan la división como parte de la revisión de solicitud de extracción.
La idea es avanzar lentamente hacia su objetivo. Sentirá que el progreso es lento, pero de repente te darás cuenta de que tu código es mucho mejor. Lleva mucho tiempo girar un transatlántico.
fuente
Voy a sugerir una solución diferente a la normal para este problema.
Use esto como un evento de código de equipo. Haga que todos revisen su código y puedan ayudar a otros que todavía están trabajando con el archivo. Una vez que todos los relevantes tengan su código registrado, busque una sala de conferencias con un proyector y trabajen juntos para comenzar a mover las cosas y a nuevos archivos.
Es posible que desee establecer una cantidad de tiempo específica para esto, de modo que no termine siendo una semana de argumentos sin un final a la vista. En cambio, esto podría incluso ser un evento semanal de 1-2 horas hasta que todos tengan las cosas como deben ser. Tal vez solo necesite 1-2 horas para refactorizar el archivo. No lo sabrás hasta que lo intentes, probablemente.
Esto tiene el beneficio de que todos estén en la misma página (sin juego de palabras) con la refactorización, pero también puede ayudarlo a evitar errores y a obtener información de otros sobre posibles agrupaciones de métodos para mantener, si es necesario.
Hacerlo de esta manera puede considerarse que tiene una revisión de código incorporada, si hace ese tipo de cosas. Esto permite que la cantidad adecuada de desarrolladores firmen su código tan pronto como lo registren y estén listos para su revisión. Es posible que aún desee que verifiquen el código de cualquier cosa que se haya perdido, pero es muy importante asegurarse de que el proceso de revisión sea más corto.
Es posible que esto no funcione en todas las situaciones, equipos o empresas, ya que el trabajo no se distribuye de manera que esto suceda fácilmente. También se puede interpretar (incorrectamente) como un mal uso del tiempo de desarrollo. Este código de grupo necesita la aceptación del administrador y del refactorizador.
Para ayudar a vender esta idea a su gerente, mencione el bit de revisión de código, así como que todos sepan dónde están las cosas desde el principio. Evitar que los desarrolladores pierdan tiempo buscando en una gran cantidad de archivos nuevos puede valer la pena. Además, evitar que los desarrolladores se pongan a prueba sobre dónde terminaron las cosas o "faltaban por completo" suele ser algo bueno. (Cuantas menos crisis, mejor, OMI).
Una vez que obtenga un archivo refactorizado de esta manera, es posible que pueda obtener más fácilmente la aprobación de más refactores, si fue exitoso y útil.
Como sea que decidas hacer tu refactorización, ¡buena suerte!
fuente
master
principio, al menos tiene a todos en la sala para ayudar a lidiar con las fusiones en esas ramas.La solución de este problema requiere la aceptación de los otros equipos porque está tratando de cambiar un recurso compartido (el código en sí). Dicho esto, creo que hay una manera de "migrar" de tener grandes archivos monolíticos sin interrumpir a las personas.
También recomendaría no apuntar a todos los archivos grandes a la vez, a menos que la cantidad de archivos grandes crezca sin control además del tamaño de los archivos individuales.
Refactorizar archivos grandes como este con frecuencia causa problemas inesperados. El primer paso es evitar que los archivos grandes acumulen funcionalidades adicionales más allá de lo que está actualmente en las ramas maestras o de desarrollo .
Creo que la mejor manera de hacer esto es con enlaces de confirmación que bloquean ciertas adiciones a los archivos grandes de forma predeterminada, pero se pueden anular con un comentario mágico en el mensaje de confirmación, como
@bigfileok
o algo así. Es importante poder anular la política de una manera que sea indolora pero rastreable. Idealmente, debería poder ejecutar el enlace de confirmación localmente y debería indicarle cómo anular este error particular en el mensaje de error mismo . Además, esto es solo mi preferencia, pero los comentarios mágicos no reconocidos o los comentarios mágicos que suprimen los errores que en realidad no se activaron en el mensaje de confirmación deberían ser una advertencia o un error de tiempo de confirmación, por lo que no capacita inadvertidamente a las personas para suprimir los ganchos independientemente de si lo necesitan o no.El enlace de confirmación podría buscar nuevas clases o hacer otro análisis estático (ad hoc o no). También puede elegir un recuento de líneas o caracteres que sea un 10% más grande que el archivo actual y decir que el archivo grande no puede crecer más allá del nuevo límite. También puede rechazar confirmaciones individuales que hacen crecer el archivo grande por demasiadas líneas o demasiados caracteres o w / e.
Una vez que el archivo grande deja de acumular nueva funcionalidad, puede refactorizar las cosas de a una por vez (y reducir los límites impuestos por los ganchos de confirmación al mismo tiempo para evitar que vuelva a crecer).
Eventualmente, los archivos grandes serán lo suficientemente pequeños como para que los ganchos de confirmación se puedan eliminar por completo.
fuente
Espera hasta la hora de casa. Dividir el archivo, confirmar y fusionar con master.
Otras personas tendrán que colocar los cambios en sus ramas de características en la mañana como cualquier otro cambio.
fuente