Git:手元にある古い古い状態のブランチをoriginの最新のもので更新したいけれどいちいちcheckoutしたくない場合にどうすればいいかという話


2012年 10月 16日

問題

git checkout another_branch にすら時間がかかる……というのは大規模なプロジェクトだとありがちです。
例えば

  1. 自分が長期休暇を取ったら
  2. 自分の居ない間に盛大なリリースが行われ
  3. master にコミットがとんでもなく積み重なっている

という状況を考えてみましょう。
普通なら

git checkout master
git pull

だけで自分が居ない間に行われた修正が取り込めますが、

  • checkout 前のブランチと master が結構背離してて作業ツリーの更新に時間がかかる
  • しかもその時間をかけて行われた作業ツリーの更新が pull ですぐに上書きされる

という精神衛生上大変よろしくない事態が発生します。
どうにかしてブランチを checkout せずに共有リポジトリの取り込むことができないものでしょうか。

方法1: 一から作り直す

git branch -d master
git fetch
git branch master origin/master

しかしこれだと手違いで自分のリポジトリの master にしかない変更点があった時に気付けないままなのでよろしくありませんね。

方法2: 手元で push する

git fetch
git push . origin/master:master

git push は引数を色々と省略できるのですが、省略せずに使うと git push $remote $local_branch:$remote_branch になります。意味としては「$remote リポジトリの $remote_branch ブランチを自分のリポジトリの $local_branch で更新する」になります。

$remote には push 先のリポジトリのアドレスを指定します。これは URL でも構いませんし、ローカルマシンにあるリポジトリなら普通のパス(/foo/bar/baz 等)でも構いません。ということは現在のリポジトリそのものは . で表すことができます。

であれば fetch してきた master の内容を手元の master に反映するのは git push . origin/master:master でできる、という訳です。

しかし master から origin/master へ fast-forward できない場合は push できません。そういう場合は素直に checkout してから merge する必要があります。ただまあこういう小手先のテクニックが必要に感じるケースは統合ブランチが相手なので fast-forward 出来ないというケースはまずないでしょう(というより出来なかったら何かがおかしい)。

方法3: 時間が解決するのを待つ

git checkout master
git pull

先述のような小手先のテクニックを駆使するよりは素直に(あるいは富豪的に)処理の完了を待つというのも一つの手です。

補足

次回は Mercurial 編です。