git fetchとブランチ取り込み系コマンドの引数を省略すると?


執筆時のgitのversion 2.22.0

対象のコマンド

コマンド 第1引数 第2引数
git fetch <リモート名> <リモートブランチ名>
git merge <ローカルブランチ名> --
git rebase <ローカルブランチ名> --
git pull <リモート名> <リモートブランチ名>
git pull --rebase <リモート名> <リモートブランチ名>

引数はmergeとrebaseが1つ、
fetchおよびコマンドの中にfetchが含まれるpullとpull --rebaseは2つです。

このページでは、引数を省略した場合の挙動を解説します。
省略しなかった場合については、こちらをご覧ください。

結論

以下2つの条件で決まります。

  1. カレントブランチに上流ブランチが登録されているか
  2. originという名で登録したリモートがあるかどうか
コマンド 第2引数を省略した 第1,第2引数どちらも省略した
fetch リモートブランチをすべてをフェッチ 上記条件により3パターン
mergeまたはrebase 上記条件により2パターン --
pullまたはpull --rebase 上記条件により2パターン 上記条件により3パターン

以降リポジトリを以下と仮定し説明します

ローカルとリモートそれぞれのリポジトリに、以下のブランチがあることを仮定し説明をします。

  • リモートリポジトリ (ローカルにoriginという名前で登録されている)

    • master
    • develop
  • ローカルリポジトリ

    • コミット可能なブランチ
      • master
      • develop
    • リモートにあるブランチを追跡するためのブランチ
      • origin/master
        リモート(origin)のmasterブランチを追跡している
      • origin/develop
        リモート(origin)のdevelopブランチを追跡している

ところで上流ブランチとは?

以下のコマンドの引数を省略したとき処理の対象となるブランチです。

  • git fetch
  • git merge
  • git rebase
  • git pull
  • git pull --rebase

各ローカルブランチに、リモート追跡ブランチの中から1つのみ設定することが可能です。
以下のコマンドで、ローカルブランチに上流ブランチを設定することができます。

$ git branch -u <リモート追跡ブランチ名> <ローカルブランチ名>

今どう設定されているかは、対象のローカルリポジトリのconfigファイルから分かります。
以下の例では、master ブランチの上流ブランチは、リモート追跡ブランチ origin/master です。

# リポジトリルート/.git/config

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

フェッチについて

$ git fetch <リモート名> <リモートブランチ名>

第2引数を省略した場合

第一引数に指定したリモートにあるブランチがすべてフェッチされます。
下の例では、originのブランチをすべてフェッチします。

$ git fetch origin

## 以下2つの組み合わせと同様な結果が得られます。
$ git fetch origin master
$ git fetch origin develop

第1引数、第2引数どちらも省略した場合

【パターン1】 カレントブランチに上流ブランチがある場合

カレントブランチの上流ブランチが追跡しているリモートブランチを、上流ブランチにフェッチします。
カレントブランチがdevelopdevelopの上流ブランチがorigin/developだとすると、origindevelopをフェッチすることになります。

#########################################
#  カレントブランチ: develop               #
#  developの上流ブランチ: origin/develop  # 
#########################################

$ git fetch

#以下と同様な結果が得られます。
$ git fetch origin develop

【パターン2】 カレントブランチに上流ブランチがない、かつoriginという名で登録したリモートがある場合

originのブランチ全てをフェッチします。

#########################################
#  カレントブランチ: develop               #
#  developの上流ブランチ: なし             # 
#########################################

$ git fetch

#以下のコマンドの組み合わせと同様な結果が得られます。

##組み合わせ1
$ git fetch origin

##組み合わせ2
$ git fetch origin master
$ git fetch origin develop

【パターン3】 カレントブランチに上流ブランチがない、かつoriginという名で登録したリモートもない場合

どのブランチもフェッチできません。

マージとリベースについて

$ git merge <ブランチ名>
$ git rebase <ブランチ名>

上流ブランチを設定していなければ失敗となります。

【パターン1】 カレントブランチに上流ブランチがある場合

mergeの場合は、カレントブランチに上流ブランチをマージします。
rebaseの場合は、カレントブランチを上流ブランチにリベースします。

