肉とビールとパンケーキ by @sotarok

少し大人になった「肉とご飯と甘いもの」

2011年、今年変わったもの sotarok 版

毎年この時期に、今年のまとめ記事とか書こうと思ってだいたい面倒になって書かないで終わるので、今年はなんとなくちゃんと書いてみようかと思います。

テーマは、今年変わったもの、です。僕にとって変わってものもあれば、世の中的に変わったものもあるかもしれません。そのへんは割りと適当です。

ガラケーiPhone

これは今年のはじめですが、僕もいよいよ iPhone にしました。遅いって?遅いですよね。
ガラケーでもGoogle Maps見れるし、メールもできるし、なによりケータイサイトが見れるし、アプリもそこまで必要でもないじゃろ、と思っていた割りとずっと必要ないと思ってたんですが、特に、Facebook のようなものは、写真をばしばし投げたい、スマホで見たい、と思い始めたのがきっかけで、ついに iPhone4 を買いました。

それにともない、以下のような変化も。

  • モバイルで Twitter: movatter → iPhoneTwitter 公式アプリ
  • 携帯で写真: ほとんどとらない → iPhone でよく撮る
  • 一眼レフ: いつも持ち歩いてた → ちょっとしたことの場合はもち歩かなくなった
  • 出かける先の地図とか: 事前に調べてケータイにURL送ってた → 移動中とかに調べるようになった
  • 持ち歩きでアニメ: iPod で小さい画面で見てた → iPhone で見るようになった
  • 位置情報の記録: とくになにもしてなかった → Facebook やら、最近だと Path やらで色々チェックインするようになった

その他小さな事が様々変わったと思います。音楽とかは相変わらず容量が足りないので iPod Classic で聞いてます。
やっぱり、ネットに張り付いて生活しているので、iPhone だと、Macの前から離れるときでも、シームレスな感じがします。(まぁ、それが良いことかどうかはよくわかりませんが)

mixiFacebook

オフライン、リアルな友達とのやりとりはほとんど Facebook になりました。特にここ2~3ヶ月、高校や大学の友人も次々と Facebook を始め、あらゆるコミュニケーションがとりやすくなったし、飲み会の調整コストも下がりましたね。
人が増えまくったらまた別の問題も発生するんだろうけど、今のところ、リストを上手いこと管理することで、昔よくあった、人と繋がりすぎてプライベートなことがつぶやけなくなった〜的な問題は、今のところ僕には発生していません(ま、リストを真面目に管理するって人はそんなに多くないとはおもいますが)

位置情報、写真の共有、メッセージのやりとりのすべてがやりやすくなった気がします。

1つあるとすれば、mixi にあった日記のような、フローではないストック型のひとまとまりの文章を共有する場所がなくなりましたね。mixi でみんなの日記をたまに見てまわるのは好きだったのですが。

グリー → クロコス

完全に個人の話ですが、転職しました。

転職に際しては、自分の中でも迷いがありました。当時もブログに書きましたが、絶賛成長中のグリーでの仕事はアプリ系のインフラとしてフレームワーク作ったりとかしていたので、それはそれでめちゃくちゃ楽しかったし、様々な課題がそこら中に転がっていたし、なにより、尊敬できるエンジニアが回りにたくさんいて、エンジニアとして働く環境としては、自分にとっては非常に良い場所だったからです。

でも、去年の12月に岡元さん、小澤さんと出会い、これほどの機会は、今後ほとんど無いんだろうな、と考えた時、自分が後悔しないためには、とりあえずやってみるしかないっしょ、と思い、会社をつくり、参画することを決めました。

会社を移ってから半年ですが、まだまだスピード感が足りないとか、足回りが整ってないとか色々ありつつも、自分たちでサービスをつくりそれをどうやって広めていくか、使ってもらうか、今後それをビジネスにしていくかを必死に考え、とにかく手を動かすことはできたのではないかと思います。
今年はまだまだ荒削りでざっくり前に進んできた感があるので、来年はより具体的に自分たちの成長路線を定めて、変わらず手を動かしつつ、新しいことにチャレンジしていこうと思います。

それにともなって変わったものは、もう書き切れないですね。とにかく、ひとつ言えるのは、人付き合いの幅が広くなったと思います。
来年も、よりよい変化を起こしていきたいと思います。

その他よく使うようになったツールとかサイトとか変わらないものとか

  • Twitter : まあ、ずっと、息を吸うように使っている
  • Path: 最近よくつかう
  • Speaker Deck: SlideShare から移った
  • Sparrow: メーラ。Thunderbird から移った。
  • Alfred: ランチャ。Spotlight/QuickSilverから移った。
  • Lion: Mac OSSnow Leopard から移った。
  • 変わらないもの: Twitter, vim, Opera, はてダ, Red Bull

あと、Facebook のタイムラインによると。

  • Facebook上で増えたともだち: +222人
  • いいね: +278
  • スポット: 382チェックイン

開発の話

ちょっと細かい話。

SVN → Git

いや、これ必ずしも今年というわけではないですが、個人的には 2008 年あたりから移りつつ合った Git ですが、Ethnaリポジトリ、会社のリポジトリ、自分の周りの環境はあらゆるものが Git になりました。SVN を使っている環境はほとんどもう触れないため svn コマンドは忘れたほどです。

Git にして、開発スタイルもあらゆる面で変化しました。

  • とりあえずコミットできる
  • とりあえずブランチを切れる
  • ローカルでもオフラインでもどこでも開発できる、コミットできる
  • 歴史をどうにでもできる
  • 他人との開発で patch のやりとりが簡単にできる
FirefoxGoogle Chrome (Canary)

Google Chrome の開発者ツールは、昔一度使ってみたもののいまいち慣れなくて Firebug を愛用していたためずっと開発用ブラウザは Firefox だったのですが、ふと Google Chrome の Canary を開発用ツールとして使い始めたら、だいぶ使いやすくなっているし機能も圧倒的に良いし軽いしってことで、開発用ブラウザは Google Chrome Canary になりました。

そんなわけで

変わったもの、変わらないもの、色々ありますが、来年は何がどう変わるか、楽しみですね。僕も、自分/自分たちのチカラで、自分のこと、自分の周りの人のことを、良い方向に変えていけたらいいなあと思います。

みなさま今年も大変お世話になりました。

良いお年を!

PHP Apocalypse で発表してきました #phpapoc

PHP - Be Happy with PHP というタイトルで発表してきました。PHPというか、なんとなく、PHP全般とか、チーム開発とか、開発全般とかの話です。



※スライドだけ見ても全然伝わらない風の発表でしたね

今後の話とか、その他のまとめ

  • 今回の発表は、今、僕が感じていることであって、今後僕はまたいろんな壁にあたったり乗り越えたり挫折したりしながらきっと成長していく(つもり)ですし、その時に何考えてるのかはわかりませんし、未来の僕がこのときの自分を振り返ってあの頃はガキだったな、と思うことは多分ありますし、まぁそうでないといけないですし、などなど色々あります。
  • なので、そういった意味でも、最初のお断り通り、この話をどう受け取るかは聞いてくださったみなさん次第です。まぁそもそもまとまってないですが。
  • @koriyam さんの話はとても共感できるものでした。僕の話まとまらなかったけどとってもまとまっていて素敵な発表でしたね。
  • 最後に、いろいろまとめてくれた @tsuyoshikawa、会場運営のカトーくん、会場貸してくださったグリーさん、ありがとうございました。

git add -p のときの e(手動編集)

自分ではあまり add -p の e ってつかったことなかったんだけど友達がよくわからんってことだったので調べてみた。

以下のような diff を add -p して、 e してみます。

$ git add -p
diff --git a/fuga b/fuga
index 1a39df0..5bc676d 100644
--- a/fuga
+++ b/fuga
@@ -1,5 +1,5 @@
 //
 hoge
-fuga
 piyo
 hogera
+fugera
Stage this hunk [y,n,q,a,d,/,s,e,?]? e


