2008-09-15 6 views
40

Ho chiesto di recente su keyword expansion in Git e sono disposto ad accettare il progetto per non supportare realmente questa idea in Git.Gestire l'espansione delle parole chiave SVN con git-svn

bene o nel male, il progetto su cui sto lavorando in questo momento richiede SVN espansione parole chiave come questo:

svn propset svn:keywords "Id" expl3.dtx 

per mantenere questa stringa up-to-date:

$Id: expl3.dtx 803 2008-09-11 14:01:58Z will $ 

Ma mi piacerebbe molto usare Git per fare il controllo della mia versione. Purtroppo, git-svn non supporta questo, secondo la documentazione:

"ignoriamo tutte le proprietà ad eccezione di SVN svn: eseguibili"

Ma non sembra troppo difficile da avere questa roba per parole chiave emulata da un paio di hook pre/post commit. Sono io il primo a volerlo? Qualcuno ha del codice per farlo?

risposta

39

Cosa sta succedendo qui: Git è ottimizzato per passare da un ramo all'altro il più rapidamente possibile. In particolare, git checkout è progettato per non toccare alcun file identico in entrambi i rami.

Sfortunatamente, la sostituzione di parole chiave di RCS si rompe. Ad esempio, utilizzando $Date$ richiedere git checkout per toccare ogni file nell'albero quando si cambia ramo. Per un repository delle dimensioni del kernel di Linux, questo porterebbe tutto a una brusca frenata.

In generale, la soluzione migliore è quella di etichettare almeno una versione:

$ git tag v0.5.whatever 

... e quindi chiamare il seguente comando dal Makefile:

$ git describe --tags 
v0.5.15.1-6-g61cde1d 

Qui, git sta dicendo io che sto lavorando su una versione anonima 6, ho passato la v0.5.15.1, con un hash SHA1 che inizia con g61cde1d. Se si configura l'output di questo comando in un file *.h da qualche parte, si è in affari e non avrà alcun problema a collegare il software rilasciato al codice sorgente. Questo è il modo preferito di fare le cose.

Se non è possibile evitare l'uso di parole chiave RCS, è possibile iniziare con questo explanation by Lars Hjemli. Fondamentalmente, $Id$ è abbastanza semplice, e se si utilizza git archive, è anche possibile utilizzare $Format$.

Ma, se proprio non si può evitare di parole chiave RCS, il seguente dovrebbe iniziare:

git config filter.rcs-keyword.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"' 
git config filter.rcs-keyword.smudge 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date: `date`\\\$/"' 

echo '$Date$' > test.html 
echo 'test.html filter=rcs-keyword' >> .gitattributes 
git add test.html .gitattributes 
git commit -m "Experimental RCS keyword support for git" 

rm test.html 
git checkout test.html 
cat test.html 

Sul mio sistema, ottengo:

$Date: Tue Sep 16 10:15:02 EDT 2008$ 

Se hai difficoltà a raggiungere le uscite della shell nei comandi smudge e clean per lavorare, basta scrivere i propri script Perl per espandere e rimuovere le parole chiave RCS, rispettivamente, e usare quegli script come filtro.

Si noti che si davvero non si vuole fare questo per più file di quanto assolutamente necessario, o git perderà gran parte della sua velocità.

+0

può questa cosa "git descrivere" essere eseguita in modo trasparente come parte delle normali operazioni git? Non possiamo aspettarci attendibilmente che il comando git sia disponibile nelle nostre istanze di Hudson. –

+0

@ Thorbjørn Ravn Andersen, non ho familiarità con Hudson, ma se l'istanza di Hudson non ha una copia di git, allora un altro sistema deve aver eseguito git per generare un checkout della fonte. Usa _that_ system per eseguire git describe. Non sono sicuro se questo aiuti. – emk

+0

Ho finito per usare jGit - supporta "rev-parse HEAD" ma è molto silenzioso al riguardo. –

2

è possibile impostare l'attributo ident sui vostri file, ma che produrrebbe stringhe come

$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$ 

dove deadbeef... è la SHA1 del blob corrispondente a tale file. Se hai davvero bisogno dell'espansione di questa parola chiave, e ne hai bisogno nel repository git (al contrario di un archivio esportato), penso che dovrai andare con il gitattribute ident con uno script personalizzato che fa l'espansione per te. Il problema con l'uso di un hook è che il file nell'albero di lavoro non corrisponde all'indice e git penserebbe che sia stato modificato.

22

Sfortunatamente, la sostituzione di parola chiave RCS si rompe. Ad esempio, utilizzando $ Date $ richiederebbe il checkout git per toccare ogni file nell'albero quando si passa da un ramo all'altro.

Questo non è vero. $ Date $ ecc. Si espande al valore che detiene al momento del check-in. Questo è molto più utile comunque. Quindi non cambia su altre revisioni o rami, a meno che il file non venga effettivamente ricontrollato. Dal manuale RCS:

$Date$ The date and time the revision was checked in. With -zzone a 
      numeric time zone offset is appended; otherwise, the date is 
      UTC. 

Questo significa anche che la risposta suggerito sopra, con il filtro RCS-keyword.smudge, non è corretto. Inserisce l'ora/la data del checkout, o qualsiasi altra cosa che lo faccia funzionare.

6

Ecco un progetto di esempio che contiene il codice di configurazione e il filtro necessario per aggiungere il supporto parola chiave RCS a un progetto git:

https://github.com/turon/git-rcs-keywords

Non è così semplice da configurare come si vorrebbe, ma sembra lavoro. Usa una coppia di filtri sfumati/puliti scritti in perl (simile a quella descritta dalla risposta di emk), e sì, toccherà tutti i file con le estensioni impostate in .gitattributes, generalmente rallentando un po 'le cose.