tanaka51のブログ

Ruby on Rails とか Emacs とか

よく忘れる Git コマンドメモ(主にリモート系)

コマンドの体系をきちんと覚えれば忘れる事もなくなると思うんだけどね:p

origin の登録(リモートの登録)

git remote add origin <URL>

origin の変更(リモートの変更)

git remote set-url origin <URL>

push と同時にリモートの情報設定

git push -u origin master

リモートにブランチを作成

git push origin <remote-branch-name>

リモートのブランチを削除

git push origin :<remote-branch-name>

リモートのブランチをローカルに作成

git checkout -b <local-branch-name> origin/<remote-branch-name>

Git のマージについて、自分的まとめ

チーム開発で Git を使ってから半年ちょい位経ちました。
Git 玄人な人たちに囲まれて開発していたおかげで、そこそこ Git 力がついてきました。
そんな中で、ブランチの統合(マージ)についての考え方が大分固まって来たのでまとめます。

まずは結論から。

  • 統合するブランチ → 統合されるブランチ : 統合の為に使うコマンド
    • ローカル(自分用) → ローカル(自分用) : 適当に
    • ローカル(自分用) → ローカル(リモート用) : merge --squash
    • リモート → ローカル(リモート用) : pull --rebase
    • ローカル(リモート用) → ローカル(自分用) : rebase
    • ローカル(リモート用) → ローカル(リモート用) : merge --no-ff

ローカル(リモート用)は、リモートドラッキングブランチからチェックアウトしたブランチを指してます。
要は、git checkout -b topic origin/topic みたいな感じで作成したブランチ。
ローカル(自分用)は、リモートに push する事の無い、完全にローカルなブランチです。
リモートは、リモートにあるブランチです。

ではその理由をしこしこと並べていきたいと思います。
玄人の方達には当たり前の事かもしれません。
そして、割と長いです。
(マージと統合が入り乱れてますが、同じ意味で使ってます。なおすの面倒なのでこのままで…)

前提

中央リポジトリには、リリース用ブランチ、開発用ブランチがあります。
普段は開発用ブランチにコミットし、レビューが終了したらリリース用ブランチにマージされます。

また、他にも以下のような考えのもとに上記結論に至っています。

Git のコミュニティ

Git の世界では、「コミットの歴史を綺麗に保つ」事が非常に重視されています。
(そんな風に僕は感じています)
これは、開発者にとって非常にメリットのあることなので、僕もそうするように努力をします。
ブランチの統合で使うコマンドをわざわざ使い分けるのも、その為です。

チーム開発

Git が一番力を発揮するのは、多人数で開発する時だと思っています。
そうすると必然的に「中央リポジトリ」が存在します。
中央リポジトリ = 誰でも見る事ができるリポジトリ です。

コミットの歴史を綺麗に保つ対象は、リモートにある中央リポジトリになります。
逆に言えば、ローカルにある自分だけのリポジトリはどうでも良いです。

ブランチの統合

中央リポジトリを持った開発をしている限り、ブランチの統合作業無しでは開発できません。
リポジトリとのやりとりは、いうなればブランチの統合作業のことです。
自分が操作するブランチがどのような意味・役割を持っているのか、意識する事が重要です。

ローカルリポジトリ内には、リモートリポジトリへ push されるブランチと、自分だけのブランチがあります。
普段の開発は、自分だけのブランチで行います。
みんなに見てもらいたい区切りで、リモートへ push されるブランチに統合、push します。

統合の種類
  • merge --no-ff
    • マージコミットを明示的につくる事によってブランチを統合する。
  • rebase
    • 統合対象ブランチに対して、統合するブランチと全く同じ内容のコミットの歴史を載せる。マージコミットをつくらない。
  • merge --squash
    • 統合対象ブランチに対して、統合するブランチの歴史を一つにまとめたコミットをつくる。マージコミットをつくらない。
開発の流れ

今回想定する流れは、以下のようになります。

  1. 「自分の開発用ブランチ」をきる
  2. ある程度できたら、「みんなの開発用ブランチ」へ統合する
  3. 「みんなの開発用ブランチ」を push する
  4. レビューする
  5. 「みんなの開発用ブランチ」から「リリース用ブランチ」へ統合する
何を達成したいのか
  1. コミットの歴史を綺麗に保つ
  2. コードレビューを必ずする

以上の2点を満足させるようなマージ戦略を考えます。

結論に至った理由

