miauのブログ

はてなダイアリー「miauの避難所」をはてなブログに移行しました

Git で一部のブランチだけ取得する

Git で本番サーバ上のモジュールを管理するために production ブランチを作ってみたのですが、

  • production 以外のブランチに巨大なファイルを置いてしまったが、本番サーバには置きたくない
  • 本番サーバでの誤操作防止のため、production 以外のブランチは取得したくない

という事情で、producton ブランチの内容だけを取得したくなりました。

こういうやり方は見かけたことがある気がするんですが、ちょっと探したら見つけられなかったので、こんな風にやりましたメモです。もっと楽なやり方があれば教えてくださいませ。

本番サーバ上で取得用のリポジトリを作る

git clone だと細かい設定はできないっぽいので

git init

で空のリポジトリを作成します。

リモートブランチの設定を行う

-t production でトラッキングを行うブランチを限定するのがポイントです。

git remote add -t production origin ssh://user@git-server/var/git/hoge.git

-t オプションなしの場合は、.git/config は

[remote "origin"]
	url = ssh://user@git-server/var/git/hoge.git
	fetch = +refs/heads/*:refs/remotes/origin/*

こんな感じになって全部のブランチが fetch されるんですが、-t オプションをつけたので、

[remote "origin"]
	url = ssh://user@git-server/var/git/hoge.git
	fetch = +refs/heads/production:refs/remotes/origin/production

のように production だけが fetch されるようになっています。

モジュールの取得

git fetch

でモジュールを取得します。

設定を確認しながら操作したかったので今回はやりませんでしたが、 git remote add に -f オプションを付加しておけば、そのタイミングで fetch も実行されます。

fetch の対象を production に限定しない場合は

remote: Counting objects: 7483, done.
remote: Compressing objects: 100% (5627/5627), done.
remote: Total 7483 (delta 2134), reused 7079 (delta 1767)
Receiving objects: 100% (7483/7483), 109.71 MiB | 1.33 MiB/s, done.
Resolving deltas: 100% (2134/2134), done.

という感じなんですが、今回は限定しているので

remote: Counting objects: 6823, done.
remote: Compressing objects: 100% (5339/5339), done.
remote: Total 6823 (delta 1541), reused 6676 (delta 1400)
Receiving objects: 100% (6823/6823), 107.73 MiB | 1.32 MiB/s, done.
Resolving deltas: 100% (1541/1541), done.

のように容量が節約・・・ってあんまり変わってないですね。10 MB くらいのダンプファイルが入ってるはずなんですけど、圧縮されてるせいか転送量の差は 2 MB 程度になっていました。

production ブランチのチェックアウト

git checkout origin/production -b production

とやって、production ブランチをチェックアウトします。

最初は「もう fetch の設定終わってるから git pull でいけるでしょ」と勘違いして git pull やったんですけど、この方法だと master ブランチにチェックアウトされてしまいました。.git/config で設定した fetch の左辺は「取得元のリポジトリからどのブランチを取得するか」の設定であって、ローカルブランチとの対応付けには

[branch "production"]
	remote = origin
	merge = refs/heads/production

の部分が使われるってことですね。

以降は特に意識せずに production ブランチが使われますし、間違って git checkout master とかやってしまっても、

error: pathspec 'master' did not match any file(s) known to git.

のように言われるので、そこそこ安全に使えるはずです。