Posibilidad de versión perdida en Subversion (entorno de investigación)

Mi primera pregunta aquí y no la he visto en otro lado. Trabajo en un instituto de investigación, por lo que nos gustaría poder decir qué versión de código produjo un set particular de resultados. Mi pregunta es si mi análisis es correcto, como se muestra en la siguiente ilustración (Tenga en count que los id. De nodo de versión son sólo para fines ilustrativos y no corresponden a los id de la versión real en SVN, Git o Hg. Los numbers de versión con letras representan el estado del código no confirmado en SVN, los identificadores de versión de número integer representan el estado comprometido en SVN, todos los ID de versión en el cuadro Git / Hg representan el estado de código comprometido):

¿Desventaja de usar SVN para proyectos de investigación?

Escenario de ejemplo:

  • Supongamos que hay dos copys de trabajo "A" y "B" que comienzan en la revisión 1.

  • "A" revisa los valores pnetworkingeterminados en la function foo() , genera resultados y comtesting la versión (repo ver2).

  • "B" no revisa foo() sino otra parte del código, usa los valores pnetworkingeterminados anteriores para generar resultados e intenta registrar la versión 1b utilizada. Falla porque se necesita una actualización, pero en el process de fusión de la versión 2 y 1b, SVN perderá el hecho de que la versión 1b utilizó diferentes valores pnetworkingeterminados en foo() . Esto no se detecta como un conflicto ya que "A" y "B" no cambiaron la misma parte del código. La versión 3 no es idéntica a la versión 1b, por lo que la replicabilidad no está garantizada.

No puedo simular este escenario en mi disco local usando TortoiseSVN (No puedo crear copys de trabajo debido al error de SVN Checkout – "No se puede abrir una session ra_local a URL"). Sé con certeza que tanto Git como Hg manejarán la situación correctamente y mostrarán la versión 1b en el historial si se cometió y si la function de rebase no se usó. (Creo que rebase es esencialmente el comportamiento normal en SVN cuando no hay twigs involucradas).

¿Este análisis es correcto?

En principio, su análisis es correcto, aunque me opondría a la denominación de la "versión 1b". La versión 1b nunca existe en el dominio SVN, porque 1b es el estado de un directory de trabajo antes de confirmar.

Su flujo de trabajo tiene un problema fundamental: cuando quiere una identificación confiable de los resultados, primero debe adquirir un identificador y luego producir resultados. Check-in, luego generar. Si esto genera problemas de fiabilidad, regístrese en una sucursal, genere resultados y luego fusione. El enfoque de ramificación y fusión es similar a la forma en que funciona el software VCS distribuido como git o hg, donde los repositorys locales son twigs implícitas y el empuje es una fusión implícita.

Sí, tiene razón en que Subversion tiene este problema. De hecho, es incluso peor de lo que crees. Subversion opera por file cuando determina si su copy de trabajo está desactualizada. Entonces puedes terminar con

  • A revisa los valores pnetworkingeterminados en foo() y vuelve a ejecutar el experimento. Digamos que el cambio solo afecta los results/output-0001.dat .

  • A lo confirma como revisión SVN 2.

  • B revisa otra parte del código y genera nuevos resultados. Como B no tiene el cambio de A, solo los results/output-1000.dat son cambiados por la repetición.

  • B lo comete como revisión SVN 3.

B podría comprometerse sin actualizar primero, ya que los cambios que realizó no se cruzan con los cambios realizados por A. Además, la revisión SVN 3 no corresponde a la copy de trabajo en la máquina A o B. Si el profesor C aparece y hace un checkout de la revisión 3 de SVN, entonces ve:

  • results/output-0001.dat con los resultados de A, y
  • results/output-1000.dat con los resultados de B.

Esto es altamente inconsistente.

El concepto subyacente que permite esto es copys de trabajo de revisión mixta . Subversion le permite tener files en diferentes revisiones en su copy de trabajo. Cuando crea la revisión 2 con un cambio a foo.c , dicho file se marca como en la revisión 2. Los otros files en la copy de trabajo permanecen en la revisión 1. Esto le permite actualizar selectivamente parte de su copy de trabajo a una una revisión anterior con fines de debugging, y le permite confirmar files sin actualizar, siempre y cuando nadie más haya tocado el file.

Herramientas como Mercurial y Git evitarán que hagas esto, ya que modelan la historia como un DAG (gráfico acíclico dirigido). Cada cambio se convierte en un nuevo nodo en el gráfico y debe realizar una fusión explícita para combinar dos sets de cambios. En el escenario anterior, B intentaría impulsar su cambio y Mercurial abortaría. Él entonces lo hace

 $ hg pull $ hg merge # he now has both his own and A's changes to the code $ run-experiment $ hg commit -m "Merge with new results" 

Las tres versiones de los resultados ahora están almacenadas en el historial.