Subrepositorys mercuriales: evitar compromisos y empujones recursivos accidentales

Trabajo en un equipo donde tenemos un código en un repository mercurial con varios subrepositorys:

main/ main/subrepo1/ main/subrepo1/subrepo2/ 

El comportamiento pnetworkingeterminado de Mercurial es que cuando se realiza una hg commit en "main", también se confirmará cualquier cambio pendiente en los subrepositorys "subrepo1" y "subrepo2". De manera similar, cuando se presiona "main", también se presionarán las confirmaciones salientes en "subrepo1" y "subrepo2".

Encontramos que las personas con frecuencia involuntariamente confirman y presionan cambios en sus subrepositorys (porque olvidaron que habían realizado cambios, y el hg status por defecto no muestra cambios recursivos). También encontramos que tales compromisos / empujes globales son casi siempre accidentales en nuestro equipo.

Mercurial 1.7 mejoró recientemente la situación con el hg status -S y hg outgoing -S , que muestran cambios en los subrepositorys; pero aún así, esto requiere que la gente esté prestando atención.

¿Hay alguna manera en Mercurial de hacer que hg commit y hg push aborten si hay cambios / confirmaciones en los subinsertos que de otro modo serían confirmados / enviados?

Desde Mercurial 1.8 hay una configuration que deshabilita las confirmaciones recursivas . En los repositorys principales .hg/hgrc , puede agregar:

 [ui] commitsubrepos = no 

Si una confirmación en el repository principal encuentra cambios no confirmados en un subrepository, la confirmación completa se cancela, en lugar de confirmar silenciosamente los subrepositorys.

Mercurial 2.0 evita automáticamente que se confirmen subrepositorys a less que se especifique manualmente el --subrepos (o, alternativamente, -S ) para commit .

Por ejemplo, si intenta realizar una confirmación mientras hay cambios pendientes en un subrepository, recibirá el siguiente post:

 # hg commit -m 'change main repo' abort: uncommitted changes in subrepo hello (use --subrepos for recursive commit) 

Sin embargo, puede realizar la confirmación con éxito agregando --subrepos al command:

 # hg commit --subrepos -m 'commit subrepos' committing subrepository hello 

Algunas cosas que deben tenerse en count: si ha cambiado la revisión en la que se encuentra actualmente un subrepository, pero no el contenido del subrepository, Mercurial se comprometerá a modificar la versión sin el --subrepos . Además, los empujes recursivos todavía se realizan sin previo aviso.

Una noción es usar URL a las que tiene acceso de solo lectura en sus files .hgsub . Entonces, cuando realmente desee insert el subrepo, puede simplemente ingresarlo y hacer un hg push THE_READ_WRITE_URL .

Puede ser un pre-commit ( no precommit ) podría hacer el hg status -S para usted, y bloquear la confirmación si detecta algún cambio?

Una posible solución, usando la idea de "precompromiso" de VonC.

Configurar dos scripts; el primer check_subrepo_commit.sh :

 #!/bin/bash # If the environment variable "SUBREPO" is set, allow changes. [ "x$SUBREPO" != "x" ] && exit 0 # Otherwise, ensure that subrepositories have not changed. LOCAL_CHANGES=`hg status -a -m` GLOBAL_CHANGES=`hg status -S -a -m` if [ "x${LOCAL_CHANGES}" != "x$GLOBAL_CHANGES" ]; then echo "Subrepository changes exist!" exit 1 fi exit 0 

El segundo, check_subrepo_push.sh :

 #!/bin/bash # If the environment variable "SUBREPO" is set, allow changes. [ "x$SUBREPO" != "x" ] && exit 0 # Otherwise, ensure that subrepositories have not changed. LOCAL_CHANGES=`hg outgoing | grep '^changeset:'` GLOBAL_CHANGES=`hg outgoing -S | grep '^changeset:'` if [ "x${LOCAL_CHANGES}" != "x$GLOBAL_CHANGES" ]; then echo "Global changes exist!" exit 1 fi exit 0 

Agregue lo siguiente a su .hgrc :

 [hooks] pre-commit.subrepo = check_subrepo_commit.sh pre-push.subrepo = check_subrepo_push.sh 

De forma pnetworkingeterminada, hg push y hg commit se cancelarán si hay cambios pendientes en los subrepositorys. Ejecutando un command como ese:

 SUBREPO=1 hg commit 

anulará el cheque, lo que le permite realizar el compromiso / empuje global si realmente lo desea.