DevLOVE現場甲子園2013に出場しました

DevLOVE現場甲子園2013に出場しました。
DevLOVE現場甲子園2013 - DevLOVE | Doorkeeper

出場するようになった経緯はスタッフであるDevLOVE関西の中村洋さん(@yohhatu)に「ロケーションが離れながらも開発をし、価値を届けているという貴重な経験を是非皆さんにご紹介して頂けないか」というお誘いを頂いたためです。
DevLOVE現場甲子園についてはお話を頂く2、3日前に知って「面白そうだな〜。行きたいな〜。でもさすがに愛媛からは行けないや( ̄□ ̄;)」と思ってたので本当にありがたいお誘いで、2つ返事で「ぜひお願いします!」と返事させて頂きました。

私は団チームの四回裏に発表させて頂きました。

本当は「在宅勤務でエンジニアとしての矜持を磨く」というテーマで、在宅勤務だと周囲との対話などコミュニケーションに割くリソースが最小化される代わりに開発(仕事)のリソースを最大化出来る、仕事と向き合う時間が増えることによってエンジニアとしての矜持を磨ける、みたいな話を予定してたんですが・・・この方向で資料作っていって自分が聞き手になって見直したときにイマイチだったんですw なんだか独りよがりで聞き手に得るものがあまり無いような気がして。。。
どうせなら聞き手のみなさんにも私の発表を通して何かしら考えるきっかけにしてもらいたいと思っていたので、直前に内容もテーマも変えちゃいましたw

で、変えた内容は在宅勤務で信頼関係を築くためには「信頼される仕事」が必要であり、「信頼される仕事」のためには以下の3つが重要であるというもの。

  1. 成果にコミットする
  2. トレードオフを考える
  3. 毎日成果を出す

まぁこれらは私の見解にしか過ぎず、これを推し通したいわけでも何でもないですが「信頼される仕事」というキーワードの元に聞き手のみなさんに自分の仕事を見直すちょっとしたきっかけになればいいなと思って発表しました。
発表を聞いて頂いたみなさんからはその場で質問を頂いたり、発表後にも質問を頂いたり、興味を持って頂けて目的は果たせたかなと思っています。


さすがに全60話というだけあって胸熱な技術思考の発表あり、笑い満載の発表ありで色んな意味で白熱した場となっていました。
そんな中でMVPとなったのはこの人!!
株式会社ツクロア - 「つくり・つたえる」秋葉ちひろさんでした。(お願いして写真を撮らせてもらいました。)


秋葉さんの発表内容は「UIと画面遷移を設計するときに破綻しないようにするための、ひと手間」

要約すると

  • 機能ありきの機械的な画面フローは実は難解 =>人間的な対話からの機能設計
  • UIデザインを静止画で確認しないで! =>プロトタイプで確認する(デザイン+操作性)

といった話でした。
実際にはスライドとは別にデモもあり、「お〜確かにコレは静止画で仕様を詰めるのは無理だわな」ということがひしひしと伝わる内容でした。(さすがMVP!!)


そんなこんなで11:00〜20:30というとても長い時間だったんですが、とにかく熱意あふれる場だったので楽しく刺激的で有意義な時間を過ごせたと思います。
ここで得た熱意を元にもっともっといいエンジニアになるべく精進していきたいと思う今日この頃でした。

Amazon RDSのリードレプリカ+Rails4.0+multi_dbを試してみました

Webで負荷分散する場合、アプリケーションは簡単にスケールアウト出来ますが、DB(がRDBMSの場合)は1つに集約するパターンが多いと思います。
しかしこの構成だとどうしてもDBが性能面でのボトルネックとなりがちで、それを解消する1つのスケーリングテクニックとしてReadをレプリカへ分散させるというものがあります。
今回はそれをAmazon RDSのリードレプリカとmulti_dbというgemを使って試してみました。

すでにDBはRDS(MySQL)を利用しているがリードレプリカは利用していない、ということをスタート地点としています。

Amazon RDSのリードレプリカ

Amazon Web Services ブログ: Amazon RDSの新機能:Read Replica(リードレプリカ)の発表

リードレプリカとはその名の通り、RDSの読取り専用複製インスタンスです。
RDSマスタから定期的にデータ同期され、Readはレプリカを参照することによってボトルネックになりがちなDBの負荷を軽減することができます。
リードレプリカを導入した構成はこんなイメージになります。(今回レプリカは1つで検証しました。)

