¿Es realmente sagrado el historial de versiones o es mejor rebase?

26

Siempre he estado de acuerdo con el mantra 1 de Mercurial , sin embargo, ahora que Mercurial viene incluido con la extensión de rebase y es una práctica popular en git, me pregunto si realmente podría considerarse como una "mala práctica", o al menos lo suficientemente malo como para evitar usarlo. En cualquier caso, soy consciente de que rebase es peligroso después de empujar.

OTOH, veo el punto de tratar de agrupar 5 commits en uno solo para que parezca más ágil (especialmente en una rama de producción), sin embargo, personalmente creo que sería mejor poder ver commits parciales en una característica donde algunos la experimentación se realiza, incluso si no es tan ingeniosa, pero ver algo como "Intenté hacerlo de la manera X, pero no es tan óptimo como Y, después de todo, hacerlo Z tomando Y como base" en mi humilde opinión tendría un buen valor para aquellos que estudian la base de código y seguir el tren de pensamiento de los desarrolladores.

Mi punto de vista muy obstinado (como tonto, visceral, parcial) es que a los programadores les gusta rebase para ocultar errores ... y no creo que esto sea bueno para el proyecto en absoluto.

Entonces, mi pregunta es: ¿realmente ha encontrado valioso tener tales "compromisos orgánicos" (es decir, historia sin restricciones) en la práctica? O, por el contrario, ¿prefiere encontrarse con compromisos ingeniosos y bien empaquetados y no tener en cuenta el proceso de experimentación de los programadores ?; cualquiera que elijas, ¿por qué te funciona eso? (tener otros miembros del equipo para mantener el historial o, alternativamente, cambiarlo).


1 por análisis de Google DVCS , en Mercurial "La historia es sagrada".

dukeofgaming
fuente
¿podría proporcionar una referencia a donde se afirma como "mantra de Mercurial"?
mosquito
Ahora que lo mencionas, creo que en realidad proviene de análisis DVCS de Google code.google.com/p/support/wiki/DVCSAnalysis (pero los restos de hecho)
dukeofgaming

Respuestas:

22

La historia es sagrada, el presente no lo es. Puede dividir su "árbol" DVCS en dos partes:

  • El pasado / historial que contiene una vista precisa de cómo ha alcanzado el estado actual del código. Esta parte de la historia crece con el tiempo.

  • El presente en qué parte está trabajando actualmente para que su código evolucione. Este consejo, la mayor parte de la historia, tiene casi siempre el mismo tamaño.

Cada código que lanzaste o usaste de alguna manera es parte del pasado . El pasado es sagrado porque necesita poder reproducir una configuración o comprender qué introdujo una regresión. Nunca volverás a escribir el pasado . En git generalmente nunca reescribes nada una vez que está en master: master es la parte pasada de la historia. En Mercurial tiene este concepto de fase pública que realiza un seguimiento de la parte anterior de su "árbol" y hace cumplir su inmutabilidad.

La parte actual del código es el conjunto de cambios en el que está trabajando actualmente. La rama de características que está intentando hacer utilizable, libre de errores y correctamente refactorizada. Está perfectamente bien reescribirlo, incluso es una buena idea porque hace que la parte del pasado sea más bonita, simple y útil. Mercurial sigue esto en la fase de borrador .

Entonces sí, por favor modifique si mejora su historial. Mercurial evitará que te dispares en el pie si estás rebatiendo cosas que no deberías.

Marmoute
fuente
Ahora, me gustó tu respuesta mejor
dukeofgaming
7

No todos los errores son del tipo que necesita ocultar, por ejemplo, una vez accidentalmente cometí un archivo binario en mi repositorio. La manipulación del historial solo es mala cuando la falla no está exclusivamente en el historial en sí, como los archivos comprometidos que no deberían estarlo.

DeadMG
fuente
1
¿Entonces nunca volverías a hacer una confirmación más "lógica"?
dukeofgaming
7

La revisión de código es mucho más fácil cuando hay un gran cambio coherente en comparación con muchos pequeños dependientes.

Cuando trabajo en una nueva función, me gusta cometer muchos pequeños cambios en mi sucursal. Cuando estoy listo para enviar el parche, colapso esas pequeñas confirmaciones en una gran confirmación que representa todo el nuevo código requerido para esa función. Aquí es donde la rebase es útil.

Por otro lado, rebase no es aconsejable si los commits no tienen nada que ver entre sí. Las adiciones de funciones múltiples deben ser confirmaciones separadas (e idealmente provienen de ramas separadas).

