2009-06-06 14 views
15

Non uso Mercurial, ma mi piacerebbe iniziare, quindi sto leggendo a riguardo. L'unico sistema SCM che ho usato ampiamente è CVS. La maggior parte di ciò che ho letto su Mercurial ha senso e suona bene. Ma sono alternativamente scioccato e perplesso in questo modo con i tag.Come posso sapere sempre tutti i tag in Mercurial?

Un tag è solo un soprannome per un insieme di modifiche (e da 'changeset' abbiamo davvero: lo Stato derivante dal changeset). Freddo. La mappatura dai tag agli ID changeset è memorizzata nel file .hgtags. Anche bello. Il file .hgtags è versionato.

Cosa?

Questo ha un sacco di conseguenze controintuitivo. Ad esempio, se commetto un changeset che poi voglio taggare (ad esempio, il codice che formerà la versione 1.0), devo eseguire nuovamente il commit dopo aver effettuato il tagging, per inserire il file di tag aggiornato nel repository. E se poi aggiorno a quel changeset con tag in un secondo momento, la copia di lavoro non conterrà alcuna conoscenza di quel tag. Se faccio un po 'di lavoro, quindi fondando un nuovo ramo (diciamo, per correzioni di bug, verso 1.1), quel ramo non avrà alcuna conoscenza del tag da cui è cresciuto. A meno che non lo copio manualmente, cioè.

E mentre lo sviluppo continua sia sul trunk originale che sul mio nuovo ramo, con tag creati per contrassegnare importanti changeset (la versione 2.0 sul trunk, i rilasci di correzioni 1.1 e 1.2 sul ramo), entrambi i rami procederanno in ignoranza dei tag dell'altro ramo. Quindi, se finisco di lavorare su un ramo e voglio passare ad un particolare changeset su un altro (ad esempio, ho finito il rilascio del bugfix 1.2, ma ora devo iniziare con il bugfix 2.1, basato su 2.0), ora sono riempito. Il mio attuale changeset non sa di 2.0!

Cosa posso fare?

  • posso chiedere a qualcuno che sta lavorando sul ramo 2.x di leggere l'identificatore di changeset effettivo per 2.0, e l'uso che in modo esplicito, ma questo è spaventosa.
  • Potrei citare i miei rami, così come con i tag, in modo che io potessi saltare attraverso al capo del ramo 2.x, imparando così sui nuovi tag, e poi saltare indietro al tag 2.0. Supponendo che i rami, a differenza dei tag, siano universalmente visibili - è così? Anche se lo fosse, questo sembra goffo.
  • È possibile mantenere un singolo file globale hgtags al di fuori del repository e utilizzare un paio di hook per inserire una copia su un aggiornamento, sovrascrivendo la copia locale e copiare le modifiche su un commit. Non sono sicuro di come funzionerebbe in un ambiente multiutente, in cui gli sviluppatori stanno spingendo le modifiche a un repository condiviso; Potrei aver bisogno di un repository separato solo per il file hgtags.
  • Potrei usare i tag locali, che stanno fuori dal meccanismo di versioning, e quindi evitare l'intero problema. Come con i tag globali condivisi, dovrei mettere in atto un meccanismo per sincronizzare il file localtags tra gli sviluppatori.

Nessuna di queste soluzioni sembrano totalmente grande. Cosa dovrei fare?

Un presupposto qui è che sto gestione rami utilizzando rami con nome in un unico repository, piuttosto che repository-per-branch. La situazione sarebbe migliore se avessi fatto il secondo?

+0

@SilentGhost: ho rimosso il tag 'hg' poiché il tag 'mercurial' è molto più utilizzato. Ma forse è stato un errore? –

risposta

19

Versioning file .hgtags si permette di

  • modificare i tag e vedere chi li curato (e perché se hanno lasciato un messaggio di commit corretto)
  • tag di trasferimento tra i repository utilizzando i normali meccanismi

Tuttavia, c'è una certa confusione in corso qui.

  • Lei scrive che

    [...] E se io quindi aggiornare a quel changeset tag in una data successiva, la copia di lavoro sarà non contiene alcuna conoscenza di quel tag. [...]

    che è sbagliato, i tag sono raccolti dai file .hgtags si trovano in tutte le teste . Ciò significa che è possibile aggiornare a un vecchio tag (hg update 0.1) e vedere ancora tutti i tag (hg tags).

  • Chiedi se i rami sono universalmente visibili. Sì, lo sono: i nomi dei rami nominati possono essere utilizzati in qualsiasi contesto in cui è necessario specificare un changeset, così come i tag.

Assicurati di capire quali rami nominati sono prima di iniziare a utilizzarli. In realtà sono non necessarie per creare un ramo di bugfix. Puoi invece scegliere di tornare indietro (hg update 1.0) e correggere il bug e quindi eseguire il commit. Ciò creerà una nuova testa, che sarà la linea di sviluppo verso 1.1 (questo ti dà multiple heads). Quindi non devi creare un ramo con nome per aggiungere un nuovo ramo di sviluppo al tuo repository.

Avere più teste è completamente equivalente ad avere più cloni. È anche possibile convertire avanti e indietro: è possibile utilizzare

% hg clone -r X-head repo repo-X 

a districare il X-head di modifiche ei suoi antenati dagli altri gruppi di modifiche in repo. E puoi combinare più cloni semplicemente trascinando tutti i changeset in un unico grande clone.

Named branches sono simili, ma diversi. Ti permettono di incorporare un nome in ogni changeset. Quindi puoi avere più changeset nella tua cronologia con il nome "pippo". Quando fai hg update foo finirai con il tip-most di questi changeset. In questo modo, i rami nominati funzionano come una specie di tag mobile.

Se sei a disagio con l'idea di un'etichetta permanente per i vostri gruppi di modifiche, si può invece provare il bookmarks extension. Ciò ti darà anche "tag fluttuanti" che puoi usare per l'aggiornamento, ma non saranno permanentemente parte della cronologia poiché non sono versionati.

Spero che questo aiuti un po '.

+0

Aha! Martin, grazie per aver chiarito da dove proviene il set di tag visibili: il mio problema evapora completamente. Prendo il vostro punto sui rami nominati, vale a dire che non è necessario assegnare un nome a un ramo perché esista. Il mio istinto è che i rami senza nome porterebbero alla confusione (avendo commesso il changeset di bugfix basato su 1.0, se poi aggiorni a qualcos'altro, come torni alla linea di bugfix - non devi conoscere l'ID del changeset?), ma ovviamente devo ancora provarlo nella pratica. –

+0

Hai ragione, devi conoscere l'ID del changeset. "hg heads" può dirlo, e l'estensione dei segnalibri può dargli un nome. Il modo più semplice per usare diversi cloni come lo facciamo nel progetto Mercurial stesso. Ci sono cloni hg e hg-stable e correzioni di bug in hg-stable. Potremmo anche aver usato i rami nominati, suppongo che non lo facciamo perché i rami nominati sono stati aggiunti molto tempo dopo che è stato utilizzato lo schema hg/hg-stable. –

+3

Ora usiamo le branch nominate nel progetto Mercurial stesso. Inoltre, l'estensione dei segnalibri fa ora parte delle funzionalità di base, il che significa che è sempre abilitata dopo l'aggiornamento a Mercurial 1.8. –

1

La scelta del metodo per la codifica sicuramente ha alcuni effetti collaterali strani, ma sono spiegato bene in this wiki.Si suggerisce anche di clonare un intero repository e quindi aggiornare il punto di interesse per evitare il caso in cui si sarà creato un repository che non contiene il tag che è stato utilizzato per crearlo.

Problemi correlati