GitとGitHubを利用した共同開発の練習（コンフリクト解消まで）の備忘録①

#はじめに
先日、現役エンジニアの方が主催された共同開発の練習を他の参加者の方と一緒に行いましたので、内容をまとめて備忘録にすることにしました。（コンフリクト解消まで）


私のように未経験からエンジニアを目指す場合に意外に軽視されがちな`Git` と　`GitHub`など を使用して行う共同開発の学習（練習）は非常に重要かと思いましたので下記に列挙して行きます。


#1. まずはソースコードをクローンする
ターミナルで以下のコマンドを打ってGitHubに公開されているソースコードをクローンします。

```bush:ターミナル
$ git clone [クローンするソースコードのURL](https://github.com/hoge/hogehoge.gitの様な部分)
```
今回、クローンしてきたソースコードのディレクトリ名を仮に ***git_sample***として下記の様に、このディレクトリに移動します。

```bush:ターミナル
$ cd git_sample
```

その状態でターミナルにて ```bundle install```を行って、インストールが終わったら
```bundle exec rake db:create``` を行います。

続けて`rails s`でRailsを立ち上げて`http://localhost:3000`にアクセスしてViewを確認します。

#2. 自分専用のブランチを作る
ソースコードをクローンしてきて、ブラウザでも確認ができたら次に下記の様にコマンドを打って自分専用のブランチを作って行きます。ブランチの名前はどの様な機能を実装する（変更点）のかが、わかるブランチ名にするのが基本ですが、今回は簡略化して私の名前である***shoの開発***という意味で`sho_dev`というブランチ名で作成して行きます。

```bush:ターミナル
$ git checkout -b sho_dev
```

これでブランチを作成でき、同時に`sho_dev`というブランチに移動できました。
（`git branch`と打つことで今どこのブランチにいるか確認できます！）

その状態で試しにディレクトリ内のファイルをテキストエディタで編集して見ましょう。
(viewのindex.html.erbなど変更が確認しやすいファイルなど）

編集後に`git status` と打つことでまだ変更が`commit`されていないファイルがあることが確認できます。

<font color="Red">modified   app/view/users/index.html.erb</font>

この様にターミナル上に<font color="Red">赤色</font>で表示されると思います。

そして今回の変更を`commit`するために

```bush:ターミナル
$ git add .
$ git commit -m "add introduce" ←　ここの名前も何を変更したのかわかる様な名付けをする
```

を行います。また`git add .`の後に、もう一度`git status`をしてみると

<font color="ForestGreen">modified   app/view/users/index.html.erb</font>

の様に今度は<font color="ForestGreen">緑色</font>で変更したファイルが表示され`commit`する準備が整いました。


そして`git commit -m "add introduce" ` 後に`push`を行っていくのですが、ここで下記の様に`push`しては<font color="Red">***絶対ダメです！！！***</font>

```bush:ターミナル
$ git push origin master #やったらあかん！ダメ絶対
```

なぜか？　

それは`git push origin master`としてしまうとその通りですが、リモートリポジトリのmasterブランチに誰のチェック（コードレビュー）も受けずに直接`push`してしまうことになり、大元のソースコードが変わってしまいます（泣）

これは開発現場では絶対にしてはいけないことの1つなので気をつけましょう！やってしまうとメチャクチャ怒られるそうです（現役エンジニアは語る）。まあ、怒られるだけならいいのですが、現場に多大なる迷惑をかけるので本当に気をつけて行きましょう！

ではどうやっていくかと言いますと…

```bush:ターミナル
$ git push origin sho_dev ←　先ほど作った自分専用のブランチ
```

の様にして`push`すると*GitHub*上で`sho_dev`なるブランチが作られていてそこに`push`されております。

実際の開発現場であると、この後にGitHub上でプルリクエストを行って上司のエンジニアの方などにレビューをしてもらって修正箇所があればそこを改めて修正し、OKが出ればmasterに変更を反映してもらえます。

次は***コンフリクト***について見て行きます。

#3. マスターが最新の状態になっていないのにブランチを切ると…

先ほどからの続きで、ターミナルにて`git checkout master`でブランチを`master`に切り替えてテキストエディタで変更した箇所を確認しに行ってみると、まだ`master`には変更が反映されていないことが確認できると思います。

よくこの状況で有りがちなのミスとして、`master`が最新の状態に書き換わっていないのに、ここで下記の様に「ブランチを切る」ということを行うと、いわゆる<font color="Red">コンフリクト</font>（衝突）が発生します。
***（ブランチを切る　＝　ブランチを作る）***



```bush:ターミナル
$ git checkout master
$ git checkout -b sho_dev2　　←　　新たにブランチを作ってしまいファイルを編集すると・・・
```

とターミナルで打ってテキストエディタにてファイルを編集して

```bush:ターミナル
$ git add .
$ git commit -m "hogehoge"
$ git push origin sho_dev2
```

という一連の流れを行って*GitHub*で`Compare & pull request`のボタンを押してみると

***Conflicting files***

という風に表示されて注意されてしまいます。


#4. コンフリクトを起こさない様にするには
まずコンフリクトを起こさない様にするには、下記の様にコマンドを打って`master`の最新の状態を引き出しておく必要があります。

```bush:ターミナル
$ git checkout master　　　　→　ブランチをマスターに切り替えて

$ git pull origin master →　マスターの最新の状態を引き出してくる
```


そしてテキストエディタの方で最新の状態が反映されていることを確認します。

この状態で

```bush:ターミナル
$ git checkout -b sho_dev2
　　
```

としてブランチを切って(ブランチを作る）ファイルを編集して`push`するとコンフリクトは起こらない。

#5. コンフリクトを解消する方法
今回の様にしてコンフリクトを起こしてしまい、そのコンフリクトを起こした`sho_dev2`のブランチが残ってしまっていますよね・・・

なので、コンフリクトを起こしたブランチの`sho_dev2`と最新の状態である`master`ブランチを合併（merge)させて行きます。（下記参照）

```bush:ターミナル
$ git checkout sho_dev2  #コンフリクトを起こしたブランチに移動
$ git　　merge master       #sho_dev2　と　masterを合併する
　　
```

そうするとテキストエディタがAtomの場合はAtomの便利機能の１つで今回コンフリクトを起こしている箇所を教えてくれます。

そこでどの内容の方を使うかを選択します。

これで`merge`完了です。

その後に`push`までの一連の流れを行います（下記参照）

```bush:ターミナル
$ git add .
$ git commit -m "modify conflict"
$ git push origin sho_dev2
```


そして*GitHub*に戻り、`Conflicting files`と表示されていた部分を見てみるとコンフリクトが解消されているはずです！（下の画像の様な表示が出ます↓↓）

[![Image from Gyazo](https://i.gyazo.com/6395563285b45cf7260b4238cf22dbac.png)](https://gyazo.com/6395563285b45cf7260b4238cf22dbac)

お疲れ様でした:grin:

#最後に

今回はコンフリクトの解消までの基本的なGit・GitHubの操作について、自分が学ばせてもらった内容をテキストという形でまとめさせて頂きましたが、この他にもフェッチ(fetch)や、リベース(rebase)、フォーク(fork)、.gitignore、cherry-pickなどの用語があり、学ばなくてはならないことはあるのでどんどん学習・復習していかないといけないなーと改めて感じております。

備忘録として書いたものですが、今回の記事が誰かのお役に立てれば幸いです！

この記事がよかったら`いいね!`ボタン押してください（ムチャクチャ喜びますw）

それではまた！