【Git】別の人が同じところを編集してたらどうなるの?

同じファイルでも異なる行を編集した場合はマージを行うだけで合流できますが、
同じ行を編集した場合は競合が発生し、
競合を解決するか、マージを中止するかの選択をすることになります。
この記事では競合が発生する過程の詳細を解説します。

Linux 知識の要らない Git 講座 目次にもどる

ストーリー

ビジネスオーナー A さんと Web ディレクター B さん
ビジネスオーナー A さんと Web ディレクター B さん

前回までのあらすじ
ビジネスオーナーの A さんが営業時間の変更をプッシュし終えた頃、
Web ディレクターの B さんは、 A さんから依頼を引き受けたとき
A さんに提案したお店のコピーの変更をホームページに適用しようとしました。

お店のキャッチコピーを変更しよう

B さん作業用フォルダーで
HTML ファイルを以下の内容に更新してコミットします。

<html lang="ja">
    <head>
        <link rel="stylesheet" href="style.css" type="text/css">
        <title>Cafe First Knowledge | 都内 カフェ</title>
    </head>
    <body>
        <header>
            未知との出会いを応援する 勉強会カフェ 「First Knowledge」 オープン! 営業時間:平日 07:00〜21:00 / 土日祝 07:30〜21:00
        </header>
        <div id="content" class="flex">
            <div id="store-name" class="flex">
                <div>
                    Welcome to First Knowledge
                </div>
            </div>
        </div>
        <footer>
            Photo by Eloise Ambursley on Unsplash
            © First Knowledge Cafe
        </footer>
    </body>
</html>

更新前との差分は以下のように、
文頭の部分にキャッチコピーが追加されただけになっているはずです。

更新前との差分
更新前との差分

いま、 HTML ファイルをブラウザで表示すると、以下のようになっているはずです。

ブラウザでの表示 キャッチコピーの追加
ブラウザでの表示 キャッチコピーの追加

そして、この編集履歴をプッシュした場合、やはり失敗します。

プッシュした結果
プッシュした結果

先に A さんがプッシュしているからです。

A さんの変更履歴をマージしてみよう

そこで、A さんの変更履歴をマージするためにフェッチしましょう。
フェッチした後のローカルリポジトリーのログは以下のようになっています。
※ [すべてのブランチ] にチェックが入っていることを確認してください。

フェッチした後のローカルリポジトリーのログ
フェッチした後のローカルリポジトリーのログ

これから A さんの編集履歴をマージしますが、
ここで、 A さんの編集履歴の流れには
まだ B さんの編集履歴の流れに含まれていない編集履歴として、
今 B さんがコミットした行と同じ編集履歴が含まれていることに注意します。

まだ B さんの編集履歴の流れに含まれていない編集履歴
まだ B さんの編集履歴の流れに含まれていない編集履歴
営業時間変更の差分
営業時間変更の差分

それでは、「origin/master」ブランチを「master」ブランチにマージしてみましょう。
すると、以下のようなダイアログが表示されます。

TortoiseGit のダイアログ
TortoiseGit のダイアログ
While merging, i.e. integrating changes of another (remote) branch into your local branch, a conflict in at least one file occurred.
This means that you need to resolve this manually (i.e. you need to integrate your changes into a file which was also modified on another branch). After resolbing all files. you need to perform a commit in order to complete the merge. If you want to abort the merge, do a hard reset on HEAD or select abort merge on the context menu.

日本語訳すると、だいたい次のような意味になります。

マージ中、つまり別の (リモート) ブランチの変更を
ローカルブランチに統合しているときに、
少なくとも1つのファイルで競合が発生しました。
これは、競合を手動で解決する必要があることを意味します。
(つまり、変更を別のブランチで変更されたファイルに統合する必要があります)すべての競合を解決した後でマージを完了するには
コミットを実行する必要があります。
マージを中止する場合は (中略) コンテキストメニューでマージの中止を選択します。

「競合」とは
「マージするブランチ同士が同じ行を更新しており、自動マージできない状態」です。

そして、ダイアログを閉じると以下のようなエラーメッセージが表示され、
[競合の解決] ボタンが表示されます。

「origin/master」ブランチを「master」ブランチにマージした結果
「origin/master」ブランチを「master」ブランチにマージした結果
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.

これは、だいたい次のような意味です。

index.html の自動マージ中に競合が発生したため
自動マージに失敗しました。 競合を修正してから結果をコミットしてください。

この時点で、 以下のどちらかが行われるまで
Git は「マージ中」という特別な状態になります。

  • 競合を解決してコミットする
  • マージを中止する

競合を解決する手順については次の記事で説明します。

Linux 知識の要らない Git 講座 目次にもどる

タイトルとURLをコピーしました