【Git初心者向け】Git管理されているプロジェクトに参加するときの基本所作

社内向け研修資料をQiitaに残しておくシリーズです。本記事では、チームで開発している時の基本的なGitの使い方とどうしてそうなるのかの理由についてまとめてみます。

「理由はわかったので、じゃあ具体的にどういうルールで運用するの？」と思った方は「[Git Flow](https://qiita.com/search?q=git+flow)」で検索するか、弊社スタッフであれば各プロジェクトのBacklogのWikiに記載してあるGit運用フローを参照してください。

それでは始めましょう。

## Git とは？

現在ソフトウェア開発において広く使われているバージョン管理ツールです。ソースコードに与えた変更点をコミットという単位で記録します。差分が履歴として残ることで、いつ誰がどんな変更を行ったかという情報が残り後から参照できますし、任意の時点の状態を呼び出すことが可能です。

Git の基本的な使い方の解説は[サルでもわかるGit入門](https://backlog.com/ja/git-tutorial/)がおすすめです。

## チームで Git を使ううえでもっとも重要なことは？

ズバリ、**「他の人に迷惑をかけないこと」**です。さらに具体的には、**「無意味な履歴を残さないこと」「自分だけの失敗を履歴に残さないこと」**になります。

よく**「コンフリクトを起こさないこと」**と勘違いされるのですが、コンフリクト自体は場合によっては不可避ですし、適切に解消できるものなので、怖がる必要はありません。

### 無意味な履歴とは？

ホワイトスペースのみのコミットがこれに当たります。例えば、

* 改行コードがLFのファイルをCRLFにしてコミットしてしまう
* スペースによるインデントをタブにしてコミットしてしまう

…など。これらのコミットはコードの改修でもバグ修正でもなく、なんの意味もありません。しかも、[git blame](https://git-scm.com/docs/git-blame)でそれぞれの行がいつ最後に変更されたのかを調べる際も、改行コードの変更が全ての行で行われたという記録が残ってしまい、バグ探しの邪魔になってしまいます。Windowsで開発に参加する際は注意してください。

Git には[改行コードの自動変換の設定](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)があります。

また、コーディングガイドラインが制定されている時は、PHPであれば[PHP Coding Standards Fixer](https://cs.symfony.com/)を使うなど、自動でコーディングスタイルを合わせてからコミットする方が良いでしょう。CS Fixer自体の設定もチームで合わせる必要がありますが、concrete5であれば[設定ファイルが公式リポジトリに含まれています](https://github.com/concrete5/concrete5/blob/develop/.php_cs.dist)し、同様のプロジェクトも多いでしょうから、うまく活用しましょう。

### 自分だけの失敗とは？

Gitに失敗を残すなという話ではありません。バグがいつ発生しいつ解消されたかというのは、プロジェクトの保守の上で重要な情報ですので、隠ぺいはよくありません。

しかし、**自分のローカル上だけで発生した失敗**は別です。例えば、そもそもの指示を勘違いしていて作り直す、コミットする必要がないファイルをコミットに間違って入れてしまった、などです。このような、そもそも存在する必要がないコミットが履歴に残ると迷惑ですし、修正する作業が無駄です。

*（ただし、そのコミットが本番環境にリリースされていないことも条件です。どんな凡ミスでも、本番環境へのリリースまで行ってしまったら、きちんと修正コミットを履歴に残すべきです）*

このような自分だけの失敗でプロジェクト全体に迷惑をかけないために、ブランチという機能があります。

## ブランチとは？

ブランチ＝**枝**の用語の通り、時系列に連なった変更履歴を枝分かれさせることができる機能です。枝分かれさせることのメリットは、複数の作業を同時並行することができるという点です。作業ごとに時系列が異なる場合があります。

例えば、Aという修正とBという修正が同時に動いているとします。Aの修正は先に終わりコミットしたが、クライアントの確認に時間がかかっている。Bの修正はあとで終わりコミットしたところ、クライアントからすぐにリリースしてほしいと言われた。Aの修正はまだOKが出ていないので、いったん元に戻すコミットをするべきでしょうか？

答えは、それぞれのブランチを分けておく、です。Aの作業をする際に、A用のブランチを作成してそこで作業する。Bも同様です。このようにブランチを分けることで、リリースしてもよいブランチだけマージすることができます。マージとは、分岐した枝を再度合流させることです。

また、ブランチを分岐しておけば、ブランチごと破棄することができるのも便利なポイントです。

### ということで、具体的な作業手順の一例

1. masterブランチをチェックアウト
2. 作業ブランチを分岐（ブランチ名はチームで決められたルールに従いましょう）
3. ローカル環境で開発し、レビューしてもらえる状態になったら作業ブランチをoriginにpushする
4. Backlog(もしくはGitHubなど)で、作業ブランチからdevelopにプルリクエストを作成し、レビューを依頼する
5. 問題なければレビュアーが作業ブランチからdevelopにマージしてくれますので、開発環境にデプロイしクライアントに確認を取ります
6. 確認が取れたら、作業ブランチからmasterにプルリクエストを作成します
7. 問題なければプルリクエストがマージされますので、本番環境にデプロイします

上記の手順は、masterブランチを本番環境と同期したブランチ、developブランチを開発環境と同期したブランチと簡略化したワークフローを想定しています。また、自社サービスではなく受託開発におけるフローをイメージしています。

実際には他の環境のブランチやリリースブランチも存在しますので、くれぐれもチームのGit運用ルールを確認しましょう！

### なぜmasterから分岐すべきなのか？

ここが強調したいポイントです。なぜdevelopからの分岐ではダメなのか。理由は、作業ブランチをdevelopから分岐してしまうと、masterにマージできなくなるからです。

developブランチには、開発環境でのみ存在し、まだリリースしてはいけないコードが含まれている可能性があります。そこから作業を開始してしまうと、それらのリリースできないコードが作業ブランチに混入してしまいます。こうなると、もうmasterブランチにマージができません。

作業ブランチは、本番環境に出してもいい状態のブランチから分岐するのが原則です。

## コミットの単位について

最後に、これもよくある「どのくらいの頻度でコミットすべきか？」問題について少し補足しておきます。これはググっても諸説あるのですが、個人的には[コミットは作業ログではない！](https://qiita.com/suzuki-hoge/items/cc91877ce69527ced692)という記事に共感します。

ひとことでまとめると「お願いだからレビューしやすいコミットにしてくれ」ってことなんですが、こればかりはレビュアーになってみないと分かりにくい感覚でもあるので、「少なくともコミットした時点ではバグがないようにしたほうがいい」と言い換えても良いと思います。CTOからお小言を言われながら覚えるしかないのかもしれません :relaxed: