リモートタグをプレフィックス付きで取り込む

昨日のエントリでは read-tree の感動的な能力を垣間見れた。つまり Rails アプリケーションの git リポジトリの中で、rails や cucumber などの外部プロジェクトをルートブランチとして取り込んで、read-tree で vendor 以下に配置できるってこと。この機能を実装した人に千歳鶴を贈りたいっていうくらい便利だ。

ところが、複数の外部プロジェクトを remote add して fetch するときに、別の問題が発生していることに今日気がついちゃった。例えばこんな感じ。

$ git remote
jrails  git://github.com/mrkn/jrails.git (fetch)
jrails  git://github.com/mrkn/jrails.git (push)
origin  <censored> (fetch)
origin  <censored> (push)
rails   git://github.com/mrkn/rails.git (push)
rails   git://github.com/mrkn/rails.git (fetch)
rspec   git://github.com/dchelimsky/rspec.git (fetch)
rspec   git://github.com/dchelimsky/rspec.git (push)
rspec-rails     git://github.com/dchelimsky/rspec-rails.git (fetch)
rspec-rails     git://github.com/dchelimsky/rspec-rails.git (push)
$ git tag
1.1.10
1.1.11
1.1.12
1.1.4
1.1.5
1.1.6
1.1.7
1.1.8
1.1.9
1.1.99.1
1.1.99.10
1.1.99.11
1.1.99.12
1.1.99.13
1.1.99.14
1.1.99.15
1.1.99.16
1.1.99.2
1.1.99.3
1.1.99.4
1.1.99.5
1.1.99.6
1.1.99.9
1.2.0
1.2.1
1.2.2
1.2.2.1
1.2.3
1.2.4
1.2.5
1.2.6
1.2.6.99
1.2.7
1.2.7.1
1.2.7.rc1
1.2.8
1.2.9
1.2.9.rc1
1.3.0
1.3.1
1.3.2
v0.10.0
v0.10.1
v0.11.0
v0.11.1
v0.12.0
v0.13.0
v0.13.1
v0.14.1
v0.14.2
v0.14.3
v0.14.4
v0.9.1
v0.9.2
v0.9.3
v0.9.4
v0.9.4.1
v0.9.5
v1.0.0
v1.1.0
v1.1.0_RC1
v1.1.1
v1.1.2
v1.1.3
v1.1.4
v1.1.5
v1.1.6
v1.2.0
v1.2.0_RC1
v1.2.0_RC2
v1.2.1
v1.2.2
v1.2.3
v1.2.4
v1.2.5
v1.2.6
v2.0.0
v2.0.0_PR
v2.0.0_RC1
v2.0.0_RC2
v2.0.1
v2.0.2
v2.0.3
v2.0.4
v2.0.5
v2.1.0
v2.1.0_RC1
v2.1.1
v2.1.2
v2.2.0
v2.2.1
v2.2.2
v2.2.3
v2.3.0
v2.3.1
v2.3.2
v2.3.2.1
v2.3.3
v2.3.3.1
v2.3.4
v2.3.5

さて、どのタグがどのリモートリポジトリのものか分かるだろうか?ムリだろwww

この問題を解決するには、rails から取り込むタグに例えば rails/ っていうプレフィックスを付けたりする方法が考えられるんだけど、まさにその方法を git fetch にオプションを付けるだけで実現できることが分かった。

方法

git fetchに--no-tagsオプションを付けることでタグを取得しないことができる

$ git fetch --no-tags library-a
   # タグ以外のものを取得

その後、場所を明示的に指定してタグだけもってくる

$ git fetch --no-tags library-a refs/tags/*:refs/tags/library-a/*
    # リモートのタグをローカルに転送。その際プレフィクス library-a/ をつける
$ git tag
library-a/v1.0
library-a/v2.0
:
:
my_tag

グッド。

http://d.hatena.ne.jp/gnarl/20091110/1257856639

これを真似してやってみた。

$ git tag | xargs git tag -d
$ git fetch --no-tags rails refs/tags/*:refs/tags/rails/*
ls/v0.10.0
rails/v0.10.1
  <snip>
rails/v2.3.5
$ git fetch --no-tags rspec refs/tags/*:refs/tags/rspec/*
rspec/1.1.10
  <snip>
rspec/1.3.0
$ git fetch --no-tags rspec-rails refs/tags/*:refs/tags/rspec-rails/*
rspec-rails/1.1.10
  <snip>
rspec-rails/1.3.2

グッド。