2010-09-22 11 views
6

como la guía definitiva aptly points out (búsqueda de "Etiquetas y clonación"):¿Cómo obtener el cambio de etiqueta después de clonar o tirar a una etiqueta usando mercurial?

Cuando se ejecuta hg clone -r foo para clonar un repositorio como de etiqueta foo, el nuevo clon no contendrá ninguna revisión más reciente que la del la etiqueta se refiere a , incluida la revisión donde se creó la etiqueta. El resultado es que obtendrá exactamente el subconjunto correcto del historial del proyecto en el nuevo repositorio , pero no la etiqueta que podría haber esperado.

Significa hg tags en su nuevo clon NO muestra la etiqueta foo. Lo mismo sucede si se clonó antes de agregar la etiqueta foo, y usted hace hg pull -r foo.

(Digression: la etiqueta es lo único que no entiendo bastante hg. Entiendo que hay ventajas (por ejemplo, fusionar) en ponerlo en un conjunto de cambios, pero siempre se siente extraño tener metadatos mezclados con la fuente código.)

Debería ser obvio que estoy pidiendo una forma automática, en lugar de tirar del conjunto de cambios de etiqueta como un paso manual por separado.

Sé que podría verificar este escenario en un gancho incoming (para que funcione tanto para clonar como para extraer), o ajustar clone y pull.

¿Pero hay una manera mejor/más fácil?


ACTUALIZACIÓN fallo hg rastreador ya tiene this issue.

+2

etiquetas que introducen changesets tiene que ser una de las pocas cosas que realmente no me gusta de Mercurial –

Respuesta

0

Sí, se puede hacer por ganchos post-clon/pull, pero hay un par de ladrones.

En primer lugar, solo funciona para el repositorio local, ya que no puede obtener la lista de etiquetas en un repositorio remoto.

En segundo lugar, lidiar con los argumentos y opciones de clonación/extracción no es trivial. (Para clon que necesito para obtener el repositorio de destino, -r, -u, -U. Para tirón necesito -r y -u.) He intentado utilizar fancyopts, pero no puedo hacer frente a las opciones globales, que se procesan en la distancia de despacho. Logré hackear el despacho para darme solo los args y opts de un comando, pero se siente y se ve feo.

El uso del envoltorio de comandos eliminaría el segundo problema.

Espero que un día hg agregue una opción para clonar y tirar para hacerlo limpiamente.

+1

Si usa un gancho no puede verificar el valor de la variable '$ HG_URL'. –

+0

