git merge コマンド

参考:

git-merge | Git Documentation [Official]

使い方

過去に master からフォークしたトピックブランチ topic を、元の本流のブランチ master にマージ (統合) する。

$ git checkout master
$ git merge topic

master のコミット G に、topic の コミット C をマージして、マージコミット H を作成すると下の図のようなコミットグラフの状態となる。

	  A---B---C topic
	 /         \
    D---E---F---G---H master

参考:

ブランチとマージの基本 | Pro Git book [公式]

高度なマージ手法 | Pro Git Book [公式]

概要

参考:

git のマージとコンフリクトを理解する – Qiita

マージ方向

参考:

git で双方向に merge してるとひどいはまり方をするときがある件 | はこべにっき

merge two branches: what direction? – Stack Overflow

Git Cherry-pick vs Merge Workflow – Stack Overflow

Git merge in wrong direction – Stack Overflow

コンフリクト

コンフリクトが発生した場合、コード内にこのように手動でマージが必要な部分が生成される。

<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
 please contact us at support@github.com
</div>
>>>>>>> iss53:index.html

<<<<<<< から ======= までが HEAD つまり master などのマージされている側のブランチ由来のコード、======= から >>>>>>> までが現在マージしている新しいコミット由来のコード。

コードの重複を解消してどちらかのコードを選択するか、あるいは融合したコードに編集を行う必要がある。

参考:

ブランチとマージの基本 | Pro Git book [公式]

diff3 スタイル

コンフリクト発生時に3ウェイマージにおける共通祖先のコードが確認できるように、merge.conflictStylediff3 スタイルに変更する。

$ git config --global merge.conflictStyle diff3

||||||| から `=======` の間に共通の祖先のコードが挿入されるようになる。

This is the first sentence from branch 'master'.
<<<<<<< HEAD
This is the modified second sentence from branch 'master'.
This is the third sentence from branch 'master'.
||||||| merged common ancestors
This is the second sentence from branch 'master'.
=======
This is the second sentence from branch 'master'.
This is the third sentence from branch 'hotfix'.
>>>>>>> hotfix

コミット B とコミット C の共通の祖先がコミット A の場合に、コミット C をコミット B にマージしてマージコミット M を作成するとする。

	    C---  fix
	   /     \
    ...---A---B---M master

次のようなマージファイルが作成される。

<<<<<<< HEAD (ours)
Code from B
||||||| common ancestor (base)
Code from A
=======
Code from C
>>>>>>> fix (theirs)

参考:

Git の merge.conflictStyle を merge から diff3 に変更したら, マージコンフリクトがより解決しやすくなった | yu8mada

高度なマージ手法 | Pro Git book [公式]

コンフリクトを解消する

参考:

コンフリクト解消手順 – Qiita

Git のマージコンフリクトを解決する方法 | yu8mada

削除したファイルのコンフリクトを解消する

マージした際に、片方のコミットでファイルを変更し、もう片方のコミットでファイルを削除していた場合にコンフリクトが発生する。

基本的なマージ方針として、考えられる選択肢は2つある。

  • 変更されたファイルを追加してコミットする。(git add conflicted_file → git commit --amend)
  • Git 管理から当該ファイルを取り除いて、ファイルの削除を受け入れる。(git rm conflicted_file → git commit --amend)

参考:

Git で 削除したファイルのコンフリクト解消方法 – Qiita

How do I fix a merge conflict due to removal of a file in a branch? – Stack Overflow

git checkout --ours / --theirs

マージ元のファイルをチェックアウトする。

$ git checkout --ours the_confilicted_file

マージ先のファイルをチェックアウトする。

$ git checkout --theirs the_confilicted_file

参考:

マージ時のコンフリクトで片側の変更だけ適用する方法 – Qiita

マージのコンフリクトで片方ブランチのファイル変更内容を採用 | EasyRamble

マージでバイナリファイルがコンフリクトした場合の Git の動作と対処方法 | アインシュタインの電話番号

Git でマージしたバイナリファイルが conflict した場合の解決策|DIGITAL SQUADブログ

マージでコンフリクトした際にどちらかのブランチの内容を適用 (git merge, conflict, checkout, –ours, –theirs) | いろいろ備忘録日記

git で conflict した時の ours / theirs – Qiita

git で conflict が起きて、一方を全部優先する方法 | MasK の permission denied.

git で conflict が起きた時に面倒なので一方のコミット内容を全て優先したい!| teratail

ストラテジー

--strategy オプション (もしくは、短縮オプション -s) で指定する。

  • resolve
  • recursive
  • octopus
  • ours
  • subtree

参考:

merge-strategies | Git Documentation [Official]

-s / --strategy – git-merge | Git Documentation [Official]

merge -X ours / theirs

再帰マージにおいて、コンフリクト発生時に優先するブランチをオプションで指定する。

参考:

git merge でコンフリクトしたとき片方のブランチの変更を優先させる | TaillookTech

Git で再帰的ストラテジでマージする時のストラテジオプション ours と theirs の違い | yu8mada

Force Git to always choose the newer version during a merge? – Stack Overflow

Git merge with force overwrite – Stack Overflow

git merge recursive theirs, how does it work? – Stack Overflow

-s ours

参考:

master ブランチを別のブランチに書き換え方法 – Qiita

オクトパスマージ

fix1fix2fix3 をまとめて master に統合する。(ファストフォワードマージのみが可能)

$ git checkout master
$ git merge -s octopus fix1 fix2 fix3

コンフリクトが発生した場合にマージを中止して、ブランチを元の状態に戻す。

$ git reset --hard HEAD

参考:

Octopus マージストラテジーとは | kledgeb

Octopus マージストラテジーでマージを行う | kledgeb

Octopus マージストラテジーでマージを中止する | kledgeb

git で複数のブランチを同時に non fast forward マージする | YoshinoriN’s Memento

親を3つ以上持つコミット – Qiita

merge -s theirs

参考:

Git merge -s theirs: Simply? – Stack Overflow

git command for making one branch like another – Stack Overflow

Is there a “theirs” version of “git merge -s ours”? – Stack Overflow

git pull におけるコンフリクト

参考:

git pull を強制し、リモートでローカルを上書きする方法 | WWWクリエイターズ

git merge 後の commit に -m を使ってはいけない | The Diary of Aska

マージ後に変更履歴を確認する

参考:

git log でマージしたファイルを確認する | 作業ノート

checkout せずに merge する

参考:

checkout せずに merge する – Qiita

rerere

参考:

git-rerere のメモ | unpush の日記

コンフリクトの解決を記録して再適用する git rerere – Qiita

git-rerere [clear|forget <pathspec>|diff|remaining|status|gc] – Qiita

Rerere | Pro Git book [Official]

git-merge-distinct

参考:

tpettersen/git-merge-distinct – Bitbucket

git-merge-distinct – npm

git merge-distinct: staging multiple branches with octopus-merge | Atlassian Developer Blog

タグ:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です