Gestire l’espansione delle parole chiave SVN con git-svn

Di recente ho chiesto dell’espansione delle parole chiave in Git e sono disposto ad accettare il design per non supportare realmente questa idea in Git.

Nel bene o nel male, il progetto al quale sto lavorando al momento richiede un’espansione delle parole chiave SVN come questa:

svn propset svn:keywords "Id" expl3.dtx 

per mantenere questa stringa aggiornata:

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

Ma mi piacerebbe molto usare Git per fare il controllo della mia versione. Sfortunatamente, git-svn non supporta questo, secondo i documenti:

“Ignoriamo tutte le proprietà SVN tranne svn: eseguibile”

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

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

Sfortunatamente, la sostituzione della parola chiave RCS rompe questo. Ad esempio, l’utilizzo di $Date$ richiede il git checkout per toccare ogni file nell’albero quando si passa da un ramo all’altro. Per un repository delle dimensioni del kernel di Linux, questo porterebbe tutto a una brusca frenata.

In generale, la soluzione migliore è taggare almeno una versione:

 $ git tag v0.5.whatever 

… e poi chiama il seguente comando dal tuo Makefile:

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

Qui, git mi sta dicendo che sto lavorando su una versione anonima 6 che impegna oltre la v0.5.15.1, con un hash SHA1 che inizia con g61cde1d . Se si configura l’output di questo comando in un *.h da qualche parte, si è in affari e non si avranno problemi a colbind il software rilasciato al codice sorgente. Questo è il modo preferito di fare le cose.

Se non puoi evitare di usare le parole chiave di RCS, potresti iniziare con questa spiegazione di Lars Hjemli . Fondamentalmente, $Id$ è abbastanza facile, e tu se stai usando git archive , puoi anche usare $Format$ .

Ma, se assolutamente non puoi evitare le parole chiave RCS, quanto segue 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 non riesci a far fuggire la shell nella smudge e clean comandi, scrivi solo i tuoi script Perl per espandere e rimuovere le parole chiave RCS, rispettivamente, e usa quegli script come filtro.

Nota che davvero non vuoi farlo per più file di quanto sia assolutamente necessario, o git perderà gran parte della sua velocità.

Sfortunatamente, la sostituzione della parola chiave RCS rompe questo. Ad esempio, l’utilizzo di $ Date $ richiede il checkout git per toccare ogni file nell’albero quando si passa da un ramo all’altro.

Quello 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. 

Ciò significa anche che la risposta suggerita sopra, con il filtro rcs-keyword.smudge, non è corretta. Inserisce l’ora / la data del checkout, o qualsiasi altra cosa che lo faccia funzionare.

Ecco un progetto di esempio contenente la configurazione e il codice del filtro necessari per aggiungere il supporto per le parole chiave RCS a un progetto git:

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

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

È ansible impostare l’attributo ident sui file, ma ciò produrrebbe stringhe come

 $Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$ 

dove deadbeef... è lo sha1 del blob corrispondente a quel 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 gitattribuit 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.