彷徨えるフジワラ

年がら年中さまよってます

SCMBootCamp in Tokyo 2 を振り返って

※ 2011/11/27 追記あり
時間枠中は、Twitter のタイムラインを見ている暇が無かったので、togetter でのまとめを元に、落穂拾い的に tweet された質問/疑問に答えることに。

まとめて頂いた @shinyaa31( id:absj31 ) 氏に感謝!(※ @shinyaa31氏自身のまとめはこちら)

そして、改めて主催の id:kyon_mm 氏に感謝!

基調講演枠での tweet

講演内容は好評だったようで一安心。

SCM ツール世代分類に関して:

(@oota_ken) ClearCaseClearCaseClearCase

まぁ多分、「ClearCase も忘れないであげてください」ニュアンスだとは思うけど、一応答えておく事に(笑)。

私自身、ClearCase を触ったことが無いので、『パターンによるソフトウェア構成管理』に記載された情報ベースで見る限りでは、BitKeeper に関する説明で、「リポジトリと作業領域の統合」+「リポジトリ間での連携」に関して明言している一方で、ClearCase の説明では、そういった事に一切触れていないので、多分第2世代。

>>>> 2011/11/21 追記: ここから

最初は上記の tweet が「SCM ツール世代分類」に関してのものだと思ったのだけど、基調講演のビデオを見返してみたら:

  1. 参加者の SCM ツール利用歴について、僕の方から確認の質問
  2. 会場から「Subversion は SCM ツールに含めて良いですか?」と質問
  3. 僕が「Subversion が SCM ツールではない、などという差別的な発言はしません!」と回答

というやり取りの中で、各種ツールの名前を列挙した際の tweet な気がしてきた。

RUP 繋がりで ClearCase は知っていたのだけど、ド忘れで名前が出てこなかったのだ....orz

ちなみに、「Bryan O'Sullivan 氏が Mercurial の開発中枢から抜けざるを得なくしてしまった元凶」ネタで BitKeeper に関しても言及すれば良かったと後から気が付いた .... orz

<<<< 2011/11/21 追記: ここまで

(@nobusue) 次の商品を購入しました:'入門Mercurial Linux/Windows対応':藤原 克則

お買い上げありがとうございます!皆様による地道な購買が、増刷 ⇒ 改訂版出版の原動力です!(笑)

「21世紀のバイトあたり記録単価」に関して:

(@shin_semiya) いま2TBは1万円では買えませェん!
(@methane) 2Tで1万切ってる時代は一時的に中断してるけどねw

被災されているタイ国民の皆様には、謹んでお見舞い申し上げます。

(@naka_aki_spl) ていうかさ、まともなバージョン管理ツールだと、差分保持とかしてるから、かえってディスク安上がりじゃね?とか思うことが時々。リポジトリ案外小さいんだよね

Git の格納形式だと、個々のリビジョン時点の内容を保持している(= スナップショット相当)ので、厳密には「まともなバージョン管理ツール = 差分保持」は間違い。

完全な「差分格納」だと、特定時点の状態の再現をするために、多数の差分を積み重ねる処理が必要となり、応答性能の点で問題がある。

例えば、CVS の履歴管理情報は、一番アクセスが頻繁な「最新の状態」のみを現物で保持し、古い状態に遡る際には、記録された変更履歴を逆順で適用する、という手法を用いている。直近の数回分の変更を遡るには問題無いが、遡る履歴が 100 とか 1000 とかなった場合の性能劣化は容易に想像が付く。

そこで Mercurial では、動画符号化で言うところの「キーフレーム」的なコンセプトを導入することで、一定数以上の履歴は遡らなくても良いようになっている。

# 詳細は "4.2 Safe, efficient storage" 参照

Git の「スナップショット格納」は、「ストレージ効率」よりも「応答性能」を選択した結果と言える。

