1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NITICNoobsによるGit/GitHub講座 第5回 〜競合を解決する〜

Last updated at Posted at 2020-06-07

フライさん(loxygen)です。限界開発鯖でのだのだ言っています。フライさんにおまかせなのだ!
説明はあまり得意ではありません。

※この記事は茨城高専生向けに書かれたものです。

お説明

前回使用したリポジトリを引っ張ってきて、そこでGit Bashを開いておいてください。
現在のコミット履歴は以下のようになっています。
image.png

コンフリクト

hello.txtがこれまでどのように編集されてきたかを見てみましょう。

image.png

add-new-funcブランチとadd-new-func-2ブランチの編集場所がまるっきりかぶっています
これでは**add-new-funcブランチとadd-new-func-2ブランチ両方の内容を取り入れることができません**。
だからと言ってどちらかの変更を消し飛ばすのも人間性がありません。

通常Gitはgit merge 〇〇コマンドを打てば自動でマージしてくれますが、こうなってしまうとどうすれば良いのかわかりません。するとGitは「コンフリクト」を宣言します。

コンフリクトになると、Gitの代わりに開発者自らの手で変更内容をマージする作業が必要になります。
だから開発者はコンフリクトを忌み嫌うわけですね。

確認作業

前回、「マージする前に確認作業をするとお作法がいいよ」という話をしました。

どうして確認作業が必要なんですか

確認作業の説明の前に、存在意義を説明させてください。
ちょっとこの図をご覧ください。
image.png
さっき上に出した図の簡略版です。
前回のお練習の中でadd-new-func-2ブランチを作りましたね。
同じ要領でマージしようとしてみました。

すると、先程の理由で**コンフリクトします。**コミット履歴はこのようになります:
image.png

この後手動でマージ作業を行うわけですが、その作業を行うブランチは先程チェックアウトした**masterブランチです。
前回**masterブランチは品質が保証される**ということを記述しましたが、そんなmasterブランチで作業をするのは
極めておっかないことはわかりますよね。
マージ作業に失敗したら
バグがあったり、最悪の場合全く動かない状態のものがmasterブランチにコミットされてしまいます**。ああ、怖い怖い!

確認作業

そこで、masterブランチにチェックアウトした状態でのコンフリクトを防ぐために、
事前にadd-new-func-2ブランチでコンフリクトを発生させるということを行います。
これこそが確認作業です。便宜上確認作業と読んでいますが、正式なお名前はたぶんないです。

こういうことです:
image.png
masterブランチからadd-new-func-2に、逆方向にマージしてからmasterにマージしています。
こうすることでマージ作業をadd-new-func-2ブランチで行ってからmasterにマージすることができます。
masterブランチじゃないところでマージ作業ができるので、気が楽ですし、何より安全です

確認作業を行った上でマージしてみる

習うより慣れろ、と昔偉い人は言いました。実際にやってみましょう。

逆マージする

まずはadd-new-func-2masterをマージするんでしたね。
マージの方法は前回説明しました。やってみましょう。

Bash
$ git checkout add-new-func-2
Switched to branch 'add-new-func-2'.

$ git merge master
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.

…ん?failedですって?
はい。先程の理由でコンフリクトしました

git statusも見てみましょう。

Bash
$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

You have unmerged paths…まだマージしきれてないやつがあるで!
と言われていますね。

現在、コミット履歴は以下のようになっています:
image.png

ファイルには何が起こっている?

hello.txtの中身を見てみましょう。
中身はcatコマンドで見れます。もちろん任意のテキストエディタで見ても大丈夫です。

Bash
$ cat hello.txt

上のコマンドを叩く、またはテキストファイルを任意のエディタで見ると以下のようになっています:

hello.txt
<<<<<<< HEAD
I am the kindest person.
=======
I am the greatest people.
>>>>>>> add-new-func-2

世界が急に混沌に包まれてしまいました。落ち着いて読み解いて行きましょう。と言っても簡単です。
image.png
これだけです。現在のブランチ(マージ先)の状態とマージ元の変更内容が一緒に書いてあるだけです。

解消する

解消方法は至って簡単で、2つのブランチの変更内容をいい感じにフュージョンしてやればOKです。1
今回の場合は、I am the kindest human.I am the greatest people.をいい感じにフュージョンしてやればいいわけです。

hello.txtをご自由に変更してみてください。

おヒント

