前置き
git rebaseコマンドについて学んだのまとめます。ものすごく単純な例で説明します。
git rebaseは何ができる?
以下の2つのことができます。
- コミットをつなげ直すこと
- コミットをまとめる
まずは、「1.コミットをつなげ直すこと」について記載します。
実例(コミットをつなげ直す)
以下の例で説明します。
- 開発者がAさん、Bさんの2名いるとします。
- test.txtという空のファイルがあります。これがmasterブランチとします。
- 開発のゴールは、test.txtに"a","b","c"という文字を追加したファイルを作ることとします。
- Aさん、Bさんで作業を以下のように分担します。
- Aさんには"a"を追加してもらう
- Bさんには"b","c"を追加してもらう
- AさんはブランチAを切り、test.txtに"a"という文字を追加しました。
- BさんはブランチBを切り、test.txtに"b"という文字を追加しました。
- Bさんは"c"を追加する前にAさんの作業内容を取込みたいとします。
ここでBさんはAさんの作業内容取込に、mergeとrebaseの2つの手段がとれます。
以下の実例でmergeする場合と、rebaseする場合の両方やってみます。
準備
空のファイルtest.txtがあるmasterブランチの状態まで準備します。
$ mkdir test
$ cd test
$ git init
$ touch test.txt
$ git add test.txt
$ git commit -m 'initial commit'
Aさんの作業
"a"という文字を追加します
$ git checkout -b branchA
$ echo a >> test.txt
$ git add test.txt
$ git commit -m 'add a'
Bさんの作業
"b"という文字を追加します
$ git checkout master
$ git checkout -b branchB
$ echo b >> test.txt
$ git add test.txt
$ git commit -m 'add b'
BさんがAさんの作業内容を取込(rebase Version)
# rebaseします。(branchBにいる状態で、branchAを取込)
$ git rebase branchA
# conflictするので解消します
$ cat test.txt
<<<<<<< HEAD
a
=======
b
>>>>>>> 4d86c92... add b
# 解消後
cat test.txt
a
b
# rebase続行
$ git add test.txt
$ git rebase --continue # エディタが開いてコミットコメントの編集画面になりますが、そのまま保存して続けます
# コミットログ確認
$ git log --oneline --graph
* f68bdb7 (HEAD -> branchB) add b
* d17bed1 (branchA) add a
* a1d7f67 (master) initial commit
git logを見ると、mergeと違ってコミット履歴が一直線であることがわかりやすいですね。
BさんがAさんの作業内容を取込(merge Version)
mergeとの違いも気になるかと思いますので、mergeバージョンと比較してみます。
# マージ
$ git merge branchA # conflictするので解消します。
$ git add test.txt
$ git commit -m 'merged branchA'
# コミットログ確認
$ git log --oneline --graph
* ff731a9 (HEAD -> branchB) merged branchA
|\
| * e2915b7 (branchA) add a
* | 63fff00 add b
|/
* b9ef1dd (master) initial commit
git logを見ると、コミット履歴が一直線ではありません。mergeなので当然ですね。
まとめ
上記の「BさんがAさんの作業内容を取込」のrebaseバージョンとmergeバージョンのコミットログを
確認するとわかるように、rebaseはmergeと違って、過去のコミットを今のブランチにつなげ直す
ことができます。
実例(コミットをまとめる)
次はコミットをまとめてみます。作業者はさきほどと異なり、Aさん1人とします。
- test.txtに"a"を追加してコミット。(commitA)
- test.txtに"b"を追加してコミット。(commitB)
- test.txtに"c"を追加してコミット。(commitC)
ここで、commitBとcommitCをまとめてしまいたいとします。
準備
$ mkdir test
$ cd test
$ git init
$ touch test.txt
$ git add test.txt
$ git commit -m 'initial commit'
$ echo a >> test.txt
$ git add test.txt
$ git commit -m 'add a'
$ echo b >> test.txt
$ git add test.txt
$ git commit -m 'add b'
$ echo c >> test.txt
$ git add test.txt
$ git commit -m 'add c'
$ git log --oneline --graph
* 1f9a66d (HEAD -> master) add c
* bc48053 add b
* f8625d9 add a
* 239ee02 initial commit
コミットをまとめるときはrebaseのiオプションを指定します。
引数には、まとめたいコミットの1つ前のコミットIDを指定します。
ここでは、commitBとcommitCをまとめたいので、commitBの1つ前のcommitAのコミットIDを指定します。
$ git rebase -i f8625d9
上記コマンドを打つと、エディタが開きます。
pick bc48053 add b
pick 1f9a66d add c
# Rebase f8625d9..1f9a66d onto f8625d9 (2 commands)
(以下割愛)
まとめたいcommitBとcommitCが表示されています。一番上のコミットは統合元のコミットになるのでいじらず、
その下のコミットの「pick」を「squash」(統合)に変更します。
pick bc48053 add b
squash 1f9a66d add c
# Rebase f8625d9..1f9a66d onto f8625d9 (2 commands)
(以下割愛)
保存すると、続いてコミットメッセージの編集画面になります。
# This is a combination of 2 commits.
# This is the 1st commit message:
add b
# This is the commit message #2:
add c
# Please enter the commit message for your changes. Lines starting
(以下割愛)
「add b」のメッセージに「add c」のメッセージをまとめます。
# This is a combination of 2 commits.
# This is the 1st commit message:
add b and c
# This is the commit message #2:
# Please enter the commit message for your changes. Lines starting
(以下割愛)
コミットログを確認してみます。
$ git log --oneline --graph
* 4139507 (HEAD -> master) add b and c
* f8625d9 add a
* 239ee02 initial commit
commitBとcommitCがまとまりました。
まとめ
コミットを細かくしすぎた場合は、git rebase -i
でコミットをある程度まとめると
コミットログが見やすくなりますね。
今回は以上です。