git fetch, git pull, git cloneは何が違うのか?使い方を実例で解説|Githubのリモートレポジトリからデータや最新のコミットを取得する方法(クローン、フェッチ、プルの違い)

github-prograshi(プロぐらし)-kv git/github
記事内に広告が含まれていることがあります。

コードの履歴を管理するGitには、Githubにあるリモートレポジトリからデータを取得する主なコマンド、git clone(クローン), git fetch(フェッチ),git pull(プル)の3つがあります。

どれもGithub上のリモートレポジトリからデータを取得してくるだけなのに何が違うの?という方も少なくないでしょう。

ここでは、git clone(クローン), git fetch(フェッチ),git pull(プル)のそれぞれのコマンドによる処理の違いを実例で解説しています。


  1. clone(クローン), fetch(フェッチ), pull(プル)の違い
  2. git clone
    1. git cloneとは何か?
    2. git cloneの使い方
    3. 現在のディレクトリにリモートレポジトリを丸ごと展開する場合
    4. 現在のディレクトリにディレクトリ名を指定して、リモートレポジトリを丸ごと展開する
    5. ディレクトリと名前を指定してリモートレポジトリを丸ごと展開する場合
    6. ローカルレポジトリの内容をコピーする
    7. 指定したディレクトリが存在場合はエラーになる
    8. ローカルに登録されるリモートレポジトリ名
  3. git fetch
    1. git fetchとは何か?
    2. リモート追跡ブランチとは何か?
    3. git fetchの使いどころやメリット
    4. git fetchの使い方
    5. 引数なしのgit fetch
    6. git fetchで上流ブランチを設定する方法
    7. リモートレポジトリ名を指定したgit fetch
    8. リモートレポジトリ名とブランチ名を指定してgit fetchする
    9. リモートレポジトリ名とブランチ名と、生成するブランチ名を指定してgit fetchする
    10. 全てのリモートレポジトリの全てのブランチの情報をとってくるオプション(--all)
    11. サブモジュールがある場合のgit fetch
  4. git pull
    1. git pullとは何か?
    2. git pullの裏側の処理内容
    3. git pullの使い方
    4. git pullの注意点
    5. リモートレポジトリ名とブランチ名を指定してマージする
    6. リモート追跡ブランチとは何か?(git pullの処理内容)
    7. FETCH_HEADとは何か?
    8. 引数を省略してマージ(git pullのみ。上流ブランチの設定)
    9. --rebaseオプションでリベースする
  5. 上流ブランチの設定方法
    1. オプションで指定する方法
    2. 設定ファイルを編集する方法(コマンドで.git/configファイルに追記)
    3. 設定ファイルを直接編集する方法(.git/configファイルに追記)
  6. 上流ブランチを活用するコマンド

clone(クローン), fetch(フェッチ), pull(プル)の違い

clone(クローン), fetch(フェッチ), pull(プル)で大きく異なるのは、リモートレポジトリからとってきたデータをどのように保存するかです。

簡単にまとめると次のようになります。

コマンド内容
clone(クローン)リモートレポジトリの内容を丸ごとコピーして、新しいディレクトリを作成する。
fetch(フェッチ)リモートレポジトリのコミット履歴をすべて取得してくる。ただしマージはしない。
pull(プル)fetch(フェッチ)とmerge(マージ)を組み合わせたコマンド。リモートレポジトリのコミット履歴を取得して、マージする。

使いどころは、git clone(クローン)がプロジェクトを作成する一番初め。

git fetch(フェッチ)は各リモートレポジトリの各ブランチで更新があるかを確認したい場合など(結構頻繁に使う)。マージは自分のタイミングでしたい場合。

git pull(プル)は、自分のローカルレポジトリのブランチにリモートリポジトリの内容を取り込みたい(マージ)したいときに使います。

以下で、各コマンドについて実例で解説しています。


git clone

git cloneとは何か?

git clone(クローン)はGithub上の指定したリモートレポジトリをローカルに丸ごとコピーするコマンドです。クローンという名前の通りのコマンドです。


git cloneの使い方

git cloneは使い方が大きく4つあります。

git cloneの使い方
  1. 現在のディレクトリにリモートレポジトリを丸ごと展開する。
  2. 現在のディレクトリにディレクトリ名を指定して、リモートレポジトリを丸ごと展開する。
  3. ディレクトリと名前を指定してリモートレポジトリを丸ごと展開する。
  4. ローカルレポジトリの内容をコピーする。

第1引数でリモートレポジトリのURLを指定し、必要に応じて第2引数でコピー先のディレクトリを指定します。

(4)はあまり知られていませんが自分のローカル環境にあるレポジトリを他のディレクトリに丸ごとコピーすることもできます。(単に使う場面がないだけですが、、)

point

リモートレポジトリのURLは、HTTPSでもSSHでも可能です。(※SSHを使う場合は、公開鍵を登録し、SSH接続ができる状態であること)

  • HTTPS: https://github.com/xxxxx/リモートレポジトリ名.git
  • SSH: git@github.com:/xxxxx/リモートレポジトリ名.git


現在のディレクトリにリモートレポジトリを丸ごと展開する場合

git cloneでは引数にリモートレポジトリのURLを指定します。

git clone <リモートレポジトリのURL>
point

第2引数を指定しない場合、現在のディレクトリに、リモートレポジトリ名のディレクトリが生成されます。


実例

例えば、現在のディレクトリが「~/documents/projects/vue」で、ディレクトリの中身が以下のようになっているとします。

$ ls
local-pj/  vuecli/

