RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのエンジニアブログ

5分でわかる!git fetch

f:id:FM_Harmony:20180828013445p:plain

はじめに

FM_Harmonyです、8月2回目の投稿になります。
↓前回の記事はコチラです tech-blog.rakus.co.jp

今回はgitコマンドのfetchについて、学んだ内容をまとめてみました。
今回の記事を書こうと思ったきっかけはpullとfetchの違いについて尋ねられた時、細かいところまで答えられなかったことです。
(大雑把にfetchはデータを持ってくるだけ、pullはmergeまで行うということまでは答えられたのですが...)

そこで、この機会にfetchについて学びなおしてみました。
Gitを学び始めたばかりの方や、復習したいと考えている方の参考になれば幸いです。

fetchの説明...の前にリモート追跡ブランチの説明

fetchを説明するうえでリモート追跡ブランチの説明は欠かせません。
では、リモート追跡ブランチとは何でしょうか?

リモート追跡ブランチ(Remote-tracking branch)とは、ローカルリポジトリにあってリモートリポジトリの状態を保持する参照です。
簡単に言うと、リモートにある同名のブランチと同一のコミットを指すブランチの事です。
このブランチの特徴として、リモート追跡ブランチのブランチ名は(リポジトリ名)/(リモートのブランチ名)で固定される、ユーザが変更をコミットするなどしてブランチが指すコミットを直接操作することはできない、といったことが挙げられます。

f:id:FM_Harmony:20180828003703p:plain

そのため、ローカルリポジトリからもリモート追跡ブランチを通じて、リモートリポジトリの変更を確認する、ローカルの作業ブランチにリモートの変更を取り込むといったことができるようになっています。

しかし、ローカルリポジトリは24時間365日ネットワークに接続はしていません。
そのため、ローカルリポジトリにあるリモート追跡ブランチは常にリモートのブランチと同じものを指すわけではありません。
誰かがリモートのブランチに変更をpushしてしまうと、リモート追跡ブランチとリモートにある同名のブランチが指すコミットが異なるということが発生します。

f:id:FM_Harmony:20180828003916p:plain

この状況を解消するために使うコマンドがfetchなのです!

本題、fetchの説明

fetchコマンドを利用することで、リモートリポジトリの変更をローカルリポジトリに取り込み、リモート追跡ブランチを同期することができます。

例えば、下記のコマンドを利用すると、リモートリポジトリoriginmasterブランチについて、変更をローカルリポジトリに取り込み、リモート追跡ブランチorigin/masterをリモートブランチmasterと同期させます。

$ git fetch origin master

f:id:FM_Harmony:20180828005033p:plain

この時点では、ローカルの作業ブランチに変更は反映されません。
そのため、例えばローカルのブランチmasterに対してコミットを行っていた場合、リモート追跡ブランチとローカルのブランチとが分岐することになります。

f:id:FM_Harmony:20180828010111p:plain

merge, pullの説明

さて、こうして取り込んだリモートブランチの変更をローカルブランチに反映するにはどうすればよいでしょうか?
その方法の一つとして、ローカルブランチにリモート追跡ブランチをmergeするという方法があります。

例えば、origin/masterとローカルブランチmasterが分岐する場合、下記のコマンドを実行することで図のようなブランチ構造になります。

$ git checkout master
$ git merge origin/master

f:id:FM_Harmony:20180828005055p:plain

また、同じコマンドを実行した場合でも、origin/masterがローカルブランチの先のコミットを指しているだけで分岐していない場合、masterの指すコミットを変更するだけのいわゆるFast-forwardマージを行います。

f:id:FM_Harmony:20180828005049p:plain

別の方法として、pullコマンドを利用するというものがあります。
これは、fetch + mergeと同じ動作を行います。

すなわち、

$ git checkout master
$ git pull origin master

というコマンドは、下記のコマンドと同義です 。*1

$ git checkout master
$ git fetch origin master
$ git merge origin/master

おわりに

fetchについて簡単にまとめてみたのですが、いかがでしたでしょうか。
個人的にはリモート追跡ブランチの存在を知らなかったため、この機会に知ることができて良かったと思います。

今回の記事作成を通して、Gitについてまだまだ知識が足りないことが分かったので、また別の機会に他の操作(addやpush, etc...)について、機会を作って調べてみようと思います。

参考


*1:厳密には同義ではなく、masterにmergeされるのはFETCH_HEADというfetchした際に作成されるブランチです。

Copyright © RAKUS Co., Ltd. All rights reserved.