email - Flujo de trabajo para sincronizar repositorios Mercurial por correo electrónico con paquetes
synchronization (2)
- Cambios intermedios: ¿qué ocurre cuando, después de crear un paquete (Paso 1) y antes de aplicarlo de forma remota (Paso 2), se producen cambios en el equipo remoto B? Tuve un caso donde simplemente sobrescribió los cambios con el nuevo paquete sin advertencia de conflicto o sugerencia de fusión.
Si se realiza un cambio en la máquina B, este cambio se realizará en paralelo con los cambios que incluyó en la máquina A. En realidad, no importa si los cambios se realizan antes o después de crear el paquete (en función del tiempo) , solo importa que los cambios en la máquina B no tengan la cabeza de la máquina A como su antecesor.
En otras palabras, el mundo se ve así cuando las dos máquinas están sincronizadas:
A: ... [a]
B: ... [a]
A continuación, crea algunos commits nuevos en la máquina A:
A: ... [a] --- [b] --- [c]
B: ... [a]
Agrupe usando [a]
como base, por lo que obtiene un paquete con [b]
y [c]
. Digamos ahora que alguien (quizás usted mismo) hace una confirmación en la máquina B:
A: ... [a] --- [b] --- [c]
( bundled )
B: ... [a] --- [x]
Hasta el momento, no se ha intercambiado nada entre los dos repositorios, por lo que este es solo un caso normal de personas que trabajan en paralelo. Esta es la norma en un sistema de control de versiones distribuidas: las personas que trabajan en paralelo crean la necesidad de realizar asignaciones de fusión.
La necesidad de una fusión no es evidente en ninguno de los repositorios en este punto, ambos tienen historias lineales. Sin embargo, cuando se separa en la máquina B, ve la divergencia:
A: ... [a] --- [b] --- [c]
( bundled )
B: ... [a] --- [x]
/
[b] --- [c]
( unbundled )
Es útil darse cuenta de que hg unbundle
es exactamente como hg pull
, excepto que se puede hacer sin conexión. Es decir, los datos almacenados en un paquete son solo los datos que hg pull
habría transferido si hubiera tenido una conexión en línea entre los dos repositorios.
Ahora procedería fusionando las dos cabezas [x]
y [c]
para crear [y]
en la máquina B:
A: ... [a] --- [b] --- [c]
B: ... [a] --- [x] --- [y]
/ /
[b] --- [c]
en la máquina B, su último paquete se creó con [a]
como base. Sin embargo, también sabe que la máquina A tiene commit [c]
, por lo que puede especificar eso como una base adicional si lo desea:
$ hg bundle --base a --base c stuff-from-machine-b.hg
Eso pondrá [x]
y [y]
en el paquete:
bundle: (a) --- [x] --- [y]
/
(c)
Aquí uso (a)
y (c)
para indicar las bases requeridas del paquete. Solo puede desglosar este paquete si tiene ambos [a]
y [c]
en su repositorio. Si omite la segunda base (solo use [a]
), también incluirá [b]
y [c]
:
bundle: (a) --- [x] --- [y]
/ /
[b] --- [c]
Aquí incluyó todo excepto [a]
en el paquete. Agrupar demasiado está bien , como veremos a continuación.
- Doble aplicación del paquete: ¿qué sucede cuando por accidente un paquete se aplica dos veces? ¿Sería necesario grabar los paquetes aplicados de alguna manera con etiquetas locales?
Aplicar un paquete dos veces es exactamente como ejecutar hg pull
dos veces: nada sucede la segunda vez. Al desagregar, Mercurial busca en el paquete e importa los conjuntos de cambios faltantes. Entonces, si se separa dos veces, no hay nada que hacer la segunda vez.
Tengo dos directorios en dos computadoras diferentes, la máquina A (Windows) y la máquina B (OSX), y quiero mantener sincronizados los dos directorios a través de Mercurial. [*]
La restricción es que las dos máquinas no están conectadas a través de LAN / WAN; la única forma de mover datos entre ellos es por correo electrónico . Así que pensé que enviar por correo electrónico paquetes de Mercurial como deltas podría hacer el truco.
Mi flujo de trabajo actual es más o menos así (usando una etiqueta local lcb
para el último paquete de cambios):
Digamos que trabajo en la máquina A. Al final del día, lo hago:
hg commit -A -m "changes 123" hg bundle --base lcb bundle_123.hg hg tag --local -f lcb --rev tip
finalmente, le envío ese paquete por correo electrónico a la máquina B.
Luego, sentado en la máquina B, lo hago
hg unbundle bundle_123.hg hg merge hg commit -A -m "remote changes 123" hg tag --local -f lcb --rev tip
Ahora estoy trabajando en la máquina B y al final del día hago lo que se menciona en 1., pero en la máquina B. Y el ciclo continúa ...
Sin embargo, me preocupa que este sistema no sea lo suficientemente robusto:
Cambios intermedios : ¿Qué sucede cuando después de crear un paquete (Paso 1) y antes de aplicarlo de forma remota (Paso 2) se producen cambios en el equipo remoto B ? Tuve un caso donde simplemente sobrescribió los cambios con el nuevo paquete sin advertencia de conflicto o sugerencia de fusión.
Doble aplicación del paquete : ¿qué sucede cuando por accidente un paquete se aplica dos veces? ¿Sería necesario grabar los paquetes aplicados de alguna manera con etiquetas locales?
¿O hay otro mejor flujo de trabajo para transferir deltas Mercurial por correo electrónico?
[*] De la respuesta a una pregunta de superusuario , pensé que Mercurial podría ser la forma más factible de hacerlo.
Estado inicial
A>hg log --template "{rev}:{node|short} /"{desc}/" - files: {files}/n"
2:415231dbafb8 "Added C" - files: C.txt
1:6d9709a42687 "Added B" - files: B.txt
0:e26d1e14507e "Initial data" - files: .hgignore A.txt
B>hg log --template "{rev}:{node|short} /"{desc}/" - files: {files}/n"
1:72ef13990d0d "Edited A" - files: A.txt
0:e26d1e14507e "Initial data" - files: .hgignore A.txt
es decir:
Los repos idénticos divergieron en la revisión 1 en ambos lados: aparecieron cambios independientes
Prueba para el caso 1: cambios paralelos
72ef13990d0d en B no interfiere con 6d9709a42687: 415231dbafb8 en A
A>hg bundle --base e26d1e14507e ../bundle1-2.hg
2 changesets found
B>hg pull ../bundle1-2.hg
pulling from ../bundle1-2.hg
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
(run ''hg heads'' to see heads, ''hg merge'' to merge)
porque B tenía un hijo propio para e26d1e14507e, tirando del paquete agregado cabeza adicional (y rama anónima para conjuntos de cambios de A)
B>hg glog --template "{rev}:{node|short} /"{desc}/" - files: {files}/n"
o 3:415231dbafb8 "Added C" - files: C.txt
|
o 2:6d9709a42687 "Added B" - files: B.txt
|
| @ 1:72ef13990d0d "Edited A" - files: A.txt
|/
o 0:e26d1e14507e "Initial data" - files: .hgignore A.txt
Prueba para el caso 2: aplicar el paquete dos veces
Sé antes que los conjuntos de cambios existentes en repo no se volverán a tirar (y prefieren un estilo unificado de hg pull
del paquete en lugar de hg unbundle
), pero muéstrenlo
B>hg pull ../bundle1-2.hg
pulling from ../bundle1-2.hg
searching for changes
no changes found
Beneficio adicional del comportamiento de extracción: no puede preocuparse por mover el conjunto de cambios base para agrupar y siempre usar uno, el punto de divergencia más antiguo ; aumentará (ligeramente) el tamaño del paquete (levemente) porque por defecto el paquete es archivo comprimido bzip2) , pero también garantizará la inclusión de todos los conjuntos de cambios hijos en conjunto y extraerá todos los conjuntos de cambios faltantes (y los únicos que faltan ) en el repositorio de destino.
Y, en cualquier caso, incluso desagregar el mismo paquete dos veces no tendrá ningún contratiempo.
El mismo paquete en el mismo repositorio B, intento de desagregar el paquete ya retirado
B>hg unbundle ../bundle1-2.hg
adding changesets
adding manifests
adding file changes
added 0 changesets with 0 changes to 2 files
(run ''hg update'' to get a working copy)