動機
入社先企業の新人研修の中でGit/Githubを使用しているのですが、その中である程度厳密なルール設定をすることで円滑な開発ができるようになると学びました。今回はどんなルールが適切か、自分なりに言語化し、理由を併せて説明していきます。
目次
§. ルール
ブランチ名
ブランチ名を統一することでそのブランチでどんな作業をしているか他の人が一目で理解できるようにするため、ブランチ名のルールは設定する必要があると考えています。例えば cherry-pick というとても便利なサブコマンドがGitにありますが、ブランチ名やコミット名がごちゃごちゃだと cherry-pick が大変になったりします。そのためまずはGitHubでブランチの命名規則を制限する方法とか【github】mainブランチに対して直接pushを禁止する保護ルールを設定をするとかを参考に、ブランチルールやを設けることを推奨します。私なら以下のルールを設定します。ブランチ名に以下の条件を満たす物以外は push することもできません。
main
development
feat/**/*
fix/**/*
docs/**/*
それぞれどんな意味を持たせるべきか説明します。
-
main: 基本的にはPRを出すルールとしてmainにPRを出せるのはdevelopmentからでしかできないものとしましょう。PRのレビュワーもそこは意識してチェックしてください。 -
development: 基本的にはこのブランチにみんなPRをだします。PRを出すことをmerge先をdevelopmentに合わせるようにしてください。またmainと同等の保護ルールをかけることを推奨します。そうしないと、GitHubの設定次第ではmainにmergeするとdevelopmentが消えます。 -
feat/**/*: まずこの/**/*ってなんなんやねんという感じですが、それはあとで解説します。featは機能やページ、コンポーネントを新規追加した場合に使用するブランチです。 -
fix/**/*: バグ修正をした場合に使用するブランチです。 -
docs/**/*: ドキュメントのみをリポジトリに追加した場合に使用するブランチです。
良いブランチ名の例を以下に挙げます。ブランチ名は相対パスのような記述ができて(本当に何らかのディレクトリ構造が生成されるわけではない)、feat/**/*は/ を2回までなら使えるという意味です。
-
feat/add-header…〇ルールを満たす。かつ何をしているか分かりやすい。 -
feat/addHeader/navigation…〇ルールを満たす、かつ何をしているか分かりやすい。 -
feat/header/settingIcon…〇同上 -
feat/header/page/icon…×/**を3回使用した記法は許可されていません。 -
Taro20250430react…×featから始まらないブランチはpushできないはず。かつそもそも何をブランチなのか不明。
コミット名
これは特に制約を掛けていないことですが、誰から見ても何をしたかわかるようなコミット名に設定しましょう。設定を設ける場合にはコミットメッセージのスタイルを統一するの記事を参考にしてください。
-
feat: ...:ページやコンポーネント、機能を新規追加した場合に使用するコミットです。 -
fix: ...:バグ修正をした場合に使用するコミットです。 -
docs: ...:ドキュメントのみをリポジトリに追加した場合に使用するコミットです。
他人のPRをレビューする側が気を付けること
- merge先は
developmentかどうか?(※開発の状況によってはfeat/**/*などをmerge先とすることもある。) - 不自然なPRやコミットをしないこと。例えば…
- コミット名は妥当か?
- PR名、コミット名に関して、変更内容が一目で分かるかどうか?
- 人名、日付が入っていないか?
これらに該当する場合はPRをリジェクトしてほしい。Fileを編集した人名と日付はコミットログを見れば分かる。例えばfeat/Taro0615はよくない。
-
File Changesは正当か。-
./node_modulesやPW、IPAキーなどが記載されたdocsファイルなど不必要なファイルが入っている場合はリジェクトしてほしい。 - 変なコメントアウトがないかを確認する。例えば
などは見れば分かることなので、そういった不要なコメントアウトがある場合はPRをリジェクトしてほしい。# 2025/04/30に変更しました(Taro) -
§. きれいなコミットを push するために心がけること
はじめのうちコミットは小さい機能をこまめにコミットし、こまめにPRを作成しても良いかもしれません。ページ単位・コンポーネント単位・機能単位の粒度が良いかもしれません。全員がドガっとPRを出すと、File changeが多すぎて、全員が不幸になる可能性があります。何かとこまめにコミット/PR作成をしましょう。
初級編
この初級編は難しい操作は一切ないので、全員しましょう。
エイリアスの作成
まず以下のエイリアスを作成してください。エイリアスは「ショートカットキー」のようなもので、わざわざ git status だとか git log --oneline だとかを打たなくても、git st だとか git logo だとかって打てばOK…というのがエイリアスです。これがあると作業速度がほんのちょっと向上します。
-
.gitconfigファイルを編集する。グローバルに導入したくない場合はリポジトリでのみ適用するよう設定することも可能である(参考)。vim ~/.gitconfig -
vimが起動したら以下の内容をコピペ。例えばstatus = stと設定すると、git statusと打たなくてもgit stと打てば正しく出力される。もし各々こだわりがあればエイリアスを設定して下さい。[alias] al = config --get-regexp ^alias\. logo = log --oneline b = branch sw = switch cm = commit -m rb = rebase rbi = rebase -i chp = cherry-pick -
vimから離脱したら、ローカルリポジトリまで移動してgit stと打って何かしたら出たら成功。
一応備考…i で編集モード、Esc→:wqで保存終了。
きれいなコミットを作るコツ
- まず細かく
st,logoなどを確認する。息をするようにgit st,git logoをチェック。変なファイルをaddしないか?変なコミットログになっていないか?などを確認する。 - 機能ごとに意味のあるコミットを作成する。
git stを確認しながらばいいが、安易にgit add .をしてはいけない(※余談だが、同様にgit restore .も安易にしない。爆死することがある。頑張って編集したファイルがすべて消える。)
中級編
個人的に、この中級編までは全員できてほしいと思っています。
もしorigin/developmentのHEADがlocalの先を行っていた場合
何も考えずに push するとコンフリクトがとんでもないことになる可能性があるので、いったん以下の操作をしてみてください。今、仮にブランチ feat/testで作業していたとします。
git sw development
git pull origin development // origin/developmentのHEADまでの情報をlocalに取得・反映。
git sw feat/test
git b feat/testBK // 今からいろいろコミットを破壊する恐れのある操作をするため、バックアップ(BK)ブランチを作成しておく。これ忘れると痛い目を見る可能性がある。
git rb development
これでrebaseという操作ができ、手元でいろいろコンフリクトを解消してあげると、origin/development の HEAD から feat/test を生やし直すことができます(Gitのコミットログはtree構造!)。もし大失敗したら、feat/testを削除して、feat/testBKからバックアップ情報を持ってきたら良い。
もし不要なコミットログを生まれてしまった場合
例えばfeat/testブランチにおいてgit logoをしてみると、
40d404 feat: Bを修正2 // これはHEAD
afh29a feat: Bを修正
8c8fcf feat: Aを修正
のようなコミットログが出力されたとする。HEADのコミットは明らかに汚い。そんな時は
git rebase -i HEAD~2
と打つと、vimが起動するのでコミットログをきれいにしてあげれば良い。ここら辺の操作をすると、もしかするとリモートリポジトリの development の HEAD がずれる可能性があるので、その場合は
git push origin feat/test -f
などをしてあげること。
その他きれいなコミットを作るコマンド
-
git cherry-pick <コミットのHASH値>…他のブランチのコミットをそのまま持ってくる。 -
git commit --amend…直前のコミットを修正する。コミットメッセージを直せる。 -
git reset --mixed <コミットのHASH値>…コミットを消して、stagingまで落とす。