2010-09-22 12 views
6

Come la guida definitiva aptly points out (ricerca di "Tag e la clonazione"):Come ottenere il set di modifiche del tag dopo aver clonato o estratto un tag usando mercurial?

Quando si esegue hg clone -r foo clonare un repository come di tag foo, il nuovo clone non conterrà alcuna revisione più recente di quella del l'etichetta si riferisce a, inclusa la revisione in cui è stato creato il tag. Il risultato è che avrai esattamente il sottoinsieme giusto della cronologia del progetto nel nuovo repository , ma non è il tag che ti saresti aspettato.

Significa hg tags nel tuo nuovo clone NON mostra il tag foo. La stessa cosa accade se si è clonato prima che sia stato aggiunto il tag foo e si faccia hg pull -r foo.

(Digressione: il tag è l'unica cosa che non riesco a ottenere in hg. Capisco che ci sono dei vantaggi (ad esempio unire) nel metterlo in un changeset, ma è sempre strano avere metadati mescolati con l'origine codice.)

Dovrebbe essere ovvio che sto chiedendo un modo automatico, invece di tirare il changeset del tag come una fase manuale separata.

So che potrei verificare per questo scenario in un hook incoming (quindi funziona sia per clonare sia per tirare), oppure per avvolgere clone e pull.

Ma c'è un modo migliore/più semplice?


UPDATE hg bug tracker ha già this issue.

+2

I tag che introducono i changeset devono essere una delle poche cose che non mi piacciono di Mercurial –

risposta

0

Sì, può essere eseguito da ganci post-clone/pull, ma ci sono un paio di imbroglioni.

Innanzitutto, funziona solo per il repository locale, poiché non è possibile ottenere l'elenco dei tag in un repository remoto.

In secondo luogo, trattare argomenti e opzioni clone/pull non è banale. (Per clone ho bisogno di ottenere il repository di destinazione, -r, -u, -U. Per tirare ho bisogno di -r e -u.) Ho provato a usare fancyopts, ma non può occuparsi di opzioni globali, che vengono elaborate in spedizione. Sono riuscito a modificare il dispatch per darmi solo gli args e le opts di un comando, ma sembra e sembra brutto.

L'utilizzo del wrapper dei comandi eliminerebbe il secondo problema.

Spero che un giorno hg aggiunga un'opzione per clonare e tirare per farlo in modo pulito.

+1

Se stai usando un hook non puoi controllare il valore della variabile '$ HG_URL'. –

+0

Ho anche bisogno delle parole chiave e opts, ma la tua menzione di $ HG_URL mi ha aiutato a scoprire da [man hgrc] (http://www.selenic.com/mercurial/hgrc.5.html#hooks) che tutti i pre/post gli hook ottengono $ HG_PATS e $ HG_OPTS. –

1

C'è un hook postclone. Si chiama post-clone (la pagina man di hgrc mostra un numero post-ANYCOMMAND e pre-ANYCOMMAND) sebbene, come hai indicato, potresti utilizzare anche gli hook *changegroup o update, poiché clone utilizza entrambe le funzioni (a meno che non si sopprima l'aggiornamento con -U).

Che ne dici di aggiungere un --localtag in modo da avere il nome ma non il set di modifiche aggiuntivo se necessario per riferimento. Qualcosa come

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

che potresti facilmente costruire in un alias di shell.

Oltre a questo non è necessariamente garantito un modo per avere la revisione X e la revisione in cui la revisione X viene taggata senza avere anche altre revisioni che non si desidera poiché il tag potrebbe essere stato applicato dopo che è stato eseguito altro lavoro. Ovviamente puoi sempre aggiornare a "X" e avere i successivi changeset nella tua directory di lavoro, ma saranno ancora nel tuo repository.

Onestamente, una volta ho capito che il nome del tag non arriva molto tempo quando cloni fino a un tag, che ammetto di aver confuso all'inizio, non ho trovato alcun bisogno di portare con me il changeset con il tag in esso.

+0

Grazie per l'hook 'post-clone'. Ho rimosso "e dal momento che non esiste un hook" postclone "dalla domanda. Non mi piace il tag locale dato che cercherò di inserire il tag changeset un po 'di tempo dopo. Anche senza il changeset del tag, potrei commettere un tag da solo, quindi dovrò unire i tag. –

+0

Sì, non è perfetto ma non c'è modo di farlo senza creare ulteriori changeset che potresti non volere (tutti quelli tra il lavoro e il tag cset). Almeno i tag si fondono perfettamente e il locale non può entrare in conflitto o essere spinto. –

+0

Estrarrò il set di modifiche del tag solo se è l'unico figlio del taggato. @ La risposta di Richard mi ha dato l'idea di usare un gancio pre-clone e pre-pull per controllare il caso e cambiare la revisione clone/pull al changeset del tag. Postback. –

3

Vuoi un attacco gigantesco con bash e uno script Perl incorporato? Bene, eccolo ...

#!/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 

Questo richiama il comando hg log per estrarre il numero di revisione dopo la prima revisione tag correlati e quindi cloni a questa revisione.

Attualmente questo non funziona sui repository remoti: lo switch -R funziona solo su repository locali, sfortunatamente.

+3

Sicuramente l'avrei accettato se tu non avessi esplicitamente incluso parole git-tish come "gigante", "hack" (oops, ho appena offeso Lord Linus? * Raduno tuono remoto ... *), "bash", e "perl". Spero in una piccola, elegante, soluzione basata su hg, python :) +1 tuttavia. –

+1

Dovrebbe essere semplice per Pythonize usando 'os.system' e alcune espressioni regolari corrispondenti. Bel commento: +1 te stesso! –

+2

Questo non funzionerà quando tagghi una vecchia revisione ... se faccio il tag 'hg -r 100 pippo', allora potrei creare la revisione 1000. Quindi prendere la revisione 101 non porterà il tag. –

3

Più ci penso e più mi sono convinto della destra risposta è quella di clonare proprio tutto e aggiornamento per il tag, che può essere fatto in una sola fase:

hg clone http://host/path#tagname 

che ottiene fai tutto e poi fa hg update in tagname che imposta la tua directory di lavoro sulla revisione corretta. Dato che la compressione delta non è necessariamente molto più grande, e se lo è puoi automatizzare la clonazione del grosso da un precedente clone locale.

+0

Grazie, non sapevo di poter usare anche #. Comunque il problema è, come dice la mia domanda, che non ho il changeset del tag nel clone, quindi non so a quale tag è clone. –

+0

Eh? Sembra che tu conosca il nome e che il nome sia 'foo'. Quindi puoi fare 'hg clone http: // host/path # foo'. Se davvero non conosci il nome del tag, dovresti clonare tutto e quindi aggiornare: non c'è niente di male nell'avere più giri nel repository, ma non nella directory di lavoro. –

+0

Mi spiace intendevo "a quale tag ** il ** clone è", poiché il clone non ha il changeset del tag 'foo'. Naturalmente lo sapevo subito dopo il clone, ma non dopo un po '(ho una memoria terribile a breve termine). Come hai detto, facendo un clone completo, l'aggiornamento è una soluzione ovvia, e lo faccio sempre comunque. È solo che la semantica 'clone parent # foo' sembra un po 'strana senza ottenere il changeset del tag. –

Problemi correlati