リードレプリカの作成はAWS Management Consoleから簡単に行えます。AWS にログインして[AWS Management Console]-->[Services]-->[RDS]-->[Instances] といってRDSマスタのインスタンスを右クリック、「Create Read Replica」を選択します。

その後、インスタスタイプやらAZやらを選択して「Yes, Create Read Replica」をクリックするとリードレプリカが作成されます。作成が完了するとInstancesの一覧にレプリカのインスタンスが追加されます。(今回はmulti-dbがマスタ、multi-db-readがレプリカとなっています)

たったこれだけでMySQLレプリケーションの設定も必要なくレプリカが作成されました。(RDSすごい!)

multi_dbの導入

GitHub - schoefmann/multi_db: Connection proxy for ActiveRecord for single master / multiple slave database deployments

multi_dbとはReadクエリ(SELECT)をslaveへ、Writeクエリ(INSERT/UPDATE/DELETE)をmasterへ振り分けてくれるgemで主にRailsで用いられます。レプリカのインスタンスが全滅していた場合は自然にmasterに繋がるようになっています。
導入はとても簡単です。

(1)Gemfileに以下を追記します。

gem 'multi_db'

(2)bundle install後、config/database.yml と config/environments/.rb を編集します。

●config/database.yml
データベース定義にリードレプリカを追加します。リードレプリカは「_slave_database」のように定義します。(今回はdevelopmentで実施)

development_slave_database:
  adapter: mysql2
  encoding: utf8
  database: multi_db_development_read
  host: yyyyyyyy.ap-northeast-1.rds.amazonaws.com
  username: root
  password: replica_password

●config/environments/.rb
multi_dbを利用するためのコードを追記します。(今回はdevelopment.rbに追記)

  config.after_initialize do
    MultiDb::ConnectionProxy.setup!
  end

さあコレでOK、と思って rails console を実行したらエラー。

