目的
- エンジニアリングマネージャーをやっているが、あまりにもエンジニアリングがわかっていない
- 作業者として実務を行った経験しかなく、0から開発ができない
- 開発環境の構築とは?
- アーキテクチャの選定とは?
- Gitの使い方を忘れている... etc
- -> これでEMを名乗るのは恥ずかしい
- 作ってみたいアプリがあるので、それを作って生活をリッチにする
そもそもGitとは
ソースコードを含むドキュメントを管理するツール。ざっくり言えば、以下のことを教えてくれる。
- こういう文章(フォルダ/ファイル)が増えましたよ
- こういう文章(フォルダ/ファイル)が消えましたよ
Gitの前提
Gitを理解するには、以下の2つの概念を知る必要がある。
- ローカルとリモート
- バージョン管理とブランチ
順を追って説明する
1. ローカルとリモート
- ローカルは自分のPCのことで、リモートはGitのサーバーのこと
- ローカルに(Gitを経由して)ファイルを保存することをCommitといい、リモートに保存することをPushという
- リモートに保存すると、自分とPCを共有していない人(同僚や世界中の人)もドキュメントを見られるようになる
※ 直接リモートに保存することはできないので、必ずCommit -> Push の手順になる
※ ローカルからリモートに押し出すイメージでPushと呼んでいる
2. バージョン管理の思想
-
バージョン管理とは、「正しいコードベース(ドキュメント)を定義して保存する」こと
- たとえば(後述の)mainブランチは、正しいと検証されたコードベースの集合体
-
本当は正しいコードベースだけを保存したいのだが、
- 複数人で協働作業をしていると何が正しいのかわからなくなるし
- 人間だから間違いもある
-
Gitでは間違えたときの解消方法をたくさん提供している
- Conflict(競合)の解消
- Revert(過去のバージョンへの切り戻し)
- 変更履歴の保存
Gitの機能
Commit
ローカルPCに、Gitを経由して(つまりバージョン管理する状態で)ファイルを保存すること
切り戻しというバージョン管理本来の目的を発揮するために、Commitはこまめに、小さい単位で行うことが望ましい
Push
ローカルPCに保存されたファイルを、Gitのサーバー上で保存してもらうこと
ステージング(Staging)
- どこで機能するか
- ローカル
- これはなに
- 変更があったファイルと、コミットするファイルを仕切る概念
- なぜやるか
- 一度に大量の作業を行った場合、コミット量も多くなる
- 一方コミットはスモールかつ一定の単位で行われることが理想的
- そのため、瞬間的に以下の2つを切り分ける必要が生じる
- 変更があった && 今すぐコミットするファイル
- 変更があった && でも今はコミットしないファイル
リセット(Reset)
- どこで機能するか
- ローカル
- これはなに
- 誤ってローカルから削除してしまったファイルを、Commitする前に復活させる機能
- Soft, Mixed, Hardの3タイプがある
- なぜやるか
- うっかりミスでローカルからファイルを削除してしまうことがあるため
- 他の手段としてバージョンを切り戻して対応することも可能
無視する(Git Ignore)
- どこで機能するか
- ローカル
- これはなに
- Gitで管理する必要のないファイルを指定して、リポジトリに追加されないようにする
- ログファイル(.log)や環境設定ファイル(.env)バイナリファイル(.exe、.dll)などはバージョン管理する必要がなかったりする
- Ignoreするパターンも設定できる
- なぜやるか
- リポジトリが不要なデータで膨らむのを防ぐことができる
- 類似機能として、「追跡から外す」というのもあるが、これは今回は書かない
タグづけ(Tag)
- どこで機能するか
- (両方。説明に関係ない)
- これはなに
- コミットに対して、タグをつける機能
- つけ方は英語で短くつける場合が多い
- なぜやるか
- 重要なコミットを識別し、検索したりジャンプしたりできるようにするため
ブランチを作る
- どこで機能するか
- (両方。説明に関係ない)
- これはなに
- 機能や作業者など、任意の単位で、作業するコードベースを隔離する機能
- なぜやるか
- 複数人で作業をしていると、「Aさんの作業内容が全体(Bさん、Cさん、Dさん)に、リアルタイムに影響を及ぼしてしまう」という状態が発生する
- Google Documentを複数人でリアルタイム編集しているときのカオス感をイメージしてほしい
- 個々人(あるいは個々の機能)ごとにブランチを切って作業をすることで、影響がリアルタイムに及ぶのを防ぐ
- 複数人で作業をしていると、「Aさんの作業内容が全体(Bさん、Cさん、Dさん)に、リアルタイムに影響を及ぼしてしまう」という状態が発生する
Merge
- どこで機能するか
- (両方。説明に関係ない)
- これはなに
- 複数のブランチを1つに統合すること(大体は、1つの派生ブランチを大元のブランチに統合する)
- なぜやるか
- 機能や作業者などの、任意の単位でどんどん開発を進めていくと、全体での整合性が取れなくなっていく
- そのため、一定のタイミングで統合して、全体との足並みをそろえる必要がある
Confilict(競合)の解消
- どこで機能するか
- (両方。説明に関係ない)
- これはなに
- 個別の作業と、全体(他の機能・他の人)との間で発生した差異を解消する
- どちらかの作業を削除するか、両方取り込めるような新しい作業を追加するか
- なぜやるか
- 個別に作業をしていると、全体(他の機能・他の人)の作業と齟齬が発生する
- 「どちらの作業が全体として正しいのか?」を判断し、より正しいコードベースを保存するため
ブランチの削除
- どこで機能するか
- ローカル、リモート
- これはなに
- mergeが終わったあとのブランチを削除すること
- なぜやるか
- 統合されたあとのブランチは、変更内容が大元に反映されているため差分のない状態になり、不要になる
- 残しておくと不必要な混乱のもとになるので、削除する
その他
コミットメッセージの書き方
-
Gitのコミットメッセージの書き方を参考に考えてみた
-
1行目は [ コミット種別 ] 要約
種別 内容 add 新しいソースコードの追加 fix バグ修正による既存ソースコードの変更 update 機能追加による既存ソースコードの変更 remove ファイルの削除 -
2行目は空行
-
3行目は変更した理由および拝啓と、その内容を詳細に記す
-
ブランチ戦略
- ブランチには大きく分けて3つの思想(スタイル)がある
- 今回はGit Flowだけ説明
- Git Flow
ブランチ名 主な目的 更新元 存在期間 正しさの程度 main 本番環境用 releaseやhotfixからのマージ 永続的(常に存在) 直接ユーザーに提供できるくらい正しい release リリース前の最終調整やバグ修正 developの集合体 一時的(リリース準備期間のみ存在) リリース前にしかわからないバグが見つかってもよい develop 開発中の機能の統合とテスト featureの集合体 永続的(常に存在) テストを通してバグが見つかってもよい feature 新機能の実装 developからpull 一時的(特定の機能開発が完了するまで存在) 開発バグがたくさんあってもよい
- Git Flow
- 他にも、よりシンプルな、GitLab Flow、GitHub Flowなどがある