で、エディタが起動するわけです。以下のような感じで書いてあります。

# Manual hunk edit mode -- see bottom for a quick guide
@@ -1,5 +1,5 @@
 //
 hoge
-fuga
 piyo
 hogera
+fugera
# ---
# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.
#
# If the patch applies cleanly, the edited hunk will immediately be
# marked for staging. If it does not apply cleanly, you will be given
# an opportunity to edit again. If all lines of the hunk are removed,
# then the edit is aborted and the hunk is left unchanged.

ここで出てくる謎のメッセージ(いや、謎でもないんだけど)

# To remove '-' lines, make them ' ' lines (context).
# To remove '+' lines, delete them.
# Lines starting with # will be removed.

これの意味がわかりづらいですね。先に結論を言うと、

  • - の行を add したくなかったら - を スペース (' ') にかえてください
  • + の行を add したくなかったらその行を削除してください
  • # から始まる行は、add されません

ということなんですが、'delete' が hunk からの削除 = diff からの削除、つまり、add する patch に含めない、つまり、add しない、ということです。

読み替えると、

  • 削除行 (-) を add しないなら、- をスペースにかえてください
  • 追加行 (+) を add しないなら、その行を削除してください
  • add したくない行は先頭に # って書いてください

ですかね。

実際にやってみる

エディタ上で、次のようにしてみます。 (- を ' ' に変更)

# Manual hunk edit mode -- see bottom for a quick guide
@@ -1,5 +1,5 @@
 //
 hoge
 fuga
 piyo
 hogera
+fugera

で、エディタを閉じると、次のようになります。

$ git status
# On branch master
# Changes to be committed:
#
#       modified:   fuga
#
# Changed but not updated:
#
#       modified:   fuga

$ git diff
diff --git a/fuga b/fuga
index 387b231..5bc676d 100644
--- a/fuga
+++ b/fuga
@@ -1,6 +1,5 @@
 //
 hoge
-fuga
 piyo
 hogera
 fugera

$ git diff --cached
diff --git a/fuga b/fuga
index 1a39df0..387b231 100644
--- a/fuga
+++ b/fuga
@@ -3,3 +3,4 @@ hoge
 fuga
 piyo
 hogera
+fugera

hunk から削除した「fugaの行の削除」という diff が add されてないですね。

つまりそういうことでした

まぁわかってしまえば簡単ですが最初はよくわからないかも。
+ の行の削除とかも、気になったら試してみてね。


多分自分では add -p の「e」は使わないと思うけどw

Redmine で Wiki 内に画像っぽいリンクが含まれていたら画像に展開する

世間ではアドベントカレンダーが大流行の昨今ですがちまちまRedmineネタとかなんですけど皆様いかがおすごしでしょうか。

なんでこれてブログ書こうと思ったのかわからないほどの小ネタだけど、こういうネタを適当にブログに書いていくということは大切だと思いました。
最近適当にTwitterとかでつぶやいて満足してしまっていますね。

Redmine の Wiki に画像っぽいリンク

Wiki、というか、チケットの説明文本文とかなんですけど。
チケットに画像の添付とかって、もはや面倒じゃないですか。

スクリーンショットとって、それをローカルに保存して、チケット作成画面から、アップロードとか...

そんなものは最近でいうと、Gyazoとか、社内用Gyazo とかで URL で投げ合っているので、ぱっと撮ってぱっと張る、が一番楽だとおもうのです。
というわけで、 ****.png とかがチケットの説明文にあったら、img タグにしてほしいなーとおもいました。

theme の JavaScript を読みこませる

このへんのことよしなにやってくれるプラグインがあると良いのかもしれないけど、いやプラグインとか面倒だしそんなもの JavaScript でいいよねってことで、theme の JS に仕込んでしまうことにします。
久々に Prototype.js 使いました。相変わらず Prototype 拡張しまくってますね!