さて、以上の前提を念頭に、最初に提示した結論に至った理由を書いていきます。
説明しやすい順に書いていきます。

ローカル(自分用) → ローカル(自分用)

自分用は他の人に晒される事もないので、適当にやれば良いです。
最終的には、squash して一つにまとめますし。

結論 : 適当にやる

ローカル(自分用) → ローカル(リモート用)

ローカルで切ったブランチを他の人に晒したくなったタイミングで行われます。
この作業をしたあとに、ローカル(リモート用) はリモートにある中央リポジトリに push されます。

では、それぞれのブランチについて考えます。

  • ローカル(自分用)
    • 試行錯誤の末、小さなたくさんのコミットがつまれている。とてもじゃないけど、人様に見せられない。
  • ローカル(リモート用)
    • 人様にお見せする為の(push される)ブランチ。
    • レビュー対象だから、レビューしやすい様にまとめたい。

どうやって2つのブランチを統合するか、「統合の種類」に出てた3種類から考察します。

  • merge --no-ff
    • マージコミットつくるのは良いが、結局恥ずかしい歴史が晒される事には変わりない。
    • マージコミット、ファイルの差分を表示しないので、レビューしづらい。
  • rebase
    • 恥ずかしい歴史をそのまま載せるとか考えられない。
    • そもそも、リモート用リポジトリのコミットハッシュが変わって危険。
    • みんなが共有しているコミットがたった一つの間違いで変わってしまう…怖いよね。やらないように。
  • merge --squash
    • 今までの変更を一つのコミットにまとめられるなんて、まさに理想。
    • 一つにまとまってると、レビューもしやすい。

結論 : git merge --squash を使う

注意 : あまり大きいコミットになると分かりづらいから、そこら辺はうまいこと調整すれば良いんじゃないかな。

リモート → ローカル(リモート用)

これが行われる場面は、他の人の歴史を自分の歴史に統合する時です。
要は pull する時です。
それぞれのブランチの役割を考えます。

  • リモート
    • みんなが綺麗に保って育てた自慢のブランチ
  • ローカル(リモート用)
    • 私の自慢の修正をみんなに周知する為のブランチ
    • 後でリモートに統合する

ここに出てくるローカルブランチは、後でリモートに統合する事になります。
つまり綺麗に保つ必要性があります。

そして、pull にはブランチの統合の方法が2つあります。
一つはデフォルトの merge で、もう一つは rebase になります。
それぞれの特徴と、結論を見ます。

  • merge
    • マージコミットができる可能性があり、みんなが綺麗に保って育ててきた歴史を汚す事になる。
    • 私の自慢のコミットは統合されるべきだが、必要の無いコミットはいらない。
  • rebaes
    • みんなが綺麗に保って育ててきた歴史をそのまま載せられるから素晴らしい

結論 : git pull --rebase を使う

ローカル(リモート用) → ローカル(自分用)

これだけは入れてー!っていう急な修正が入った時とか。
上記と全く同じ理屈で rebase を使いましょう。
選択肢としては他にも merge --squash がありますね。
が、みんなが綺麗に保って育ててきた歴史を一つにまとめるなんて考えられないので却下です。

結論 : git rebase を使う

ローカル(リモート用) → ローカル(リモート用)

これは、開発ブランチ上でのレビューが終了して、リリースブランチにマージする時に行われます。
基本的にリポジトリ管理者だったり、チームリーダーがやったりします。

リポジトリの考察です。
マージする側を開発、される側をリモートとしましょう。

  • 開発
    • レビュー済みの綺麗な歴史が積まれている。
  • リモート
    • 後からみた時に、どんな歴史が刻まれたのか、しっかり把握しておきたい。
    • マージ後、タグが打たれたりする。

では、「統合の種類」からどれが適切か考えます。

  • merge --no-ff
    • マージコミットがつくられると、どの地点でこのブランチの歴史が変わったかが分かるので良い。
    • かつ、マージ元の歴史も参照できるのが良い。
  • rebase
    • 開発ブランチの歴史がそのまま残るのは良い。
    • が、コミットハッシュが変わる可能性を秘めてるので良い子はやらないように。
  • merge --squash
    • 開発ブランチの綺麗な歴史をひとまとめにするのは、もったいない。