#########################################
#  カレントブランチ: develop               #
#  developの上流ブランチ: origin/develop  # 
#########################################

# マージのとき

$ git merge

## 以下と同様な実行結果になります。
$ git merge origin/develop



#リベースのとき


$ git rebase

## 以下と同様な実行結果になります。
$ git rebase origin/develop

【パターン2】 カレントブランチに上流ブランチがない場合

なにも起こりません。

プルとプルリベースについて

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

第2引数を省略した場合

第一引数に指定したリモートにあるブランチがすべてをフェッチします。
つぎにプルの場合は、カレントブランチに上流ブランチをマージしようとします。
次にプルリベースの場合は、カレントブランチに上流ブランチにリベースしようとします。
上流ブランチがない場合は、フェッチだけ実行されます。

【パターン1】 カレントブランチに上流ブランチがある場合

#########################################
#  カレントブランチ: master                  #
#  masterの上流ブランチ: origin/master     # 
#########################################


# pullのとき
$ git pull origin

## コマンドの組み合わせと同じ結果が得られます

### 組み合わせ1
$ git fetch origin
$ git merge origin/develop

### 組み合わせ2
$ git fetch origin master
$ git fetch origin develop
$ git merge origin/develop


# pull --rebaseのとき
$ git pull --rebase origin

## コマンドの組み合わせと同じ結果が得られます

### 組み合わせ1
$ git fetch origin
$ git rebase origin/develop

### 組み合わせ2
$ git fetch origin master
$ git fetch origin develop
$ git rebase origin/develop

【パターン2】 カレントブランチに上流ブランチがない場合

mergeまたrebaseは実行されず、引数で指定したリモートすべてのブランチのフェッチのみです。

#########################################
#  カレントブランチ: master                  #
#  masterの上流ブランチ: origin/master     # 
#########################################


# pullのとき
$ git pull origin

## 以下2つの組み合わせと同様な結果が得られます。
$ git fetch origin master
$ git fetch origin develop

# pull --rebaseのとき
$ git pull --rebase origin

## 以下2つの組み合わせと同様な結果が得られます。
$ git fetch origin master
$ git fetch origin develop

第1引数、第2引数どちらも省略した場合

【パターン1】 カレントブランチに上流ブランチがある場合

上流ブランチが追跡しているリモートブランチを上流ブランチにフェッチし、上流ブランチをカレントブランチにマージ(リベース)する。

########################################
#  カレントブランチ: master               #
#  masterの上流ブランチ: origin/master   # 
########################################

# プルとき

$ git pull


##以下のコマンドの組み合わせと同じです。

### 組み合わせ1
$ git pull origin

## 組み合わせ2
$ git pull origin master

## 組み合わせ3
$ git fetch origin master
$ git merge origin/master



# プルリベースとき

$ git pull --rebase


##以下のコマンドの組み合わせと同じです。

### 組み合わせ1
$ git pull --rebase origin

## 組み合わせ2
$ git pull --rebase origin master

## 組み合わせ3
$ git fetch origin master
$ git rebase origin/master

【パターン2】 カレントブランチに上流ブランチがない、かつoriginという名で登録したリモートがある場合

mergeまたrebaseは実行されず、引数で指定したリモートすべてのブランチのフェッチのみです。

#########################################
#  カレントブランチ: master                  #
#  masterの上流ブランチ: origin/master     # 
#########################################


# pullのとき
$ git pull

##以下のコマンドの組み合わせと同じ結果です。

### 組み合わせ1
$ git pull origin

### 組み合わせ2
$ git fetch origin master
$ git fetch origin develop

### 組み合わせ3
$ git fetch origin

### 組み合わせ4
$ git fetch



# pull --rebaseのとき
$ git pull --rebase

##以下のコマンドの組み合わせと同じ結果です。

### 組み合わせ1
$ git pull --rebase origin

### 組み合わせ2
$ git fetch origin master
$ git fetch origin develop

### 組み合わせ3
$ git fetch origin

### 組み合わせ4
$ git fetch

【パターン3】 カレントブランチに上流ブランチがない、かつoriginという名で登録したリモートがない場合

なにも起こりません。