theme 用の JavaScript は、バージョン 1.?? から、 theme のディレクトリの javascripts/theme.js に置けば読み込んでくれるようになったらしいので、そのファイルを作ります。
で、その中に↓みたいなかんじのことを書いておきます。自分で適当に枠とか CSS をあてたかったので、class も指定しておきました。

document.observe("dom:loaded", function(){
    $$('#main div.wiki a').each(function(name, index){
        var link = name.readAttribute('href');
        if (link.match(/\.(gif|jpg|jpeg|png)$/i)) {
            var imgElm = new Element('img', {src: link, 'class': 'wiki-image'});
            name.insert({
                after: imgElm
            });
        }
    });
});

中身がないので以上

すごく小さなことですが、これだけで相当便利になりました!めでたし

Ethna 2.6.0 beta3 リリース

以前のリリースからまた少し空いてしまったのですが、PHPカンファレンスでの宣言を実現すべく、2.6の開発を進めています。
で、2.6 beta3 リリースしました。


Ethna 、ついこないだ GitHub に移行したんですけど、その直後から Pull Request たくさんいただいてて、いやまじ GitHub すげーなというか本当ありがとうございますというかんじです、GitHub に移して少し patch のやりとりがしやすくなるといいな程度の考えだったんですが、まさかこんなに活発になるとは思いませんでした、GitHub すごいです。

で、beta3 は、まあ色々細かいアップデートがかかってるんですが、まぁそこは CHANGES をご覧いただくとして、環境周りで、

と、移行したりしてました。GitHub バンザイ。


というかんじでひきつづきがんばってまいります。
とにかく、フィードバック、Pull Request くださったみなさんありがとうございます。beta3 でもどうか人柱になりどんどんバグ報告などをいただけると嬉しいです。

#pyfes で git-daily について話してきました

git-daily について #pyfes で話してきました。


Webアプリケーション開発におけるGitのブランチ運用戦略についての話です。
パッケージものの開発などと大きく異なるのはやはりリリース頻度や、リリース環境です。デプロイサーバが登場するとかもそういうことですね *1

ちなみにこのへんの、概要的な話は、GREEのころエンジニアブログにも書きましたので、そちらを参照ください。

発表資料

SpeakerDeck におきました (はてなに埋め込めるようにならないかなー)

demo の内容

demoはコマンドの切り替えが速すぎて流れが読めない的な感じになってしまってすみません。良い機会なので、図と一緒にまとめようかと思います。

前提とストーリー

以下の話はgitflowのブランチモデルを採用したgit-dailyでのリリース作業のフローですね。


前提:

  • 開発者A (a_dev) さんと開発者B (b_dev)、deployサーバ(deploy)、Gitリポジトリサーバ(server)がいます
  • Gitサーバは、GitHub でも gitosis でも代わりません。bareリポジトリを保持していてアカウント管理されているリモートのサーバだと思ってください
  • deployサーバで、リリースマネージャ的な人が、リリースブランチ切ったりmasterにマージする人だったりします。

ストーリー:

  • Aさんがリポジトリを作成し、serverにそれをcloneします
  • Aさん、Bさんはdevelopブランチで開発を進めます
  • developブランチの開発がある程度まとまってリリースしたいという状況になります
  • deployサーバで、リリースマネージャ的な人がリリース作業を開始します。
  • リリース前に、修正が必要なことがわかりました。Bさんが手元で修正してリリースブランチにpushします。
  • 修正が完了し、リリースブランチをproductionにデプロイしました。その後、deployサーバでreleaseを閉じる作業をします。
  • 各開発者は、syncすることでremoteで閉じられたリリースブランチを、ローカルから掃除します。


※コマンドのログ中にある右に出てるのはRPROMPTです。ディレクトリ名とかブランチ名が出てます。

リポジトリの作成とserverへのclone

まず基本的なところですが、Aさんがリポジトリを作成してserverにcloneします。serverにclone するところですが、serverやら、Bさんの開発環境などは、すべて別のサーバにある前提です。
今回は、demoシミュレーションについては、同じサーバ内でやりますが、ディレクトリがそれぞれの開発環境/サーバに対応すると思ってください。また、RPROMPTにディレクトリ名出しておくので、cd とか書いてないのにディレクトリ移動してる場合とかはそっちを見て判断してください(とかいう)


