tag - ¿Cómo evitar los conflictos de git en un equipo?
git config--global (8)
Bueno, para ser realmente honesto, el flujo de trabajo adecuado implica una buena comunicación y gestión. Los miembros del equipo a menudo no deben trabajar en lo mismo y causar conflictos. Cosas como las peleas diarias, y un gerente atento que sabe lo que hace cada miembro del equipo - al menos en general - recorrer un largo camino en muchos casos para limitar esto.
Depende de la naturaleza exacta del producto, por supuesto, pero esto es más un problema de organización que un problema de git. De hecho, los conflictos a menudo se consideran cosas "buenas" porque hacen que las personas se levanten de sus escritorios, o se llaman entre sí para hablar sobre por qué hubo un conflicto y qué se debe hacer al respecto. Esta es una oportunidad para descubrir que una persona debe poseer un área, o un conjunto de archivos, o al menos ser el punto de contacto para discutir los cambios en esa sección.
Aparte de hacer un plan inicial, no hay forma de evitar conflictos de git, pero este sería el mismo problema en cualquier sistema de control de versiones. Cada vez que dos personas cambian la misma sección de código, debes averiguar quién gana. Esta es la razón por la cual no es realmente apropiado mirar hacia el versionador para la solución, sino observar los métodos y prácticas de su equipo. Dos autos no pueden atravesar una intersección al mismo tiempo, pero es extremadamente difícil inventar autos que se puedan atravesar entre sí, así que en su lugar inventamos los sistemas de control de señales de stop y señales de tráfico. Este es un problema similar. Realmente no podemos hacer dos cambios en la misma cosa, no en conflicto, así que debemos controlar cómo trabajamos con los archivos.
Podría considerar uno de los front-ends que permite bloquear git, pero realmente no estoy de acuerdo con el concepto, fuera de los tipos de archivo no fusibles. Creo que es mejor descubrir un mejor flujo de trabajo en el equipo, y mientras tanto, utilizar esto como una oportunidad para ser realmente bueno en la fusión de archivos. Hice eso, y ahora después de meses de hacerlo, los conflictos no son algo molesto para mí.
Somos algunos desarrolladores que trabajan en el mismo proyecto y usamos git para el proyecto. Si dos o más de nosotros trabajamos en el mismo archivo, recibimos conflictos de git que son difíciles de tratar, a veces los cambios realizados por un desarrollador se pierden cuando ocurren estos conflictos.
¿Cómo trabajan con git en un equipo? ¿Cuál debería ser el flujo adecuado para evitar conflictos de git?
Gracias por adelantado.
Antes de profundizar en su flujo de trabajo, antes de dedicar un momento o un dólar de dinero a reconstruir sus procesos de comunicación, haga tres preguntas a su equipo:
- ¿Hacemos cumplir las convenciones de espacios en blanco?
- Si usamos IDEs, ¿todos usan el mismo formato y la misma configuración de palabras clave? Por ejemplo, Eclipse puede finalizar automáticamente los parámetros .
- ¿Generamos artefactos de construcción textual? Por ejemplo, ¿minimizamos js, generamos reglas css desde archivos
.sass
o.scss
, o construimos configuraciones xml sobre la marcha? ¿Los registramos?
Después de años de generar conflictos y ayudar a otros a resolverlos en flujos de trabajo centralizados, presento estas tres cosas porque causan la gran mayoría de nuestro dolor de conflicto colectivo:
En la imagen de arriba, el ''!'' slice representa conflictos de combinación legítimos. La gran mayoría de las fusiones terribles provienen de convenciones de espacios en blanco perezosos o IDEs demasiado agresivos (u ocasionalmente, desarrolladores demasiado refactorios). Antes de hacer nada más, estandarice sus configuraciones IDE y las convenciones de espacios en blanco. Luego haga que todos emitan este comando en sus repositorios locales:
# Enable the repository''s stock pre-commit hook
mv .git/hooks/pre-commit.sample .git/hooks/pre-commit
Ese gancho precompromiso llevará a cabo una serie de comprobaciones cada vez que emita un git commit
, incluida una versión de git diff --check
, un comando que verifica si los cambios cometidos introducen errores de espacio en blanco. La confirmación será rechazada si lo hace. Si realmente necesita evitarlo, puede emitir git commit --no-verify
, pero no lo hace: Los errores de espacio en blanco son como la ordenanza sin explotar del control de versión. Son conflictos de fusión esperando a suceder.
Si desea limpiar espacios en blanco, refactorizar un archivo para mejorar su sangría o realizar una gran serie de cambios puramente de formato, hágalo en compromisos aislados y advierta primero al equipo que verifique el conflicto de trabajo en progreso.
Si lleva a cabo revisiones de código, haga que estas sean las primeras preguntas que haga cada revisor: "¿Este conjunto de cambios tocó todo lo que no se suponía que debía hacer? ¿Limpió el formato? ¿Refactorizó innecesariamente un método?" Si lo hizo, no pasa la revisión. O, si no puede, asegúrese de que esos cambios estén lo suficientemente aislados de los cambios lógicos (es decir, en diferentes confirmaciones) para que su historial sea útil.
Los lenguajes de hojas de estilo, RequireJS y js minifiers también causan conflictos, si sus objetivos generados están marcados. Los archivos creados por estas tecnologías son artefactos de construcción. No verificaría en un archivo WAR; no verifique en un archivo CSS compilado por SASS. O, si cree que debe hacerlo, use un archivo .gitattributes
para que git los trate como binarios.
Si después de hacer todo esto, aún tiene conflictos de fusión, instituya mejoras en el flujo de trabajo. La respuesta de Gary Fixler es absolutamente correcta: los conflictos de fusión legítimos surgen porque los equipos no pueden o no se comunican bien sobre el alcance de sus proyectos. Solo asegúrese de que sus reglas de formateo no se apliquen primero.
Solo hay una forma de evitar conflictos: no hay personas diferentes que editen el mismo archivo al mismo tiempo. Esencialmente, cada archivo tiene un propietario que es responsable de todas las ediciones y que puede pasar la propiedad a otro. La propiedad de un archivo puede transmitirse según una característica / sucursal en particular o día a día, siempre que la propiedad esté clara.
Si encuentra que no puede asignarle un propietario a cada archivo, entonces:
- necesita dividir sus archivos en archivos más pequeños que se pueden asignar a un propietario
- absolutamente requiere que los conflictos GIT se resuelvan (con todos los editores sentados juntos para resolver los conflictos individuales).
- Use una buena herramienta de fusión múltiple para visualizar y luego resolver los conflictos.
Para reducir la cantidad de conflictos en el control de versiones sin preocuparse por quién está editando qué, solo necesita hacer pequeños cambios y enviarlos / presionarlos incrementalmente. Divida el problema en partes lo suficientemente pequeñas para que pueda modificar rápidamente los archivos y volver a colocarlos en el tronco. Cuanto más cortas sean sus ramas, menos posibilidades habrá de conflictos de fusión.
Incluso entonces, en algún momento, dos personas editarán el mismo archivo al mismo tiempo sin tener culpa alguna. La pregunta obvia cuando eso sucede es:
"¿Cómo puedo aliviar el dolor de resolver conflictos de git?"
La respuesta es que debe tirar del baúl y volver a colocar su bifurcación en él con frecuencia, y notará los conflictos tan pronto como sea posible, mientras que todavía son pequeños. En este punto, ambos desarrolladores deben sentarse juntos y debatir calmadamente sobre la mejor manera de proceder mientras los cambios están frescos en sus mentes.
Compare este enfoque con el intento de resolver conflictos en grandes ramas de larga vida en pánico justo antes de la fecha límite de lanzamiento, cuando los desarrolladores luchan por recordar el pensamiento detrás de todos los cambios que hicieron hace algún tiempo.
Informar a los colegas cuando ha empujado sus cambios
Otra forma de reducir el dolor de los conflictos es simplemente informar a los colegas cuando ha impulsado sus cambios. Les permite extraer sus cambios y resolver algunos conflictos en ese momento. Es probable que cualquier conflicto entre su cambio reciente, lo fresco en su mente y lo que están trabajando, esté fresco en sus mentes.
Si las personas no sacan los cambios de la rama principal hasta que hayan terminado un gran desarrollo y luego tengan conflictos con los cambios realizados por varias personas, todas en la misma área, entonces será más difícil resolverlas.
Use una herramienta de combinación
Uno de los propósitos de Git es el control de versiones. Otros programas se especializan en fusionar archivos y resolver conflictos. Si configura una herramienta de combinación para usar con git, puede resolver automáticamente muchos problemas que considere un conflicto, o al menos hacer una buena conjetura para que lo inspeccione y simplemente dejarlo intacto si se ve bien, o si confía en la herramienta .
Eso deja menos conflictos genuinos que necesitan una decisión inteligente para la resolución.
Usa archivos más pequeños
Agrego un nuevo controlador en la parte inferior de mycontrollers.js y agregas un nuevo controlador en la parte inferior de yourcontrollers.js : no hay problema.
Ambos agregamos un nuevo controlador en la parte inferior de allcontrollers.js : conflict.
(Sin embargo, recuerde los consejos sobre ordenar las cosas alfabéticamente también. MyNewController () comenzando con M podría ir en el medio de un archivo y su NeNeController () comenzando con Y podría ir al final del mismo archivo, nuevamente sin conflicto).
Ordenando
Hay algunas otras cosas que puede hacer que también podrían ayudar. Será más claro si los publico por separado.
Donde inserte cosas nuevas le ayudará a determinar si crea conflictos.
Imagine una lista de nombres de empleados
Andy,
Oliver,
Ivan,
Luego, Brad y Patrick se unen y sus nombres se agregan a la lista. Agregas a Brad y agrego a Patrick. Ambos agregamos los nombres al final de la lista y luego usamos git para fusionar nuestras listas. El resultado será familiar para los usuarios de git:
Merge branch ''Patrick'' into Brad
Conflicts:
names.txt
@@@ -1,4 -1,4 +1,8 @@@
Andy,
Oliver,
Ivan,
<<<<<<< HEAD
+Brad,
=======
+ Patrick,
>>>>>>> Patrick
Supongamos ahora que hicimos lo mismo pero impusimos una regla de ordenamiento alfabético simple en nuestra lista. Ahora cuando fusionamos las dos ramas, los resultados son un poco más agradables:
Andy,
Ivan,
Oliver,
Agregue un nombre usted mismo y luego combine el cambio de la otra persona con git, para agregar el otro nombre.
Auto-merging names.txt
Merge made by the ''recursive'' strategy.
names.txt | 1 +
1 file changed, 1 insertion(+)
Y obtenemos
Andy,
Brad,
Ivan,
Oliver,
Patrick,
Dado que no sabemos quién se unirá a la empresa próximamente, estamos agregando efectivamente la lista al azar, y al insertar en lugares aleatorios, los conflictos de ubicación en los archivos son menos probables.
Use el inicio de bloque adjunto
En un software como este ...
function chess()
{
while (!end_of_game)
{
make_move()
las líneas que comienzan con bloques con llaves de apertura se confundirán fácilmente con otras líneas en el software que consiste en llaves de apertura simple. Si el mismo software se escribe así, al anexar el bloque comienzan las líneas anteriores ...
function chess() {
while (!end_of_game) {
make_move()
que personalmente no me gusta, pero Git sí, hay muchas menos líneas que se parecen a Git y se confunden, es decir, es más probable que Git perciba la edición de la misma manera que nosotros, haciendo que cualquier conflicto sea mucho más fácil. resolver.
Y comentarios sobre finales de bloque
Use comentarios para hacer distinguibles líneas similares.
Si escribe muchos javascript y JSON, puede tener muchas líneas que se parecen un poco a esto.
}
}
}
)
Si comenta cosas, entonces pueden volverse distinguibles.
}
}
}
) // end of weekdays()
y
}
}
}
) // end of weekend()
Ya no se ve igual a git. Esto puede ayudar a Git a comprender mejor sus cambios. Si agrega algo, como
function a()
{
...
} // end of a()
Es más probable que git lo vea como una unidad de cambio y no piense que ha agregado algo como
}
function a()
{
...
justo antes del final de alguna otra función. Incluso cuando esto no evite conflictos, si git ve y presenta sus cambios de forma sensata (es decir, la forma en que los vemos mentalmente), entonces quizás pueda resolver conflictos más fácilmente. Un encabezado descriptivo que comente qué funciones hacen, los parámetros que toman, etc., ayudará a evitar que git mezcle los contenidos de las funciones vecinas.
Use UTF-8 y no UTF-16 para archivos de texto.
Muchas versiones de Git (es decir, cada versión que he usado, hasta donde yo sé) pueden tratar archivos UTF-16 como archivos binarios debido a la presencia de muchos bytes cero en un archivo de texto UTF-16 típico.
Una vez que Git cree que un archivo es un archivo binario, es probable que continúe tratando el archivo como un archivo binario, incluso cuando se lo cambia. Esto significa que el control de la versión se realiza almacenando versiones completas del archivo en lugar de las diferencias entre ellos y se pierden algunas de las ventajas de un sistema de control de versiones. (Edición: No. Probé esto recientemente cambiando un archivo UTF-16 a UTF-8 comprometiéndolo, editándolo y volviendo a comprometerlo) y comenzó a tratar los cambios ya que el texto cambia una vez que tanto el original como los archivos editados eran UTF-8. )
La mayoría de los editores modernos reconocerán la codificación de caracteres y el estilo de final de línea de un archivo y guardarán el archivo en el mismo formato. Algunos editores (por ejemplo, Babelpad) le permitirán elegir si guarda su archivo en UTF-8 o UTF-16, y con o sin una marca de orden de bytes, etc.
Si el archivo que desea controlar la versión es (i) en formato UTF-16 y (ii) funcionaría igual de bien en UTF-8, por ejemplo, un programa fuente para un compilador moderno decente, vale la pena considerar convertirlo a UTF-8.
Si Git piensa que el texto fuente es un archivo binario antes de la primera confirmación, míralo y verifica si vale la pena cargarlo en un editor y guardarlo en un formato diferente que Git reconozca como texto.
(Nota: los archivos de Linux tienden a ser UTF-8 por defecto. Algunos programas de Windows tenían la costumbre de crear UTF-16. Por lo tanto, son los usuarios de Windows los que tienen más probabilidades de tener el problema. También tenga en cuenta que desea corregir esto antes de la primer commit del archivo, ¡antes de que Git crea que tiene un archivo binario!)
Use Gitrerere
¡Reutiliza la resolución grabada!