以前、 Git が「リビジョン毎の完全な状態保持」から「(一部?)差分格納」へ舵を切った、とかいう噂を耳にして、「何事もお互いの長所を取り込んで中庸に収束するんだなぁ」と思ったのだけれど、SCMBC 開催準備のチャットで Git 系スタッフに聞いたら、特にそんな話は聞いてないとの事だったので、今でも「スナップショット格納」のままっぽい > Git

なので、21 世紀のバイトあたり記録単価はわかるが、ストレージ効率を優先したい!というのであれば、Git よりも Mercurial (or Bazaar ?) の方が良いかも。

基調講演ネタでは無いけれど:

(@naka_aki_spl) そういやこないだも喚いたけど、 DVCS over SMTPとかは有るんだべか?

Mercurial では:

  • patchbomb エクステンション(標準同梱)を用いることで、リポジトリ内のリビジョンを電子メールで送信可能
  • "hg import" コマンドによる取り込みには、電子メールをそのまま入力可能

という仕組みがあるので、SSH/HTTP 以外の伝送経路として SMTP を選択する事も可能。

これも基調講演外のネタ:

(@naka_aki_spl) 分散リポって味噌はつまり「バージョンは通し番号じゃなくランダムぽいやつ」だと思っていい?

Git や Mercurial が影響を受けた monotone が、リビジョンの一意識別にハッシュ値を用いたのが起源っぽい。("1.2 A short history of revision control" 参照)

ちなみに、Mercurial でのハッシュ値算出には、「親リビジョン」「ユーザ名」「日付」等も使用されているので、Mercurial のテストセットでは、「ユーザ名」「日付」を固定して、記録されるリビジョンのログ出力が変動しないようにしている。

Git 入門セッション枠での tweet

履歴分岐ネタに関して:

(@methane) rebaseの何が嬉しいのか未だに理解できない。履歴が直線じゃないグラフになるのがそんなに嫌なの?

履歴が分岐すればするほど、第3世代 SCM っぽくて胸が熱くなる自分(笑)としては、激しく同意。

もっとも、"hg bisect" で問題リビジョンを探す時などは、マージが入ると検索効率が落ちてしまうので、一直線である方が便利ではあるけれど、「一直線でないと駄目」的な潔癖症はちょっとなぁ。

# 一応 Mercurial にも rebase エクステンションがあるけれど...

Mercurial/Bazaar 入門セッション枠での tweet

コマンド挙動に関して:

(@suzzsegv) Git と Mercurial で pull と fetch が逆だった記憶が。

これ、確か昼食時にも @troter 氏と話した記憶が....

その時にも話したのだけれど、この逆転現象って、"fetch" (取ってくる) のニュアンスが、「リポジトリ to リポジトリ」に掛かるのか、「リポジトリ to 作業領域」に掛かるのかの差に思える。

時として Git ユーザ自身が「履歴管理は高速/強力で素晴らしいけれど、UI 設計はアレ」と表現するのを目にするのだけれど、「データ管理さえ出来れば、後は好きな UI を選べば(or 実装すれば)いいジャン!」なポリシーと、fetch のニュアンスが「リポジトリ to リポジトリ」に掛かっているあたりが、一貫していて面白い。

.hgignore 運用に関して:

(@katzchang) ignore設定とかって複数ヶ所でできるけど、実際はどう使い分けるべきなんだろう。

使い分けるとしたら、ユーザ毎設定 (${HOME}/.hgrc とか) には常用するエディタとか環境に固有の設定、リポジトリ毎設定には成果物/作業形態固有の設定かなぁ。

とは言っても、システム毎/ユーザ毎の設定を前提にすると、他の環境で作業する際に不都合が生じるので、僕は基本的には毎回リポジトリ毎設定に列挙しているけれど (^ ^;;;) 。「完結している」事が重要なのだ。

>>>> 2011/11/27 追記:ここから

.hgignore 読み込みの運用例に関して、なるほどと思われるものが、本家の user-ml に投函されていた