デモに用いるディレクトリ。最初は空です。

% ls -la                                             [~/tmp/gitdaily-demo]
合計 8
drwxr-xr-x  2 sotarok sotarok 4096 2011-10-15 16:10 .
drwxr-xr-x 50 sotarok sotarok 4096 2011-10-15 13:59 ..

Aさんがリポジトリを作成

% mkdir a_dev                                        [~/tmp/gitdaily-demo]
% cd a_dev                                           [~/tmp/gitdaily-demo]
% git init                                       [tmp/gitdaily-demo/a_dev]
Initialized empty Git repository in /home/sotarok/tmp/gitdaily-demo/a_dev/.git/
% touch README                           [tmp/gitdaily-demo/a_dev @master]
% git add README                         [tmp/gitdaily-demo/a_dev @master]
% git commit -m "initialize"             [tmp/gitdaily-demo/a_dev @master]
[master (root-commit) d7a313d] initialize
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README

これでリポジトリが作成されました。今回は、gitosisなどを用いないため、server というディレクトリ名でmirrorを作成します。--mirrorは、bareリポジトリとしてcloneするという意味です。

% git clone --mirror a_dev ./server                  [~/tmp/gitdaily-demo]
Cloning into bare repository ./server...
done.
% ls server                                          [~/tmp/gitdaily-demo]
HEAD      config       hooks  objects      refs
branches  description  info   packed-refs

Aさんがこれをoriginとしてremoteに追加します。これで、なんとなくGitHub <-> 開発者、とか、社内のGitサーバ <-> 開発者、の関係性がイメージ出来る状態になったと思います。

% cd a_dev                                           [~/tmp/gitdaily-demo]
% git remote add origin ../server        [tmp/gitdaily-demo/a_dev @master]
% git remote                             [tmp/gitdaily-demo/a_dev @master]
origin
% git fetch origin                       [tmp/gitdaily-demo/a_dev @master]
From ../server
 * [new branch]      master     -> origin/master
% git branch -a                          [tmp/gitdaily-demo/a_dev @master]
* master
  remotes/origin/master
developブランチの作成とBさんの開発への参加

develop ブランチは master ブランチからの派生で作ります。また、それをoriginにもpushします。

% git branch -a                          [tmp/gitdaily-demo/a_dev @master]
* master
  remotes/origin/master
% git checkout -b develop                [tmp/gitdaily-demo/a_dev @master]
Switched to a new branch 'develop'
% git push -u origin develop            [tmp/gitdaily-demo/a_dev @develop]
Total 0 (delta 0), reused 0 (delta 0)
To ../server
 * [new branch]      develop -> develop
Branch develop set up to track remote branch develop from origin.

続いて、Aさんのローカルで、git daily initしておきます。masterとかどうする?とか聞かれますが、ここで他のブランチ名を指定することも可能です。何も入力しなければ、デフォルトです。

% git daily init                        [tmp/gitdaily-demo/a_dev @develop]
Your remote is [origin]
Name master branch [master]:
Name develop branch [develop]:

git-daily completed to initialize.

続いて、Bさんの環境も整えます。Bさんは、最初から server から clone してきます。また、git daily init もしておきます。

% git clone server ./b_dev                           [~/tmp/gitdaily-demo]
Cloning into ./b_dev...
done.
% cd b_dev                                           [~/tmp/gitdaily-demo]
% git log                                [tmp/gitdaily-demo/b_dev @master]
commit d7a313d863aa1938d4aff0caf43460e30562ffb7
Author: Sotaro KARASAWA <sotarok@crocos.co.jp>
Date:   Sat Oct 15 16:11:16 2011 +0900

    initialize

% git daily init                         [tmp/gitdaily-demo/b_dev @master]
Your remote is [origin]
Name master branch [master]:
Name develop branch [develop]:

git-daily completed to initialize.

% git branch -a                         [tmp/gitdaily-demo/b_dev @develop]
* develop
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master

また、deployサーバという位置づけで、 deployというディレクトリにも clone を作って git daily init しておきます。(結果省略)

% git clone server ./deploy                          [~/tmp/gitdaily-demo]
% cd deploy                                          [~/tmp/gitdaily-demo]
% git daily init                        [tmp/gitdaily-demo/deploy @master]
% git branch -a                        [tmp/gitdaily-demo/deploy @develop]
* develop
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master


ここまでの状況を図にすると以下のようなかんじです。(a_dev意外のリポジトリ内部の構成は省略)

リリースしたい状況、deployサーバでrelease作業の開始

developブランチで開発がすすめられてしばらくたったとしましょう。リリースしても良いかな、と思える状況になったとします。

以下はAさんの手元のdevelopブランチです。開発中、originへのpush/pullは適宜行われているものとします。この例では、--decorateしてみてmasterから、開発が2コミット分進んでいることがわかります。

% git log --oneline --graph --all --decorate
* efbe37b (HEAD, origin/develop, develop) modify comment
* 107be63 added sample
* d7a313d (origin/master, master) initialize

さて、deployサーバで、リリースマネージャ的な人が、release openします。現在は、まだ一番最初にcloneしただけの状態です。

% cd deploy                                          [~/tmp/gitdaily-demo]
% git log --oneline --graph --all --decorate         [~/tmp/gitdaily-demo/deploy @develop]
* d7a313d (HEAD, origin/master, origin/develop, origin/HEAD, master, develop)

git daily release open すると、日付でreleaseブランチが作成され、自動的にremoteにpushされます。あ、ちなみに最新のdevelopがremoteから取得された後openされます。

% git daily release open               [tmp/gitdaily-demo/deploy @develop]
[INFO] first, fetch remotes
Confirm: create branch release/20111015-1635 from develop ? [yN] : y
[INFO] merge develop branch from remote
[INFO] create release branch: release/20111015-1635
[INFO] push to remote: origin
To /home/sotarok/tmp/gitdaily-demo/server
 * [new branch]      release/20111015-1635 -> release/20111015-1635
release opened

% git branch -a          [tmp/gitdaily-demo/deploy @release/20111015-1635]
  develop
  master
* release/20111015-1635
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/release/20111015-1635

% git log --oneline      [tmp/gitdaily-demo/deploy @release/20111015-1635]
efbe37b modify comment
107be63 added sample
d7a313d initialize

この状態で、デプロイサーバから、stagingサーバなどへdeployし、確認作業などをするわけですね。以下では、たとえば capistrano (いや実際設定とか作ってないけど)

% cap staging deploy     [tmp/gitdaily-demo/deploy @release/20111015-1635]

ここまでを図にすると以下のような感じです。

releaseブランチ上で修正作業

さて、staging環境などでテストをしていたら、このままではリリースできない、修正したいなー、という状況が発生しました。
この修正はBさんが担当することにします。

Bさんは、最初、release ブランチをローカルにもっていません。remoteにしかない状態ですね。

% git branch -a                         [tmp/gitdaily-demo/b_dev @develop]
* develop
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/release/20111015-1635

ここで、git daily release sync します。すると、remoteにあるreleaseブランチがローカルのブランチとしてチェックアウトされます。

% git daily release sync                [tmp/gitdaily-demo/b_dev @develop]
[INFO] first, fetch remotes
[INFO] cleanup remote
[INFO] checkout and tracking release/20111015-1635
Switched to a new branch 'release/20111015-1635'
Branch release/20111015-1635 set up to track remote branch release/20111015
-1635 from origin.
start to tracking release branch

% git branch -a           [tmp/gitdaily-demo/b_dev @release/20111015-1635]
  develop
  master
* release/20111015-1635
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/release/20111015-1635

修正作業をし、コミットしたらもう一度 sync することで、push されます。ログを確認すると、ローカルのほうが1つだけコミットが進んでいる状態ですね(releaseブランチに、1つ修正コミット)

