【Git】コンフリクト解消&プルリクエストのマージ方法について
はじめに
リーダーの引継ぎ作業をしていまして、コンフリクト解消方法とプルリクエストのマージ方法について教えて頂いたので、今回は学んだ方法についてブログを投稿させていただきます。
至らない点もあるかと思いますが、ご意見・ご感想をいただけると嬉しいです。
コンフリクトが起きる原因その1
コンフリクトが起きる原因は2つあります。
1つ目が作業ブランチを2つ作成して、一つ目の作業ブランチで「Aファイルの1行目」を編集して、メインブランチにマージ、二つ目の作業ブランチで同じ1行目を別の内容に編集しメインブランチをマージしようとするとコンフリクトが発生します。
コンフリクト発生時はGithub上で解消するか二つ目の作業ブランチでメインブランチの内容をマージしてコンフリクトを解消してからコミットプッシュをする必要があります。
Github上でコンフリクトを解消する方法は
1.コンフリクトが発生したプルリクエストをGitHub上で開きます。
2.プルリクエストのページで、「This branch has conflicts that must be resolved」というメッセージが表示されている場合、コンフリクトが発生していることがわかります。
3.プルリクエストのページで、「Resolve conflicts」ボタンをクリックします。このボタンは、コンフリクトが発生しているファイルがある場合に表示されます。
4.「Resolve conflicts」をクリックすると、コンフリクトが発生しているファイルが表示され、編集できる状態になります。ここでは、Gitがどの部分でコンフリクトが発生しているかを示します。
コンフリクト部分は、以下のように表示されます:
<<<<<<< HEAD 現在の変更(あなたのブランチ) ======= 競合している変更(マージしようとしているブランチ)>>>>>>> main
競合している内容の中から、どちらかの変更を採用するか、両方を組み合わせるのかを決めて
<<<<<<< HEADから>>>>>>> mainのメッセージを削除すると「Mark as resolved」ボタンが活性状態となり、押下するとコンフリクトが解消されます。
コンフリクトが起きる原因その2
2つ目が同じブランチを複数人で触って、プル、プッシュしたときに発生します。
下記手順にてコンフリクトを発生させる事が出来ます。
1.Githubでリポジトリを作成(名前はConflict-Resolution )
2.index.htmlをアップロード
3.作業ブランチを作成(名前はconflict-test)
3.デスクトップにフォルダを作成
4.フォルダの中にproject-main 、project-main-copyをクローンして作成
5.project-mainでconflict-testブランチに切り替えてコードの内容を変更してコミットプッシュ
6.project-main-copyでconflict-testブランチに切り替えてコードの内容を5.とは違う内容で変更しコミット(プッシュはしない)
7.project-main-copyでプルをするとコンフリクト発生
補足
流れ
最初の状態
みんなの共通の祖先 → A2
HくんがコミットH1を作る → プッシュする
FくんがコミットF1を作る(まだプッシュしてない)
Fくんがプルするとき
リモートにはH1があるが、自分のローカルにはない。
Gitは祖先A2から見て、H1とF1を統合しようとする。
ここで同じ箇所を違うふうに直していたらコンフリクトが発生する!
解決できたらマージコミットができる。
コンフリクトが起きる原因その2の続き
1.コンフリクト解消しコミットプッシュ
2.project-mainでプルをする(ブランチ名はconflict-test)
3.コードの内容を変更してコミットプッシュ
4.project-main-copyに切り替えてコードの内容を3.とは違う内容で変更しコミット
5.project-main-copyでプルをするとコンフリクト発生(1.マージコミットが祖先になる。
)
補足
流れ
Hくん → H2を作成してプッシュ
Fくん → F2を作成(プッシュしてない)
Fくんがまたプルするとき
今度の祖先は「A2」じゃない。
前回プルしてマージしたマージコミットが祖先になる。
そこからリモート(H2)とローカル(F2)を比較して統合する。
ここでも同じ場所を直してたらコンフリクトが起きる!
プルリクエストのマージ方法
マージには3つ種類があり基本的には通常のマージで良いのですが、今朝しまぶーさんに他のマージ方法について質問してみたら「リベースマージはコミットメッセージを奇麗に出来るので、覚えておいた方が良い」とおっしゃっていたので、一度試してみようと思います。
マージの種類
1.通常のマージは、ブランチの変更履歴をそのまま残すため、基本的には大きな機能の追加や開発の統合に使います。
2.スカッシュマージは、複数の細かい修正やバグ修正を1つのまとまったコミットとして履歴に残したい場合に使います。
3.リベースマージは、履歴を綺麗に保ちたい時や、複数の開発作業が直線的に続いていく形を求める時に使います。
プルリクエストがマージされると、GitHubが「Delete branch」のボタンを表示します。これをクリックすると、そのブランチがリモートリポジトリから削除されます。
使い終わったブランチを残しておくと、不要なブランチがどんどん溜まり、どれが有効なのか分かりにくくなるので、マージ済みのブランチは削除しましょう。
最後に
しまぶーさんに今朝コンフリクトとマージについて質問してみました。
基本的に同じ作業ブランチを使用しない方が良いとおっしゃっていたのでコンフリクトが起きる原因その2に関してはめったに起きないかなと思っています。ただ「作業ブランチを分けていてもコンフリクトはよく発生している」とおっしゃっていたので、コンフリクトが発生した際に自分で解消できないといけないなと思いました。
Discussion