ファイル名では判定できないような除外判定 (user-ml では「シンボリックリンクのみを除外したい」というケース) の場合に:

  • リポジトリの作業領域等に対象ファイルの一覧を格納するファイルを配置
  • リポジトリの .hg/hgrc における ui.ignore 設定で上記ファイルを読み込み

とすることで、ファイル名パターンでは判定できない軸から、除外ファイルを指定することができる。

後は一覧ファイルの更新が問題になるのだが、pre-commit フック等で一覧妥当性をチェックして、更新が必要ならエラー中断させる、とかいうのが良いのかな?

<<<< 2011/11/27 追記:ここまで

リビジョンの持つ情報に関して:

(@katzchang) 「ぱっと見、見えない場合あり)」とは?

これ、その下に例示したような、"hg log" 出力を前提としての記述です。

その場で補足すればよかったのだけれど、"hg log" で出力される情報に「親リビジョン」 (parent) が表示されない状況を指している。

Mercurial の log コマンド系出力 (parents とか tip とかね) では、親と子のリビジョン番号が連続している場合、親リビジョンの表示を省略する、という仕様があって、UI 的に「ぱっと見、見えない場合あり」なのだ。

名前付きブランチに関して:

(@katzchang) mercurialの場合、ブランチ名はリビジョンの属性の一つということでよろしかったでしょうか?

よろしかったです。

「名前付きブランチ」における「名前」は、「枝分かれ」に付くのではなく、ニュアンス的には「リビジョングループ」を特定するための属性。

但し、ブランチ名が単なる属性として管理されている事により、困った事態もあって、「ブランチの分岐元リビジョン」を特定するのが面倒だったりする。

まぁ、間接的な手としては、そのブランチの一番リビジョン番号の小さいリビジョン = ブランチの最初リビジョンを探して、その親リビジョンを特定する、という方法で出来なくも無い。

でもそれって面倒じゃねぇ?ということで、「入門 Mercurial」での名前付きブランチの説明でも書いたけど:

ブランチの最初のリビジョンは、分岐元リビジョンに「ブランチ名-base」をタグ付けするリビジョン

という方法がお勧め。こうすれば、ブランチの分岐元の参照には「ブランチ名-base」を指定すれば良くなる。

ツール間の差異に関して:

(@oota_ken) 用語がツールによって違うのはまだ発展途上だからなんだろうけど混乱しそう。

そのうち、Rational が Grady BoochIvar Hjalmar JacobsonJames Rumbaugh の「スリーアミーゴス」を抱えることで、オブジェクト志向設計の記法が UML に統一されたように、第3世代 SCM にも、にも、..... 来る気がしないなぁ(笑)。

マルチプルヘッドに関して:

(@shin_semiya) マルチプルヘッド怖い

むしろ、マルチプルヘッドこそが第3世代 SCM っぽくて燃える!というのが、正しい Mercurial 使いです(嘘)。

昼食時間枠での tweet

著者サインに関して:

