differences control and version-control mercurial dvcs mercurial-subrepos

version control - control - Subrepositorios mercuriales: evitar compromisos y empujones recursivos accidentales



differences between git and mercurial (5)

Trabajo en un equipo donde tenemos un código en un repositorio mercurial con varios subrepositorios:

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

El comportamiento predeterminado de Mercurial es que cuando se realiza una hg commit en "main", también se confirmará cualquier cambio pendiente en los subrepositorios "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 subrepositorios (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 subrepositorios; 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?


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


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 predeterminada, hg push y hg commit se cancelarán si hay cambios pendientes en los subrepositorios. Ejecutando un comando como ese:

SUBREPO=1 hg commit

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


Desde Mercurial 1.8 hay una configuración que deshabilita las confirmaciones recursivas . En los repositorios principales .hg/hgrc , puede agregar:

[ui] commitsubrepos = no

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


Mercurial 2.0 evita automáticamente que se confirmen subrepositorios a menos 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 subrepositorio, recibirá el siguiente mensaje:

# 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 comando:

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

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


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?