mercurial

MQのタグ

hgのMQをつかうとパッチをあてたり外したりを機械的にできるようになるところが便利。

たとえば作業ディレクトリのリビジョン番号が1234だとしよう。

  1234        1235
__o___________o tip
  いまここ

じつは作業ディレクトリもひとつのチェンジセットだとおもうと hg parent で作業ディレクトリのリビジョンが表示されることに納得。

          work
          o
  1234   /    1235
__o_____/_____o tip
  いまここ

このときに hg qpush patch3 すると、こんなグラフになる。

              qbase           qtip,tip
          ____o_______o_______o
         /    patch1  patch2  patch3
__o_____/______o
  qparent      one of head
qparent パッチをあてた元チェンジセット
qbase いちばん先にあてたパッチ
qtip いちばん最後にあてたパッチ
tip 最後にcommitしたチェンジセット

ほんとtipって何の役にたつのかわからないが、たとえばパッチがあたった状態で hg pull してqparentの先がのびるとtipがかわる。

              qbase           qtip
          ____o_______o_______o
         /    patch1  patch2  patch3   tip
__o_____/______o_______________________o
  qparent                              one of head

diffのとりかたも、どことどこの差分を表示するのかでいろいろあってめんどくさい。

hg diff qtip(patch3)からworkへの変更(作業領域内での変更)
hg export qtip リビジョンpatch2からリビジョンpatch3への変更(patch3の内容そのもの)
hg qdiff patch3 + workの変更 (= hg export tip + hg diff)

実際にやってみるとこんなかんじ:

% cat -n foo
     1	export LANG=C
     2	export HGUSER=koie@example.jp
     3	rm -r repo
     4	hg init repo
     5	cd repo
     6	echo 111111111 >file
     7	hg add file
     8	hg commit -m xxx file
     9	hg qinit
    10	hg qnew patch
    11	echo 222222222 >>file
    12	hg qrefresh
    13	echo 333333333 >>file
    14	hg glog
    15	hg diff
    16	hg export qtip
    17	hg qdiff
% sh -x foo
+ export LANG=C
+ export HGUSER=koie@example.jp
+ rm -r repo
+ hg init repo
+ cd repo
+ echo 111111111
+ hg add file
+ hg commit -m xxx file
+ hg qinit
+ hg qnew patch
+ echo 222222222
+ hg qrefresh
+ echo 333333333
+ hg glog
@  changeset:   1:56e00314d749
|  tag:         patch
|  tag:         qbase
|  tag:         qtip
|  tag:         tip
|  user:        koie@example.jp
|  date:        Fri Nov 25 15:37:02 2011 +0900
|  summary:     [mq]: patch
|
o  changeset:   0:e0bf2be8ddd5
   tag:         qparent
   user:        koie@example.jp
   date:        Fri Nov 25 15:37:01 2011 +0900
   summary:     xxx

+ hg diff
diff --git a/file b/file
--- a/file
+++ b/file
@@ -1,2 +1,3 @@
 111111111
 222222222
+333333333
+ hg export qtip
# HG changeset patch
# User koie@example.jp
# Date 1322203022 -32400
# Node ID 56e00314d749987b2548cf4073f9202f9bb40c46
# Parent  e0bf2be8ddd5b4b2886984b82fe9faf9713a4604
[mq]: patch

diff --git a/file b/file
--- a/file
+++ b/file
@@ -1,1 +1,2 @@
 111111111
+222222222
+ hg qdiff
diff --git a/file b/file
--- a/file
+++ b/file
@@ -1,1 +1,3 @@
 111111111
+222222222
+333333333
%

pypyでmercurialを動かしてみた

FreeBSDの/usr/srcはhgsubversionでとってきていて、いまの/usr/srcは

% hg tip
changeset:   162828:8fff0f0c3911
svnrevision: 226824
tag:         tip
user:        alc@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
date:        2011-10-27 02:52 +0000 (27 hours ago)
summary:     contigmalloc(9) and contigfree(9) are now implemented in terms of other
% hg log -r0
changeset:   0:6d11119de1ac
svnrevision: 3
user:        rgrimes@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
date:        1993-06-12 14:49 +0000 (1993-06-12)
summary:     This commit was generated by cvs2svn to compensate for changes in r2,
%

というかんじで、最初からとってきているのでとてもでかい。途中のリビジョンからとってくればいいんだけど、せっかくなのでそのままにしてある。チェンジセットがたくさんあるせいなのか、hgコマンドはなにするにも1秒以上かかって、ちょっとイライラする。以前は数秒もかかってほんとうにイライラしたがhgsubversionなのかhgなのか改善されてましになった。

で、pypyというpythonの実装があるらしくて、素のpython(CPythonというらしい)よりも速いらしいので、じゃあためしてみるか、と。

portsにpypyがないのでFreeBSDでは動かないのかとおもったがチャレンジ。

Building from sourceをみながらpypyのインストール。

% hg clone https://bitbucket.org/pypy/pypy
% cd pypy/pypy/translator/goal
% python translate.py -Ojit  ←←まだpypyがないのでCPythonでつくる

途中コンパイルエラーも見えたような気がするがbuildはどんどん進んでいく。しばらくすると何かカラフルな模様がでてきて、なにかのプログレスバーかとおもってたら、上下対象の模様がみえだしてきてやっとマンデルブローだと気付いた。たしかにBuilding from sourceにも書いてある。で4GBのメモリが必要だとも書いてある。そのときは物理メモリは11GB載っているので問題ないぜ!とおもってた。もうかなりの時間がたつのに終わらないのでtopでみてみるとプロセスサイズが3.5GB(常駐3.0GB)になったところで頭打ちになってpageoutがはじまっていたので、できるだけ不要なプロセスを閉じて放置しといた。

夜になって終わってるかみてみたらまだ何かやっていてswapin/swapoutもおこっていた。どうやらZFSのARC(adaptive replacement cache)が3GBで下げ止まっている。しかたないのでX serverを止めたりしてみたが、ほとんどのプロセスからメモリが剥されたあとだったので効果なし。放置。

朝になったらおわっていたが、11時間ちかくかかったようだ。おそろしい。openoffice並だ。会社のpython野郎にきいてみたら自分でコンパイルしたことがないから知らんといわれた。最近の若いのはそんなんだよね。

[translation:info] usession directory: /tmp/usession-default-0
[translation:info] created: /home/koie/repo/pypy/pypy/translator/goal/pypy-c
[Timer] Timings:
[Timer] annotate                       ---  4436.3 s
[Timer] rtype_lltype                   ---  2757.3 s
[Timer] pyjitpl_lltype                 ---  4861.3 s
[Timer] backendopt_lltype              ---  2436.0 s
[Timer] stackcheckinsertion_lltype     ---   566.4 s
[Timer] database_c                     ---  5688.6 s
[Timer] source_c                       --- 13597.5 s
[Timer] compile_c                      ---  4305.5 s
[Timer] ============================================
[Timer] Total:                         --- 38649.0 s

とりあえずインストールイメージをつくってからインストール。

いろいろGNUツールやLinuxしか考えてないようなでFreeBSDではちょっと手直しが必要だった。tarはgtarに、グループrootはwheelに。linuxってgid=0はrootなんだね。はじめてしった。

diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -124,11 +124,11 @@
         else:
             archive = str(builddir.join(name + '.tar.bz2'))
             if sys.platform == 'darwin':
-                e = os.system('tar --numeric-owner -cvjf ' + archive + " " + name)
+                e = os.system('gtar --numeric-owner -cvjf ' + archive + " " + name)
             else:
-                e = os.system('tar --owner=root --group=root --numeric-owner -cvjf ' + archive + " " + name)
+                e = os.system('gtar --owner=root --group=wheel --numeric-owner -cvjf ' + archive + " " + name)
             if e:
-                raise OSError('"tar" returned exit status %r' % e)
+                raise OSError('"gtar" returned exit status %r' % e)
     finally:
         os.chdir(old_dir)
     if copy_to_dir is not None:
% cd pypy/tool/release
% python package.py ../../.. pypy-my-own-package-name
% cd /tmp/usession-default-5/build
% mkdir ~/tmp/pypy-a2b911e61392
% tar xvf pypy-my-own-package-name.tar.bz2 -C ~/tmp/pypy-a2b911e61392
% cd ~/tmp/pypy-a2b911e61392
% ln -s pypy-a2b911e61392 pypy

次はhgのビルド。

PYTHON=$(HOME)/tmp/pypy/bin/pypy に書き換えて gmake all して、 gmake PREFIX=$HOME/tmp/hg install。

そしてついに/usr/srcで簡単にベンチマーク。「hg log --style=compact >/dev/null」の実行時間を測ってみた。

cpython 113.216u 16.762s 2:10.19 99.8% 1458+1471k 0+0io 0pf+0w
pypy 149.352u 22.263s 2:51.88 99.8% 21542+28179k 0+0io 0pf+0w

どうみてもpypyの方が遅い。なんだこれは。ふたたびpython野郎に「どういうことなんだ、これはっ!」聞いてみたら、「まぁそんなもんですよ」って返事。脱力。パイパイって音からしてはずかしいのに使うのもはずかしいとは。またしても地球温暖化に貢献してしまった。

hg transplant

hg transplantの基本的な使い方を覚えた。

~/.hgrcか.hg/hgrcにこれ↓をいれると使えるようになる。

[extensions]
transplant=

transplantした結果は.hg/transplant/transplantsに記録されるようだ。ただhg cloneしたときに引き継がれないので注意が必要か。このへんが基本機能のmergeと扱いが違うところ。CVSではcherry pickが基本だったのでユーザがどこをマージしたのかを覚えておかなければならなかったが、hgではグラフ構造でマージ関係を覚えるのでマージがとてもわかりやすくなった一方で、特定の変更だけをとりこむことができなくなり、拡張機能として hg transplat が用意されている、とおもう。

以下ためしてみたときのログ。画像は https://bitbucket.org/koie/hg-dot/ で作成した。

% hg init repo
% cd repo
% echo "11111" >file
% hg commit -A -m initial file
% echo "22222" >>file
% hg commit -m second file
% echo "33333" >>file
% hg commit -m third file
% hg glog --style compact
@  2[tip]   4c711a087ccd   2010-12-28 13:39 +0900   koie
|    third
|
o  1   2a9a9bbae480   2010-12-28 13:39 +0900   koie
|    second
|
o  0   7c68bdadd780   2010-12-28 13:38 +0900   koie
     initial

% hg up 1
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
% echo "XXXXX" >>file
% hg commit -m hack file
created new head
% hg glog --style compact
@  3[tip]:1   f983fc95151f   2010-12-28 13:41 +0900   koie
|    hack
|
| o  2   4c711a087ccd   2010-12-28 13:39 +0900   koie
|/     third
|
o  1   2a9a9bbae480   2010-12-28 13:39 +0900   koie
|    second
|
o  0   7c68bdadd780   2010-12-28 13:38 +0900   koie
     initial

3

% echo "YYYYY" >>file
% hg commit -m hack2 file
% hg glog --style compact
@  4[tip]   c80cf7c8095d   2010-12-28 13:43 +0900   koie
|    hack2
|
o  3:1   f983fc95151f   2010-12-28 13:41 +0900   koie
|    hack
|
| o  2   4c711a087ccd   2010-12-28 13:39 +0900   koie
|/     third
|
o  1   2a9a9bbae480   2010-12-28 13:39 +0900   koie
|    second
|
o  0   7c68bdadd780   2010-12-28 13:38 +0900   koie
     initial

4

% cat -n file
     1  11111
     2  22222
     3  XXXXX
     4  YYYYY
% hg up 2
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
% cat -n file
     1  11111
     2  22222
     3  33333
% hg transplant 4
applying c80cf7c8095d
patching file file
Hunk #1 FAILED at 0
1 out of 1 hunks FAILED -- saving rejects to file file.rej
patch failed to apply
abort: fix up the merge and run hg transplant --continue
% cat file.rej
--- file
+++ file
@@ -1,3 +1,4 @@
 11111
 22222
 XXXXX