También necesito las palmaditas y las opciones, pero su mención de $ HG_URL me ayudó a descubrir de [man hgrc] (http://www.selenic.com/mercurial/hgrc.5.html#hooks) que todo pre/post los ganchos obtienen $ HG_PATS y $ HG_OPTS. –

1

Hay un gancho postclone. Se llama post-clone (la página de manual de hgrc muestra post-ANYCOMMAND y pre-ANYCOMMAND existen), aunque como señaló, también podría usar los ganchos *changegroup o update, ya que clone usa ambas funciones (a menos que suprima la actualización con -U).

¿Qué tal si agregas un --localtag para que tengas el nombre pero no el conjunto de cambios adicional si lo necesitas solo como referencia. Algo así como

hg clone -r tagname URL 
hg tag --local tagname 

que fácilmente podría construir en un alias de shell.

Aparte de eso, no es necesariamente una forma segura de tener la revisión X y la revisión donde se etiqueta la revisión X sin tener otras revisiones que no desea ya que la etiqueta podría haberse aplicado después de que se realizara otro trabajo. Por supuesto, siempre puede actualizar a 'X' y tener conjuntos de cambios posteriores en su directorio de trabajo, pero aún estarán en su repositorio.

Honestamente, una vez que descubrí que el nombre de la etiqueta no tarda en clonar una etiqueta, lo que admito me confundió al principio, no encontré ninguna necesidad de llevarlo el conjunto de cambios con la etiqueta en él.

+0

Gracias por el gancho 'post-clon'. Eliminé "y dado que no hay un gancho' postclone' de la pregunta. No me gusta mucho la etiqueta local ya que seguro que introduciré el conjunto de cambios de etiquetas más adelante. También sin el conjunto de cambios de etiqueta, puedo enviar una etiqueta yo mismo, luego tendré que fusionar las etiquetas. –

+0

Sí, no es perfecto, pero no hay forma de hacerlo sin tirar de conjuntos de cambios adicionales que quizás aún no desee (todos los que están entre el trabajo y el cset de etiquetado). Al menos las etiquetas se fusionan a la perfección y las locales no pueden entrar en conflicto ni ser presionadas. –

+0

Solo extraeré el conjunto de cambios de etiquetas si es el único hijo de los etiquetados. La respuesta de @ Richard me dio la idea de usar un gancho pre-clon y pre-pull para verificar el caso y cambiar la revisión de clon/extracción al conjunto de cambios de etiqueta. Publicaremos de nuevo. –

3

¿Quieres un hack gigante con bash y un script Perl incrustado? Bueno, aquí está ...

#!/bin/bash 
if [[ "$1" == "" || "$2" == "" || "$3" == "" ]]; then 
    echo 'hgclonetag <src> <tgt> <tag>' 
    exit 1; 
fi 

REV=`hg log -R $1 --rev $3: --limit=2 | perl -F: -lane 'if (/:([\dA-Fa-f]+)$/) {print $F[2] if defined($flag);$flag=1;}'` 
hg clone --rev $REV $1 $2 

Esto invoca el comando hg log para extraer el número de revisión después de la primera revisión relacionada tag-y, a continuación clones para esta revisión.

Actualmente esto no funciona en los repos remotos: -R switch solo funciona en repos locales desafortunadamente.

+3

Seguramente lo habría aceptado si no hubiera incluido explícitamente palabras de git-tish como "gigante", "hack" (oops, ¿acabo de ofender a Lord Linus? * Reunión remota de truenos ... *), "bash", y "perl". Estoy esperando una solución pequeña, elegante, basada en hg, python :) +1 sin embargo. –

+1

Debería ser sencillo Pythonize esto usando 'os.system' y algunas coincidencias de expresiones regulares. Buen comentario: +1 usted mismo! –

+2

Esto no funcionará cuando marque una revisión anterior ... si hago 'hg tag -r 100 foo', entonces puedo estar creando la revisión 1000. Así que ir a la revisión 101 no traerá la etiqueta. –

3

Cuanto más pienso en ello, más estoy convencido de que el derecho respuesta es simplemente clonar todo y actualización de la etiqueta, que se puede hacer en un solo paso:

hg clone http://host/path#tagname 

que recibe usted todo y luego hace hg update a tagname que establece su directorio de trabajo a la revisión correcta. Dada la compresión delta que no es necesariamente mucho más grande, y si lo es, puede automatizar la clonación de la mayor parte de un clon local anterior.

+0

Gracias, no sabía que también puedo usar #. Sin embargo, el problema es que, como dice mi pregunta, no tiene el conjunto de cambios de etiqueta en el clon, por lo que no sé en qué etiqueta está el clon. –

+0

¿Eh? Parece que sabes el nombre y ese nombre es 'foo'. Entonces puede hacer 'hg clone http: // host/path # foo'. Si realmente no conoce el nombre de la etiqueta, debe clonar todo y luego actualizar; no hay inconveniente en tener revoluciones adicionales en su repositorio, pero no en su directorio de trabajo. –

+0

Lo siento, quise decir "en qué etiqueta ** está ** el clon", ya que el clon no tiene el conjunto de cambios de etiqueta 'foo'. Por supuesto que lo sabía justo después del clon, pero no después de un tiempo (tengo una terrible memoria a corto plazo). Como dijiste, hacer una clonación completa y luego actualizar es una solución obvia, y siempre lo hago de todos modos. Es solo que la semántica 'clone parent # foo' se siente un poco rara sin obtener el conjunto de cambios de etiqueta. –

Cuestiones relacionadas