git rebaseした時のコンフリクトを直して新しいブランチに二つのブランチを合流させてみる
気軽に使えるえけど一知半解でなんとなく使ってると身を滅ぼしかねないGit兄貴。僕の人間関係がコンフリクトしそうで恐ろしいです。今回は、他にもっといい方法があるのかもしれないけど、自分流に考えたgit rebase
で新しいブランチに二つのブランチを合流する方法をアウトプットとして書き残します。やりたいことは単純で、二つのブランチを無傷の状態で残しつつ新しいブランチに二つのブランチのコンフリクトを合流させるというものです。コンフリクトの選別をミスってもやり直せるように。
結論
先に結論だけ
//コンフリクトを直してcontinu
git rebase --continu
//普通はrebaseの後はコミットではなくマージする
git commit -m "二つのブランチを結合させた新しいブランチを作る"
//gitが謎のデタッチブランチに謎のコミットがあると教えてくれるのでそのコミットで新しいブランチを生成
git branch developmastere c5ab09d
初めてのコミット
新しく作ったtest.txt
というファイルにhello
と書いて、masterブランチでの初めてのコミットをしたとしましょう。test.txt
というファイルにhello
と書いてある状態でコミットした後にdevelopブランチを作ります
$checkout -b develop
$ git branch
* develop
master
今ブランチの状態はどんな感じ
今、developブランチとmasterブランチでは互いに下記のようなコミットログを持っています。つまり、developブランチとmasterブランチは全く同じ状態ってこと。
$ git log
commit 500fe42cdb75786a91ed9394b5d27c028c3b7097
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 11:58:18 2017 +0900
始めてのコミット
developブランチでcommit
じゃあ、今developブランチにいる状態でtest.txt
にdevelopメーン
と書いてコミットします。そーするとdevelopとmasterでは実態が変わります。
今developのコミットログはこんな感じ
git log
commit a66d5795d0a1fcfdbcf1b3855424fc3bd5bc5314
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 12:03:30 2017 +0900
developメーン
commit 500fe42cdb75786a91ed9394b5d27c028c3b7097
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 11:58:18 2017 +0900
始めてのコミット
今masterのコミットログはこんな感じ
git log
commit 500fe42cdb75786a91ed9394b5d27c028c3b7097
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 11:58:18 2017 +0900
始めてのコミット
masterブランチを三回コミット
ここで、大胆にもmasterブランチで三回コミットしました。内容は、一回コミットするたびに「masterメーン」を書いていくだけですが。
今masterの状態はこんな感じ
git log
commit 6bd62ac51df549daaa45875da79391a75cbe4857
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 12:08:10 2017 +0900
masterメーン3
commit 4b6db8881ff9355d2d88eccc9b1d693d13f557da
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 12:06:59 2017 +0900
masterメーン2
commit 8c3f955a37430f06e7b9e4e30ea2506170df5547
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 12:06:17 2017 +0900
masterメーン1
commit 500fe42cdb75786a91ed9394b5d27c028c3b7097
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 11:58:18 2017 +0900
始めてのコミット
:
今developの状態はこんな感じ
git log
commit a66d5795d0a1fcfdbcf1b3855424fc3bd5bc5314
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 12:03:30 2017 +0900
developメーン
commit 500fe42cdb75786a91ed9394b5d27c028c3b7097
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date: Fri Jun 2 11:58:18 2017 +0900
始めてのコミット
コンフリクト起こる
この状態でgit rebaseしたらどーなるでしょうか。コンフリクトします。developでコミットしたdevelopメーン
はmasterに存在しないしmasterブランチの1〜3のmasterメーンはdevelopブランチに存在しないからです。どっちの変更を反映していいかわからないからコンフリクトします。では、ためにしコンフリクトを起こしてみます。
まずgit branchでdevelopにいることを確認して
git branch
* develop
master
git rebase master
コンフリクトしました
git rebase master
First, rewinding head to replay your work on top of it...
Applying: developメーン
Using index info to reconstruct a base tree...
M test.txt
Falling back to patching base and 3-way merge...
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
error: Failed to merge in the changes.
Patch failed at 0001 developメーン
The copy of the patch that failed is found in: .git/rebase-apply/patch
When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
コンフリクトを直す
ここがコンフリクトしてる場所だから
CONFLICT (content): Merge conflict in test.txt
開く
vi test.txt
そうすると
hello
<<<<<<< HEAD
masterメーン1
masterメーン2
masterメーン3
=======
ddevelopメーン
>>>>>>> developメーン
はい!案の定、test.txtに関してどっちの変更を取り込めばいいか迷ってしまっていますね。今回は、どっちの変更も取り込むことにしましょう〜
直した後
hello
masterメーン1
masterメーン2
masterメーン3
ddevelopメーン
直したらひとまず–continueします
rebaseはコンフリクトを直した後にcommitするんじゃなしに–continueします。はい、やってみましょう
$ git rebase --continu
test.txt: needs merge
You must edit all merge conflicts and then
mark them as resolved using git add
merge しなさいとおっしゃられていますが、仮に僕がマージしたくないとしたらどうでしょうか。ここでやっと本題のgit rebaseした時のコンフリクトを直して新しいブランチに二つのブランチを合流させてみる
に入ります。この状態で git branch
をすると下記のような表示になっています。
git branch
* (no branch, rebasing develop)
develop
master
要はrebasing途中で、developでもないmasterでもないわけのわからないブランチにいるぜ!ってことです。rebasingを完了させるにはマージする訳ですが、マージしたくない場合どうすればいいでしょうか。
git commit -m "二つのブランチを結合させた新しいブランチを作る"
コミットしてしまいましょう。そして git checkout develop
しようとすると、gitは下記のように親切にも教えてくれます。
git checkout develop
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
c5ab09d 二つのブランチを結合させた新しいブランチを作る
If you want to keep it by creating a new branch, this may be a good time
to do so with:
git branch <new-branch-name> c5ab09d
Switched to branch 'develop'
これは、developに行きたいけれど、どこにも反映されてない変更があるぜ。ってことです。この変更を反映するには新しいブランチを作ればいいよ!と教えてくれます。
git branch developmastere c5ab09d
git checkout developmastere
Switched to branch 'developmastere'
はい、これでdevelopブランチとmasterブランチの変更を取り込んだ新しいブランチが作成されました。developブランチもmasterブランチも無傷で新しいブランチができましたね。仮にコンフリクトの修正でミスってもこれならやり直せます。
masteの状態
cat test.txt
hello
masterメーン1
masterメーン2
masterメーン3
developの状態
cat test.txt
hello
ddevelopメーン
developmasterの状態
cat test.txt
hello
masterメーン1
masterメーン2
masterメーン3
ddevelopメーン