Trance Shift 8 - Notes

クルマと温泉とキャンプとゲームと登山、たまにDTM。

Git/GitHubでWeb開発する時ちょっと工夫してること

たまには技術ネタでも。

MBPR

よくある世の中のまとめ記事みたいなのじゃなくて私はこうやってますよ、という紹介。受託開発みたいなプロジェクトを想定してます。自社サービスとかだともうちょっと違ったフローになるんじゃないですかね。

Gitのブランチ戦略

プロジェクトの中核となっているのはGitHubなので、基本的にはGitHub Flowに従います。また、一部A successful Git branching modelの考えを取り入れてます。

それと、GitHubのforkは原則として行いません。forkを行うプロジェクトもあるんですが、forkが必要な程の人数が開発に参加するようなことがまずないので…(うちの場合多くても10人ぐらいです)

ブランチは主に4種類あって、メインとなるのは masterdevelop の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を追加することを示している)

という具合に命名するようにしてもらってます。

ちなみに masterdevelop にコミットしたら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 モードですね。

f:id:skyriser:20160120004554p:plain

コレを使うと、嬉しいのは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の是非は置いておいて)

なんとなくお風呂場で思い浮かんだもの書いてみたけど他にもあるかも。また浮かんだら書きます。