+YYYYY
% cat -n file.rej
     1  --- file
     2  +++ file
     3  @@ -1,3 +1,4 @@
     4   11111
     5   22222
     6   XXXXX
     7  +YYYYY
% cat -n file
     1  11111
     2  22222
     3  33333
% (EDIT)
% cat -n file
     1  11111
     2  22222
     3  33333
     4  YYYYY
% hg transplant --continue
c80cf7c8095d transplanted as 22e2895df1d2
% hg glog --style compact
@  5[tip]:2   22e2895df1d2   2010-12-28 13:43 +0900   koie
|    hack2
|
| o  4   c80cf7c8095d   2010-12-28 13:43 +0900   koie
| |    hack2
| |
| o  3:1   f983fc95151f   2010-12-28 13:41 +0900   koie
| |    hack
| |
o |  2   4c711a087ccd   2010-12-28 13:39 +0900   koie
|/     third
|
o  1   2a9a9bbae480   2010-12-28 13:39 +0900   koie
|    second
|
o  0   7c68bdadd780   2010-12-28 13:38 +0900   koie
     initial

%

5

「分散バージョン管理勉強会」にいってきた

dscn5241都営大江戸線の門前仲町から歩いた。暗いし方向音痴なのでかなり不安になりながらも、一発で到着できた。厚着してたせいで、汗をかいてしまった。

電源の延長ケーブルは2mのをもっていったが、ちょっと足りなくて、机の上まで届かず失敗。

WiMAXはアンテナ2本立ってだいじょうぶだった。


[最初の挨拶]d76eaf11.jpg

  • 挙手でどのユーザが多いかみてみると:
    • git多数
    • hg少数
  • スイーツいっぱい食べてください。大福はいちご・くり・バナナ・わさび(大当り)。
  • お茶もあります。

[一般発表]

1. おかもとさん - 前説 分散バージョン管理システムってなんなん?

  • さわりであっておさわりではない
  • エルシャダジャイル?
    • 「そんな担当者でだいじょうぶか?」
  • Trac Lightning
  • OSSバージョン管理システムの発展
    • CVS: 共有モデル、ファイル単位の履歴
    • Subversion: アトミックなコミット(途中で死んでもだいじょうぶ)、タスク単位での履歴管理
    • 分散バージョン管理: ブランチマージモデル、ローカルコミット、ログのリファクタリング、マージトラッキング
  • いろいろ
    • git:
      • google trendsでいちばん多い。
      • linux/ruby系につかっているひとが多い。
    • hg: mercurialは盗賊の意味もある。subversionからシェアをうばってやるぞ!といういみもあるか?。スポンサーがおおい。
      • google trends: フランス(ヨーロッパ圏)で強い?
      • リビジョンがハッシュでなくて数字もあるのでわかりやすい。TortoiseHgでwindowsでばっちり。
    • bazaar:
      • gnuプロジェクト、日本語のあつかいが完璧。

2. bleis - GitとHudsonによるきれいなリポジトリの作り方

  • ソフトウェア開発に対する思い:
    • 集中管理型だと間違った操作がすぐに全体に影響をあたえてしまう。
    • 誤操作を恐れるあまり、日付のついたディレクトリをつくってしまったり。→VCつかっている意味なし。
    • 1つのリポジトリに対して1つの作業領域しかもてない。
    • DVCSだと更新先を複数もてる。
  • DVCSだけでは解決でいない問題:
    • ビルドできなくなるとか。
  • きれいなリポジトリとは:
    • ここでは「最新版がいつでもビルド可能なリポジトリ」のこと。
  • CI(継続的統合;continuous integration)を導入する:
    • ビルドがこわれるとすぐにフィードバックがえられる。
    • 用語定義:
      • 開発者ごとのブランチ: private branch
      • 開発者ごとのリポジトリ: private repository
      • きれいなリポジトリ: central repository
    • ブランチをわける方法:
      • hookでmaterブランチにpushできないようにする。
      • ビルドに成功してもfast forward mergeできなかったら拒否する。
      • 手軽。CIを増やすだけ。
    • リポジトリを分ける方法:
      • central repositoryは外部からは取得専用に、localからのpushは許可。
      • 更新の流れ(更新の循環): centralリポジトリ→(pull)→手元のリポジトリ→(push)→中央のプライベートリポジトリ→(CI)→centralリポジトリ
      • ロールバックすれば簡単に元にもどせるのがミソ。
      • リポジトリ単位でhookを設定できるのでhookを入れる個所が多いのが利点。private repoで単体テストをやって、central repoで結合テストをするとか。
  • Q: CIのジョブはどうやって管理してるのか?
  • A: scalaで。(外野)グルービーとかがいいじゃない?
  • Q: リベースがうまくいかかいとつらい?
  • A: ?

