リベースでのコンフリクトを直そう – GIT

やりたいこと

下記のような状態から


(初期のmasterコミットはdevelopもmasterも持っている共通コミット)

         ↑ → develop01
         ↑
master01 → master02

developブランチを下記のようにしたい

 

master02がリベースしたコミット

 

つまり、masterの変更箇所をdevelopにリベースした(mergeと違って歴史が一本道に!)

 

master01 → master02 → develop01

 

ブランチの状態

masterブランチとdevelopブランチがある

$ gb
  develop
* master

コミットの状態

developブランチはmaster commit 02の変更を持っていなくて、masterブランチはdevelop commit 01の変更を持っていないことがわかる。masterブランチとdevelopブランチが共通して持ってるのはmaster commit 01だということがわかる。

develop

 
$ gl
commit 1e77143508f3abea4305f235db800eb45d7a686a
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date:   Wed Jul 5 13:49:27 2017 +0900

    develop commit 01

commit 3b35a163876cbec3feea6e0d91b61a40993399e7
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date:   Wed Jul 5 13:46:29 2017 +0900

    master commit 01
 

master

 
$ gl
commit 3b295d44151fdbc5f54d9d591bd2b658f411c312
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date:   Wed Jul 5 13:48:10 2017 +0900

    master commit 02

commit 3b35a163876cbec3feea6e0d91b61a40993399e7
Author: hujisawa-ryosuke <vaaaval@gmail.com>
Date:   Wed Jul 5 13:46:29 2017 +0900

    master commit 01
 

developとmasterのファイルの状態

masterブランチでの初期コミットを分岐点を界にdevelopとmasterで一回ずつコミットしてあって、コンフリクト状態

develop

 
$ cat sample.tex 
develop commit 01
master commit 01
 

master

 
$ cat sample.tex 
master commit 02
master commit 01
 

説明

masterブランチから分岐したdevelopブランチがあって、developブランチにチェックアウトして一回コミットしたあとにmasterブランチに戻って一回コミットすれば、当然rebaseするとコンフリクトを起こします。

$ gcd
Switched to branch 'develop'

developブランチに移動して、developに対して、masterの差分をリベースします。

 

だから、developブランチのファイルが変わります。

 

masterブランチのファイルは何も変わりません。

 

逆に、masterブランチに移動してmasterブランチに対してdevelopブランチをリベースすると、

 

developブランチの変更がmasterブランチに変更されるから、

 

developブランチは何も変わらず,masterブランチが変わることになります。

$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: develop commit 01
Using index info to reconstruct a base tree...
M    sample.tex
Falling back to patching base and 3-way merge...
Auto-merging sample.tex
CONFLICT (content): Merge conflict in sample.tex
error: Failed to merge in the changes.
Patch failed at 0001 develop commit 01
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".

コンフリクトの画面

<<<<<<< HEAD
master commit 02
=======
develop commit 01

>>>>>>> develop commit 01
master commit 01
二つのコミットを採用する

master commit 02
develop commit 01
master commit 01

git add

ここ、大切、手順を間違えるとうまくいかない

 

リベースの場合はコンフリクトを直したらaddしてコミットせずにリベースコンテニューする。

 

addしてコンテニュー

 

それからaddを忘れてコンテニューだけしてももうまくいかないし

 

addしたあとにcommitしてもうまくいかない

 

リベースの場合はコンフリクトを直したらaddしてリベースコンテニューする

 

$ git add sample.tex
$ git rebase --continue
Applying: develop commit 01

 

 

これで、masterの変更をdebelopに書き込んだ。今回は、masterとdevelopの変更を二つ採用した。

developの状態

master commit 02 
develop commit 01 
master commit 01

masterの状態

master commit 02 
master commit 01

参考

 

ここら辺の本を読んで、めっちゃ勉強になりました、ブログって簡単にわかるけど、深い部分で基礎が結構抜け落ちてたりするんだよね… 基礎の徹底は、良いエンジニアの基本なので、ここら辺を横着するか否かで将来のエンジニア人生も大きく変わる。なので、こういう本はしっかり読もうと思います。(お勧めなので、是非勝ってみればいいと思います :))

 

Gitで老ける。エンジニアの僕が勧めるGit入門本[2020年]

藤沢瞭介(Ryosuke Hujisawa)
  • りょすけと申します。18歳からプログラミングをはじめ、今はフロントエンドでReactを書いたり、AIの勉強を頑張っています。off.tokyoでは、ハイテクやガジェット、それからプログラミングに関する情報まで、エンジニアに役立つ情報を日々発信しています!

未整理記事