ここに、リモートレポジトリ名 rails-testをクローンします。(URL: https://github.com/xxxxx/rails-test.git)

$ git clone https://github.com/xxxxx/rails-test.git
Cloning into 'rails-test'...
remote: Enumerating objects: 539, done.
remote: Counting objects: 100% (539/539), done.
remote: Compressing objects: 100% (291/291), done.
remote: Total 539 (delta 235), reused 503 (delta 199), pack-reused 0Receiving objects:  87% (469/539), 4.50 MiB | 8.98 MiB/s
Receiving objects: 100% (539/539), 7.27 MiB | 9.68 MiB/s, done.
Resolving deltas: 100% (235/235), done.

これでクローンが完了です。

ディレクトリの状態を確認すると、クローンしたレポジトリ名のディレクトリができていることが確認できます。

$ ls
local-pj/  rails-test/  vuecli/

クローンしたディレクトリの中身を確認すると、リモートレポジトリのファイル一式がインストールされていることがわかります。

$ ls -a rails-test
./               .gitignore       config/             entrypoint.sh*  package.json       storage/
../              .ruby-version    config.ru           Gemfile         postcss.config.js  test/
.browserslistrc  app/             db/                 Gemfile.lock    public/            tmp/
.git/            babel.config.js  docker-compose.yml  lib/            Rakefile           vendor/
.gitattributes   bin/             Dockerfile          log/            README.md          yarn.lock

.gitなどの隠しディレクトリやファイルもきちんとコピーされています。

これで、該当のディレクトリでコミット履歴も参照することができます。


現在のディレクトリにディレクトリ名を指定して、リモートレポジトリを丸ごと展開する

git clone <リモートレポジトリのURL> ではリモートレポジトリ名と同じ名前のディレクトリが自動生成されます。

ディレクトリ名を変えたいな~という場合もあるでしょう。その場合は第2引数でディレクトリ名を指定します。

git clone <リモートレポジトリのURL> <ディレクトリ名>


実例

例えば、現在のディレクトリが「~/documents/projects/vue」で、ディレクトリの中身が以下のようになっているとします。

$ ls
local-pj/  vuecli/

ここに、リモートレポジトリ名 rails-testの中身一式を「clone-test」というディレクトリ名の中にクローンします。(URL: https://github.com/xxxxx/rails-test.git)

第2引数を「clone-test」としてgit cloneを実行します。

$ git clone https://github.com/xxxxx/rails-test.git clone-test
Cloning into 'clone-test'...
remote: Enumerating objects: 539, done.
remote: Counting objects: 100% (539/539), done.
remote: Compressing objects: 100% (291/291), done.
remote: Total 539 (delta 235), reused 503 (delta 199), pack-reused 0Receiving objects:  87% (469/539), 6.38 MiB | 12.77 MiB/s
Receiving objects: 100% (539/539), 7.27 MiB | 12.10 MiB/s, done.
Resolving deltas: 100% (235/235), done.

これでクローンが完了です。

ディレクトリの状態を確認すると、クローンしたレポジトリ名のディレクトリができていることが確認できます。

$ ls
clone-test/  local-pj/  vuecli/

クローンしたディレクトリの中身を確認すると、リモートレポジトリのファイル一式がインストールされていることがわかります。

$ ls -a clone-test
./               .gitignore       config/             entrypoint.sh*  package.json       storage/
../              .ruby-version    config.ru           Gemfile         postcss.config.js  test/
.browserslistrc  app/             db/                 Gemfile.lock    public/            tmp/
.git/            babel.config.js  docker-compose.yml  lib/            Rakefile           vendor/
.gitattributes   bin/             Dockerfile          log/            README.md          yarn.lock

.gitなどの隠しディレクトリやファイルもきちんとコピーされています。

これで、該当のディレクトリでコミット履歴も参照することができます。


ディレクトリと名前を指定してリモートレポジトリを丸ごと展開する場合

git cloneでは第2引数でディレクトリパスを指定することで、指定したディレクトリにリモートレポジトリを丸ごと展開することができます。

現在のディレクトリじゃなくて、一階層上や一階層下などに新しくディレクトリを作成したい場合に使えます。

git clone <リモートレポジトリのURL> <ディレクトリのパス>
注意点

指定したパスに、指定した名前のディレクトリが生成され、その中にファイルが展開されます。ディレクトリ名はリモートレポジトリ名ではなくなります。

リモートレポジトリ名でディレクトリを作成する場合は、第2引数のディレクトリパスの末尾にリモートレポジトリ名を記述する必要があります。


実例

例えば、現在のディレクトリが「~/documents/projects/vue」で、ディレクトリの中身が以下のようになっているとします。

$ ls
local-pj/  vuecli/

一つ上の階層に新たに「new_dir」というディレクトリを作成して、その中に、リモートレポジトリ名 rails-testをクローンします。(URL: https://github.com/xxxxx/rails-test.git)

第2引数で「../new_dir」を指定します。

$ git clone https://github.com/xxxxx/rails-test.git ../new_dir
Cloning into '../new_dir'...
remote: Enumerating objects: 539, done.
remote: Counting objects: 100% (539/539), done.
remote: Compressing objects: 100% (291/291), done.
remote: Total 539 (delta 235), reused 503 (delta 199), pack-reused 0
Receiving objects: 100% (539/539), 7.27 MiB | 11.19 MiB/s, done.
Resolving deltas: 100% (235/235), done.

これでクローンが完了です。

ディレクトリの状態を確認すると、クローンしたレポジトリ名のディレクトリができていることが確認できます。

#一つ上の階層に移動
$ cd ..

$ ls
vue/  new_dir/

クローンしたディレクトリの中身を確認すると、リモートレポジトリのファイル一式がインストールされていることがわかります。

$ ls -a new_dir
./               .gitignore       config/             entrypoint.sh*  package.json       storage/
../              .ruby-version    config.ru           Gemfile         postcss.config.js  test/
.browserslistrc  app/             db/                 Gemfile.lock    public/            tmp/
.git/            babel.config.js  docker-compose.yml  lib/            Rakefile           vendor/
.gitattributes   bin/             Dockerfile          log/            README.md          yarn.lock

.gitなどの隠しディレクトリやファイルもきちんとコピーされています。

これで、該当のディレクトリでコミット履歴も参照することができます。


ローカルレポジトリの内容をコピーする

あまり知られていませんが、ローカルレポジトリの内容をクローンすることもできます。

その際は第1引数でローカルレポジトリのパスを指定します。

git clone <ローカルレポジトリのパス> <コピー先ディレクトリのパス>


実例

例えば、現在のディレクトリが「~/documents/projects/vue」で、ディレクトリの中身が以下のようになっているとします。

$ ls
local-pj/  vuecli/

一つ上の階層に新たに「new_dir」というディレクトリを作成して、その中に、ローカルレポジトリ「local-pj」というディレクトリを作成し、ファイル一式をコピーします。

第2引数で「../new_dir/local-pj」を指定します。

$ git clone local-pj ../new_dir/local-pj
Cloning into '../new_dir/local-pj'...
done.

これでクローンが完了です。

現在のディレクトリを確認すると対象のローカルレポジトリはそのまま存在しているのがわかります。

$ ls
local-pj/  vuecli/

一つ上の階層のディレクトリの状態を確認すると、クローンしたレポジトリ名のディレクトリができていることが確認できます。

#一つ上の階層に移動
$ cd ..

$ ls
vue/  new_dir/

#new_dirの中身を確認
$ ls new_dir
local-pj/

new_dirのディレクトリの中に、local-pjというディレクトリが生成されています。

クローンしたディレクトリの中身を確認すると、リモートレポジトリのファイル一式がインストールされていることがわかります。

$ ls -a new_dir/local-pj
./  ../  .git/  .gitignore  babel.config.js  package.json  package-lock.json  public/  README.md  src/

.gitなどの隠しディレクトリやファイルもきちんとコピーされています。

これで、該当のディレクトリでコミット履歴も参照することができます。


補足

なお、ローカルレポジトリのクローンは単純にディレクトリをコピーしただけなので以下の処理と同じです。

cp -r  <コピー元のディレクトリパス> <コピー先のディレクトリパス>

-rオプションは--recursiveのショートオプションで、ディレクトリの深い階層も含めて再帰的にコピーするという意味です。



指定したディレクトリが存在場合はエラーになる

なお、クローン先に指定したディレクトリに既に同じ名前のディレクトリ名がある場合は、「fatal: destination path ‘生成するディレクトリ名’ already exists and is not an empty directory.」というエラーが表示されます。

実例

$ git clone git@github.com:xxx/git-test.git
fatal: destination path 'git-test' already exists and is not an empty directory.

対処法

既に同じ名前のディレクトリ名がありますというエラー「fatal: destination path ‘生成するディレクトリ名’ already exists and is not an empty directory.」が表示された場合は以下で対応します。

エラー時の対処法
  1. コマンドを実行するディレクトリを変更する。
  2. ディレクトリ名やディレクトリパスを指定してコマンドを実行する。


ローカルに登録されるリモートレポジトリ名

git cloneすると、指定したリモートレポジトリが「origin」というエイリアス(別名)でリモートレポジトリに登録されます。

登録されているリモートレポジトリ名とURLを確認するには git remote -vを実行します。

$ git remote -v
origin  https://github.com/xxxxx/レポジトリ名.git (fetch)
origin  https://github.com/xxxxx/レポジトリ名.git (push)

なお、ローカルレポジトリをクローンした場合は、URLではなくディレクトリパスが登録されています。

$ git remote -v
origin  C:/Users/hlaup/Documents/projects/xxxxx/レポジトリ名 (fetch)
origin  C:/Users/hlaup/Documents/projects/xxxxx/レポジトリ名 (push)


git fetch

git fetchとは何か?

git fetch(フェッチ)はリモートレポジトリのコミット履歴をとってきて、ローカルレポジトリにコピーするコマンドです。

ローカルレポジトリのリモート追跡ブランチのコミット履歴をアップデートするだけで、マージは行いません。

なお、「fetch」は取ってくると言う意味です。


リモート追跡ブランチとは何か?

Gitではローカルレポジトリのブランチとリモートレポジトリの同じ名前のブランチが直接連携しているわけではありません

このため、例えば、ローカルレポジトリのmainブランチで作業しているときに、git fetchを行うと、コミット履歴が更新されるのはローカルレポジトリのmainブランチではありません。

リモートレポジトリの各ブランチと直接連動しているブランチは他にあり、そのブランチのことを「リモート追跡ブランチ」と呼びます。

リモート追跡ブランチは「remotes/リモートレポジトリ名/リモートブランチ名」という名前がついているブランチです。(例: remotes/origin/main)

リモート追跡ブランチは「git branch -a」で参照できます。-aはall(全てのブランチ)という意味です。


実例:リモート追跡ブランチの参照

$ git branch -a
* aa
  main
  vue-router
  remotes/origin/HEAD -> origin/main
  remotes/origin/aa
  remotes/origin/main

上記の例だと、リモートレポジトリには「main」と「aa」の2つのブランチがあり、それぞれのリモート追跡ブランチは「remotes/origin/main」「remotes/origin/aa」となっていることがわかります。

なお、「remotes/origin/HEAD -> origin/main」は取得してきた時点で最新のリモートレポジトリのデフォルトブランチを指しています。

「remotes/origin/HEAD」を使うことはほぼないので、あまり気にする必要はありません。

「remotes/origin/ブランチ名」はよく使うので覚えておく必要があります。


git fetchの使いどころやメリット

他のプロジェクトメンバーが作業進めたかな?メインのブランチ(mainやmasterなど)でアップデートがあったかな?といったことを調べたいときに使います。

git fetchした後は、ローカルレポジトリのコミット履歴がアップデートされるので、必要に応じてgit mergeやgit rebaseを実行してコミットを取り込むことができます。

強制的にマージまで実行してしまうgit pullと違って、自分でマージのタイミングを選べるのもgit fetchのポイントです。

リモートレポジトリのブランチの状態をそのまま再現できる。


git fetchの使い方

git fetchは主に次の5つの使い方があります。

git fetchの主な使い方
  1. 【引数なし】git fetch
  2. 【レポジトリ名を指定】 指定したリモートレポジトリの全てのブランチの最新のコミット履歴をとってくる。
  3. 【レポジトリ名とブランチ名を指定】 指定したリモートレポジトリのブランチの最新のコミット履歴のみをとってくる。
  4. 【レポジトリ名とブランチ名と、生成するブランチ名を指定】指定したリモートレポジトリのブランチの最新のコミット履歴のみをとってきて、新たなブランチを作る。
  5. --allオプション】全てのリモートレポジトリの全てのブランチの最新のコミット履歴をとってくる。


それぞれのコマンドは以下のようになります。

コマンドコマンド例内容
git fetch(引数無し)git fetch取得対象のリモートレポジトリの優先度: 「上流ブランチ」 > 「origin」 
git fetch <リモートレポジトリ名>git fetch second指定したリモートレポジトリの最新のコミット履歴をまるごと取得
git fetch <リモートレポジトリ名> <ブランチ名>git fetch origin main指定したリモートレポジトリの指定したブランチのみの最新のコミット履歴を取得
git fetch <リモートレポジトリ名> <ブランチ名>:<生成するブランチ名>git fetch origin main:test指定したリモートレポジトリの指定したブランチのみの最新のコミット履歴を取得して、新たなローカルブランチを作成
git fetch --allgit fetch --all全てのリモートレポジトリの全てのブランチの最新のコミット履歴をとってくる


引数なしのgit fetch

git fetchを引数なしで実行した場合は、実行したブランチに上流ブランチが設定してある場合は、上流ブランチの最新のコミット履歴を取得してきます。

上流ブランチが設定されておらず、リモートレポジトリ名に「origin」が登録されている場合は、「origin」というリモートレポジトリのすべてのブランチの最新のコミットをまるごととってきます。

git fetch

上流ブランチとは、ローカルレポジトリのブランチ毎に設定するもので、ローカルブランチをリモートレポジトリのブランチと紐づけるものです。

上流ブランチを設定すると、git pushなどのコマンドの引数を省略することができます。

合わせて読みたい

上流ブランチの設定方法や詳しい実例を知りたい方は下記をご参考ください。

【Github】git pushの-uオプションとは何か?upstreamや上流ブランチについて実例で解説


実例

まずはローカルレポジトリに登録してあるリモートレポジトリ名確認します。上流ブランチの有無も含めて確認する場合は git remote -vvを実行します。

$ git remote -vv
origin  https://github.com/xxxx/rails-test.git (fetch)
origin  https://github.com/xxxx/rails-test.git (push)

上流ブランチはなしでリモートレポジトリ「origin」があります。このためgit fetchを実行すると「origin」の全てのブランチの最新のコミット履歴をとってくる処理になります。

git fetch

remote: Enumerating objects: 89, done.
remote: Counting objects: 100% (89/89), done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 89 (delta 46), reused 80 (delta 38), pack-reused 0
Unpacking objects: 100% (89/89), done.
From github.com:xxx/git-test
   8fccfd033..2a06b79c8  hotfix           -> origin/hotfix
   6115dc29d..1f60a6761  develop          -> origin/develop
 * [new branch]      ft1        -> origin/ft1
 * [new branch]      test       -> origin/test

大きく2つの記述があることがわかります。


既存のリモート追跡ブランチのコミット履歴を更新

1つ目はコミット番号とブランチ名が表示されているものです。

8fccfd033..2a06b79c8  hotfix           -> origin/hotfix

これは以下のような記述になります。

<更新していない最初のコミット番号>..<最新のコミット番号>  <リモートレポジトリのブランチ名>           -> <リモート追跡ブランチ名>

つまり、既にリモート追跡ブランチとして存在している「hotfix」ブランチにコミット番号「8fccfd033」から「2a06b79c8」までが追加されたという内容です。


新たなリモート追跡ブランチを作成

2つ目は[new branch]と記載があるものです。

* [new branch]      ft1        -> origin/ft1

これは以下のような記述になります。

* [new branch]     <リモートレポジトリのブランチ名>           -> <リモート追跡ブランチ名>

つまり、リモートレポジトリに新たに「ft1」というブランチが追加されているので、「origin/ft1」というリモート追跡ブランチを新たに生成しましたという意味です。


git fetchで上流ブランチを設定する方法

git fetchで上流ブランチを設定するには、通常のgit fetch <リモートレポジトリ名> <リモートのブランチ名>に「--set-upstream」オプションを付けて実行します。

git fetch --set-upstream <リモートレポジトリ名> <リモートのブランチ名>

なお、upstreamは上流という意味です。

初回の実行で上流ブランチをセットすれば、後は引数無しのgit fetchコマンドが使えます。

注意点
  • 上流ブランチを設定するための初回のgit fetchでは引数を省略することはできません。
  • git pushと違いショートオプション「-u」は存在しません。


リモートレポジトリ名を指定したgit fetch

リモートレポジトリが複数登録してある場合など、対象のリモートレポジトリを指定してgit fetchすることもできます。

その場合は第2引数でリモートレポジトリ名を指定します。

git fetch <リモートレポジトリ名>


実例

まずはローカルレポジトリに登録してあるリモートレポジトリ名確認します。

$ git remote -v
origin  https://github.com/xxxx/rails-test.git (fetch)
origin  https://github.com/xxxx/rails-test.git (push)
second  https://github.com/yyyy/git-test.git (fetch)
second  https://github.com/yyyy/git-test.git (push)

「origin」と「second」という名前のリモートレポジトリが2つ登録されていることがわかります。

git fetchで「second」のリモートレポジトリの全てのブランチの最新のコミット履歴をとってきます。

git fetch second

remote: Enumerating objects: 89, done.
remote: Counting objects: 100% (89/89), done.
remote: Compressing objects: 100% (40/40), done.
remote: Total 89 (delta 46), reused 80 (delta 38), pack-reused 0
Unpacking objects: 100% (89/89), done.
From github.com:yyyy/git-test
 * [new branch]      aa         -> second/aa
 * [new branch]      main       -> second/main

上記の場合は、git fetchの結果、新しいリモート追跡ブランチ「second/aa」と「second/main」が追加されたことがわかります。

実際にブランチを確認すると以下のようにリモート追跡ブランチが生成されているのがわかります。

$ git branch -a
* aa
  main
  vue-router
  remotes/origin/HEAD -> origin/main
  remotes/origin/aa
  remotes/origin/main
  remotes/second/aa
  remotes/second/main


リモートレポジトリが存在しない場合

指定したリモートレポジトリが存在しない場合は「fatal: ‘リモートレポジトリ名’ does not appear to be a git repository」「fatal: Could not read from remote repository.」というエラーが表示されます。

$ git fetch no
fatal: 'no' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.


リモートレポジトリ名とブランチ名を指定してgit fetchする

「全てのブランチの情報ではなく、特定のブランチの更新履歴だけが欲しい」という場合は、リモートレポジトリのブランチ名を指定することもできます。

git fetch <リモートレポジトリ名> <リモートレポジトリのブランチ名>


実例

まずはローカルレポジトリに登録してあるリモート追跡ブランチを確認します。

$ git branch -a
* aa
  main
  vue-router
  remotes/origin/HEAD -> origin/main
  remotes/origin/aa
  remotes/origin/main
  remotes/second/aa
  remotes/second/main

この中で、リモート追跡ブランチ「remotes/origin/main」すなわちリモートレポジトリ名「origin」ブランチ名「main」のみを更新したい場合は、git fetchの第1引数に「origin」、第2引数に「main」を指定します。

$ git fetch origin main
From https://github.com/xxxxx/rails-test
 * branch            main       -> FETCH_HEAD

上記のように表示され、指定したリモート追跡ブランチの情報のみが更新されていることがわかります。


ブランチが存在しない場合

指定したブランチが存在しない場合は「fatal: couldn’t find remote ref ブランチ名」というエラーが表示されます。

$ git fetch second no
fatal: couldn't find remote ref no



リモートレポジトリ名とブランチ名と、生成するブランチ名を指定してgit fetchする

リモートレポジトリ名とブランチ名と、生成するブランチ名を指定してgit fetchすると、指定したリモートレポジトリのブランチの内容で、新たなブランチをローカルに生成することができます。

git fetch <リモートレポジトリ名> <リモートのブランチ名>:<ローカルに生成するブランチ名>

なお、ローカルに指定したリモートの追跡ブランチが存在する場合は、指定したローカルブランチのみを生成します。

どちらもない場合は、(1)追跡ブランチと(2)指定したローカルブランチの2つを作成します。


実例

リモートレポジトリ名「origin」のブランチ「master」を、ローカルレポジトリに「test」というブランチ名として生成する場合は以下のようになります。

$ git fetch origin master:test

remote: Enumerating objects: 70, done.
remote: Counting objects: 100% (70/70), done.
remote: Compressing objects: 100% (31/31), done.
remote: Total 70 (delta 41), reused 62 (delta 34), pack-reused 0
Unpacking objects: 100% (70/70), done.
From github.com:xxxx/rails-test
 * [new branch]      master     -> test
 * [new branch]      master     -> origin/master

新たにローカルブランチ「test」と、リモートブランチ「origin/master」が生成されたことがわかります。

ブランチの状態を確認すると、それぞれのブランチが生成されていることがわかります。

$ git branch -a
  test
  remotes/origin/master


全てのリモートレポジトリの全てのブランチの情報をとってくるオプション(--all)

引数無しのgit fetchを実行した場合、上流ブランチがある場合や、リモートレポジトリ名「origin」がある場合といった制約がつきます。

細かいことは抜きにして登録してある全てのリモートレポジトリの全てのブランチの最新のコミットを取ってきたい場合は「--all」オプションを使用します。

git fetch --all


実例

ローカルレポジトリに登録してあるリモートレポジトリ名が以下のような状態だとします。

$ git remote -v
origin  https://github.com/xxxx/rails-test.git (fetch)
origin  https://github.com/xxxx/rails-test.git (push)
second  https://github.com/yyyy/git-test.git (fetch)
second  https://github.com/yyyy/git-test.git (push)

登録してあるリモートレポジトリは「origin」と「second」の2つです。この状態で--allオプションをつけたgit fetchを実行すると次のようになります。

$ git fetch --all
Fetching origin
Fetching second

このように、「origin」と「second」の両方とものリモートレポジトリをfetchしていることがわかります。



サブモジュールがある場合のgit fetch

リモートレポジトリにサブモジュールが存在するときに「git fetch」を実行すると、メインのリモートレポジトリの内容だけでなく、サブモジュールの内容も取得することができます。

実例

$ git fetch
remote: Enumerating objects: 193, done.
remote: Counting objects: 100% (193/193), done.
remote: Compressing objects: 100% (79/79), done.
remote: Total 193 (delta 135), reused 156 (delta 114), pack-reused 0
Receiving objects: 100% (193/193), 82.78 KiB | 657.00 KiB/s, done.
Resolving deltas: 100% (135/135), completed with 48 local objects.
From github.com:xxxx/rails-pj
   8fccfd033..2a06b79c8  test            -> origin/test
 * [new branch]          apc              -> origin/apc
   888570c19..0ce7f2188  master           -> origin/master
 + 98ab8117f...c3d2ff203 test_ga            -> origin/test_ga  (forced update)
Fetching submodule rails-user
From github.com:xxxx/rails-user
   f5bd9fa..e0af519  master     -> origin/master
   6439adb..e63c502  test      -> origin/test
Fetching submodule rails-api
From github.com:xxxx/rails-api
   d2ab8a8..865f236  master          -> origin/master
 + 302d6ae...8aa0c0e ft              -> origin/ft  (forced update)
 * [new branch]      pr              -> origin/pr

上記の場合、実行したのはgit fetchのみですが、メインのリモートレポジトリ「rails-pj」以外に、サブモジュール「rails-user」と「rails-api」の全てのブランチの最新のコミットも取得していることがわかります。


git pull

git pullとは何か?

git pullとは、リモートレポジトリの更新内容を取得してきて、現在のブランチに統合(マージ)するコマンドです。

git fetchを使った場合、取得してきたコミットをマージするにはgit merge(あるいはgit rebase)を使います。この、git mergeのマージ作業もまとめて行うのがgit pullです。

なお、オプションに--rebaseをつけることで、git fetch + git rebaseの処理にすることもできます。

コミットのマージまで行うので、cloneやfetchと異なりコンフリクトが発生する可能性があります。

合わせて読みたい

git mergeやgit rebaseって何?コンフリクトが発生したらどう対処したらいいの?という疑問を持たれた方は下記をご参考ください。

【図解】git mergeとgit rebaseの違いを実例で解説(マージとリベースは何が違うのか?)


git pullの裏側の処理内容

git pullの処理はgit fetchとgit mergeを同時に実行しているのですが、具体的には以下のようになっています。

$ git pull <リモートレポジトリ名> <リモートのブランチ名>

 ↑↓ 同じ

$ git fetch <リモートレポジトリ名> <リモートのブランチ名>
$ git merge FETCH_HEAD

FETCH_HEADについは後述しています。

合わせて読みたい

git mergeで具体的にどのようなことが起こっているかや、コマンドの実例については下記をご参考ください。

【Git】git merge(マージ)とは何か?使い方を実例で解説


git pullの使い方

git pullの使い方は主に以下の3個です。

git pullの使い方
  1. リモートレポジトリ名とブランチ名を指定してマージする。
  2. 引数を省略してマージ(git pullのみ。上流ブランチの設定)
  3. --rebaseオプションでリベースする。


git pullの注意点

どこのブランチで実行するかが重要

GitにはGithubのリモートレポジトリからコミットを取得してくるコマンドに、git pull以外にもgit cloneやgit fetchがあります。

git cloneやgit fetchはローカルレポジトリのどのブランチでコマンドを実行するかは関係ありません。

一方、git pullはgit fetchしてgit mergeまで行うのでどこのブランチで実行するかが大きく関係してきます

git pullを実行する前に、自分がどのブランチにいるかを確認し、マージしたいブランチにいるかを確認しておくことが重要です。


コンフリクトが発生する可能性がある

git cloneやgit fetchのようにただ情報をとってくるだけではなく、マージ(あるいはリベース)まで行うので、コンフリクト(conflict)が発生することがあります。

コンフリクトが発生した場合は下記をご参考ください。

【Git】git merge(マージ)でconflict(コンフリクト)が発生したファイルの修正方法をわかりやすく解説


リモートレポジトリ名とブランチ名を指定してマージする

git pullで現在のブランチで、リモートレポジトリ名とブランチ名を指定してマージするときは以下のようにします。

git pull <リモートレポジトリ名> <リモートのブランチ名>


実例

リモートレポジトリ名「origin」のブランチ「aa」をコミット履歴を、ローカルレポジトリのブランチ「test」にマージする場合例を紹介します。

まずは、マージを実行したいブランチに移動します。

#現在のブランチはmain
$ git branch
  aa
* main
  test

#マージを実行したいブランチに移動
$ git checkout test
Switched to branch 'test'


#きちんと移動できてるか確認
$ git branch
  aa
  main
* test

マージを実行したいブランチ(ここでは「test」)にいることが確認できたら、マージしたいコミットを持つリモートレポジトリ名「origin」のブランチ「aa」を指定して、git pullを実行します。

$ git pull origin aa
From https://github.com/xxxxx/rails-test
 * branch            aa         -> FETCH_HEAD
Updating 61d3b4b..0701d9d
Fast-forward
 app/controllers/api/pj1/clients_controller.rb  |   8 +-
 app/javascript/components/Modal.vue            | 106 +++++++++++++++++++++++++
 app/javascript/components/clients/Clients.vue  |  42 +++++++++-
 config/initializers/content_security_policy.rb |  12 +--
 config/routes.rb                               |   2 +-
 docker-compose.yml                             |   2 +
 6 files changed, 162 insertions(+), 10 deletions(-)
 create mode 100644 app/javascript/components/Modal.vue

上記のように表示され、マージが実行されます。

「61d3b4b」から「0701d9d」のコミットを取り込んだことがわかります。

コミットログを確認すると、指定したリモートレポジトリのブランチと対応するリモート追跡ブランチ「origin/aa」と、git pullを実行したtestブランチが同じコミットを指していることがわかります。

$ git log --oneline --graph
* 0701d9d (HEAD -> test, origin/aa, aa) [U]docker-compose add webpack port 3035
* a90d4ef [U]content-security-policy(CSP) enable webpack-dev-server
* 6adca49 [A]destroyメソッド & Modal追加
* 61d3b4b [A]ClientEdit.vue
* 00093d1 [F]ClientNewからClientForm.vueを切り出し

なお上記の例では、コミットが分岐していないので、コミットのポインタを前に進めただけ(Fast-forwardしただけ)ですが、コミットが分岐しているブランチでgit pullを行った場合、コミット履歴は以下のようになります。

$ git log --oneline --graph
*   7f02744 (HEAD -> master, origin/master) Merge branch 'ft2'
|\
| * d6eb207 add h3 again
* | 07ea837 add h4
|/
* 788f5b1 remove all marks

分岐したコミット履歴が、マージされ統合されたことがわかります。


リモート追跡ブランチとは何か?(git pullの処理内容)

Gitではローカルレポジトリのブランチとリモートレポジトリの同じ名前のブランチが直接連携しているわけではありません

このため、例えば、ローカルレポジトリのブランチでgit pullしたときに、指定したリモートレポジトリのブランチを直接取り込んでいるわけではありません。

ローカルレポジトリには「リモート追跡ブランチ」というものがあり、これがリモートレポジトリの各ブランチと直接連動しているブランチです。

このため、まずリモートレポジトリの指定したブランチの内容をリモートレポジトリに同期し、それから、git pullしたブランチのコミット履歴に、リモート追跡ブランチのコミット履歴をマージするという処理が行われます。

リモート追跡ブランチは「remotes/リモートレポジトリ名/リモートブランチ名」という名前がついているブランチのことです。(例: remotes/origin/main)

リモート追跡ブランチは「git branch -a」で参照できます。-aはall(全てのブランチ)という意味です。


実例:リモート追跡ブランチの参照

$ git branch -a
* aa
  main
  vue-router
  remotes/origin/HEAD -> origin/main
  remotes/origin/aa
  remotes/origin/main

上記の例だと、リモートレポジトリには「main」と「aa」の2つのブランチがあり、それぞれのリモート追跡ブランチは「remotes/origin/main」「remotes/origin/aa」となっていることがわかります。

なお、「remotes/origin/HEAD -> origin/main」は取得してきた時点で最新のリモートレポジトリのデフォルトブランチを指しています。

「remotes/origin/HEAD」を使うことはほぼないので、あまり気にする必要はありません。

「remotes/origin/ブランチ名」はよく使うので覚えておく必要があります。


FETCH_HEADとは何か?

git pullすると以下のように「FETCH_HEAD」という表示がでます。

$ git pull origin master

From github.com:xxx/git-test
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master

これは、git mergeの前段階として、git fetchでコミット履歴を取得したブランチの最新のコミットがどこかを示す目印です

FETCH_HEADというポインタをセットしましたという意味になります。


引数を省略してマージ(git pullのみ。上流ブランチの設定)

git pullでは現在のローカルレポジトリのブランチに「上流ブランチ」を設定すると、引数を省略してgit pullを実行することができます。

git pull

とてもシンプルなコマンドになります。


上流ブランチとは何か?

上流ブランチとは、ローカルレポジトリのブランチ毎に設定するもので、ローカルレポジトリのブランチをリモートレポジトリのブランチと紐づけるものです。

上流ブランチを設定すると、git pushなどのコマンドの引数を省略することができます。


上流ブランチの設定方法

上流ブランチを設定するには、通常のgit pull <リモートレポジトリ名> <リモートのブランチ名>のオプションとして「--set-upstream」を付けて実行します。

git pull --set-upstream <リモートレポジトリ名> <リモートのブランチ名>

なお、upstreamは上流という意味です。

注意点
  • 上流ブランチを設定するための初回のgit pullでは引数を省略することはできません。
  • git pushと違いショートオプション「-u」は存在しません。


実例:上流ブランチの設定

現在のローカルレポジトリの「main」ブランチにおいて、リモートレポジトリ「origin」の「aa」ブランチを上流ブランチに設定する場合は以下のようになります。

$ git pull --set-upstream origin aa
From https://github.com/xxxxx/rails-test
 * branch            aa         -> FETCH_HEAD
Merge made by the 'recursive' strategy.
 app/controllers/api/pj1/clients_controller.rb    |  10 ++-
 app/javascript/app.vue                           |   8 +-
 app/javascript/components/Modal.vue              | 106 +++++++++++++++++++++++
 8 files changed, 215 insertions(+), 12 deletions(-)
 create mode 100644 app/javascript/components/Modal.vue

特に、上流ブランチを設定したという情報は表示されません。



上流ブランチの確認方法

上流ブランチが設定してあるかどうかはgit branch -vvコマンドを実行することで確認できます。

#上流ブランチがない場合
$ git branch -vv
* main dc53f35 first commit

#上流ブランチある場合
$ git branch -vv
* main dc53f35 [origin/main] first commit

上流ブランチがある場合は、[リモートレポジトリ名/リモートレポジトリのブランチ名] が表示されます。

よって、このローカルレポジトリのmainブランチでgit pushを実行すると、リモートレポジトリ名originのmainブランチにpushを行います。

なお、ブランチ名の横の 数値(例 dc54f35)は最新のコミット番号、末尾の「first commit」はコミットメッセージです。

リモートブランチ確認時の注意点

リモートブランチを確認するコマンド git branch -vv は「v」が2つ必要です。

「v」が一つだけだと、上流ブランチが設定されていても画面上に表示されません。

#「v」が2つの場合
$ git branch -vv
* main dc53f35 [origin/main] first commit
#「v」が1つの場合
$ git branch -v
* main dc53f35 first commit


実例:引数なしのgit pull

まずは上流ブランチが設定されていることを確認します。

$ git branch -vv
  aa         0701d9d [U]docker-compose add webpack port 3035
  main       21f31d2 [origin/main] [A]test.html.rb
* test       718eea7 [origin/aa: behind 6] [A]Client.vue

「main」ブランチと「test」ブランチの2つに上流ブランチが設定されていることがわかります。

testブランチでgit pullを実行します。

$ git pull
From https://github.com/xxxx/rails-test
 * [new tag]         v2.0       -> v2.0
 * [new tag]         v3.0       -> v3.0
Updating 718eea7..0701d9d
Fast-forward
 app/controllers/api/pj1/clients_controller.rb    |  46 +++++++++-
 app/javascript/app.vue                           |  16 +++-
 app/javascript/components/Modal.vue              | 106 +++++++++++++++++++++++
 app/javascript/components/clients/Client.vue     |  24 ++---
 12 files changed, 412 insertions(+), 29 deletions(-)
 create mode 100644 app/javascript/components/Modal.vue
 create mode 100644 app/javascript/components/clients/ClientEdit.vue

引数なしでgit pullが実行できました。


上流ブランチが設定されていない場合はエラーになる

上流ブランチが設定されていない状態で引数なしのgit pullを実行すると「There is no tracking information for the current branch.」という以下のようなエラーが発生します。

(参考)エラー:上流ブランチが設定されていない場合

$ git pull

There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=<remote>/<branch> master

表示されている内容は次の2つです。

git pull <remote> <branch>
通常通り、リモート名とブランチ名を指定する。または、

git branch --set-upstream-to=<remote>/<branch> masterで上流ブランチをセットしてくださいとの示唆。


--rebaseオプションでリベースする

git pullのオプションで「--rebase」をつけると、git mergeの処理をgit rebaseに変えることができます。

git pull --rebase <リモートレポジトリ名> <リモートのブランチ名>

上流ブランチが設定してある場合は引数を省略できます。

git pull --rebase


git rebaseとは何か?

git rebaseは本質的にはマージではなく、コミット履歴を移動したり修正、削除したりするコマンドです。

マージ前にコミット履歴をきれいにする目的で使用するのが一般的です。(例えば、git rebaseをしてから、プルリクを出すなど)

ただし、他のブランチから分岐した以降のコミットをとってくることができるので、マージと似たような処理をすることになります。

git rebaseをすると、分岐している他のブランチのコミットを分岐した時点からとってきて、自分のコミットの前に付け足すことができます。

枝分かれの枝を根本からポッキっと追って、本流にくっつけるイメージです。

なお、rebaseとは土台を完全に移行するという意味です。このため元のブランチの内容を根っこから、指定したブランチのコミットログの先端にとりつける処理を指しています。

注意点

git rebaseをすると、分岐した時点からのコミット内容をとってきて、自分の変更後のコミットをその先端に移動します。

取得してきたコミット番号は変わりませんが、自分ブランチのコミットは変更になります。(過去のコミット履歴が変わるため)

合わせて読みたい

git rebaseで具体的にどのようなことが起こっているかや、コマンドの実例については下記をご参考ください。

【Git】git rebase(リベース)とは何か?使い方を実例で解説git rebase(リベース)とは何か?使い方を実例で解説


git pull --rebaseの裏側の処理内容

git pull --rebaseの処理はgit fetchとgit rebaseを同時に実行しているのですが、具体的には以下のようになっています。

$ git pull --rebase <リモートレポジトリ名> <リモートのブランチ名>

 ↑↓ 同じ

$ git fetch <リモートレポジトリ名> <リモートのブランチ名>
$ git rebase FETCH_HEAD


実例:git pull --rebase

現在のコミット履歴が以下のような状態とします。

例えば、現在のブランチが「test」ブランチで以下のようにリモートレポジトリ名「origin」ブランチ名「aa」という上流ブランチが設定されているとします。

$ git branch -vv
  aa         0701d9d [U]docker-compose add webpack port 3035
  main       21f31d2 [origin/main] [A]test.html.rb
* test       3aeb158 [origin/aa] [F]div-tag

testブランチのコミット履歴は以下のようになっているとします。一番最近のコミット「3aeb158」が上流ブランチ「aa」のコミットから分岐しているコミットです。

$ git log --oneline --graph
* 3aeb158 (HEAD -> test) [F]div-tag
* 00093d1 [F]ClientNewからClientForm.vueを切り出し
* a84cfc5 [A]ClientNew.vue
* 718eea7 [A]Client.vue

この状態でgit pull --rebaseを実行して、上流ブランチのコミット履歴をfetchしてrebaseします。

$ git pull --rebase
From https://github.com/shizen-shin/rails-aa
 * [new tag]         v2.1       -> v2.1
Successfully rebased and updated refs/heads/test.

「Successfully rebased and updated refs/heads/test.」と表示され、リベースが正しく行われたことがわかります。

コミット履歴を確認すると以下のようになっています。

$ git log --oneline
5095d55 (HEAD -> test) [F]div-tag
0701d9d (second/aa, origin/aa, aa) [U]docker-compose add webpack port 3035
a90d4ef [U]content-security-policy(CSP) enable webpack-dev-server
6adca49 [A]destroyメソッド & Modal追加
61d3b4b [A]ClientEdit.vue
00093d1 [F]ClientNewからClientForm.vueを切り出し
a84cfc5 (tag: v2.1) [A]ClientNew.vue
718eea7 [A]Client.vue

もとのコミット履歴に対して、「61d3b4b」~「0701d9d」が追加されています。

また、「a84cfc5」にタグ「v2.1」も追加されています。

過去の履歴が変わったので、これまでのtestブランチの最新のコミット番号が「3aeb158」から「5095d55」に変化していることも注目してください。

(※コミット番号は過去のコミット履歴と紐づいているため、履歴が変わればコミット番号のハッシュ値も変わります)

合わせて読みたい

上記で「v2.1」というタグが追加されています。タグは非常に便利なツールです。タグって何?という方は下記をご参考ください。

【Git】git tagコマンド完全理解|メリット・デメリットや注意点、使い方を実例で解説



上流ブランチの設定方法

上流ブランチは、git pull, git fetch, git push, git branchなどのコマンドでも設定可能です。

コマンドのオプション以外にも、コマンドでconfigファイルに追記したり、configファイル自体を書き換えする方法もあります。

オプションで指定する方法

--set-upstreamオプション

pull, fetch, pushのいずれでも使用可能です。

・git pull --set-upstream <リモートレポジトリ名> <リモートのブランチ名>

・git fetch --set-upstream <リモートレポジトリ名> <リモートのブランチ名>

・git push --set-upstream <リモートレポジトリ名> <リモートのブランチ名>


-uオプション(git pushのみ)

git pushのみショートオプションの「-u」が使えます。

git push -u <リモートレポジトリ名> <リモートのブランチ名>


--set-upstream-toオプション(git pushのみ)

git branchコマンドにも上流ブランチを設定するコマンドがあります。


設定ファイルを編集する方法(コマンドで.git/configファイルに追記)

configファイルに追記する場合は、対象のリモートブランチの(1)remote、(2)mergeの2つの値を設定する必要があります。

(1) $ git config branch.<ローカルブランチ名>.remote <リモートブランチ名>

(2)$ git config branch.<ローカルブランチ名>.merge refs/heads/<リモートブランチ名>

実例

$ git config branch.topic.remote origin
$ git config branch.topic.merge refs/heads/master


configファイルの確認

#configファイルの中身を見る
cat .git/config

エディタでファイルの中身を見ると以下のようにtopicブランチに対して、上流となる、リモートレポジトリ名とブランチ名が登録されていることがわかります。

[branch "topic"]
    remote = origin
    merge = refs/heads/master


設定ファイルを直接編集する方法(.git/configファイルに追記)

configファイルの中身を直接編集することもできます。

#エディタで開く
vim .git/config

vimエディタが起動するので、以下のように追加すれば完了です。

[branch "ローカルのブランチ名"]
    remote = リモートレポジトリ名
    merge = refs/heads/リモートのブランチ名
合わせて読みたい

Vimエディタの使い方については下記をご参照ください。

【vi(vim)とは?】vimテキストエディタを使う方法とコマンド一覧


上流ブランチを活用するコマンド

現在のローカルブランチに上流ブランチの設定ができれば、git pull, fetch, push時に引数を省略して実行することができます。

上流ブランチを活用するコマンド
  • git pull
  • git fetch
  • git push

使うときは、どのブランチでコマンドを実行しているかに注意してください。

タイトルとURLをコピーしました