[休憩(15分)]

3. ゆかわさん - TracLightningとTortoiseHgのゆるふわな連携

  • pythonで書かれている。
  • http://martinfowler.com/bliki/VersionControlTools.html
    • hgはgitよりもオススメで、gitよりも簡単!
    • bzrはどこいった!
  • hgはsubversionににている。
  • 1コマンド1機能
    • gitは1つのコマンドでいろんなことができるので、そのぶんオプションが多い。
  • MQはあえていうならgitのステージににている。
  • ブランチにいろいろある:
    • hg clone
    • hg bookmark
    • hg branch
    • 名前なしブランチ
  • hgsubvresionは重い。日本語ファイルはだめ。
  • hgでは拡張機能をつかう必要がある。基本機能だけだとちょっとつらい。

4. riskさん - git-svn使ってみる?

  • 職場でしかコミットできないとか、客先に行かないとできないとか。そのような場合にgit-svnが便利。
  • とりあえずおぼえておくコマンド:
    • git-svn: clone dcommit rebase
    • git: branch checkout add rm revert reset status log commit merge
  • gitとsvnの対応表:
----------------- --------------
git svn clone svn checkout
----------------- --------------
git branch svn branch
git checkout
----------------- --------------
git commit svn commit
----------------- --------------
git svn rebaes svn update
----------------- --------------
git merge ???
----------------- --------------
git svn dcommit svn commit
----------------- --------------

5. monjudohさん - Mercurialで別オリジンのリポジトリ間で同期を取る運用の仕方について

  • 素朴なやりかた:
    • hg clone django-apps
    • cd django-apps
    • hg pull --force django-static
    • mergeできるけどやったら二度とぶんりできない。pushするとくっついてっちゃう。
  • 別のやりたかた:
    • hg update djsnag-apps-head
    • hg revert statis/ -r django-static-head
    • hg commit -m "message"
    • 履歴がきえちゃうのが問題。
  • transplantをつかうやり方:
    • hg pull django-static
    • hg update django-apps-head
    • hg transplant
  • まとめ:
  • django-apps からpull
  • ldjango-stati-headへtransplant
  • django-static個人へpush
    1. hg push django-static -f -r django-static-head
  • django-staticでrebase
  • django-staticからpull
  • django-apps-headへtransplant
    1. 必要ならtransplantした分をcommit圧縮
  • django-appsにpush
  • Q: subrepostoryの方が簡単では?
  • A: 最初からできるならsubrepositoryをつかう方が簡単だけど。途中からだと。

[休憩(10分)]

[LT発表]

1. 神速さん - Git での歴史の改変方法の紹介

  • 資料はReST。その場で作成
  • rst2s5.pyでReSTからHTMLに変換。
  • add -p 部分コミット
  • rebase -i ローカルだけで 歴史の改変 順序の入れ換えがでいる

2. iwataさん - SVNユーザのためのBazaarガイド

  • バザー。バザールではない
  • concenpts:
    • version control for human beings → バカでもつかえるバージョン管理
    • better svn
      • checkoutするとbindされた状態になる。commitするとすると自動でpushされる。集中型っぽいふるまい。もちろんlocal commitもできる。

3. さぼてんさん - Hudsonからみるバージョン管理

  • pre-test commit
  • TeamCity
  • きれいなコミットができる
  • (ここでbleisさんのブランチを分ける方法と同じ絵がでてくる)

4. かわにしさん - ビューティフルなデバッグの話

  • git bisect
  • しんそくさんの「ナンパ」になった時期をしらべる。
    • 事前にtwitterの内容をcommit済で、pythonで文字列"ナンパ"を探すテストプログラムをくわせる。