筆者の場合は…

  • kindestgreatestについては、2つの特徴を両方取り入れて、I am the kindest and greatest ***.にしたい
  • humanpeopleという単語は不適切2なので、personに修正したい

と考えました。

というわけで、筆者であれば以下のように修正します。

hello.txt
I am the kindest and greatest person.

いい感じにフュージョンできたら、「<<<<<<< HEAD」から「>>>>>>> add-new-func-2」は消してください。

コンフリクト解消

全てのコンフリクトが解消できたら(今回の場合は一箇所だけなのでこれで終わりです)、いつものようにAddしてCommitしましょう。

Bash
$ git add --all

git statusも見ておきましょう。

Bash
$ git status   
On branch add-new-func-2
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
	modified:   hello.txt

All conflicts fixed but you are still merging…「コンフリクトは全部直ったけどまだマージ作業中やで!」と言われています。まだコミットしてないからですね。コミットをしましょう。

Bash
$ git commit -m "Resolved conflict between master and add-new-func-2"
[add-new-func-2 ef01234] Resolved conflict between master and add-new-func-2

これでコンフリクトが解消され、add-new-func-2上でコンフリクトの修正に成功しました。
コミット履歴はこうなっています:
image.png

masterにマージする

これでmasterブランチとのコンフリクトが起きない状態になったので、心に余裕を持ってマージすることができます。ちゃちゃっとやってしまいましょう。

Bash
$ git checkout master
Switched to branch 'master'

Updating 38f1b56..03eafb0
Fast-forward
 hello.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

一応hello.txtの中身も見てみましょう。例のごとくcatコマンドを使用しますが、お好みのエディタで確認しても大丈夫です。

Bash
$ cat hello.txt
I am the kindest and greatest person.

先程修正した内容が正常にmasterブランチに反映されていますね。
コミット履歴はこうなりました:
image.png

これでようやくコンフリクトした状態からのマージに成功しました。お疲れ様でした。

マージ作業を取りやめたい場合

なにか事情があって途中でマージ作業をキャンセルしたくなったとします。その時は以下のコマンドを入力してください:

Bash
$ git merge --abort

「コンフリクト起こらんやろ!」って場合

例えば小さい変更だったり、他の人が全くいじらなかったところを変更したりした場合などで、コンフリクトする確率は低いと判断できる場合があります。
その場合はちょっとお行儀悪いですが、確認作業を踏まずにmasterにマージして問題ないでしょう。

コンフリクトしてしまった場合は、そこで直さずにgit merge --abortを実行してから、マージする元のブランチにいって確認作業を踏むと世界が平和になります。

以下に**「コンフリクト起こらんやろ!と信じてmasterブランチに直接マージしようとしたものの、コンフリクトしてしまい元のブランチで確認作業を行ったときの動き」**を記しておきます。
(なお、すでにadd-new-func-2はマージしてしまったので以下のコマンドは動きません)

Bash(動きません)
$ git checkout master
Switched to branch 'master'

$ git merge add-new-func-2
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.

$ git merge --abort # 一旦マージ作業をやめる

$ git checkout add-new-func-2
Switched to branch 'add-new-func-2'

# 以下確認作業を行う

おまとめ

  • 別々のブランチで同じファイルの同じ場所を編集するとコンフリクトが起こる
  • 以下の「確認作業」を踏むのが好ましい
    • 1.masterブランチを作業中のブランチにマージする
      1. コンフリクトが発生したら以下の手段を踏む:
        1. >>>>>>> 〇〇<<<<<<< ⬜⬜の間をいい感じにフュージョンする
        1. 全部終わったらgit add --allしてgit commit
      1. masterブランチにチェックアウトする
      1. マージする
  • 強制ではないので、「多分コンフリクト起こらんやろ〜」と判断できる場合は飛ばしても良い

これでブランチについてはひとまず終了です。ここまで本当にお疲れ様でした!

おリンク

第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 いまここ
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編

執筆者

  1. 実際のプログラミングでコンフリクトに遭遇すると、フュージョンさせるのが大変だから困るんですよね…
    もちろん楽なケースもあります。場合によってはツールが自動解決してくれる場合もあります。

  2. 主語がIなので、単数であることは確実です。単数に対してpeopleは使わないので不適切です。
    humanは良いかも知れませんが…personのほうが自然です。不適切とまでは行きませんが、personのほうが適切です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?