Git
章 ▾ 第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に指示します。

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ブランチのプルは、高速な進捗リファレンスとしてリストされていなかったため、拒否されました。refspecの前に+を指定することで、これを上書きできます。

設定ファイルでフェッチするための複数のrefspecを指定することもできます。originリモートから常にmasterブランチとexperimentブランチをフェッチしたい場合は、次の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チームがブランチをプッシュし、開発者がブランチをプッシュし、インテグレーションチームがリモートブランチをプッシュして共同作業を行うような複雑なワークフロープロセスがある場合、このようにして簡単に名前空間を設定できます。

Refspecのプッシュ

このようにして名前空間付きの参照をフェッチできるのは素晴らしいですが、そもそもQAチームはどのようにしてブランチをqa/名前空間に入れるのでしょうか?refspecを使用してプッシュすることで、これを実現します。

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ブランチにプッシュされます。

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

参照の削除

次のようなコマンドを実行することで、refspecを使用してリモートサーバーから参照を削除することもできます。

$ git push origin :topic

refspecは<src>:<dst>であるため、<src>部分を省略することで、これは基本的にリモートのtopicブランチを空にすることを意味し、その結果削除されます。

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

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