web-dev-qa-db-ja.com

git-svnでSVNキーワード拡張を処理する

最近、 Gitでのキーワード拡張 について質問しましたが、Gitでこのアイデアを実際にサポートしない設計を受け入れたいと思います。

良くも悪くも、私が現在取り組んでいるプロジェクトでは、次のようなSVNキーワードの拡張が必要です。

svn propset svn:keywords "Id" expl3.dtx

この文字列を最新の状態に保つには:

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

しかし、バージョン管理を行うためにGitを使用したいと思います。残念ながら、ドキュメントによると、git-svnはこれをサポートしていません。

「svn:executableを除くすべてのSVNプロパティを無視します」

しかし、このキーワードをいくつかのコミット前後のフックでエミュレートするのはそれほど難しいことではないようです。私はこれを欲しがる最初の人ですか?誰かがこれを行うためのコードを持っていますか?

42
Will Robertson

ここで何が起こっているのか:Gitは、ブランチをできるだけ早く切り替えるように最適化されています。特に、git checkoutは、両方のブランチで同一のファイルに触れないように設計されています。

残念ながら、RCSキーワード置換はこれを破ります。たとえば、$Date$を使用すると、ブランチを切り替えるときにツリー内のすべてのファイルにアクセスするためにgit checkoutが必要になります。 Linuxカーネルのサイズのリポジトリの場合、これによりすべてがひどく停止します。

一般に、最善の策は、少なくとも1つのバージョンにタグを付けることです。

$ git tag v0.5.whatever

...次に、Makefileから次のコマンドを呼び出します。

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

ここで、gitは、v0.5.15.1以降の匿名バージョン6のコミットに取り組んでおり、SHA1ハッシュがg61cde1dで始まることを通知しています。このコマンドの出力をどこかの*.hファイルに貼り付ければ、ビジネスを行っているので、リリースされたソフトウェアをソースコードにリンクするのに問題はありません。これは物事を行うための好ましい方法です。

RCSキーワードの使用を避けられない場合は、これから始めることをお勧めします Lars Hjemliによる説明 。基本的に、$Id$は非常に簡単で、git archiveを使用している場合は、$Format$も使用できます。

ただし、RCSキーワードを絶対に避けられない場合は、次のことから始めてください。

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

私のシステムでは、次のようになります。

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

smudgeコマンドとcleanコマンドでシェルエスケープを機能させるのに問題がある場合は、RCSキーワードをそれぞれ展開および削除するための独自のPerlスクリプトを作成し、それらのスクリプトをフィルターとして使用します。

本当に絶対に必要な数より多くのファイルに対してこれを実行したくないことに注意してください。そうしないと、gitはほとんどの速度を失います。

39
emk

残念ながら、RCSキーワード置換はこれを破ります。たとえば、$ Date $を使用すると、ブランチを切り替えるときにツリー内のすべてのファイルにアクセスするためにgitcheckoutが必要になります。

それは真実ではありません。 $ Date $などは、チェックイン時に保持される値に展開されます。とにかくそれははるかに便利です。したがって、ファイルが実際に再チェックインされない限り、他のリビジョンまたはブランチでは変更されません。 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.

これは、rcs-keyword.smudgeフィルターを使用した上記の提案された回答が正しくないことも意味します。チェックアウトの日時、またはそれが実行される原因となるものは何でも挿入します。

22
Rhialto

GitプロジェクトにRCSキーワードサポートを追加するために必要な構成とフィルターコードを含むサンプルプロジェクトを次に示します。

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

セットアップは思ったほど簡単ではありませんが、うまくいくようです。 Perlで書かれたスマッジ/クリーンフィルターのペアを使用し(emkの回答で説明されているものと同様)、はい、.gitattributesで設定された拡張子を持つすべてのファイルにアクセスし、通常は少し遅くなります。

6
turon

ファイルにident属性を設定することもできますが、その場合は次のような文字列が生成されます。

$Id: deadbeefdeadbeefdeadbeefdeadbeefdeadbeef$

どこ deadbeef...は、そのファイルに対応するblobのsha1です。そのキーワード拡張が本当に必要で、(エクスポートされたアーカイブではなく)gitリポジトリで必要な場合は、identgitattributeとカスタムスクリプトを使用する必要があると思います。あなたのための拡張。フックを使用するだけの問題は、作業ツリー内のファイルがインデックスと一致せず、gitがそれが変更されたと見なすということです。

1
Lily Ballard