Gitを使ってみよう!【競合編】

Git

こんにちは ECF Tech
ブログ担当 Michiです。

Gitシリーズ第6回はコンフリクト編です。よろしくお願いします。

本記事は「Gitを使ってみよう!」というシリーズで作成している記事の1つになります。下記のリンクより、第1回からの記事を閲覧できます。ご活用ください。

Git
Gitの事を、学んで試せるページとなっています。初めてGitを利用される方に最適です。ぜひご活用ください。

対象読者

  • Gitを学んでみたい方
  • Gitのクローンやコミットをやったことがある方

今回から複数のプログラマーによる開発がスタートします。そんな中、Gitがどんな風に活躍するかを見ていきたいと思います。

まずは新規に、Cドライブ直下にwork02というフォルダを作成し、クローンします。

コマンド

C:\work02>git clone https://github.com/MichiharuT/hello_repo.git

クローンできていることを確認します。

C:\work02>cd hello_repo

C:\work02\hello_repo>dir
 ドライブ C のボリューム ラベルは OS です
 ボリューム シリアル番号は 6063-1083 です

 C:\work02\hello_repo のディレクトリ

2019/09/22  11:17    <DIR>          .
2019/09/22  11:17    <DIR>          ..
2019/09/22  11:17               124 program01.txt
2019/09/22  11:17                30 program02.txt
2019/09/22  11:17                47 readme.txt
               3 個のファイル                 201 バイト
               2 個のディレクトリ  169,050,136,576 バイトの空き領域

C:\work02\hello_repo>

ここが新しいプログラマBさんの作業フォルダだとします。現在の状態を図にすると、次のようになります。

それではprogram02.txtを開いて作業を行ないます。次のようにします。

表示するための機能A
表示するための機能B

表示するための機能Bができましたので、コミットしましょう。git addコマンド、git commitコマンドの順で実行します。

C:\work02\hello_repo>git add .

C:\work02\hello_repo>git commit -m "表示する機能Bを追加"
[master 5c646b6] 表示する機能Bを追加
 1 file changed, 2 insertions(+), 1 deletion(-)

C:\work02\hello_repo>

コミットが完了しました。

表示するための機能Bを作成したBさんは、そのままリモートリポジトリにPushすることにしました。

git push origin master

一方でAさんが同じprogram02.txtに対し、別の機能を追加していたとしましょう。

次のコマンドでC:\work01\hello_repoに移動します。

C:\work02\hello_repo>cd C:\work01\hello_repo

program02.txtを開き、次のようにします。

表示するための機能A
表示するための機能C

機能Cの追加が終わりましたので、コミットしましょう。

C:\work01\hello_repo>git add .

C:\work01\hello_repo>git commit -m "表示するための機能Cを追加"
[master 0722b84] 表示するための機能Cを追加
 1 file changed, 2 insertions(+), 1 deletion(-)

コミットが完了しました。

AさんもリモートリポジトリへPushすることにしました。git pushコマンドを実行します。

C:\work01\hello_repo>git push origin master

実行結果

To https://github.com/MichiharuT/hello_repo.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/MichiharuT/hello_repo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

C:\work01\hello_repo>

リモートリポジトリへのpushに失敗しました。理由はリモートリポジトリへ統合(マージ)する際に競合(Conflict)が発生してしまったためです。

競合とは、ファイルを編集した箇所が他の作業者と重複してしまい、うまくマージできない状態の事を言います。

今の状態を図に示すとこんな感じです。

Aさんが作成した機能もBさんが作成した機能も今回のプログラムには欠かせない機能なので、「表示するための機能B」と「表示するための機能C」の両方がprogram02.txtに入るように、ファイルを手直しする必要があります。この作業を競合の解決といいます。

手直しするためには、一旦リモートリポジトリの内容をローカルリポジトリに持ってくる必要があります。この操作をPullといいます。次のコマンドを実行しましょう。

git pull

実行結果

remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/MichiharuT/hello_repo
   b783e81..5c646b6  master     -> origin/master
Auto-merging program02.txt
CONFLICT (content): Merge conflict in program02.txt
Automatic merge failed; fix conflicts and then commit the result.

C:\work01\hello_repo>

メッセージ下部にCONFLICTと表示されています。program02.txtを自動マージしようとして失敗したというメッセージが出ています。

ここでprogram02.txtを開いてみましょう。次のようになっています。

これはリモートリポジトリ側とローカルリポジトリ側でどのような違いが発生しているかを示しています。

<<<<<<< HEAD

>>>>>>> 5c646b6a1972af939e85d7273b6d0f95a24e5d52

は、どのコミットオブジェクトかを示すものです。

このファイルを見て修正を行なっていきます。ではそのまま、program02.txtを編集しましょう。次のようにします。

表示するための機能A
表示するための機能B
表示するための機能C

これで機能A~Cがすべて入りました。AさんBさん両者の作業が報われたことになります。これで競合は解決です。

では、新しくなったprogram02.txtをコミットし、リモートリポジトリへのPushまで一気に行きましょう。

C:\work01\hello_repo>git add .

C:\work01\hello_repo>git commit -m "競合解決。機能Cを追加"
[master 70dd216] 競合解決。機能Cを追加

C:\work01\hello_repo>git push origin master
Enumerating objects: 10, done.
Counting objects: 100% (10/10), done.
Delta compression using up to 4 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 742 bytes | 742.00 KiB/s, done.
Total 6 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/MichiharuT/hello_repo.git
   5c646b6..70dd216  master -> master

C:\work01\hello_repo>

今度は無事、リモートリポジトリへのPushが成功しました。

Pullについて

ちなみにPullは競合の解決時に使うものではありません。ローカルリポジトリの内容を、最新の状態(リモートリポジトリと同じ状態)にするために使うコマンドです。

大規模なシステム開発では、多くの人が絶えずリモートリポジトリを更新している可能性があります。そのため、定期的に自身のローカルリポジトリにもその変更を反映させてあげる必要があります。そのために用いられるのがgit pullコマンドです。

おわりに

本日はここまでとさせていただきます。最後までご覧くださり、ありがとうございました。競合の解決は実際のシステム開発ではかなり大変な作業です。簡単な例で練習してその感覚をつかんでおくといいと思います。また次回もよろしくお願いします。


合同会社イー・シー・エフでは、子ども向けプログラミングなどの教育講座を実施しています。プログラミング教室の案内や教育教材の情報、また関連するご相談・問い合わせにつきましては下記よりご確認ください。

ECFエデュケーション
タイトルとURLをコピーしました