2010-04-06 13 views
7

Ho creato un sistema di compilazione per la mia applicazione Web che sta riscrivendo tutti gli URL delle risorse per includere il numero di revisione del file (per migliorare il caching del client). Ad oggi sto correndo questo comando per ogni file per ottenere il numero di revisione:Come ottenere un elenco del numero di revisione più recente per ciascun file in un repository Mercurial?

hg log --template '{rev}\n' path-to-file 

Esecuzione Hg per ogni file è davvero tempo. C'è un modo rapido per elencare tutti i file in un repository con l'ultimo numero di revisione?

+1

Non ti piacerà la risposta, ma in breve si tratta di "svn thinking". L'ultimo numero di revisione per tutti i file è lo stesso, ed è 'tip'. Solo perché un file non è stato modificato in una revisione non significa che non abbia quel numero di revisione. Questo suona pedante, ma non. È uno dei concetti fondamentali sul modo in cui funzionano i DVCS. SVN (e predecessori) consentiva di avere file con diverse revisioni nelle casse. Mercurial lo rende esplicitamente impossibile. 'hg genitori non accetta un'opzione di file per un motivo. Vi esorto a riconsiderare perché pensate di aver bisogno di questo valore. –

+0

Sì e no. Avevamo bisogno di qualcosa del genere per attivare build sulla modifica di una determinata parte di un repository, per esempio. Ma posso ancora capire il tuo punto. –

+0

@ Ry4an Come ho accennato in seguito, il numero di revisione funziona molto bene in quanto viene sempre utilizzato dal server di build. Per un po 'di tempo ho appena usato un numero casuale generato per ciascun file per distribuzione, ma in questo modo la cache del client rimane valida per più cicli di distribuzione senza la necessità di un database aggiuntivo per tenere traccia delle modifiche ai file - ecco perché disponiamo di sistemi di controllo delle versioni nel il primo posto giusto? :) – Kimble

risposta

2

Questo lo farà, ma si prega di vedere il mio commento sopra sul motivo per cui l'utilizzo di questo in qualsiasi parte del flusso di lavoro è probabilmente una cattiva idea. Nella lista stessa dovresti usare l'hash di revisione e non il numero, dal momento che non cambia sul clone. Anche questo non è molto efficiente, ma almeno è solo due istanze di processo invece di uno per file:

hg grep --all '.' | perl -na -F: -e 'next unless ($F[2] eq "+"); print "$F[0] $F[1]\n" unless ($prev eq $F[0]); $prev = $F[0]' 

Esempio:

that 3 
file 1 
+0

Grazie! Anche se non è * la * soluzione più efficiente è probabilmente molto più veloce del mio attuale approccio. Sto usando il numero di revisione invece dell'hash perché sembra un po 'più carino e la build si svolge sempre sullo stesso computer. – Kimble

+0

Sì, dovrebbe essere molto più veloce perché costruisce solo un'istanza VM Python invece di molte, anche se non ha ancora bisogno di trollare su ogni riga di ogni revisione di ogni file. Felice che stia lavorando per voi (suggerimento!). :) –

2

Codificare un comando di questo tipo in python, analizzando hg annotate o come estensione mercuriale non dovrebbe essere troppo difficile. Il seguente numero discussion sulla mailing list mercuriale sembra fornire una soluzione ragionevole, sebbene non l'abbia ancora provato.

+0

Ho trovato la voce della mailing list, ma preferisco non gestire e distribuire un plugin Mercurial solo per farlo. – Kimble

+0

Un'estensione mercurial non è altro che uno script python in ogni caso :) –

+0

+1 per estensione mercurial (meno di 30 righe di codice) Ho migliorato l'estensione citata per accettare la revisione/ramo. https://gist.github.com/2921583 –

2

C'è un comando di debug hg "hg debugdata -m REV "che potrebbe aiutarti. Di seguito è come funziona:

  1. I commit 3 file a.txt/b.txt/c.txt in changeset 0/1/2 /, rispettivamente. E modifico a.txt nella versione 3. Il DAG ha il seguente aspetto:

------- 0 -------> 1 --------> 2 - ------> 3

a.txt b.txt c.txt a.txt

So the newest rev for a/b/c should be 3/1/2; 
  1. Dopo di che, i record di log sono: registro

    hg -q

    3:31308f74291a 
        2:8d438b01dfd4 
        1:fcc0f041df56 
        0:c53934933136 
    
  2. a.txt ha due versioni, che è collegata alla changeset 0 e 3 rispettivamente. Per ogni versione di a.txt, mercurial genererà un hash (nodoide) univoco per esso. Questi nodeid appartengono solo a a.txt e sono diversi dall'hash del changeset. Possiamo usare un altro comando di debug per vedere quali sono quelle versioni:

    ~/lavoro/hg/a/.hg/negozio/dati $ hg debugindex a.txt.i

rev  offset length base linkrev nodeid    p1   p2 

0   0  3  0  0  b789fdd96dc2 000000000000 000000000000 
1   3  6  1  3  a9ecbd92f818 b789fdd96dc2 000000000000 

possiamo vedere questi due "nodeid" (b789fdd96dc2/a9ecbd92f818) corrisponde changeset rispettivamente versione (linkrev) 0/3. Poiché questi nodi sono hash basati sul contenuto del file e informazioni parent (p1/p2), sono "univoci" in senso repository. quindi "b789fdd96dc2" identifica a.txt @ version-0 e a9ecbd92f818 identificano [email protected]

  1. Infine, vediamo come funziona "hg debugdata -m REV".

Questo comando elenca un "manifest" della versione REV. Un manifest è un'istantanea di directory per tutte le versioni di file @ esistenti nel changeset specifico REV. Vediamo quello che il manifesto è alla versione 3:

~/lavoro/hg/a $ hg debugdata -m 3

a.txt^@a9ecbd92f8182efd8eeb5396468fd70884650395 b.txt^@ 1e88685f5ddec574a34c70af492f95b6debc8741 c.txt^@149da44f2a4e14f488b7bd4157945a9837408c00

per a.txt, si può vedere il suo nodeid è "a9ecbd92f8182efd8eeb5396468fd70884650395", che è un match per il breve v il nodoide di ersione menzionato al punto 3. Tale nodo deve servire bene al tuo "URL di riscrittura".

Ora avete il nome del testo e il loro nodoide alla revisione 3. Basta un comando di debug per generare tutto ciò che volete. Penso che questa sia una soluzione migliore.

Se siete interessati al debug di comandi che Mercurial fornisce, fare questo:

hg debugcomplete di debug (l'elenco di tutti i comandi di debug)

hg aiuto debugdata

hg help debugindex


Problemi correlati