もう一個、普通の merge について考えます。
merge --no-ff との違いは、fast-forward の場合にマージコミットがつくられない事です。
で、前提で話したようなやり方だと、ほぼ fast-forward でマージされます。
論点をマージコミットをつくるか、つくらないか、という所に絞れます。
そうすると、上述したように、どの時点でマージされたかが分かるようにマージコミットをつくった方が良い、という結論になります。
結果的に、リリース用ブランチにはマージコミットだけが乗っかります。

結論 : git merge --no-ff を使う。

実は不完全

開発用ブランチに自信を持ってマージして push したが、レビューでボロクソにされてリジェクトされた場合。
開発用ブランチにはボロクソなコミットが残ってしまいます。
このままだと、開発用ブランチ上の歴史が綺麗とは言えない状態です。
(このブランチ上にボロクソなコミットを残したまま、修正コミットを入れるのは残念な感じです)

解決策としては、自分のコミットは開発用ブランチに push するのでは無く、
「開発用ブランチに merge して欲しいブランチ」を remote に push して、
そのブランチをレビュー、リジェクトされたら新しいブランチを push、
レビューが通ったら開発用ブランチに merge する、
みたいな手法が考えられます。

もうここまで来ると結構面倒。
これほど労力を振り絞ってリポジトリを綺麗にする必要があるのか?
そこはチーム毎に決めれば良いと思います。
(Git に慣れればそれほど面倒でも無い気はしますが、メンバー全員 Git 堪能なチームなんてそうそう無い気もします:p)

もしくは、google 謹製の gerrit というシステムを使ったり、
github を使って pull request を用いる方法もあります。

終わり

実はこの記事を書こうと思ったのは、git のマージの為のコマンドってすごく考えられてできてるんだなーと思ったからです。
そして、マージコマンドをフル活用している俺カッコイイ!がしたいだけです。

あとは、気付いた方もいると思いますが "A successful Git branching model" に影響受けまくりです。
見えないチカラ: A successful Git branching model を翻訳しました

ツッコミ大歓迎なので、何かありましたらコメントなり @tanaka51 までメンション飛ばすなりしていただければと思います:)

Gitによるバージョン管理

Gitによるバージョン管理


入門Git

入門Git

Git道場 #1 に行ってきた

今日は Git道場 #1 に門下生として参加しました。
http://git-dojo.doorkeeper.jp/events/979-git%E9%81%93%E5%A0%B4
その感想的なものをつらつらと書いていきます。


Gitを専門にした大規模な勉強会はなかなか無いように思います。
参加費1,000円、人数50人が半日程で埋まり、予約待ちも40人以上いたようで、反響の大きさが伺えます。

プログラムは、午前、午後に分かれていました。
午前は自由参加だったのですが、意識の低い私は参加できず。
午後は師範代2人による Git の講義を聞いた後に、実際に Git を使って作業を行いました。

午後の部

会場に入ったら、番号が振られたテーブルに座ります。
各テーブルには4〜5人座れるようになっていて、テーブル毎にチームとなって作業を行う事になります。
又、テーブル上には、Git早見表が置かれていました。

着席したら、web の登録フォームにて自分の github アカウントとテーブル番号を申請。
テーブル毎につくられた github の公開リポジトリに対して、コミット権が与えられます。
(github すごい、今回の道場が開催できたのも、github がある事が一つの要員になっていると思います。)

開場

道場主である相澤さん(@ayumin)の開場の挨拶で、Git道場が始まりました。
今回の目標は、
「merge/rebase を怖がらずにできるようになること」
です。

会場提供のフューチャーアーキテクト株式会社の方から会場についての諸注意。

<心>の部

<心>の部は、岩松さん(@iwamatsu)の「Git総論、心構え」と題した講義。
Git とは何か、どんな仕組みで動いているか、というお話でした。

「会社で SVN を使っているが、Git に移行するにはどうしたら良いか」
という質問に対して、
「Git への移行を拒んでいる奴からコミット権を奪えば良い」
という回答が印象的でした。w

<技>の部

<技>の部は、小川さん(@conceal_rs)の「本日の課題、テクニックの解説」と題した講義。

本日の課題は、リポジトリに既に登録されているファイルに対して、
編集 → commit → push → リジェクト → pull(merge/rebase) → コンフリクト → 解消 → push
をひたすら行なっていく、という物でした。

編集対象のファイルは単純なテキストファイルで、以下のようなものです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10

そして相澤さんから以下のような制限が与えれれます。
「原則私語禁止!コミットメッセージで語れ!」
コンフリクトの解消を他人に相談しないで、コミットメッセージから判断できるようになれ、という意図です。

