Magicode logo
Magicode
0
6 min read

【Git/Github】コンフリクトの差分が消えてしまった際の対処法

以前コーディングをしていた際、git rerereという機能に翻弄されたことがあったので他の方が同じような状況にならないよう対処法をメモしておきます。

■その時の状況

  1. featureブランチに最新のdevelopブランチを反映させようとする (git rebase origin/develop)
  2. コンフリクトが起きる
  3. コンフリクトを間違った解消方法で解決してしまう
  4. 正しい解消方法に修正するため、直前のコミットを削除して再度1を行う
  5. git rerereの機能でコンフリクトの自動解消(前回の解消方法で)が行われ、コンフリクトの差分が見えない状態になり、正しい解消方法に修正できない状態に...

この記事でできること

  • コンフリクトが自動で解消されてしまう現象を解決できる

手順

  • git rerere の履歴を削除する
# git rerereのコンフリクト解消履歴を削除
git rerere forget your_file.sh

# ファイルに加えられた変更を再作成し、元の競合のマージ結果を破棄
git checkout -m your_file.sh

コンフリクトが自動解消される状況とその対策の再現例

  • git rerereを導入
# git rerereの適用
git config --global rerere.enabled true

# configを確認
git config --global --edit

# 下記設定が入っていればgit rerereが適用済
---
[rerere]
     enabled = true
---
  • コンフリクトさせる
# masterブランチで作業
git checkout master
vim test.sh

# 下記のようなファイルを作成
---
echo "Hello World"
---

# コミット
git add test.sh
git commit -m "make test.sh"
# masterブランチから2つのブランチを切る
git checkout -b "develop1"
git checkout -b "develop2"
# develop1で作業
git checkout develop1
vim test.sh 

# test.shを以下のように修正
---
echo "Halo World"
---

# コミット
git add test.sh
git commit -m "Halo World"
# develop2で作業
git checkout develop2
vim test.sh 

# test.shを以下のように修正
---
echo "Hello Word"
---

# コミット
git add test.sh
git commit -m "Hello Word"

それぞれのlogを確認

# develop1ブランチのlog
git checkout develop1
git log --oneline

---
6c86cbb (HEAD -> develop1) Halo World
c8ff4cd (master, develop2) make test.sh
7adac7b initial commit
---

# develop2ブランチのlog
git checkout develop2
git log --oneline

---
bc91ba1 (HEAD -> develop2) Hello Word
c8ff4cd (master) make test.sh
7adac7b initial commit
---

# masterブランチのlog
git checkout master
git log --oneline

---
c8ff4cd (master) make test.sh
7adac7b initial commit
---
# それぞれのブランチをmasterにマージしていく
git checkout master
git merge develop1
git merge develop2

# 同じファイル(test.sh)を修正しているコミットがぶつかるため、git merge develop2のタイミングで下記メッセージが出ます。
---
Auto-merging test.sh
CONFLICT (content): Merge conflict in test.sh
Recorded preimage for 'test.sh'
Automatic merge failed; fix conflicts and then commit the result.
---

↓エディタではこのような表示になります

  • 間違ったコンフリクトの解消をする
vim test.sh

---
echo "Hallo World"
---

# 差分を確認
git diff

---
@@@ -1,1 -1,1 +1,1 @@@
- echo "Halo World"
 -echo "Hello Word"
++echo "Hallo World"
---

# コンフリクトを解消する
git add test.sh
git commit -m "fix conflict"

# その際以下メッセージが出ることを確認(コンフリクトの履歴を保存したとのこと)
---
Recorded resolution for 'test.sh'.
---

今回は以下のように誤って解消する (本当は両方のechoを反映させたい)

ログはこのような状態

# masterブランチのlog
git log --oneline

---
265d844 (HEAD -> master) fix conflict
bc91ba1 (develop2) Hello Word
6c86cbb (develop1) Halo World
c8ff4cd make test.sh
7adac7b initial commit
---
  • コンフリクトが自動解消されてしまうことを確認
# コンフリクトの解消方法を間違ったので直前のコミットを削除
git reset --hard HEAD^

# 再度develop2ブランチのマージを実行
git merge develop2

# git merge develop2のタイミングで下記メッセージが出ます。
---
Auto-merging test.sh
CONFLICT (content): Merge conflict in test.sh
Resolved 'test.sh' using previous resolution.
Automatic merge failed; fix conflicts and then commit the result.
---

Resolved 'test.sh' using previous resolution.

前の解決方法でtest.shのコンフリクトを解消しましたよとメッセージがあります。

↓エディタでは下記のように自動解消された状態になってしまうのでコンフリクト時の差分が見えず、正しい解消方法に修正できない状態になります。 なのでこれをコンフリクト解消前の状態に戻します。

  • git rerere の履歴を削除
git rerere forget test.sh
git checkout -m test.sh

上記コマンドを実行すると履歴が消えて解消前の状態に戻ります。

後は正しいやり方で解消すればOK!!


閲覧いただきありがとうございました。みなさんのお役に立てましたら幸いです!

コメントやいいねしていただけますと励みになります☺️

Discussion

コメントにはログインが必要です。