2008-09-15 7 views
40

Ich fragte vor kurzem über keyword expansion in Git und ich bin bereit, das Design zu akzeptieren, nicht wirklich diese Idee in Git zu unterstützen.Umgang mit SVN-Keyword-Erweiterung mit Git-Svn

Für besser oder schlechter, das Projekt arbeite ich im Moment erfordert SVN Stichwort Expansion wie folgt aus:

svn propset svn:keywords "Id" expl3.dtx 

diese Zeichenfolge zu halten up-to-date:

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

Aber ich würde gerne Git benutzen, um meine Versionskontrolle zu machen. Leider git-svn unterstützt dies nicht, laut Doku:

„Wir ignorieren alle SVN Eigenschaften außer svn: executable“

Aber es nicht zu kompliziert scheint dies zu haben Schlüsselwörtern, die durch ein paar pre/post commit hooks emuliert werden. Bin ich die erste Person, die das will? Hat jemand Code dafür?

Antwort

39

Was passiert hier: Git ist so optimiert, dass es so schnell wie möglich zwischen den Filialen wechseln kann. Insbesondere ist git checkout entworfen, um keine Dateien zu berühren, die in beiden Zweigen identisch sind.

Leider bricht RCS Schlüsselwortsubstitution das. Wenn Sie z. B. $Date$ verwenden, müssen Sie bei der Verzweigung von Verzweigungen jede Datei im Baum mit git checkout berühren. Bei einem Repository in der Größe des Linux-Kerns würde dies alles zum Stillstand bringen.

Im Allgemeinen ist die beste Wahl mindestens eine Version zu markieren:

$ git tag v0.5.whatever 

... und rufen Sie dann den folgenden Befehl von Ihrem Makefile:

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

Hier git sagt Ich, dass ich an einer anonymen Version 6 arbeite, beginne nach v0.5.15.1, mit einem SHA1 Hash beginnend mit g61cde1d. Wenn Sie die Ausgabe dieses Befehls irgendwo in eine *.h Datei stecken, sind Sie im Geschäft und haben kein Problem, die veröffentlichte Software wieder mit dem Quellcode zu verknüpfen. Dies ist die bevorzugte Vorgehensweise.

Wenn Sie RCS-Schlüsselwörter nicht vermeiden können, möchten Sie vielleicht mit dieser explanation by Lars Hjemli beginnen. Grundsätzlich ist $Id$ ziemlich einfach, und wenn Sie git archive verwenden, können Sie auch $Format$ verwenden.

Aber, wenn Sie absolut nicht RCS Keywords vermeiden, Sie sollte folgendes erhalten begonnen:

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 

Auf meinem System, die ich erhalten:

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

Wenn Sie Schwierigkeiten haben, die Shell-Escapes haben in den smudge und clean Befehle zu arbeiten, schreiben Sie einfach Ihre eigenen Perl-Skripte zum Erweitern bzw. Entfernen von RCS-Schlüsselwörtern, und verwenden Sie diese Skripte als Ihr Filter.

Beachten Sie, dass wirklich will das nicht als unbedingt notwendig, um weitere Dateien zu tun, oder git wird den größten Teil seiner Geschwindigkeit verlieren.

+0

Kann dieses "git describe" -Ding als Teil der normalen Git-Operationen transparent ausgeführt werden? Wir können nicht zuverlässig erwarten, dass der Befehl git in unseren Hudson-Instanzen verfügbar ist. –

+0

@ Thorbjørn Ravn Andersen, ich kenne Hudson nicht, aber wenn deine Hudson-Instanz keine Kopie von git hat, muss ein anderes System git ausgeführt haben, um einen Checkout der Quelle zu generieren. Verwenden Sie _that_ system, um git describe auszuführen. Ich bin mir nicht sicher, ob das hilft. – emk

+0

Ich endete mit jGit - es unterstützt "rev-parse HEAD", ist aber sehr leise darüber. –

2

Sie könnten das ident Attribut auf Ihre Dateien festgelegt, aber das würde Strings wie

$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$ 

produzieren, wo deadbeef... die SHA1 des Blobs zu dieser Datei entspricht, ist. Wenn Sie diese Keyword-Erweiterung wirklich benötigen und sie im git-Repo (im Gegensatz zu einem exportierten Archiv) benötigen, müssen Sie mit dem ident gitattribute ein benutzerdefiniertes Skript erstellen, das die Erweiterung für Sie übernimmt. Das Problem bei der Verwendung eines Hooks ist, dass die Datei in der Arbeitsbaumstruktur nicht mit dem Index übereinstimmt und git denkt, dass sie geändert wurde.

22

Leider RCS Schlüsselwort Substitution bricht dies. Beispiel: mit $ Date $ würde git checkout erfordern, um jede Datei im Baum beim Wechseln der Zweige zu berühren.

Das ist nicht wahr. $ Date $ etc. expandiert auf den Wert, der zum Check-in-Zeitpunkt gilt. Das ist sowieso viel nützlicher. Es ändert sich also nicht bei anderen Revisionen oder Verzweigungen, es sei denn, die Datei wird tatsächlich erneut eingecheckt. Vom RCS Handbuch:

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

Dies bedeutet auch, dass die vorgeschlagene Antwort oben, mit den rcs-keyword.smudge Filter, falsch ist. Es fügt die Uhrzeit/das Datum des Checkouts oder was immer es auch sein mag, ein.

6

Hier ist ein Beispielprojekt, das die Konfiguration und Filtercode erforderlich für das Hinzufügen von RCS Keyword-Unterstützung zu einem Git-Projekt enthält:

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

Es ist nicht so einfach zu installieren wie man möchte, aber es scheint Arbeit. Es verwendet ein in pearl geschriebenes Filterpaar, das in Perl geschrieben wird (ähnlich wie die Antwort von emk beschrieben wurde), und ja, es wird alle Dateien mit den in .gitattributes gesetzten Erweiterungen berühren, was die Dinge generell etwas verlangsamt.