例外として、

  • 一人が連続して push する事のないように push したら声をかける
  • チューターさんへの質問は積極的に行う

があげられていました。

<体>の部、第1イテレーション

始まりました。
原則私語禁止ですが、各地で積極的にチューターさんへの質問が行われていたり、ニコニコ生放送でGit道場ラジオ行われていたりと、会場内はワイワイした感じでした。

作業は、ひたすら
編集 → pull → コンフリクト解消 → push
のくり返し。

1時間程作業を行った後、振り返りの時間がとられました。
チーム全員で、github でネットワーク図を見ました。
マスターからのマージコミットだらけで
「まるで地下鉄の路線図のようだ」(by 相澤さん)

しばし休憩。

<体>の部、第2イテレーション

はじめに小川さんから、
「リモートリポジトリからのプルには必ず git pull --rebase を使うように」
との指示がありました。

git pull コマンドは、実は以下のコマンドを合わせたものです。

  • git remote update
  • git merge origin/master

git pull のオプションに --rebase を指定する事で、以下のようになります。

  • git remote update
  • git rebase origin/master

merge を使わないで rebase を使う事で、マージコミットを作らないようにできるんですね。

という事で、第2部開始。
マージコミットできない!すげー!という感動よりも、度重なるコンフリクトの解消作業で疲労困憊。w

閉場

小川さんから、rebase について話があったように思いましたが、疲れていて話を聞けていませんでした。すみません。w

最後に相澤さんから閉場の挨拶。
門下生全員に師範代の認定が与えられました。
また、次回からは Git道場師範代の印である黒いリストバンドが配布されるそうです。:)

参加した感想

今回の目標は、
「merge/rebase を怖がらずにできるようになること」
でした。

作業としては、10行程度のテキストファイルに対して4〜5人でひたすら編集してはコンフリクト解消の作業を行うもので、はっきり言って面白い作業では無いです。w
しかしながら、普段の仕事で git を使っていて、1日でこれだけコンフリクトに会う事はなかなか無いので、とても良い経験になりました。
上記の目標も達成できたと思います。

道場の名に相応しい、ストイックでプラティカルな勉強会でした。

道場主である相澤さんを始め、師範代の岩松さん、小川さん、スタッフの皆さん、フューチャーアーキテクトの皆さん、又一緒のチームになった皆さん、どうもありがとうございました!

Gitによるバージョン管理

Gitによるバージョン管理


入門Git

入門Git

第2回 The RSpec Book 読書会をやっていました

実は、3/12 に The RSpec Book 読書会をやっていました。
もう2週間以上たってしまったけれども、記録を残しておきます。

今回やったのは、"Chapter 3 フィーチャを表現する" です。
この章からしばらく、"Codebreaker" という CUI のゲームをつくっていきます。
Codebreaker の作成を通して、BDD によるアジャイル開発を学べるようになっています。

Codebreaker のルールです。

  • プレイヤーは、コードブレーカーである
  • コードブレーカーは、コードメーカーによって作成された暗号を解くのが目標
  • コードメーカーは、1〜6までの4つの数字で暗号を作成する
  • コードブレーカーは、暗号を解く機会を何回か与えられる
  • コードブレーカーは、4つの数字(1〜6)を推測する
  • コードメーカーは、推測された数字に対して評価し、記号を返す
  • 推測された数字の1つが、場所・数字共にあっていれば + 記号
  • 推測された数字の1つが、数字のみあっていれば - 記号
  • + 記号は必ず - 記号の前に存在する
  • 暗号が 1234 で、推測が 4256 である場合、評価は +- となる

さっそくプロジェクトを開始します。

リリース計画

  • BDD の3大原則の1つ、「十分といったらもう十分」
  • ユーザーストーリー
  • ユーザーストーリーは、「役割+アクション」で表現する
  • 役割に焦点をあわせる
  • ユーザーストーリーから絞り込むには、コンテキストを考慮する
  • ユーザーストーリーは計画ツール
    • ビジネス価値がある
    • テストが可能
    • 1つのイテレーションで実装できるほど小さい

作成されたストーリーから、最初のリリースプランを絞り込みます。
次は、これをイテレーションに分解します。