prompt$ rails console
/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/multi_db-0.3.1/lib/multi_db/connection_proxy.rb:57:in `setup!': uninitialized constant ActiveRecord::Observer (NameError)

どうやらActiveRecord::Observer が初期化されていないのが原因のようですが・・・なんでだろう?と悩んでいたらこんなページを発見。

GitHub - rails/rails-observers: Rails observer (removed from core in Rails 4.0)

Rails Observers (removed from core in Rails 4.0)

どうやらRails 4.0ではObserversは削除されたみたいでした。

合わせてリリースノートRuby on Rails 4.0 Release Notes — Ruby on Rails Guides を見てると

In Rails 4.0, several features have been extracted into gems. You can simply add the extracted gems to your Gemfile to bring the functionality back. 
Active Record Observers (GitHub, Commit)

とあったのでGemfileにobserversを追加。

gem "rails-observers"

再び rails console を実行したところうまくいきました。

prompt$ rails console
Loading development environment (Rails 4.0.0)
irb(main):001:0> 

リードレプリカとmulti_dbの動作検証

ここまでで無事起動出来たので本題の「ちゃんと振り分けが出来ているのか?」ということを検証してみました。ここではnameという属性だけを持つUserというmodelを利用しています。

prompt$ rails console
Loading development environment (Rails 4.0.0)
irb(main):001:0> users = User.all
[MULTIDB] hijacking connection for User
  User Load (0.4ms)  SELECT `users`.* FROM `users`
=> #<ActiveRecord::Relation [#<User id: 1, name: "悟空">, #<User id: 2, name: "天津飯">, #<User id: 3, name: "カリン様">]>
irb(main):002:0> 

rails consoleにてReadクエリ(SELECT)を発行したところ、リードレプリカの方へ振り分けられました。ポイントは

[MULTIDB] hijacking connection for User

の部分で、multi_dbがコネクションをハイジャックしたことが分かります。

irb(main):002:0> User.create(name: "クリリン")
   (0.3ms)  BEGIN
  SQL (0.5ms)  INSERT INTO `users` (`name`) VALUES ('クリリン')
   (0.4ms)  COMMIT
=> #<User id: 4, name: "クリリン">
irb(main):003:0> 

次にWriteクエリ(INSERT)を発行してみると先ほどのmulti_dbのログは出力されておらず、マスタの方へ振り分けられていました。

もう少しきめ細かい制御を

これで終わってしまったら面白くないので、もう少し突っ込んでみたいと思います。
リードレプリカはマスターが更新されてから同期されるため、少なからず遅延があります。
そのため、例えば

  1. データの差分を与えられる(「身長が5cm伸びました」)
  2. 既存データをSELECTして取得(「現在の身長は170cmです」)
  3. 取得したデータに差分を付加し、UPDATEする(「170+5=175cm」としてUPDATEする)

といったようなユースケースが考えられる場合、SELECTがレプリカ、UPDATEがマスタでは完全な整合性が保たれないことがあります。
そういった場合はSELECTもマスタを向けたいものです。で、multi_dbで出来るのかと調べてたらバッチリその機構が用意されていました。(GitHub - schoefmann/multi_db: Connection proxy for ActiveRecord for single master / multiple slave database deployments の「Forcing the master for certain actions」「Forcing the master for certain models」を参照)


(1)Model単位でマスタDBへ向ける

config/environments/.rb を編集します。

Modelを1つだけ指定(User)

  config.after_initialize do
    MultiDb::ConnectionProxy.master_models = ['User']
    MultiDb::ConnectionProxy.setup!
  end

Modelを複数指定(User、Company)

  config.after_initialize do
    MultiDb::ConnectionProxy.master_models = ['User', 'Company']
    MultiDb::ConnectionProxy.setup!
  end

(2)Controllerのアクション単位でマスタDBへ向ける

各controller.rbを編集します。

アクションを1つだけ指定(index)

  around_filter(:only => :index) { |c,a| ActiveRecord::Base.connection_proxy.with_master { a.call } }

アクションを複数指定(index、show)

  around_filter(:only => [:index, :show]) { |c,a| ActiveRecord::Base.connection_proxy.with_master { a.call } }

これで特定のmodel、特定のアクションでリードレプリカを利用しない指定が出来ます。

まとめ

今回はAmazon RDSのリードレプリカとそれをRailsから利用するためのmulti_dbについて書いてみました。
multi_dbの各modelやcontrollerのアクション毎にslaveへ向ける/向けないという設定が簡単に出来るところがなかなかイケてるなぁと思いました。

昔私は同じようなことを「素のMySQL + Spring&Hibernate」で実現したことがあるのですが、それに比べるとめっちゃラクでしたね。(素のMySQLだと当然自分でレプリケーション設定をしなくちゃいけないし、Spring&Hibernateでmulti_db並みのきめ細かい制御をしようとするとモンキーパッチ的なことを実施しなくちゃならなかったり・・・)
こういったことをサクッと実践させてくれるRDSとmulti_dbに感謝しながら今日はおしまいとしたいと思います。

ビジネスモデルキャンバスの素振り会をやりました

先日、アジャイル四国の勉強会としてビジネスモデルキャンバスの素振り会をやりました。
アジャイル開発はソフトウェアの完成ではなくビジネス価値にフォーカスを当てた開発手法であり、そんなアジャイル開発においてシステムの価値をビジネスモデルとして表現することは非常に重要です。
ということでビジネスモデルキャンバスを実際に描きつつ、ビジネスについて考える良き機会としようということで開催しました。

Agile459 #17 ビジネスモデルキャンバス素振り会 - Agile459/アジャイル四国 | Doorkeeper

私はファシリテーターを務めさせて頂きました。久々の仕切り役だったのでちょっと不安だったんですが、まずまずうまくいったかなぁと思います。

ビジネスモデルキャンバスとはBusiness Model Generationという書籍の中で紹介されているビジネスモデルを描くツールのことです。
9つの構築ブロックから成っていて、それぞれのブロックに情報を載せていくことによって、キャンバス全体でビジネスモデルをconceptualに捉えられたり、なかなか言葉で表現しづらいビジネスモデルを見える化したりする効果があります。

ビジネスモデル・ジェネレーション ビジネスモデル設計書

ビジネスモデル・ジェネレーション ビジネスモデル設計書

今回の勉強会では教科書通りの描き方を学ぶというより、みんなでビジネスについて語り合う機会を最大化したいと思ってセクションを考えました。
参加者のみなさんに能動的に臨んでもらったおかげで、大体この目標は達成出来たのではないかと思います。
みんなで意見を出し合って、あ〜でもないこ〜でもないと話し合っている姿はとても印象的でした。

今回の勉強会で参加者のみなさんが学んだのは
「ビジネスモデルキャンバスのどのブロックにはどんな情報を載せるのか?」
というような教科書的なことではなく
「既存ビジネスを分析したり新規ビジネスを考える上でどういったことにフォーカスを当てるべきなのか?周りの参加者がどういった視点でビジネスを捉えているのか?」
という参加者自身が作り上げて共有した知見/知識だったと思います。
やっぱり学校みたいに先生が生徒に解き方と正解を教える、ではなくて自分たちで考えて自分たちなりの正解を導いていくのがコミュニティの勉強会っぽくていいな〜と思いました。

最後に参加者のみなさんの感想を聞いたんですが、結構ビジネスモデルについて語り合う場は新鮮だったようで、また実施したいという声を多く頂きました。なのできっとまた続編(?)をやります。
次回はもうちょっと時間を長くして、ビジネスモデルキャンバスでアイディアソンをやって、それをハッカソンで実際に作ってみる、なんてのも出来たら面白いだろうなぁと個人的には思ったりしています。
実現するかどうかは分かりませんが・・・^^;

rspecを高速化するsporkとその仕組み

最近rspecRailsのテストコードを書いてました。
書いたテストコードは動かしながら確認していくわけですが、その1回1回の実行時間がとても長くて困ってました。(私の環境では1回の実行で大体10秒くらいかかってました。)
「なんでこんな時間かかるんやろう?」と思って調べてみたところ、どうやらrspec実行の度にRails環境をロードするため時間がかかっていたようです。

rspec実行の度にRailsをロードしていたのでは時間がかかって当然ですね。
何か良い方法ないのかな?と思っていたら「spork」なるものを発見したので導入してみました。

sporkの導入

GitHub - sporkrb/spork: A DRb server for testing frameworks (RSpec / Cucumber currently) that forks before each run to ensure a clean testing state.

(1)Gemfileにsporkを追加

gem 'spork'

(2)sporkのinstall

bundle install

(3)bootstrapの設定

spork rspec --bootstrap

(4)sporkの起動

spork

(5)rspecを--drbを付けて実行

rspec --drb spec/controllers/spork_tests_controller_spec.rb

(4)で起動したsporkプロセスがシステムに常駐、(5)ではそのsporkプロセスに対して操作することによってrspecの高速化が図れるそうです。
これで大体10秒かかっていたrspecの実行が即時になりました。

なんでspork導入すると早くなるの?・・・の前に

GitHub - sporkrb/spork: A DRb server for testing frameworks (RSpec / Cucumber currently) that forks before each run to ensure a clean testing state. の一番上にはこんなことが書かれてあります。

A DRb server for testing frameworks (RSpec / Cucumber currently) 
that forks before each run to ensure a clean testing state. 

sporkはRSpecやCucumberなどのテストフレームワーク用のDRbサーバです、とのこと。
sporkの仕組みを理解するためにはDRbについて理解する必要がありそうです。

DRbとはDistributed Rubyの略称で、Rubyの分散オブジェクト技術のことです。
分散オブジェクト技術といえばCORBA、DCOM、RMISOAP、etc… 世の中にたくさんありますね。
これだけで少しイメージが掴める気がします。
とは言っても、もう少し詳しく知りたいな〜と思って色々巡っていたらこんなページを発見しました。

library drb (Ruby 2.0.0)

drbライブラリのページなのでちょっと方向性はズレますが、DRbがどんなものかを知るためにはとても分かりやすいページでした。
ざっとまとめるとこんなことが書いてあります。

  • DRb(dRuby)とはRuby専用の分散オブジェクト技術である
  • 独自のプロトコルdruby://....)で通信するため、その他の分散技術との相互運用性はない
  • リモートプロセスにあるオブジェクトはローカルのDRb::DRbObject インスタンスとして表現され、そのインスタンスはリモートオブジェクトのproxyのように振る舞う
  • CORBAのIDLのようなインタフェースの静的宣言は必要ない(すべて実行時に解決される)
  • リモート⇔ローカルではメソッドの引数/戻り値をMarshalでバイト配列に変換して受け渡しする
  • dRubyはブロック付きのメソッド呼び出しをサポートするが、Procはマーシャリング不可能なのでブロックの中身はローカルプロセス上で実行される。

動作イメージはこんな感じですかね。

なんでspork導入すると早くなるの?

ではsporkの話に戻って、なぜsporkを導入すると高速化を図れるのでしょうか?
これはsporkがRails環境とその関連クラスのロードを担ってくれるためです。

sporkがすでにRails環境とその関連クラスをロードしてくれているため、rspecはテスト実行だけに集中できます。
つまりRails起動相当のコストが丸々削減出来るため、高速化が図れるということになります。

さいごに

今回はsporkとその仕組みについて書いてみました。
sporkはとても便利ですし、使わない手はないな〜という印象でした。

2週間経って感じるリモート勤務の「予想以上」

リモート勤務を始めてから2週間が経ちました。
今回はその中で感じた色んな「予想以上」について書きたいと思います。

「予想以上」に遠隔地のハンデを感じない

これは一番不安視していたことでもあるんですが、現時点では遠隔地にいることで仕事に支障が出るということは感じていません。
ハートレイルズでは資料やコードは色んなクラウド環境を利用して共有しています。
その資料は膨大で見きれないなんてことはなく、良い意味で単純化されていて理解しやすい資料となっています。
そのため、ゴールや大体の方向性は共有した資料を通じて自然と合ってきます。
また、業務中はSkypeをオンラインにしていて疑問/質問等があればメッセージでやりとりして解決しています。
やりとりする中で言って頂いたんですが

「分からないことは何でも聞いてください、納得するまで聞いてください」

というスタンスでやりとりしているので、方向性がズレそうなときや壁にぶつかったときには私が理解出来るまで相手をしてもらっています。
そうやって納得感を持ちながら仕事出来ているため、遠隔地のハンデはあまり感じていません。

「予想以上」に孤独感を感じない

前述の通り、業務中はSkypeをオンラインとしておいて必要に応じてメッセージのやりとりをしています。
そのメッセージですが(ここが最も凄いことだと感じているんですが)、私が投げた質問に対しての回答がもの凄く早いんです。
聞いたことがすぐに返ってくるため、席の後ろにいる人に「ちょっといいですか?」って聞いたのと同じくらいの感覚なのでなんだか距離感が近い気がしてます。
そんなこともあって、遠隔地にいながらもあまり孤独感(一人でやってる感)を感じずやれています。

「予想以上」に集中できる

私がこの働き方となる前によく見聞きしていたのは

 「在宅勤務では慣れるまで生産性が落ちる」
 「在宅勤務に慣れるまでは時間がかかる」

といったことでしたが、これらの言葉がウソのように仕事に集中出来ています。
これには職場環境が関係しているのかな?と思っています。

実は私は「在宅勤務」ですが「自宅勤務」ではありません。
職場は実家に作っていて、住んでいるのはそこから車で20分くらいのところです。
なのでリモート勤務となる前と同様、出勤する1時間くらい前に起きて身の回りの準備をして、朝ご飯を食べて、実家へ出勤しています。
きっとこれがいい方向に働いていて、起きてからゆっくり時間をかけて準備することで「寝起きモード」から「仕事モード」に少しずつ気持ちを変化させていけてるのではないかなと思っています。

結果、仕事中はいい集中力を持続させられているのだと思います。

「予想以上」に充実感がある(家族編)

職場は実家にあり、その実家には祖父が住んでいます。
7月から愛媛でリモート勤務になります。 - ITエンジニアとして生きる でも書きましたが、私がリモート勤務となった大きな要因の1つは祖父の近くに居たいということで、それが実現出来ていることをとても嬉しく思います。
ちょっと休憩する時に声をかけたり、一緒に買い物に行ったり、病院に付き添ったりと、今まで出来なかった孝行が出来ていることにとても充実感を感じますし

 「この環境を維持するためにも仕事を頑張らなくては!!」

という仕事のモチベーションにも繋がっていると思います。

「予想以上」に充実感がある(仕事編)

ハートレイルズではRubyの開発がメインとなります。
私は今まで本格的なRubyの開発経験がありませんので、予想通りハマりまくってます(笑)
でも何度もハマっている分、何度も小さなブレークスルーを経験出来ています。
それがとても楽しい。

ハマっている最中は「ぅおおおおおおお」ってなるんですが、それが解決出来たときの喜びは格別です。
このブレークスルーの連続は私がRuby初級者だからこそ経験出来ることだろうと思います。
この喜びの感覚を忘れずに、今後も精進していきたいと思います。

「予想以上」に早く作る力が大事

2週間の勤務を通して一番強く感じたことはコレかもしれません。
初めに書いたように、ハートレイルズでは資料も理解しやすいものですし全体的なゴールがズレるということはあまりないように感じていますが、ちょっとした仕様の取り違えや実装ミスということは生じることがあると思います。
これはどんなプロジェクトでもそうだと思いますが、どれだけ重厚長大な設計書を用意してこと細かく仕様を規定していたとしても、それを読み取る側の人間が意図を取り違えたり、あるいはそもそも設計書の記載がミスっていたりすることがあると思います。
こういうミスは防ぎようがないので、なるべく早くそのミスを「発見」する必要があると思います。
その発見する方法として一番効果が高いのは

  • 動くものを見てもらう(そのコードを見てもらう)
  • フィードバックを受ける

というアプローチであろうと思っています。

特に私のような遠隔地で働いているものにとっては本当に早くこういったミスを発見したいわけで、そのためには私が早く作れなければならないと感じています。
もちろん早ければいいって話ではなくて、早い&エレガントなコードでないと合格点とは言えないでしょう。

今の私はまだまだ全然その辺が出来ないですね。
早く作ればコードが重複しまくってるイケてないコードになってしまいますし、エレガントに書こうとすれば「ぅ・・・」と手が止まってしまったりします。
まだRubyに慣れていないのもそうなのですが、ここは少しずつ積み重ねていって自分を鍛えていくしかないかなと思っています。

まとめ

今回は2週間のリモート勤務を通して私が感じたことを書いてみました。
総じて思うのは、家族のそばに居ながら仕事に打ち込めるこの働き方っていいな〜ってことです。

少子高齢化の進む日本社会において、私のように家族のそばに居たいと思う人も大勢いるのではないでしょうか?
そんな人達にとっても、このような働き方がもっと普通な世の中になればいいと願っています。

そのためにも私が良き前例となれるよう、今後とも頑張っていきたいと思います。
そんなことを考えていた今日この頃でした。

GITでリモートブランチへpushする前にやっておくべきこと

先日GITを使ってて、ちょっとお粗末なミスをしてしまいました。
今日はそんなミスを犯さないためにやっておくべきことについて書きたいと思います。

お粗末なミス

私がやっちゃったミスは、ずばり「コミットグラフ汚し」です。
図のように、「別の人」とのマージコミットをコミットグラフに追加してしまいました。

このときのコミットグラフ

マージコミットのメッセージは

「Merge branch 'xxxx' of ....」
「Merge commit 'xxxx'」

という本質的でないメッセージになります。
この「マージした」という情報は「自分 <==> ある時点でのコミット」のマージを指しており、チーム全体(リモート)として意識するようなコミットログではありません。
このようなコミットをしてしまったことによって、リモートブランチのコミットグラフの見通しを悪くしてしまいました。

本来はこのようなコミットログは含まず、各人の変更した内容が集約されてコミットグラフが形成されるべきだと思います。

リモートブランチのあるべきコミットグラフの姿

今回はこのようなコミットグラフのあるべき姿を保つための方法をまとめてみたいと思います。


【2013/06/30】
コメントを受けて「リモートブランチのあるべきコミットグラフの姿」の画像を差し替えました。
(元の図はコチラ)
 

まずはgitxの導入

まずはgitxを導入することがスタートラインになると思います。
導入はとても簡単でダウンロードして解凍するだけです。
導入後、メニューから「GitX」→「Enable Terminal Usage...」を選択するとコマンドラインから「gitx」を実行出来るようになります。

GitX - Home

gitxはコミットログやコミットグラフをGUIで見れるツールです。
ローカル/リモートの複数ブランチの状態を合わせてみたり出来るため、視覚的に分かりやすいツールだと思います。(Win系だと似たようなものでgitkというツールがあります。)

コミット/マージ/リベース等を実行するたびにgitxで想定通りのコミットログやコミットグラフとなっているか?を確認しながら進めていくのが良いと思います。

それでは本題

それでは本題のどうすればリモートのコミットグラフを汚さずに済むのか?について。
全体のイメージはこのようになります。
ローカルのmasterブランチでリモートブランチと同期を取りながら、自分の作業はworkブランチにコミットしていくようにします。

以降ではこの図を元に、ひとつひとつ手順を展開していきたいと思います。

(1)作業用ブランチ(work)を作成する

まずは作業用ブランチ(work)を作成します。
「git checkout -b」を利用すると作成&そのブランチへの移動を同時に実施できます。

git checkout -b work

(2)もろもろ開発〜コミット

通常通り開発し、作業用ブランチ(work)へコミットします。

git commit

(3)リモートブランチと同期

もろもろ開発していくと「そろそろリモートへpushしたいな」と思います。
そう思ったらまずはmasterブランチとリモートブランチの同期を取ります。
この時点で「別の人」がpushしていた内容を取得します。

git checkout master
git pull origin master

(4)masterブランチをベースに作業用ブランチ(work)をリベース

ここが1番のポイントです。
リモートブランチの最新と同期を取ったmasterブランチをベースに作業用ブランチ(work)をリベースします。
ここでリベースすることによってマージコミットを発生させないようにします。

git checkout work
git rebase master

(5)作業用ブランチをベースにmasterブランチをリベース

今度は逆に作業用ブランチ(work)をベースにmasterブランチをリベースします。
ここでの目的は「master = work」という単なる位置合わせなので、「git merge --ff-only」を利用してもOKです。

git checkout master
git rebase work
(もしくは git merge --ff-only work)

(6)リモートブランチへpush

ここまで作業したらgitxでコミットグラフを確認します。
きっと綺麗なコミットグラフになっていると思うので、その確認が済んだらリモートブランチへpushします。

git push origin master

※もしgitxで確認した結果が思い通りになっていなければ元に戻しましょう。

git reset --soft xxxxxxx

これで編集したファイルはそのままに、コミットログだけを取り消すことが出来ます。

まとめ

今回はコミットグラフを汚してしまわないための1つの方法を示しました。
ローカルブランチの「master <==> work」で整合性を保った上で、それをそのままリモートへpushするというのが、もろもろ保証できて良いと思っています。

また「リモートブランチへpushする前に」というテーマでしたが、これは「pull requestを送る前に」とも読み代えることが出来ます。
OSSプロジェクトやその他何に対してもですが、コミットグラフを意識したエレガントなpull requestを送りたいものですね。

7月から愛媛でリモート勤務になります。

6月30日をもって株式会社オージス総研を退職させて頂くこととなりました。
本日が最終出社日でした。
7月1日からは株式会社ハートレイルズにお世話になり、私の地元である愛媛県にUターンし、リモート勤務することとなります。(ハートレイルズは神奈川県にある会社です)

HeartRails - ハートレイルズ - 新規事業開発のエキスパート

なぜ愛媛県にUターン?

少し重い話になりますが。

私は生みの母親を生後半年で亡くし、0〜2才までを母方の祖母に、その後は実家のある隣町で父方の祖父に母親代わりとなって育ててもらいました。
その祖母が今年の2月に亡くなりました。
GWやお盆、正月と長期休みが取れた時は地元に帰っては顔を出していたものの、正直もっと長くついていてあげたかったと思いました。

祖父はまだ健在で、実家で一人暮らししています。
幸いにもまだ元気で、身の回りのこともある程度自分でやりながら、手の回らないところはデイサービスを利用して生活しています。
しかしながら、やはり一人だと突然体調を崩したりした時など不安で、その祖父についてあげたいという気持ちが強くなりました。
ということで愛媛県へUターンしようと思いました。


仕事の問題

私の地元は愛媛県の中でもかなり田舎の方で・・・ITの仕事どころか普通の仕事すらあまりない土地です。
そこで私には2つの選択肢がありました。

  1. いっそのこと職を変えて、地元で頑張って数少ない仕事を探す
  2. リモート勤務可能な企業を探し、ITの仕事を続ける(※)

はじめは正直、職を変えてもいいかなと思ってました。
でも妻と話し合った結果、これまでのキャリアを放棄してしまうのはもったいないんじゃないか?今後のことを考えてもIT業界に関わり続けた方がいいんじゃないか?という結論に至りました。

※私の地元にはITの仕事はないので、「ITの仕事を続ける ≒ リモート勤務」という方程式が成り立ってしまいます。

そして始まった転職活動

まずは以前お世話になったエージェントに「在宅勤務可能な企業は無いか?」とお伺いしてみました。
すると

「週2、3回は在宅勤務OK、その他の日は出社して欲しい」

というような部分的に在宅勤務をOKとしているところはあるものの、完全にOKとしているところはありませんでした。
ましてや私の場合は「リモート勤務」という条件も加味されるわけで、ますます条件は厳しいものだと思われました。

ということで自ら探すことにしました。

私が考えていたこと

いろいろと調べてみた結果、「在宅勤務可能」としている企業が少なからず見つかりました。
でもそこに「リモートでも可能」とは書いていません。
当時私が考えていたのは

 「まずは在宅勤務可としている企業に応募、興味を持ってもらう」
 「リモートでもOKと言ってもらえるくらい、アピールする」

という単純なことでした。
初めから私の条件に合致する企業はなかったわけですから、それに近い条件を示しているところになんとか指先でも引っ掛けて、なんとかこじ開けようという考えでした。


株式会社ハートレイルズに応募

数ある企業の中からハートレイルズに応募しました。

ハートレイルズの選考は

  1. 履歴書、職務経歴書の書類選考
  2. 面接

の2段階でした。
正直、私は書類選考で落ちると思ってました(^^;)
ハートレイルズは神奈川県が会社の所在地となっています。
在宅勤務は可能としてますが、わざわざ愛媛県という遠隔地で働きたいと言っている私を雇うメリットは無いよな〜と考えていたからです。
何かあったときにFace-to-Faceで話し合える距離感に居るというのは大事かなと思っていましたし、エージェントもそうおっしゃっていたので。

ですが嬉しいことに、私の予想に反して書類選考が通って面接の連絡がきました。
ハートレイルズが選考の回答期限としている10営業日目のことでした。


面接

面接は神奈川県で実施しました。
お相手は社長の上楽さん。
今現在私は名古屋(のとなりの市)に在住なので、SkypeやHangoutsで面接してもいいと言って頂いたんですが、直接会って私の人柄等も判断して頂きたいと無理を言って直接会って頂きました。
あとは私が実際に上楽さんにお会いして、どんな人か感じてみたいというのも強かったんですが。

ハートレイルズではRubyがメインの開発言語になります。
私はこれまで主にJavaで経歴を重ねてきたため、Rubyについて急速に学ぶ必要がありました。
その部分が面接ではネックになるだろうという思いもあり、なんとかアピールしようと思いました。

面接までに簡単なチャットアプリを作成し、herokuにアップしたものを見せてアピールしました。
全く大したものではなかったのですが、面接のご連絡を頂いてから約2週間で勉強しながら動くものを作ったということで熱意を感じて頂けたと思っています。

あと実際にお会いして、上楽さんの印象もとても良かったです。
なんというか静かなオーラがあるような気がしました。

有名な言葉で「コードの臭い(Code smell)」というものがあります。
「コードの臭い(Code smell)」というのはプログラムに潜む深刻な問題の兆候を指し、明確に形式知化されているものもあれば「なんか怪しいぞ?ココ危なそうだぞ?」というプログラマの感覚値を指すこともあります。
そういうプログラマの感覚は大体当たっているし、大事にすべきということです。
私もこれに完全に同意で、「なんかこの人凄そう」とか「この企業良さそう」という感覚値を大事にしていますし、これまでそれを大事にしてきて大体プラスな方向に働いている気がします。

上楽さんと直接お会いしてそんな何かを感じた気がして、ますますハートレイルズに入社したいという想いが強くなりました。

http://ja.wikipedia.org/wiki/コードの臭い

そして内定通知を頂く

面接からおよそ3週間後、無事内定の通知を頂きました。

愛媛で生活基盤を築きたいという私の想いを叶えるべく、やっとスタートラインに立てました。
そのチャンスを頂いたハートレイルズには本当に感謝してますし、これから全力で貢献していきたいと思っています。
もちろん全力で仕事を楽しみながら。


オージス総研への感謝

オージス総研では本当に多くの方々に刺激を受け、助け合い、切磋琢磨してきました。
多くの良き仲間(というとおこがましいですが)に知り合えたと思っています。
自分が成長できたのはオージス総研で自分に関わってくれた方々のおかげだということを確信しています。
お世話になってばかりで何も恩返し出来ていませんが、これから私が頑張ることで何かしらそういったことに答えていければと思っています。


さいごに

私のわがままな決断を理解してくれ、自分の地元でもなく知り合いもいない土地についてきてくれると言ってくれた妻に最大限感謝します。
ありがとう。