chrisaycock
fuente
44
hay muchas herramientas que hacen que la revisión de código de múltiples cambios relacionados sea bastante trivial, por lo que, por sí solo, no compro esto como respuesta
jk.
44
¿Cómo hay alguna diferencia entre revisar la diferencia entre la revisión base y la revisión completa de la característica, y revisar la confirmación única de ese conjunto de confirmaciones basado en nuevo? ¡Se verá idéntico si la re-base hizo su trabajo correctamente!
Mark Booth
3
Lo que describe aquí va directamente en contra de los consejos en el wiki de Mercurial . Se prefieren pequeños conjuntos de cambios "obviamente correctos" para las revisiones. Contraer una rama de características en un solo conjunto de cambios no es normal en Mercurial: he visto que se recomienda mucho más a menudo en Git, donde le git rebase -ipermite hacer esto de manera fácil y selectiva. El equivalente Mercurial más cercano es histedit .
Martin Geisler
99
Estoy en completo desacuerdo. En los últimos años, utilizamos una herramienta para revisiones de código, y no había nada que odiara más al enviar un gran conjunto de cambios de más de 30 archivos para su revisión. Es mucho más fácil obtener muchos pequeños cambios. Por ejemplo, cambié el nombre de esta clase a xyz porque refleja mejor la responsabilidad modificada. Agregué el método nn porque lo necesitaré para bla. Mucho más fácil de manejar revisiones más pequeñas.
Pete
3
He escuchado esta idea bastante en la comunidad git de colapsar muchos compromisos en uno antes de pasar al repositorio oficial, pero esto nunca me ha sido útil. Prefiero tener las pequeñas confirmaciones con mensajes significativos. Como otros han señalado, puede hacer una diferencia entre múltiples conjuntos de cambios.
Chris Sutton
4

Su pregunta describe la historia como un conjunto de cambios de código ordenados y le pregunta si los compromisos orgánicos le dan pistas a los futuros lectores sobre el proceso de desarrollo. Sin embargo, como ingeniero de lanzamiento / integración, a menudo no pienso en la historia como código. Estoy más absorto con la historia que cuenta mi historia, el conocimiento institucional que retiene y si me permite o no depurar problemas rápidamente.

No creo que los flujos de trabajo orgánicos lo hagan bien, ni siquiera el mío. Las cualidades que valoro sobre DVCS cuando estoy codificando (sucursales baratas, confirmaciones rápidas, guardar en el control remoto a tiempo y con frecuencia) no son lo que valoro como gerente de integración de mi empresa . Problema que git rebase, git merge, git diff, y git applymucho más a menudo en ese papel de git addo git commit. Herramientas como rebaseme permiten transformar el código que recibo de algo que funciona en algo que se puede mantener.

Los commits ilógicos o vagos no son útiles, pero son pecaminosamente fáciles de escribir orgánicamente, cuando la principal preocupación es hacer que el código funcione, no distribuirlo a otros. Me comprometo Case 15: Fixed a problem, o Refactored <cranky legacy feature>hago que mi auto mantenimiento se avergüence, incluso cuando los escribo. Sin embargo, ninguno induce la rabia del apagón como los compromisos "incrementales". Considere esta rama del tema que un desarrollador me entregó el otro día:

$ git log production..topic --oneline
f9a1184 incremental update
156d299 incremental commits
e8d50b0 new incremental updates
511c18c incremental updates, refactor
1b46217 incremental upgrade
9e2b3b8 incremental update
fa68a87 incremental update

Estas cosas son malas. Es como DVCS diseñado para el Dr. Faustus. Te daré un control de fuente rápido y fácil. Me das es el alma de tu mantenedor de código. Todos los compromisos perezosos son actos egoístas. Muchos de nosotros los escribimos, pero también les debemos a nosotros mismos una historia lógica, replicable y depurable. No podemos hacer eso sin alguna forma de hacerlo rebase.

En cuanto a los experimentos fallidos, ¿por qué no describirlos en nuestros mensajes de compromiso (nuevos)? Dentro de un año no necesito un fragmento a medio terminar. Solo quiero un registro del intento abortado, y tal vez una breve explicación si creo que soy lo suficientemente tonto como para intentarlo de nuevo. Hay muchos flujos de trabajo exitosos en el mundo, pero me cuesta pensar en alguna razón por la que a sabiendas cometería código roto en una base de código de producción.

Christopher
fuente
Muy buena respuesta, motivaciones claras sobre por qué rebasear
dukeofgaming
2

Nada debe ser sagrado, pero asegúrese de tener buenas razones para lo que está haciendo. Rebasar es extremadamente poderoso cuando se usa correctamente, pero como con cualquier herramienta poderosa, puede ser confuso y causar problemas si se usa descuidadamente.

Personalmente, me resulta muy útil volver a crear una rama de la característica local en el tronco (o rama de desarrollo principal) antes de ejecutar las pruebas finales y fusionar la característica en la rama principal. De esa manera, puedo lidiar con cualquier conflicto de fusión, etc., antes de realmente fusionarme.

harald
fuente
1

En mi humilde opinión, los experimentos generalmente pertenecen a estanterías o ramas temporales, no a líneas de base. Si sigue esto, no debería haber un problema, ya que todos los commits serán lógicamente sólidos y agregarán algún valor.

Descifrador
fuente
¿Lo que está diciendo es que prefiere las ramas de trabajo en lugar de editar una rama de línea de base (es decir, maestro / predeterminado, producción / lanzamiento, vX.X, etc.)?
dukeofgaming