Goalist Developers Blog

Gitがやばい(3/3)!

Gitがやばいの最終編です!前回はbranch, merge, fetch, pullについて書きました。普通のプロジェクトにはここまでは必ず使うでしょう。

実は、もう一つのよくみる現象があります。それは「マージコンフリクト」です。「コンフリクト」が入ってるために何か怖いものに聞こえますが、とてもよくあって、とても簡単に解決できるものです。

マージコンフリクトを再現する

一編から使ってるプロジェクトを使って、マージコンフリクトを見てみましょう。

下準備

ちょっとした準備しましょう。masterブランチでA.txtとB.txtというファイルを作成してコミットしましょう。

$ nano A.txt
$ nano B.txt
$ git add .
$ git commit -m "A.txtとB.txtを追加しました。"

私は上記のようにしましたが、コミットすればなんでもOKです。 こういうのが出ます。

(Create mode image)
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 A.txt
 create mode 100644 B.txt

コンフリクトはどういう状況でおきるのか

さて、状況を想像しましょう。

このプロジェクトには、二人が参加しています。二人はそれぞれのタスクがあります。 AくんはプロジェクトでA.txtのファイルで、「Aがすごい」を書くのがタスクです。 BさんのタスクはA.txtに「B.txtをみて!」を書き、B.txtに「Bが一番すごい」を書くことです。

くだらない内容ですが、重要なのはAくんとBさんが両方A.txtを編集することになります。こういう状況ではマージコンフリクトが起きる可能性があります。

シミュレーション

やってみましょう。AくんとBさんのためにそれぞれのブランチを切りましょう。

git branch B-branch

でBのブランチが作成できます(すでに知ってましたね)。

git checkout -b A-branch

上記のコードは

git branch A-branch
git checkout A-branch

を一行で書くためのやり方です。

f:id:c-pattamada:20180918160640p:plain

はい、現在A-branchにあります。では、Aくんのタスクをしましょう。 A.txtの中で、「Aがすごい」と書いて、保存して、コミットしましょう。

f:id:c-pattamada:20180918160723p:plain

masterに移って、マージしましょう。

git checkout master
git merge A-branch

ここでは、mergeのあとで書くブランチ名が現在checkoutされたブランチにマージされます。

f:id:c-pattamada:20180918160757p:plain

git logでAくんのコミットがみれます。ここは無事マージできましたね。問題なし!

マージコンフリクトが登場

では、Bさんのタスクも完了しましょう。git checkout B-branch

ここに気づくべきことが、A.txtがまだ空っぽのままです。なぜかというと、BさんのブランチがAくんのコミットの前の状態に切られたからです。 実際のプロジェクトでは、二人が同時に仕事している想定ですと、この状況はすごくよくあるかと思います。 A.txtに「B.txtをみて!」を書き、 B.txtに「Bが一番すごい」を書き、コミットします。 そして、masterに移ってマージしましょう。

git checkout master
git merge B-branch

うまくいきましたか?!や、ダメでした。 AくんとBさんが同じファイル(A.txt)を編集しましたので、gitが上書きすればいいのか、両方入れた方がいいのかなどがわかりません。 マージコンフリクトが行ってしまいました。

f:id:c-pattamada:20180918160825p:plain

マージコンフリクトを解決する

マージコンフリクトが起こっています。文字エディターでA.txtを開いてみますと驚くかもしれませんが…

<<<<<<< HEAD
Aがすごい
=======
B.txtをみて!
>>>>>>> B-branch

が書かれてます。javaだった場合には必ずコンパイルエラーが出るでしょう。

現在はmasterのブランチにB-branchをマージしようとしてますので、masterの現在のコミットはHEADと書かれてます。 <<<<HEAD=======の間には現在のmasterの状態。 =======>>>>>>> B-branchの間にはB-branchの状態。

今回は私が管理者で決める立場にあるので、両方の変更を含めたいと思います。 中身を編集して

「 Aがすごい
B.txtをみて!」

の状態で保存、または古い方を削除する判断もありえます。

ターミナルに戻り、git statusで様子みましょう。 マージしても大丈夫のファイル、B.txtが緑で、A.txtがまだaddされてないので

git add A.txt
git commit -m "マージコンフリクト解決"

おめでとう!初コンフリクトを解決できましたね。

最後に

ここでは、マージコンフリクトがどういう状況で起きるのか、そしてどんな風に解決できるのかについて書いてみました。この記事の内容と以前投稿した二つの記事で通常の時のgitは使えるかと思います。

Gitの機能は他にも山々あります。特にrebase, cherry-pick, submoduleなどが面白いですが、興味があるかたはそちらも調べてみてください(またあとで、私が投稿する可能性もありますw)。

これでGitに対しの自信が持てるようになってたら嬉しいです!

ちょっとした復習に、

Gitを使う利点

1) バージョニング管理で定期的にサーブ・ロールバックができる。

2) 複数の人が同時に複数の関係ない機能を同時に開発できるシステム

だと思いますので、一人のプロジェクトでも、大きいなプロジェクトでもとても便利です!

ぜひ、使ってみてください!