% git status              [tmp/gitdaily-demo/b_dev @release/20111015-1635]
# On branch release/20111015-1635
# Your branch is ahead of 'origin/release/20111015-1635' by 1 commit.
#
nothing to commit (working directory clean)

% git log --oneline --decorate
aba974f (HEAD, release/20111015-1635) fixed: not PHP but Python
efbe37b (origin/release/20111015-1635, origin/develop) modify comment
107be63 added sample
d7a313d (origin/master, origin/HEAD, master, develop) initialize

% git daily release sync  [tmp/gitdaily-demo/b_dev @release/20111015-1635]
[INFO] first, fetch remotes
[INFO] cleanup remote
[INFO] git pull
[INFO] run git pull origin release/20111015-1635
From /home/sotarok/tmp/gitdaily-demo/server
 * branch            release/20111015-1635 -> FETCH_HEAD
Already up-to-date.
pull completed
[INFO] git push
[INFO] run git push origin release/20111015-1635
To /home/sotarok/tmp/gitdaily-demo/server
   efbe37b..aba974f  release/20111015-1635 -> release/20111015-1635
push completed

これで release ブランチの修正が完了したので、deployサーバで再度 sync してその修正を取得し、再度stagingなどにdeploy、確認作業などをします。

% git daily release sync [tmp/gitdaily-demo/deploy @release/20111015-1635]
[INFO] first, fetch remotes
[INFO] cleanup remote
[INFO] git pull
[INFO] run git pull origin release/20111015-1635
From /home/sotarok/tmp/gitdaily-demo/server
 * branch            release/20111015-1635 -> FETCH_HEAD
Updating efbe37b..aba974f
Fast-forward
 sample.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
pull completed
[INFO] git push
[INFO] run git push origin release/20111015-1635
Everything up-to-date
push completed

% cap staging deploy     [tmp/gitdaily-demo/deploy @release/20111015-1635]

ここまでを図にすると以下のような感じです。

確認が完了し、リリース作業を終了します

statingで確認が完了し、productionにデプロイします。

% cap production deploy  [tmp/gitdaily-demo/deploy @release/20111015-1635]

deployサーバで、release close します。まずログ確認。

% git log --oneline --decorate --graph
* aba974f (HEAD, origin/release/20111015-1635, release/20111015-1635) fixed
* efbe37b (origin/develop, develop) modify comment
* 107be63 added sample
* d7a313d (origin/master, origin/HEAD, master) initialize

さて、closeです。

% git daily release close
[INFO] first, fetch remotes
[INFO] diff check
[INFO] checkout master and merge release/20111015-1635 to master
[INFO] run git pull origin master
From /home/sotarok/tmp/gitdaily-demo/server
 * branch            master     -> FETCH_HEAD
Already up-to-date.
pull completed
Merge made by recursive.
 sample.php |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
 create mode 100644 sample.php
[INFO] push master to origin
To /home/sotarok/tmp/gitdaily-demo/server
   d7a313d..f62dba1  master -> master
[INFO] first, fetch remotes
[INFO] diff check
[INFO] checkout develop and merge release/20111015-1635 to develop
[INFO] run git pull origin develop
From /home/sotarok/tmp/gitdaily-demo/server
 * branch            develop    -> FETCH_HEAD
Already up-to-date.
pull completed
Merge made by recursive.
 sample.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
[INFO] push develop to origin
To /home/sotarok/tmp/gitdaily-demo/server
   efbe37b..b5a59b7  develop -> develop
[INFO] delete branch: release/20111015-1635
Deleted branch release/20111015-1635 (was aba974f).
To /home/sotarok/tmp/gitdaily-demo/server
 - [deleted]         release/20111015-1635
release closed

たくさん出力されたのでよくわからないことになってるかもしれませんが、ブランチ、ログは以下のようになっています。

% git branch -a                        [tmp/gitdaily-demo/deploy @develop]
* develop
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master

