Git で意味の分かりにくい単語の一つ、「上流ブランチ」。その定義と意味をまとめました。
「上流ブランチ」とは?
「上流ブランチ(Upstream branch)」とは、あるローカルブランチが、履歴を追跡するように設定したリモートブランチの事を指します。
「追跡する」とは、そのブランチ上で発生したすべての更新をそのまま取り込む事を前提とする、という意味で、上流ブランチを設定することにより Git 自身もそのような動作をする事になります。
上流ブランチの設定値
厳密には、ローカルブランチに対する下記の設定値によって定義されます。これらの設定値は git config コマンドからは、下記の値で参照することができます。
- レポジトリ:branch.<ブランチ名>.remote
- ブランチ :branch.<ブランチ名>.merge
ですので、「上流ブランチ」は、これらリモートレポジトリとそこにあるブランチ名の設定値の組み合わせによって、一意に決まるリモートブランチと言えます。
設定値の例
試しに .git/conf のファイルを開いてみましょう。多くの場合、すでに「origin」にある「master」を上流として設定されているはずです。(そうでない方は、レポジトリを正しく開始しなかったかもしれません。)
該当項目は見つけられるはずです。
上記の例では、ローカルブランチ「master」に対して、リモートレポジトリの名前(remote = origin)と、ブランチ名(merge = master)がそれぞれ設定されていますね。merge の値は、ローカルではなく、リモートレポジトリ上のブランチ名を表している点に注意して下さい。
「リモート追跡ブランチ」との混同
「リモート追跡ブランチ」とは特定のリモートブランチの状態をそのままコピーしたローカルブランチのことです。「git branch -a」で、すべてのブランチを表示すると、ブランチ名に「remotes/origin/feature-a」などと、レポジトリ名が先に明示されます。
理解しておく必要がるのは、このようなリモート追跡ブランチが存在するからといって、同名のローカルブランチの上流ブランチが設定済みとは限らない、という点です
リモートブランチが、Git コマンドではしばしば「<レポジトリ名>/<ブランチ名>」として参照されますので、これはリモート追跡ブランチの指定と一致して混同されます。リモート追跡ブランチ「origin/cool-feature」が存在する事と、ローカルブランチ「cool-feature」の上流ブランチが設定済みかどうかは、別の話なのです。
設定方法によっては、ローカルブランチ名と異なる名前のリモートブランチを上流ブランチに設定することもできるのです。(そのような設定の必要はあまり生じないと思いますが・・。)
上流ブランチの設定状況の確認方法
上流ブランチが設定されているかどうかは、ブランチを閲覧するgit branch に、「-vv」オプションを付けると確認できます。
下記のように、上流レポジトリと上流ブランチの名前が、括弧の中に「<リモート名>/<ブランチ名>」として記載されています。(これは、リモート追跡ブランチ名ではありません。)
// 上流ブランチの設定状況
$ git branch -vv
// 結果
master b104f69 [origin/master: ahead 1] xxxx xxxxx xxxxxxxxxxxx xxx.
cool-feature b104f69 [origin/cool-feature] xxx xxxxxxxx xxxxxxxx xxxx xxxxx.
上流ブランチの設定方法
上流ブランチを設定するには、いくつかの設定方法があります。
1git branch コマンドで上流ブランチを明示的に設定
git branch コマンドを使えば、明示的に設定することもできます。下記のようにブランチ名だけを指定すれば、デフォルトでは自動で「origin」を上流レポジトリとして利用します。
// 明示的に上流ブランチを設定(2つは同義)
$ git branch <ローカルブランチ名> -u <リモートブランチ名>
$ git branch <ローカルブランチ名> --set-upstream-to=<リモートブランチ名>
// ローカルブランチ名を省略すると、自動的に現在のブランチを設定
$ git branch -u <リモートブランチ名>
$ git branch --set-upstream-to=<リモートブランチ名>
ちなみに、こちらは、git version 2 以降のオプションです。git version 1 では、「--set-upstream」という別のオプションがありましたが「名前が悪い(文法上の誤解を生みやすい)」ということで、廃止されました。(一応、v2でも利用は可能なようです)
2git branch で新規ブランチを作成するとき、--track (-t) オプションをつける
こちらは、引数を「origin/branch-name」として、明示的にリモートブランチを指定して下さい。(意図すれば、別のローカルブランチも上流ブランチとして設定することができます。そんな事しないと思いますが・・・)
// すでに origin/cool-feature が存在する状態で・・
$ git branch new-branch --track origin/remote-branch-name
// 結果
Branch new-branch set up to track remote branch master from origin.
3git branch で新規ブランチを作成するとき、リモート追跡ブランチを起点にする
これは Git の親切設計ですが、新規ブランチを作成時に起点をなんらかのリモート追跡ブランチを明示すると、自動的に該当のリモートブランチを追跡ブランチとして設定してくれます。
// すでに origin/cool-feature が存在する状態で・・
$ git branch new-branch origin/cool-feature
// 結果
Branch remote set up to track remote branch cool-feature from origin.
4git checkout にリモートブランチ名を指定する
これは、[3]の派生動作ではありますが、すでにgit fetch の実行により、該当のリモートブランチを追跡するリモート追跡ブランチが作成されており、かつ、まだ同名のローカルブランチが存在しない状態では、下記のようなgit checkout コマンドを実行すると、自動的に、リモート追跡ブランチを起点として新規のローカルブランチを作成し、該当のリモートブラチを上流ブランチとして設定します。
// すでに リモート追跡 origin/cool-feature ブランチが存在する状態で・・
$ git checkout cool-feature
// 結果
Branch cool-feature set up to track remote branch cool-feature from origin.
Switched to a new branch 'cool-feature'
5Push 時に同時に上流ブランチとして設定
push -時に「-u (--set-upstream)」オプションを付ければ、自動的に push するブランチとpush 先のレポジト、およびブランチは上流レポジトリ、上流ブランチとしてそれぞれ設定されます。
このオプションは、自分が担当したフィーチャブランチを初めてリモートにPushするときには便利ですので、よく利用すると思います。
// Push 先を上流ブランチとして設定(2つは同義)
$ git push -u origin cool-feature
$ git push --set-upstream origin cool-feature
5.git/conf に直接書き込む
これを実行することは稀だと思いますが、直接設定することももちろんできます。間違えそうで怖いですので、おすすめしません。
// cool-feature の上流ブランチをorigin/cool-featureに設定
$ git config branch.cool-feature.remote origin
$ git config master.cool-feature.merge refs/heads/cool-feature
参考情報
Git Document にも解説があります。この説明はあまりわかり易くないかもしれません。念のため:
Config 値の解説もありますので、念のため: