いづいづブログ

アジャイルコーチになりたい札幌在住SEです。アジャイル札幌スタッフ&ScrumFestSapporo実行委員。Like:パクチー/激辛/牡蠣/猫/初期仏教

fetchとpullと、リモート追跡ブランチ

f:id:izumii-19:20190410135422p:plain

gitを使っているとcommit、push、pull、mergeあたりのコマンドはよく使うのでだいぶ理解できていると思うんですが、fetchについてはいまだに理解しきれていなかったのでfetchと向き合ってみることにしました。

私が理解したいことは以下の2点です。

  1. fetchとはなにか
  2. fetchとpullの違い

リモート追跡ブランチ

まず、fetchを理解する上で欠かせないのが「リモート追跡ブランチ」の存在。

ざっくりいうとローカル側に存在する「origin/master」というやつがリモート追跡ブランチ*1で、その名の通りリモートリポジトリの変更を追いかけているブランチのこと。

ちなみに"origin/master"はリモートリポジトリに存在するmasterブランチの追跡ブランチであり、例えばtestというブランチの追跡ブランチの場合は"origin/test"になる*2

f:id:izumii-19:20190410125212p:plain

fetch

fetchをするとリモート追跡ブランチにリモートリポジトリにあるブランチの最新状態が更新される。リモート追跡ブランチが更新されるだけで、ローカルの作業ブランチは影響を受けない。ここがpullと異なる点。

ちなみにfetchは"取ってくる"という意味らしい。

$ git fetch

merge

fetchはリモート追跡ブランチを更新するだけでありローカルの作業ブランチは影響を受けないため、作業ブランチに変更を取り込むにはmergeする必要がある。

$ git merge origin/master

pull

fetchとmergeを一度にやる方法。つまり作業ブランチにもリモートリポジトリの最新状態が即座に反映される。pull = fetch + merge。

$ git pull

まとめ

ローカルには作業ブランチとリモート追跡ブランチという2種類のブランチがあり、リモート追跡ブランチはリモートの変更を管理するブランチ。リモート追跡ブランチだけを最新状態にするのはfetchで、作業ブランチとリモート追跡ブランチの両方を最新にするのがpull。

ふりかえってみると、①リモート追跡ブランチというものの存在をこれまで完全に無視していたこと、②fetchを理解せずにいきなりpullに慣れ親しんでしまったというのがfetchをちゃんと理解できてなかった原因だった気がします。

f:id:izumii-19:20190410134747p:plain

ああ、スッキリ。

2019/4/12追記 おまけ

f:id:izumii-19:20190410125212p:plain

originの存在についても曖昧な理解だったんですが、特にこれまで気にしなくても困らずにやってこれたのでスルーしてました。 結論からいうとリモートリポジトリにつける名前のことでした。

つまり、

https://github.com/izumii19/xxxxx.git = origin

だということです。

$ git push origin master

は、

https://github.com/izumii19/xxxxx.git”のmasterブランチに対してpushする

ということ。

ローカルでリポジトリを作成した場合はgit initしたあとに、そのリポジトリをリモートリポジトリに追加するためにgit remote add …をするのですが、そのときにリポジトリに名前をつけているはずです。*3

$ git remote add origin https://github.com/izumii19/xxxxx.git

originについてとてもわかりやすいサイトはこちら

reasonable-code.com

*1:ラッキングブランチという呼ばれ方もするらしい

*2:"origin"も厳密にいうと必ずしも"origin"じゃないかもしれないけど、今はそこは触れない

*3:ただ、いろんなサイトを見ていると「”git remote add origin リポジトリ名”と書けば良い」という説明もけっこうあるので、originをおまじないのように感じてしまうかもしれません。