個人開発環境にGithub Flowを適用する
Github、joinしたのは2013年で作ったものは軒並みちゃんと突っ込んではいるんだけど、単に一区切りついたらadd => commit => pushしているだけでちゃんと使っていなかったので、個人開発ではあるがGithub Flowを取り入れてみた。
What is Github flow ?
Githubを用いた開発作業を進めるにあたっての指針みたいなものです。基本的にはmasterブランチ上では作業せず、作業工程ごとにブランチ作って、終わったらプルリクしてmasterにマージしてもらうことでデプロイとしましょうね、というものだと理解している。至ってシンプルではあるけど、これを取り入れるだけで従来やっちゃってた「masterで作業してるのでデプロイしても動かないレポジトリがGithub上にある」みたいな状態が防げて良さそうだと思った。
ちなみにGit-flowというのもあるようだけど、こちらは全然別個のツールらしく理解していない。Git-flowの問題解決としてGithub Flowが提唱されたようだが、そもそも開発工程の制御のためだけにツールを追加したくはないなと思ったのでGithub Flowを採用した。
Github Flowの理解にはこの文章が良さそう。なお、dotfilesのような大した更新のないレポジトリにはさすがに適用していない。
GitHub Flow (Japanese translation)
実際の開発工程
あくまでGithub Flowに沿う形という程度なので、そのままそっくり適用できてはないとは思うが。
開発開始
ブランチを切る。ブランチ名は機能追加等の開発要件であればdev_hoge
、バグフィックスであればhotfix_hoge
とする。
$ git checkout -b dev_hoge
開発中
普通であればレビューを依頼するタイミングなど、開発の切りがついたところでpush
していくのだろうが、分散して開発しているわけではないので、1日の開発が終わる段階でpush
している。そもそも開発に使っている環境が複数あるので、Github上のdevelopブランチも常に最新化していつどこでもfetch
可能にしたいなという思いがある。従来はDropboxで各環境間の同期を取っていたが、プラグインの有無やbundleなどで度々不具合もあったので改めた。
$ git add -A
$ git commit -m "
...
$ git push origin dev_hoge
git add .
ではなく-A
なのは、そちらじゃないとgit rm
したファイル等が含まれないとこちらの記事に書いてあったゆえ。
開発終了
開発が終わり、masterへのマージを必要とする段階に来たらプルリクを出す。プルリクって別のコミッターからしか不可なのかと思っていたが、自分のレポジトリに自分で出すことも可能だったのでそうしている。本来であればテストツール等走らせるべきではあるのだろうが、今のところはプルリクに対して特にレビュー等なく(自分のコードだし)そのままマージしている。
後述するがバグや開発課題の管理にはGithub issueを用いているので、マージの際はissueのナンバーをコメントに入れている。これでGithub上のリンクとして働いてくれるので便利。
参考:Gitコミットメッセージの7大原則 - rochefort's blog
マージ後
作業ブランチを消して、ローカルのmasterを最新化する。
マージにはgit merge
を使用し、git rebase
は使わないことにしている。そもそもrebase
完全に理解してないというのもあるが、要するに歴史改変にあたるような操作があまり好めないというのが強い。個人の開発においては作業ブランチの変更中にmasterに更新が入ることは少ないので、このやり方でおそらく不都合はしないと思っている。
$ git checkout master
$ git branch -a
$ git branch -d dev_hoge
$ git push --delete origin dev_hoge
$ git fetch
$ git marge origin/master
参考 GitのRebaseによるBranchの運用 | Developers.IO git pull と git pull –rebase の違いって?図を交えて説明します! | KRAY Inc
コンフリクトした場合
git ls-files -u
でコンフリクトしたファイルが一覧化されるとのことなので、確認の上で開いて直す。もしローカルかリモートのいずれかを全面採用するのであれば、git checkout
の--ours
と--theirs
オプションを使う。
git ls-files -u
git checkout --ours hoge
git checkout --theris hoge
参考:Gitでコンフリクトした時のための備忘録 - アジャイルSEを目指すブログ
リモートのmasterがローカルより先に行っている場合
ローカル環境が複数あるので、このような場合は多々ありえる。そういうときは基本的にはmergeすればいいだけではあるが。masterはリモートレポジトリの最新化が原則となるので、コンフリクトした場合は99%リモートを優先させる。
git show-branch --all --color
git fetch origin
git diff origin/master
git merge origin/master
参考:gitのリモートリポジトリの更新を確認する - Qiita
バグ、開発課題の発生
先に少し触れたが、開発すべきTODOはすべてGithub issueで管理することにした。今までどうしていたかというと特に管理はしておらず、思いつくままに開発してしまっていたのだが、これでGithubに開発に必要なものはすべて集約できるのではないかと思う。個人でのGithub issue運営には下記の記事を参考にさせてもらっているが、特に難しいことはせず、タスク管理ツールのような形で使っている。
覚えられない
Github Flowは便利なのだが、Gitのコマンド体系がどうにも覚えづらくて仕方がない。どうにもならんのでaliasを駆使してなるべく覚える内容を少なくしようと努めているが、あとは慣れるしかないのかなぁと。Githubのコマンドは本当に多い。体系自体を学ぶのであればPro Gitがわかりやすく、epubの配布もあるのでKindleでいつでも読めて最高なのだが、数多あるコマンドを網羅しようとか思うとこれだけではつらい。Qiitaでまとめ記事が上がるたびに覗いてみて、今の自分のキャパで使えそうなのをつまみ食いしていく形で覚えればいいのかなと思っている。
今のalias設定はこんなの。
[alias]
a = add
aa = add --all
br = branch
bra = branch -a
brd = branch -d
co = checkout
cob = checkout -b
coo = checkout --ours
cot = checkout --theirs
cl = clone
clr = clone --recursive
cm = commit
cmm = commit -m
d = diff
f = fetch
lg = log
lga = log --graph --decorate --online
lgp = log -p
mg = merge
mgn = merge --no-ff
ps = push
psd = push --delete origin
pso = push origin
psm = push origin master
pl = pull
s = status -s
sb = status -s --branch
ss = status
sh = show
sba = show-branch --all
今後
やりたいこととしてはCI。Circle CIとかと連動させて自動テストしたりというところまで組み込めたら、個人開発としてだいぶ理想的な状態かなと思う。そのままデプロイまで自動化できれば最高か。またGitの理解がやはりどうにも覚束ない部分があり、まだまだ使いこなせているとは言いがたいので、aliasをカンペ代わりに育てつつ、ガンガン覚えていきたい。特にミスったときのreset
系コマンドがあまりに多くてなぁ……。