最初のイテレーション計画

  • ATDP(Acceptance Test-Driven Planning)
  • ATDD(Acceptance Test-Driven Development)
  • ATDP は ATDD の拡張であり、その違いは受け入れテストを書くタイミングが決まっているかいないか
  • Cucumber でフィーチャを表現し、アプリケーションとやりとりする
  • Cucumber でのフィーチャは、タイトル、ナラティブ(narrative-物語)、シナリオの3つで構成される
  • タイトルはフィーチャが誰を対象とし、何に関するフィーチャなのかが分かるように書く
  • ナラティブは、システムが何をしたいかを、主に Connextra フォーマットで書く
  • シナリオは、フィーチャの受け入れ条件をかく
  • Cucumber には "シナリオアウトライン" という機能があり、フィーチャとシナリオを DRY に保てる

読みつつ写経しつつ…

第3章はここで終了です。
Cucumber でフィーチャを表現しただけです。
次章から Ruby のコードが出てくる…と思います。

次回は 4/2(月)に 20:00〜 株式会社万葉のオフィスでやります。
次は第4章をやる予定です。

The RSpec Book (Professional Ruby Series)

The RSpec Book (Professional Ruby Series)

第1回 The RSpec Book 読書会 をやりました

The RSpec Book の 日本語訳が出版されました。
実は、RSpec の本ってあまり無いのでは?
という訳で、タイトルに釣られて買いました。

The RSpec Book (Professional Ruby Series)

The RSpec Book (Professional Ruby Series)

そうしましたら、弊社の笠間さんも同時に買っていました。
それなら、という事で2人で読書会をすることになり、今週の月曜日に、第1回目の読書会を行いました。

読書会の事をかく前に、この本の概要を3行でまとめたいと思います。

  • RSpec の本ではない
  • Cucmber の本でもない
  • BDDを学ぶ為の本

まえがきにはこう書いてあります。

まんまと引っかかりましたね。RSpecの本だと思って手に取ったのでしょう。

これらのページを呼んでいるときに、ミームがこっそりと頭の中に忍び込みます。プログラミング手法に関するすべてのものを変えてしまいそうな可能性を秘めたミームです。

このミームの正体は何でしょうか。(中略)ミームとは、クラフトマンシップです。

このまえがきを読むと、胸が熱くなってきます :)

そしてこの本の注意事項としては、若干情報が古い事があげられます。
例えば、今は webrat より capybara を使う事が多いそうです。(ねずみ繋がりらしい!)
日本語訳になるのを待っていると、なかなか新しい情報を手に入れるのは難しそうです。
英語の本を積極的に読んでいく方が良いですね。
なので、個人的には BDD の心を学ぶ目的で読み進めています。


さて、読書会のスタイルとしては、交互に音読しつつ、必要そうな所で写経しつつ、という形でやってます。
何か良い読書会方法があればご教授いただきたいです :)

今回は、Capter1 「概要」と、 Capter2 「Hello RSpec」 を読みました。
これらは、Part1 「RSpec と Cucumber を使うための準備」の一部となっています。

Chapter1 は、TDD、BDD、RSpec、Cucumber、BDD サイクル について、簡単な説明が書かれていました。
以下、要約です。

  • アジャイル界隈で発展してきた TDD を、より推し進める形で、BDD が出来た
  • BDD とは、振る舞い駆動開発のことで、振る舞いを先に定義し、それに対して実装を行うもの
  • BDD の目的は、"そのソフトウェアが使われる状況を説明するための言語を単純化することで、コミュニケーションを後押しすること"
  • BDD の考え方を Ruby の Test に取り入れ発展させたものが RSpec
  • 誰でも読めるような形でかかれたものを、そのままテストに使えるようにと開発されたものが Cucumber
  • 実際の開発では、Cucumber でユーザーストーリを書いて実装し、実装の細かな部分を RSpec で書いていく
  • 上記の開発では TDD のサイクルである、Red/Green/Refactor で進める

Capter2 は、RSpec と Cucumber のインストール、Hello, World! の実装を、テスト→実装の形で行います。
この章の目的はそれぞれの環境構築と、使い方に触れるだけなので、リファクタリングはしていないです。
実際に写経し、動作確認を行いました。


次回の開催は 3/12(月) に株式会社万葉のオフィスで 20:00 位から行う予定です。
次は第3章。
ここからしばらくは、実際に Cucumber と RSpec を使ってゲームをつくっていきます。
単純な実装がリファクタリング経て綺麗になっていく様はいつ見てもかっこいいですね。
そしてそれを支えるテストが既にあるという安心感は、実際に TDD をやってみると良く分かります。


もしこのエントリーを読んで参加されたい方がいらっしゃったら、@tanaka51 までお願いします。
特に、atend とかで募集をかけて大々的にやる予定はないです:p

プログラマのキャリアと今年の抱負

明けましておめでとうございました。
今年もどうぞよろしくお願いいたします。

こうしてエントリを一つ書ききったのは結構久しぶりで、ちょっとした達成感に包まれています。w
そして時間が空くと文体が毎回変わっているような気がしますが気にしない方向でいきますよ。

twitter でもつぶやきましたが、すごく共感する記事を読んだので、思い切って書ききってついでに今年の抱負も書くことにしました。

去年を少し振り返り

私の去年の一番の大きな出来事は間違いなく転職です。
おかげさまでとってもよい会社に入る事ができ、素晴らしい人達にたくさん出会うことができました。

さて、転職するっていうことは、就職活動をしたわけで、何回か面接も受けました。
そんな中、キャリアプランを聞かれる事が実に多かったです。

あなたはどんなキャリアプランを考えていますか?

就職活動をはじめてからから最初の面接です。
「あなたはどんなキャリアプランを考えていますか?」
その質問の意味が分からず、思わず聞き返してしまいました。

もちろん、言葉としてのキャリアプランという意味は分かっていました。
しかしながら、どういう意図で聞いているのかがわからず…
私は、プログラマはそれだけで一つのキャリアで、それ以上も以下も無いと思っているからです。

お話を聞いていると、どうやら、
PG -> SE -> PM
という道を進む事を前提とした質問だという事が分かりました。

「あなたはどんなキャリアプランを考えていますか?」
という質問は、
「どのようにマネージャーになりたいと思っていますか?」
エイリアスだったようです。

間違いなく、プログラマが一番かっこいい

キャリアプランを聞かれた時は必ず
「ずっとプログラマでいたい」
と答えました。

それが素直な気持ちだったからです。
プロ野球選手を目指す少年野球チームの小学生みたいなもんです。

が、どうやらそういうキャリアプランっていうものは一般的ではないようです。
世の中、コードを書く奴は底辺だ、という考え方すらあるみたいでビックリです。

私は、プログラマほどすごい職業はないと思っています。
1から全てをやれるのはプログラマだけです。
これは、SEやPGになってはできないことですよね。

間違いなく、プログラマが一番かっこいい職業であり肩書きだと思っています。

プログラマという職業

今日読んだこの記事が、私が考えていてうまく言葉にできない事を代弁してくれているようで、思わずこのエントリーを書いた次第です。

私が「プログラマ」と呼ぶのは、要件定義から開発、データベース設計、運用フェイズまでこなせる人です。もちろん、お客さんと話せる能力も必要です。

PR:変わるSI構造の中で「価値あるプログラマ」として生きる

SonicGarden さんの採用情報も引用します。

プログラマという職業

私たちのビジョンには「プログラマを一生の仕事にする」というものがあります。プログラマはいつかマネージャになるキャリアを選ばなければ報酬はあがらなくなるということはありえません。

採用情報 - SonicGarden 株式会社ソニックガーデン

一般的なプログラマという考え方とは一線を画しているのではないかと思います。

今年の抱負

私はプログラマになりたい、と考えています。

去年はその為の一歩を、転職という形で実現することができました。
プログラマになるために最適な職場に転職できたと思っています。

今年は更にその一歩を進める年にしたいです。

具体的には
「1つ以上のWebサービスを作成・運用する」
事を今年の抱負にしたいと思います。

こんな風に抱負を掲げたのは初めてで少し緊張しますが…
年末、どんな結果が待っているのか自分ごとながら楽しみです。

no such file to load -- zlib への解決策

gem install やら gem update やろうとして、

$gem update
ERROR:  Loading command: update (LoadError)
    no such file to load -- zlib
ERROR:  While executing gem ... (NameError)
    uninitialized constant Gem::Commands::UpdateCommand

とかって怒られた場合の対処方法。

環境はUbuntu11 & rvm 1.8.4 & ruby 1.8.7

$cd ~/.rvm/src/zlib-1.2.5
$./configure
$make
$sudo make install

$cd ~/.rvm/src/ruby-1.8.7-p352/ext/zlib/
$ruby extconf.rb 
$make
$sudo make install
 
$gem update
$gem install rails -v 3.0.9

参考
http://d.hatena.ne.jp/shokai/20100919/1284908455

$ruby extconf.rb が失敗してるっぽかったら、
rvm配下にあるzlibをインストールすればおkだった。