Gitコンフリクト解消手順(マージ先の差分を取り込む場合と差分を取り込みたくない場合)
2021/04/109 分で読める記事 — In プログラム
Git

はじめに


みなさん、こんにちは。
今回はGitのコンフリクトの解消法について備忘録を書いていこうと思います。

まずコンフリクトの解消には2つの場合があります。

  1. マージ先の差分を取り込みながら、コンフリクト解消したい場合
  2. マージ先の差分を取り込まずに、コンフリクト解消したい場合

当時の僕はこの2つの場合を言われてもイメージすらできていなかったので、こちらの状況についても詳しく解説していきます。

また、今回記事を書くに至った経緯としては上記2についての解説記事が少なかったからです。

上記2の例としては、開発環境ブランチ(例: development-branch, staging-branch)などに動作確認の為マージする際、
開発環境ブランチ(マージ先)の不要な差分を取り込まずにコンフリクト解消したい時などがこれに当たります。(後ほど詳しく後述)

この記事を読み終わった頃には、現場でコンフリクトが起きても完璧に対処できるようになってるはずです。
では、、早速↓↓

0. そもそもコンフリクトが起こる流れ


  1. 親ブランチから作業ブランチを切って修正を行う
  2. 修正後、作業ブランチを親ブランチにマージする
  3. 他のエンジニアとの修正が被ってコンフリクトが起きる
  4. コンフリクトを解消 ← ここで親ブランチの差分を取り込むか or 取り込まないか で対応が変わる

注意:直push は避けましょう!!

本番リリース用(master-branch)やそれに近しいブランチ(develop-branch)への直push はやめましょう。
プロジェクトや所属する開発チームによってお作法は異なるかと思いますが、直pushは事故の元です。

なのでGitHub上でプルリクを作成してからマージするようにしましょう。
GitHub上でプルリクを作成すると、コンフリクトが起きた際は下記のような表示が出てきます。

git-conflict.png

1. マージ先(親ブランチ)の差分を取り込みながらコンフリクト解消する


いわゆる一般的なコンフリクト(マージ先の差分を取り込みたい or 取り込んで良い)です。

develop-branch(プロジェクトによってブランチ名が異なる)のような、本番リリース用(余分な差分がない)ブランチへマージする場合です。

解消方法

  1. 作業ブランチにいる状態で、最新の親ブランチをpullする

    $ git branch
    * 作業ブランチ
      親ブランチ
    
    $ git pull origin 親ブランチ
    
    Auto-merging 'コンフリクトが起きたファイル名'
    CONFLICT (content): Merge conflict in 'コンフリクトが起きたファイル名'
    Auto-merging 'コンフリクトが起きたファイル名'
    CONFLICT (content): Merge conflict in 'コンフリクトが起きたファイル名'
    Automatic merge failed; fix conflicts and then commit the result.
  2. vscodeなどのエディタでコンフリクトを解消する

    # 例)vscodeを開くコマンド
    $ code .
  3. 修正が完了したら、修正したファイルをインデックスに追加し、コミットする。

    # インデックスに追加
    $ git add .
    
    # コミット
    $ git commit -m コミットメッセージ
    -> コミットメッセージを入力しなくても、コミットメッセージは自動で作成されます。
    
    # コミットメッセージを確認したい場合は下記コマンドで確認
    $ git log
  4. remotoの作業ブランチにする

    $ git push


2. マージ先(development, staging環境のブランチなど)の差分を取り込まずにコンフリクト解消する


状況の説明

ここでマージ先の差分を取り込みたくない場合の状況説明をします。

まず下記のようなブランチがあったとします。

  • master

    • 本番環境で実際にサービスを提供しているブランチ
  • develop

    • master にマージする用の開発ブランチで master さながら余計なものを入れるべきではないブランチ
  • development-branch

    • 開発検証環境用のブランチで開発中の動作確認などを行うブランチ。
    • 動作確認用のログの出力, 作業ブランチのゴミ差分(検証不要な軽微な修正の場合、開発環境用のブランチに修正が反映されず放置されたままになっていたりする)等、本番環境に反映したくない不要な差分が存在する。
  • feature-branch

    • 実際に修正を行う作業ブランチ

この差分を取り込んで、知らずにmaster などの本番リリース用にマージすると結構問題になります。なので気をつけて下さい。この記事でしっかり理解して、コンフリクト解消できるようになりましょう。


【注意】:github上でコンフリクトの修正は行わないこと!!

画像の [Resolve conflicts] をクリックして差分修正してしまうと、マージ先の不要な差分まで反映してしまいます。

git-conflict.png

それでは解消方法についてです↓↓

解消方法

  1. マージ先ブランチ(development-branch)に移動して、最新のブランチ情報をpullする

    $ git checkout development-branch
    $ git pull
    
    $ git log
    (任意)ローカルにpullした最近コミットがGithubの最新コミットと同じであることを確認する。

  2. (ローカルで)マージ先ブランチ(development-branch)に作業ブランチをマージして、vscodeなどでコンフリクトを修正する。

    # マージ先ブランチ(development-branch)にいる状態で、作業ブランチをマージする。
    $ git merge 作業ブランチ

    マージすると下記のような警告が出るので、vscodeなどのエディタでコンフリクトが起きたファイルを修正する。

    Auto-merging 'コンフリクトが起きたファイル名'
    CONFLICT (content): Merge conflict in 'コンフリクトが起きたファイル名'
    Auto-merging 'コンフリクトが起きたファイル名'
    CONFLICT (content): Merge conflict in 'コンフリクトが起きたファイル名'
    Automatic merge failed; fix conflicts and then commit the result.

  3. 修正したファイルを $ git add してコミットする。

    特にコミットメッセージを入れない場合は、下記のようなコミットメッセージがデフォルトである。

    Merge branch '作業ブランチ' into マージ先ブランチ(development-branch)

  4. 「直push」 or 「branchを生やしてpush」する

    push方法は2つ説明しています。直pushしたくない場合は、4-2 の方法で行えば大丈夫です。

    持論ですが、、開発検証用のブランチについては master, develop などとは違い検証用のブランチなので直pushしても良いと思っています。

    4-1. 直push

    # マージ先ブランチ(development-branch)にいる状態で、リモートのdevelopment-branchへ直接pushする
    $ git push

    4-2. branchを生やしてpush

    # マージ先ブランチ(development-branch)にいる状態で、「コンフリクト修正ブランチ」を生やす
    $ git checkout -b コンフリクト修正ブランチ
    
    # コンフリクト修正ブランチにいる状態で、push
    $ git push
    
    # 後はGithub上でリモートのマージ先ブランチ(development-branch)へ向けたPRなどを作成してマージする

最後に


最後の方は駆け足で説明することになりましたが、少しでも理解の手助けになれば幸いです。
git関係はミスすると偉いことになりかねないので先輩やテックリードに相談することも大切です。
誤った表現やご助言等のありましたらよろしくお願い致します。

誰かの糧になれたら幸いです。