(@shin_semiya) たった今藤原さんの大サイン会が会場後方で開催されています。判によるサインのデザインパターン化が約束する高い生産性と品質。
(@ebc_2in2crc) 入門 Mercurial の著者の藤原さんにサインいただきました!(三食刷り

折角購入してもらった書籍に悪筆のサインだけでは申し訳ないので、手製消しゴム判子による3色刷りなどを。

作った際の試し刷りはスタンプ用インクを使ったのだけれど、速乾性/発色の点から、最近は専ら顔料インクを使用。

コマンドの挙動に関して:

(@ebc_2in2crc) 藤原さん「ヘルプを見ないでソースを見ちゃうクセがついちゃってるからなー」

いや、細かい挙動のニュアンスとか、デフォルト値とかが、オンラインヘルプに書いてないことも多いので....

そんなことやっているから、翻訳漏れ/間違いとかがあるんだよなぁ(反省) ... orz

演習枠での tweet

リポジトリホスティングに関して:

(@tomy_kaira) https つかったほうがかしこかったですね
(@bleis) あ、後ろって俺の席から見て後ろのBazaarチームで、pagentとかの話が聞こえてきたので

僕も bitbucket が、push on HTTPS を受け付けるのを知らなくて、最初は SSH で話を進めてしまった...orz

あと、TortoiseHg には puttySSH クライアントが同梱されているのも忘れてた .... orz

演習作業に関して:

(@oota_ken) うちのチームのコミット68個のうち、40個がマージだそうです・・・

おそらく Mercurial で一番面倒臭い作業である、コンフリクトの解消手順 ("hg pull" ⇒ "hg merge" ⇒ "hg resolve -m" ⇒ "hg commit") を体得するには、CUI/GUI 共に実地経験が必要なので。

っつーか、盛大なマルチヘッド/コンフリクト祭りのせいで、「名前付きブランチでの作業分離」とかの運用例を出来なかったのは、本当に申し訳ない! ... orz > フジワラ卓で参加された皆様

トーク枠での tweet

ハートマン軍曹チックな発言に関して:

(@ebc_2in2crc) 藤原さん「コンフリクトマークを何度も消していかないと一人前の兵士にはなれないぞ!」

俺がこの世でただ一つ我慢できないのは----"resolve -m" し忘れた commit だ! (abort するという意味で)

コンフリクト修正は、エディタで事後修正するにしろ、GUI ツールを使うにしろ、やり方に慣れておかないと、次に何をやれば良いのか、見失っちゃうからねぇ。

っていうか、ちょっとマジで TortoiseHg の UI に習熟しておかないと、この手の集まりで右往左往しかねないなぁ > 自分

懇親会枠での tweet

バイナリファイルに関して:

(@sinsoku_listy) バイナリファイル(例えばエロ動画)を更新しないのであれば、管理すべきなのはファイルへのアクセス手段でいい。masterにはシンボリックリンクがないけど、eroブランチにはシンボリックリンクがあって、シンボリックリンクリポジトリ内のバイナリを指しているような。

(@wonderful_panda) そういうようなことをしてるのがhgのlargefile extentionらしいですよ。

Mercurial では 2.0 から largefiles エクステンションが正式サポートされているけど、2.0 版は軽微なバグがあるので、今月末の 2.1 リリースを待つか、適宜 "rm .hg/largefiles/dirstate" をやるかの二択。まぁ、今から使うなら、2.1 待ちがお勧め。

largefiles エクステンションでは、リポジトリ毎にバイナリファイルを保存する以外に、ユーザ毎のキャッシュ (${HOME}/.cache/largefiles 配下とか) されるので、同一起源のリポジトリの複製を多数持つ場合は、遠隔連携回数が抑止されるし、同一ファイルシステム上なら管理ファイルはコピーではなくハードリンクを使うので、消費容量も低減される。

マージに関して:

(@naka_aki_spl) しかしhg、svnよりは遥かに拙速さが解消されてるとはいえ、それでも「mergeで出た差異なのか、俺手書きの差異なのか」がstatusで判るわけじゃないってのは、残念だと思った。やっぱりscmも発展途上なのかなあ

マージした際に、マージ対象側の枝での変更が作業領域に反映されるから、自分が変更してなくても「変更」扱いになっている、というのは、確かに人によっては結構違和感かも。

一応、Mercurial未記録成果ベースのマージが出来るけれど、基本は commit 済み成果ベースのマージが推奨ワークフローなので、"hg parents" で親の数を確認する (= 2つならマージ中) のが妥当かな?

(@naka_aki_spl) 「意図的におこしたマルチヘッドまつり」は凄く良かったです。現場(勉強会という発想を持たないような)だとマルチヘッドまつりなんて「バカに付き合ってくれる」隣人は滅多に居なく、いざ生じる時といえば本当のトラブル時なので。ありがとう!「練習大事だよね!」と。

そう言ってもらえるとありがたいです。