執筆時のgitのversion 2.20
対象のコマンド
コマンド | 第1引数 | 第2引数 |
---|---|---|
git fetch | <リモートリポジトリ名> | <リモートブランチ名> |
git merge | <ローカルブランチ名> | -- |
git rebase | <ローカルブランチ名> | -- |
git pull | <リモートリポジトリ名> | <リモートブランチ名> |
git pull --rebase | <リモートリポジトリ名> | <リモートブランチ名> |
それぞれのコマンドは、1つまたは2つのコマンドライン引数を取ります。
省略した場合については、こちらをご覧ください。
以降リポジトリの状態を以下と仮定し説明します
本記事では、上記5つのコマンドの引数を以下のリモートリポジトリ名とブランチ名を例にして説明します。
リモートリポジトリを origin
という名前で、ローカルリポジトリに登録しているとしているとします。
また、リモート、ローカルそれぞれのリポジトリにあるブランチは以下とします。
-
リモートリポジトリ
- master
- develop
-
ローカルリポジトリ
- コミット可能なブランチ
- master
- develop
- リモートにあるブランチを追跡するためのブランチ
- origin/master
リモート(origin
)のmasterブランチを追跡している - origin/develop
リモート(origin
)のdevelopブランチを追跡している
- origin/master
- コミット可能なブランチ
フェッチ (fetch)
リモートリポジトリにあるブランチの最新状態を、それを追跡しているローカルのブランチに反映させます。
$ git fetch <リモート名> <リモートブランチ名>
例) リモートorigin
にあるdevelop
ブランチを、それを追跡しているローカルにあるorigin/develop
にフェッチする。
$ git fetch origin develop
フェッチする前は、以下の状態であったとします。
orgin/master
と orgin/develop
は、リモートの最新状態を取り込めていません。
#リモートリポジトリ #ローカルリポジトリ
コミット6 * master
| \
コミット5 | * develop
| |
コミット4 | * * develop origin/develop
| / |
コミット2 * * master origin/master
| |
コミット1 * *
以下、コマンドの実行結果です。
#リモートリポジトリ #ローカルリポジトリ
コミット6 * master
| \
コミット5 | * develop * origin/develop
| | |
コミット4 | * * develop
| / |
コミット2 * * master origin/master
| |
コミット1 * *
リモートのdevelop
を、ローカルにあるコミット可能なブランチ develop
に取り込めたわけではないので注意してください。以降で解説する マージ
と リベース
どちらかで可能になります。
マージ (merge)
引数に指定したローカルにあるブランチを、カレントブランチに取り込みます。
$ git merge <ブランチ名>
例) リモートorigin
のdevelop
ブランチを追跡するブランチであるorigin/develop
をローカルのdevelop
ブランチにマージする。
# developをチェックアウト
$ git checkout develop
# origin/developをマージ
$ git merge origin/develop
マージする前が、以下の状態だったとします。
#ローカルリポジトリ
コミット4 * origin/develop
コミット3 * | develop
| /
コミット2 * master origin/master
|
コミット1 *
以下、コマンドの実行結果です。
#ローカルリポジトリ
コミット5 * develop
| \
コミット4 | * origin/develop
コミット3 * |
| /
コミット2 * master origin/master
|
コミット1 *
マージで取り込めるブランチは、origin/developなどのリモートのブランチを追跡するブランチだけではありません。
ローカルにあるすべてのブランチを指定することができます。
**上記のブランチの状態から続けて、**以下のコマンドを実行してみましょう。
例) ローカルのdevelopブランチをローカルのmasterブランチにマージする。
# developをチェックアウト
$ git checkout master
# developをマージ
$ git merge develop
以下、コマンドの実行結果となります。
#ローカルリポジトリ
コミット5 * master develop
| \
コミット4 | * origin/develop
コミット3 * |
| /
コミット2 * origin/master
|
コミット1 *
【おさらい】 リモートのdevelopを、ローカルのdevelopに取り込むまで。 1. リモートのdevelopを、`orgin/develop` にとりこむ(fetch) 2. origin/developを、ローカルの `develop` にとりこむ(merge)
mergeは、ローカルのブランチに、指定したローカルの別のブランチをとりこむコマンドでした。
類似するコマンドに rebase
があります。
違いは、ブランチの図をみて感じ取ってみてください。
リベース (rebase)
カレントブランチの根本を、現在のコミットから、引数に指定したブランチの最新コミットへ付け替えます。
$ git rebase <ブランチ名>
例) リモートorigin
のdevelop
ブランチを追跡するブランチであるorigin/develop
に、ローカルのdevelop
ブランチをリベースする
# developをチェックアウト
$ git checkout develop
# developをorigin/developにリベース
$ git rebase origin/develop
リベースする前が、以下の状態だったとします。
マージとの比較をしやすくするため、同様の状況としました。
#ローカルリポジトリ
コミット4 * origin/develop
コミット3 * | develop
| /
コミット2 * master
|
コミット1 *
以下、コマンドの実行結果です。
#ローカルリポジトリ
コミット3.1 * develop
|
コミット4 * origin/develop
|
コミット2 * master origin/master
|
コミット1 *
リベースには、ブランチはすっきりするというメリットがある一方、コミット3はなくなってしまいます。
マージとリベースは状況によって使い分けましょう。
基本的に、フェッチ、マージ、リベースを覚えておけば、ブランチの取り込みはできるわけですが、 フェッチとマージ、フェッチとリベースを同時に行える便利なコマンドもあるので、 良ければ覚えておきましょう。以降で解説します。
プル (pull)
リモートのブランチを、それを追跡しているローカルのブランチにフェッチし、さらにそのリモート追跡ブランチをカレントブランチにマージします。フェッチとマージの組み合わせです。
$ git pull <リモート名> <リモートブランチ名>
例) リモートorigin
にあるdevelop
ブランチを、ローカルのdevelop
にプルします
#developブランチをチェックアウト
$ git checkout develop
# リモートのdevelopブランチをプルする
$ git pull origin develop
プルする前が、以下の状態だっとします。
#リモートリポジトリ #ローカルリポジトリ
コミット7 * master
| \
コミット6 | * develop
コミット5 | | * develop
| | |
コミット4 | * * origin/develop
| / |
コミット2 * * master origin/master
| |
コミット1 * *
以下、コマンドの実行結果です。
#リモートリポジトリ #ローカルリポジトリ
コミット8 * develop
コミット7 * master | \
| \ | |
コミット6 | * develop | * origin/develop
コミット5 | | * |
| | | /
コミット4 | * *
| / |
コミット2 * * master origin/master
| |
コミット1 * *
プルリベース (pull --rebase)
リモートのブランチを、それを追跡しているローカルのブランチにフェッチし、さらに、カレントブランチをそのリモートを追跡しているブランチにリベースします。フェッチとリベースの組み合わせです。
$ git pull --rebase <リモート名> <リモートブランチ名>
例) リモートorigin
にあるdevelop
ブランチをフェッチし、最新化されたorgin/develop
に、ローカルのdevelop
をリベースします
#developブランチをチェックアウト
$ git checkout develop
# 1.リモートのdevelopを、origin/developにフェッチ
# 2.ローカルのdevelopを、origin/developにリベース
$ git pull --rebase origin develop
プル・リベースする前が、以下の状態だっとします。
#リモートリポジトリ #ローカルリポジトリ
コミット7 * master
| \
コミット6 | * develop
コミット5 | | * develop
| | |
コミット4 | * * origin/develop
| / |
コミット2 * * master origin/master
| |
コミット1 * *
以下、コマンドの実行結果です。
#リモートリポジトリ #ローカルリポジトリ
コミット5.1 * develop
コミット7 * master |
| \ |
コミット6 | * develop * origin/develop
| | |
コミット4 | * *
| / |
コミット2 * * master origin/master
| |
コミット1 * *