Shoichi Matsuda's diary

このブログは移転しました。 https://shoma2da.net/ が新しいブログです。

アプリ開発にはGitlab flowが合うと思います

はじめに

みなさまのプロジェクトではどのようにバージョン管理を行っているでしょうか。
ここでのバージョン管理とは具体的にはどのようなブランチを作ってどこにマージするか、リリースはどのように進めるかといった事柄を指しています。

今日は数あるバージョン管理戦略の中で比較的新しく提唱されたGitlab flowというフローを中心にして話していきたいと思います。
最近アプリの開発においてこのGitlab flowが個人的には一番しっくり来ているのでオススメしたいです。

有名なフロー

gitは分散型のバージョン管理システムとして一世を風靡しており、いまや事実上のデファクトスタンダートです。
名前のとおり分散している(ローカル・リモートが明確に分かれている)ことやブランチ・コミットの編集も非常に容易で柔軟性が非常に高いです。
一方でその柔軟さゆえにルールをきちんと決めなければ各個人のフローが大きく異なって混乱を生んでしまうこともあるでしょう。

こうした問題に対して有名なものとして git flow と GitHub flow といった2つフローが提唱されてきました。
それぞれについて簡単に見ていきます。

git flow

git flowは古参なバージョン管理戦略の一つです。
git-flow cheatsheetでこのフローを実現するためのコマンドも配布されていたりします。

f:id:shoma2da:20151104220344p:plain
A successful Git branching model » nvie.com

git flowでは以下のようなブランチを使用します。

  • master - リリース済みのバージョンをここで管理する。タグ付けもこのブランチで行う。
  • development - 開発の中心となるブランチ。普段のPull Requestのマージ先はここ。
  • hotfixes - リリース内容に問題があった場合に緊急対応を行うためのブランチ。
  • release branch - リリース準備用のブランチ。
  • feature branches - 開発作業を進めるためのブランチ。
メリット

git flowのメリットは管理が他のどのフローよりもしっかりしていることだと思います。
役割ごとに明確に使うタイミングや意図が分けられているためコミットツリーを見ることでどのように作業が進んだかを俯瞰して把握しやすいでしょう。

デメリット

一方で控えめに言ってもgit flowはかなり複雑であると言えるでしょう。
ブランチの種類が多いことやその開始地点やマージ先が多岐にわたっています。
毎回上記の図を見ながら作業できれば良いですが実際にはそうはいきません。
一度目を離すとどれが何を表していたかを思い出すことは至難の技でしょう。

GitHub flow

もう一つの有名な戦略であるGitHub flowを見ていきましょう。
このGitHub flowは他のどのバージョン管理戦略と比較しても最も単純でしょう。

f:id:shoma2da:20151104223339p:plain

端的に言うとmasterブランチとそれ以外、という2パターンの種別でブランチを管理します。
masterから派生したブランチで作業をしてmasterにマージする、ただそれだけです。
(図中のオレンジ色のブランチはrebaseした方が良いといった話もあるかもしれませんが今は細かいところは触れません。)

メリット

特にサーバサイドとの親和性が非常に高いように思います。
CIと絡めて「masterにマージするたびにデプロイ」といった運用も取れるので、うまくすればリリース作業そのものからほぼ解放されそうです。

デメリット

リリースのタイミングを調整したい場合は不向きではないでしょうか。
例えばアプリの場合は1つの作業単位ごとにリリースをするとも限らないのでどのブランチでリリース準備をすれば良いのか迷ってしまいます*1
また、サーバサイドであっても例えば環境(ステージング環境、QA環境、広告配信テスト環境などなど)を分けてデプロイしたい場合はデプロイタイミングとブランチとの結びつきが不明確になってしまうでしょう。

Gitlab flow

それではGitlab flowです。

例1:
f:id:shoma2da:20151104225147p:plain
出典:GitLab Flow | GitLab

例2:
f:id:shoma2da:20151104225155p:plain
出典:GitLab Flow | GitLab

Gitlab flowはイメージとしては「GitHub flow + リリースに必要なブランチ」です。
masterブランチでリリースに向けた作業が終わった段階で上記図のようにproductionブランチやpre-productionブランチにマージを行いリリースの調整やリリース作業を行います。

図では省略されていますがmasterブランチに対する変更はGitHab flowと同じようにPull Requestをする形で気軽に行いましょう。

メリット

リリースに対してかなり柔軟に対応できます。
上記の図のpre-productionブランチ / productionブランチのように徐々に本番に近づけていくような形もブランチで可視化しながら進めることができます。
環境が増えるようであってもブランチを一つ足すだけで済むでしょう。
これはアプリであっても同じでリリースapk作成用、Apple審査対応用、社内配布用、本番用といった環境やリリース段階に応じた柔軟な運用ができます。

また細かい話ではありますが作業のマージ先はGitHub flowと同じく常にmasterブランチです。
git flowのような戦略を取っているとどうしても操作ミスで意図していないブランチにPull Requestを送ってしまうのですが、そうした心配もかなり少なくなります。

そのほか常にリリース関連のブランチは常に存在しているのでそれぞれに応じたCIも設定しやすいでしょう。

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

チーム開発実践入門 ~共同作業を円滑に行うツール・メソッド (WEB+DB PRESS plus)

まとめ

バージョン管理戦略の中で最近お気に入りのGitlab flowについて他の戦略と比較しながら紹介しました。
リリースまで含めた作業を考慮しやすいGitlab flowはアプリの開発においても適合しやすいのではないかと思います。