[最後の挨拶]

  • - 9回目

[後片付け]

帰り道

dscn5243江東区は路上喫煙okなので、けっこう吸ってる人がおおいな。

五反田よりもずっとにぎわっている。

忘年会シーズンなので50くらいのおっさん・おばさんが大声を出して街をさまよってた。

hgsubversionでとってきたけどsvnのリビジョンをしりたいとき

hgsubversionでFreeBSD svnをもってくるのつづき。

.hg/svn/rev_mapにhgとsvnのリビジョンの対応関係が記録されているので、これをもとに.hg/localtagsを生成すれば、-r オプションで svn のリビジョンを指定できるようになる。また hg log でタグとしてsvnのリビジョンがわかる。
ただFreeBSDのheadをとってくると2010-12-02の時点でリビジョンが157081もあり、これを全部localtagsに変換するとhgの動作が極端に遅くなるため、直近の10000個(15分の1)にすることで実用的な範囲に収めている。
さらに、localtagsを時系列と逆順にした方が速くなるっぽいので/usr/local/bin/gtac (in sysutils/coreutils)をつかっている。
スクリプト:

awk 'NF==2{print $2 " svn-r" $1}' .hg/svn/rev_map | tail -10000 | gtac >.hg/localtags
使用例:
% hg log -r svn-r216107
changeset:   157078:17db89e84c98
tag:         svn-r216107
user:        lstewart@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
date:        2010-12-02 02:32 +0000 (29 hours ago)
summary:     General cleanup of the NewReno CC module (no functional changes):

%


2010-12-06追加:
hgsubversion/hgsubversion/help/subversion.rst をみると、templateで {svnrev} がつかえるとか、リビジョン指定で -r 'svnrev(500)' とできるとか、便利になってた。
~/.hgrc or .hg/hgrc の例:

[ui]
style=~/.hgstyle

~/.hgstyleの例:
changeset = 'changeset:   {rev}:{node|short}\nsvnrevision: {svnrev}\n{branches}{
tags}{parents}user:        {author}\ndate:        {date|isodate} ({date|age})\ns
ummary:     {desc|firstline}\n\n'
changeset_quiet = '{rev}:{node|short}\n'
changeset_verbose = 'changeset:   {rev}:{node|short}\nsvnrevision: {svnrev}\n{br
anches}{tags}{parents}user:        {author}\ndate:        {date|isodate} ({date|
age})\n{files}{file_copies_switch}description:\n{desc|strip}\n\n\n'
changeset_debug = 'changeset:   {rev}:{node}\n{branches}{tags}{parents}{manifest
}user:        {author}\ndate:        {date|isodate} ({date|age})\n{file_mods}{fi
le_adds}{file_dels}{file_copies_switch}{extras}description:\n{desc|strip}\n\n\n'
start_files = 'files:      '
file = ' {file}'
end_files = '\n'
start_file_mods = 'files:      '
file_mod = ' {file_mod}'
end_file_mods = '\n'
start_file_adds = 'files+:     '
file_add = ' {file_add}'
end_file_adds = '\n'
start_file_dels = 'files-:     '
file_del = ' {file_del}'
end_file_dels = '\n'
start_file_copies = 'copies:     '
file_copy = ' {name} ({source})'
end_file_copies = '\n'
parent = 'parent:      {rev}:{node|formatnode}\n'
manifest = 'manifest:    {rev}:{node}\n'
branch = 'branch:      {branch}\n'
tag = 'tag:         {tag}\n'
extra = 'extra:       {key}={value|stringescape}\n'
記事検索
月別アーカイブ
アクセスカウンター

    タグ絞り込み検索
    ギャラリー
    • 今日の練習 2018-11-13
    • 今日の練習 2018-11-11
    • 今日の練習 2018-11-11
    • 今日の練習 2018-11-10
    • 今日の練習 2018-11-10
    • 今日の練習 2018-11-10
    Amazon
    楽天市場
    adby google
    LINE読者登録QRコード
    LINE読者登録QRコード
    • ライブドアブログ