% git log --oneline --decorate --graph --all
*   b5a59b7 (HEAD, origin/develop, develop) Merge branch 'release/20111015-
|\
| | *   f62dba1 (origin/master, origin/HEAD, master) Merge branch 'release/
| | |\
| | |/
| |/|
| * | aba974f fixed: not PHP but Python
|/ /
* | efbe37b modify comment
* | 107be63 added sample
|/
* d7a313d initialize

ブランチに --no-ff で develop と master に merge され、releaseブランチが掃除されていることがわかると思います。

これでリリース作業が完了しました。

各自の開発環境の掃除

deployサーバ上でリリースが完了しました。が、ここはGitの特徴ですが、remoteでリリースブランチが掃除されてもローカルには残ってるわけです。これを掃除しようとおもいます。

ここでも release sync が登場します。
Bさんは、先程修正作業のためにローカルにreleaseブランチを取得しましたので、以下の状態になっています。

% git branch -a           [tmp/gitdaily-demo/b_dev @release/20111015-1635]
  develop
  master
* release/20111015-1635
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master
  remotes/origin/release/20111015-1635

↑はまだfetch前の状態なので、remoteで消えたはずのreleaseブランチが、まだあります。
syncすればそのへんは適当に取得してやってくれます。

% git daily release sync  [tmp/gitdaily-demo/b_dev @release/20111015-1635]
[INFO] first, fetch remotes
[INFO] cleanup remote
[INFO] release closed! so cleanup local release branch
[INFO] checkout develop
[INFO] run git pull origin develop
From /home/sotarok/tmp/gitdaily-demo/server
 * branch            develop    -> FETCH_HEAD
Updating d7a313d..b5a59b7
Fast-forward
 sample.php |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
 create mode 100644 sample.php
pull completed
[INFO] delete release/20111015-1635
Deleted branch release/20111015-1635 (was aba974f).
Closed old release branch
sync to release close

ブランチとログを確認すると:

% git branch -a                         [tmp/gitdaily-demo/b_dev @develop]
* develop
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/master


% git log --oneline --decorate --graph  [tmp/gitdaily-demo/b_dev @develop]
*   b5a59b7 (HEAD, origin/develop, develop) Merge branch 'release/20111015...
|\
| * aba974f fixed: not PHP but Python
|/
* efbe37b modify comment
* 107be63 added sample
* d7a313d (master) initialize

これで、release ブランチがお掃除されて、developに戻りました。 *2

作業の流れのまとめ

これで一連の作業が完了しました。
簡単に普段の作業のまとめをします:

  • develop ブランチで開発作業をする
  • release 作業をはじめるとdevelopブランチからブランチが切られる (release open)
  • release ブランチで最終確認中、修正が必要ならreleaseブランチで修正作業をする (release sync)
  • 本番リリースできたら、releaseブランチをmergeします。 (release close)
  • リリース後、各開発者は sync してお掃除とかする (release sync)

まとめと余計な話

  • Python かいわいでの発表はじめてで緊張しました
  • ちなみに、git-daily本体はgitflowを使って開発しています。
  • スライド中でも話しましたが、Git運用のプラクティス、どんどん共有していきたいですね!


おまけ: zshの連携は、vsc_info使ってます。

autoload -Uz vcs_info
zstyle ':vcs_info:*' enable git
zstyle ':vcs_info:*' actionformats ' %F{3}@%F{4}%b%F{3} !!%F{1}%a%f'
zstyle ':vcs_info:*' formats       ' %F{3}@%F{4}%b%f'
RPROMPT="%F{5}[%F{2}%3~\${vcs_info_msg_0_}%F{5}]%f"

*1: id:Voluntas さんと話したら、デプロイサーバとかないしとかいわれて、ああ、そうか、と思いました

*2:ちなみに、localのmasterブランチがoriginのmasterに追いついてないですが、これはmasterでpullしてないからですね。まぁ各開発者はローカルでmasterブランチを更新することがないので、気持ち悪いかもしれませんが、masterはほったらかしでもほとんど問題ないとおもいます。