最後に、この記事ではGitlab flowをおすすめしましたが当然のことながらバージョン管理戦略に正解はないです。
実際の現場でのリリースや開発の進め方をよく考えた上でどのフローを選ぶか、選んだフローをどうカスタマイズしていくかはその時々考える必要があるでしょう。
提唱されている戦略の形にとらわれすぎずに効率よくかつ気分よく作業できることを目指しましょう!

*1:masterでそのままリリースを作業を行う方法もありますが、リリースしたコミットの確認をタグでしか行えなくなってしまいコミットツリーから判断しづらくなってしまいます

GitHubを使ってるならhubコマンドを使うべし

前回の「今さら聞けないgit pushコマンド」に続きGitネタです。
今日はGitHubを使う全てのユーザの方におすすめしたいhubコマンドを紹介します。

hubコマンドとは

GitHub社が公開しているコマンドです。
リポジトリはこちら。https://github.com/github/hub

gitコマンドをラップしていて、GitHub上の操作をCUIから行うことができるようになります。

導入

導入はとっても簡単です。

インストール

Homebrewならコマンド一発です。

$ brew install hub

alias設定

hubを直接打たなくても良いようにgitにaliasします。(.bash_profileなどに記載してください)
hubgitをラップしているので今まで素のgitで使っていたコマンドは全て使えます。

eval "$(hub alias -s)"

いきなりコマンドを置き換えるのが少し気持ち悪い方はやらなくても良いでしょう。hubって直接打てばいいだけですし。

特に便利なコマンド

hubには独自のコマンドがかなりたくさん用意されていますが、個人的に好きなコマンドを紹介していきます。
alias設定している前提でコマンドを載せています。alias設定していない場合はgithubに置き換えて実行してください。

GitHub上のリポジトリを見る

現在のリポジトリをGitHubで見ます。 地味に一番便利かもしれません。

$ git browse

Pull Requestを出す

普通はGitHubのWebページでPull Request操作をすると思いますが、これもhubコマンドで一発です。
今回は省略しますが、オプションを使ってマージ先の選択やissueとの関連付けなどもできます。

$ git pull-request #現在のブランチからmasterへのPull Requestを作成

cloneする

素のgitコマンドでは完全なURLを指定してcloneしますが、hubではかなり省略した書き方ができます。

$ git clone github/hub

#自分のリポジトリなら更に省略できます。
$ git clone myrepo

Pull Requestから直接checkout

Pull Requestを出しているブランチを直接チェックアウトできます。 こちらも地味にかなり便利。

$ git checkout https://github.com/defunkt/hub/pull/73

Pull Requestをマージ

Pull Requestをマージできます。
checkoutやこれもマスターすれば、GitHubを開くことはかなり少なくなると思います。

$ git merge https://github.com/defunkt/hub/pull/73

GitHub上でdiffを表示

GitHub上でdiffを見ることができます。
このコマンドに関してはdiffではなくてcompareなので少し覚えづらいのがつらいところです。

$ git compare before_branch..after_branch

GitHub Enterpriseを使ってる人は

ホストをデフォルトのgithub.comから変更しましょう。(なかなかいないとは思いますが...。)

$ hub config --global hub.host hostname

$ hub config --list --global #設定を確認

今さら聞けないgit pushコマンド

id:koogawaさんのgitの記事を読みました。
これを読んでそういえばみんな知ってるのかなと思った点があるので書いておきます。

取り上げるのはgitのpush周りのお話です。
(これ以降の記事中のリモートは全てoriginとします。)

このコロンは何??

リモートブランチの削除で以下のようなコマンドを実行すると思います。

git push origin :hoge

コロンが付いていますがこのコロン正体、正しく説明できますか?

実用Git

実用Git

  • 作者: Jon Loeliger,吉藤英明(監訳),本間雅洋,渡邉健太郎,浜本階生
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2010/02/19
  • メディア: 大型本
  • 購入: 7人 クリック: 287回
  • この商品を含むブログ (44件) を見る

pushコマンドの実体

普通、ローカルブランチをリモートに反映する際のコマンドはこんな感じです。

git push origin hoge

実はこのコマンド、省略されていることをご存知ですか??
省略される前のコマンドは以下のとおりです。

git push origin hoge:hoge

コロンが出てきました!!これはどういうことなのでしょうか。


実は以下のような意味になります。

ローカルのhogeブランチをリモートのhogeブランチにpush!です。

コマンドに落としこんでみましょう。

git push {ローカルのhoge}:{リモートのhoge}

2ヶ所あったhogeは前者がローカルブランチ、後者がリモートブランチです。
git push origin hogeはリモート・ローカルのどちらもhogeを指定する、という省略した書き方だったのです!)

これさえわかれば、例えばこんなことも。

git push origin master:test

ローカルのmasterブランチをリモートのtestブランチにpushしています。

ローカル作業中に間違えてmasterブランチでコミットしていた!といった場合に使えそうです。
(ローカルでブランチ整理してからpushするほうが安全そうではありますが...)

でブランチの削除って結局...?

では最初のリモートブランチ削除コマンドをもう一度見てみましょう。

git push origin :hoge

ここまでを理解していただいていればピンとくるのではないでしょうか。

そうです。実はこのコマンド、以下のような指定です。

git push origin {何もない!}:{リモートのhoge}

「何もないものをリモートのhogeにpushする = hogeの存在を何もないものにする = hogeを削除」です。

スッキリですね!!