章 ▾ 第2版

10.5 Gitの内部構造 - リフスペック

リフスペック

本書では、リモートブランチからローカル参照への単純なマッピングを使用してきましたが、これらはもっと複雑になる可能性があります。例えば、前のセクションを読み進めて小さなローカルGitリポジトリを作成し、そこにリモートを追加したいとします。

$ git remote add origin https://github.com/schacon/simplegit-progit

上記のコマンドを実行すると、リポジトリの.git/configファイルにセクションが追加され、リモート名(origin)、リモートリポジトリのURL、およびフェッチに使用するリフスペックが指定されます。

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*

リフスペックのフォーマットは、まずオプションの+に続き、<src>:<dst>です。ここで<src>はリモート側の参照のパターンを表し、<dst>はそれらの参照がローカルで追跡される場所を表します。+は、Gitにfast-forwardでない場合でも参照を更新するように指示します。

git remote add originコマンドによって自動的に書き込まれるデフォルトの場合、Gitはサーバー上のrefs/heads/以下のすべての参照をフェッチし、それらをローカルのrefs/remotes/origin/に書き込みます。したがって、サーバー上にmasterブランチがある場合、以下のいずれかの方法でそのブランチのログにローカルからアクセスできます

$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master

これらはすべて、Gitがそれぞれをrefs/remotes/origin/masterに展開するため、同等です。

代わりにGitが毎回masterブランチのみをプルダウンし、リモートサーバー上の他のすべてのブランチはプルダウンしないようにしたい場合、フェッチ行をそのブランチのみを参照するように変更できます

fetch = +refs/heads/master:refs/remotes/origin/master

これは、そのリモートに対するgit fetchのデフォルトのリフスペックです。一度だけフェッチしたい場合は、コマンドラインで特定のリフスペックを指定することもできます。リモート上のmasterブランチをローカルのorigin/mymasterにプルするには、以下を実行します

$ git fetch origin master:refs/remotes/origin/mymaster

複数のリフスペックを指定することもできます。コマンドラインでは、次のようにいくつかのブランチをプルダウンできます

$ git fetch origin master:refs/remotes/origin/mymaster \
	 topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
 ! [rejected]        master     -> origin/mymaster  (non fast forward)
 * [new branch]      topic      -> origin/topic

この場合、masterブランチのプルは、fast-forward参照としてリストされていなかったため拒否されました。リフスペックの前に+を指定することで、これを上書きできます。

設定ファイルでフェッチ用の複数のリフスペックを指定することもできます。originリモートから常にmasterexperimentブランチをフェッチしたい場合、2行を追加します

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/experiment:refs/remotes/origin/experiment

Git 2.6.0以降では、パターンに部分グロブを使用して複数のブランチをマッチさせることができるため、これは機能します

fetch = +refs/heads/qa*:refs/remotes/origin/qa*

さらに良いことに、名前空間(またはディレクトリ)を使用して、より構造化された形で同じことを達成できます。QAチームが一連のブランチをプッシュしており、masterブランチとQAチームのブランチのみを取得したい場合、次のような設定セクションを使用できます

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/master:refs/remotes/origin/master
	fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*

QAチームがブランチをプッシュし、開発者がブランチをプッシュし、統合チームがリモートブランチ上でプッシュおよび共同作業を行うような複雑なワークフロープロセスがある場合、このように簡単に名前空間を設定できます。

リフスペックのプッシュ

このように名前空間化された参照をフェッチできるのは良いことですが、そもそもQAチームはどのようにして自分のブランチをqa/名前空間に入れるのでしょうか?それは、リフスペックを使用してプッシュすることで実現します。

QAチームが自分のmasterブランチをリモートサーバーのqa/masterにプッシュしたい場合、以下を実行できます

$ git push origin master:refs/heads/qa/master

git push originを実行するたびにGitにそれを自動的に行わせたい場合、設定ファイルにpushの値を追加できます

[remote "origin"]
	url = https://github.com/schacon/simplegit-progit
	fetch = +refs/heads/*:refs/remotes/origin/*
	push = refs/heads/master:refs/heads/qa/master

これにより、git push originを実行すると、デフォルトでローカルのmasterブランチがリモートのqa/masterブランチにプッシュされます。

注記

リフスペックを使用して、あるリポジトリからフェッチし、別のリポジトリにプッシュすることはできません。その例については、GitHubの公開リポジトリを最新の状態に保つを参照してください。

参照の削除

リフスペックを使用して、次のように実行することでリモートサーバーから参照を削除することもできます

$ git push origin :topic

リフスペックは<src>:<dst>であるため、<src>の部分を省略することで、リモート上のtopicブランチを空にする、つまり削除することを意味します。

または、より新しい構文(Git v1.7.0以降で利用可能)を使用することもできます

$ git push origin --delete topic
scroll-to-top