たまには技術ネタでも。
よくある世の中のまとめ記事みたいなのじゃなくて私はこうやってますよ、という紹介。受託開発みたいなプロジェクトを想定してます。自社サービスとかだともうちょっと違ったフローになるんじゃないですかね。
Gitのブランチ戦略
プロジェクトの中核となっているのはGitHubなので、基本的にはGitHub Flowに従います。また、一部A successful Git branching modelの考えを取り入れてます。
それと、GitHubのforkは原則として行いません。forkを行うプロジェクトもあるんですが、forkが必要な程の人数が開発に参加するようなことがまずないので…(うちの場合多くても10人ぐらいです)
ブランチは主に4種類あって、メインとなるのは master
と develop
の2本。
master
: 中核となるブランチ。常に本番環境と同期。develop
: メイン開発ブランチ。常にStaging環境(テスト環境とかStagedとか色んな呼び方あると思う)と同期。feature/XXXX
: 機能ブランチ。作業はこのブランチで。hotfix/XXXX
: hotfixブランチ。致命的なbugfixなどで本番環境に緊急反映が必要な場合などに使う。
XXXXの部分は命名規則を決めてあって、
AAA/BBB_CCC (ex) feature/123_add_nginx_config AAA (feature) : featureとかhotfixとかmergeとかブランチの種別を表す (この場合は機能ブランチ) BBB (123) : GitHubのIssue番号 他のBTSを利用している場合はその番号を使ったりもする (123番のIssueであることを示している) CCC (add_nginx_config) : ブランチの内容 (Nginxのconfigを追加することを示している)
という具合に命名するようにしてもらってます。
ちなみに master
と develop
にコミットしたらCI(うちの場合はTravis CI)でそれを検知してテストを流した後オールグリーンであればCIを使ってそのままCapistranoでデプロイ、更にチャットツール(ChatWorkとSlack)にbotで発言させるような仕組みを組んでます。
PullRequestとWIP(Work In Progress)
作業をするときは、
- GitHubからローカルにリポジトリをclone (ここではGitHubをoriginとします)
origin/develop
からfeature/XXXX
ブランチを作成feature/XXXX
上でコミットを積む- だいたい出来たかなと思ったら
origin
にpush origin/feature/XXX
=>origin/develop
にPullRequestを出してレビューしてもらう
というごくごく普通のGitHub Flowに従ってやってますが、作業途中でもPullRequestを出してもOKにしてます。作業途中でも「このコードこれであってんのかなあ…」みたいなのを見てもらいたいケースとかありますしね。
ちなみにその場合はタイトルに [WIP]
(Work In Progress) と付けてもらってます。だいたいの人はChromeをメインブラウザとして使っているので、
を使わせてもらっています。これを使うと、タイトルにWIPとついてると Merge pull request
ボタンが物理的に押せなくなるので誤ってマージされる心配はないのです。
特にまだあんまり開発に慣れてない人の場合は、ブランチを切って作業を開始した時点ですぐにWIP付きでPullRequest出してもらって、随時pushしてもらうようにしてます。そうすれば作業の進捗もわかるし、間違った方向に進んでないかチェックできますしね。
ローカルで作業する場合はコミットを細かく積んで rebase -i
で仕上げる
ブランチを切って作業を開始した時のコミットの積み方は、なるべく細かく丁寧に、というのを基本にしてます。細かすぎてもアレですが、基本的には機能単位、function単位であることが多いです。だいたいの場合はテストと本体のコードをペアでコミットするようにしてます。
ただ、作業してると「やっぱやーめた」とか「さっきのfunctionいらねーわ」みたいなのが出てくるので、それは削除してからPullRequestに上げたいわけなんですが、そういう場合は rebase -i
をよく使ってます。単なる rebase
じゃなくて rebase -i
。interactive モードですね。
コレを使うと、嬉しいのはrebaseに該当するコミットが一覧で出てきて、取捨選択が簡単にできます。この画面でpickになっているところをそれぞれ書き換えることでコミットの整理が一気にできちゃうわけですね。
- 行を消す: コミットを闇に葬る
- 行の順番を入れ替える: コミットの順番を入れ替える
- p(pick) : コミットをそのまま使う
- r(reword) : コミットコメントを変更する
- e(edit) : コミットを再編集する
- s(squash) : コミットをまとめる
- f(fixup) : コミットをまとめる(まとめたコミットコメントは消す)
という感じです。fixupとrewordが特に便利ですね。中でもfixupは一度コミットしたけど後から間違いに気づいて治したいけどだいぶ前にそのコミットを積んでしまった、みたいな状況で効力を発揮します。
97bb3c6 すごいコミット b10668b 別のコミット f0c41a8 すごいコミットの修正
こういうふうに並んでいたら
pick 97bb3c6 すごいコミット fixup f0c41a8 すごいコミットの修正 pick b10668b 別のコミット
という記述に書き換えてセーブをすれば
f1d30ee すごいコミット b10668b 別のコミット
という感じで簡単にまとめられるわけですね。普段からGit使ってる人だと何を今更…という感じですが、これを使うとPullRequestに出してるブランチがとっても汚いことになっていても綺麗にしたブランチを後からforce pushすれば何事もなかったかのように綺麗なコミットに偽装できるということです。(force pushの是非は置いておいて)
なんとなくお風呂場で思い浮かんだもの書いてみたけど他にもあるかも。また浮かんだら書きます。