読者です 読者をやめる 読者になる 読者になる

MQの適用済みパッチをrebaseする #mercurialjp

このエントリはMercurial Advent Calendar 2013 の16日目です。

MQを使っていて困るのが、ファイル名の変更です。

  1. あるファイルAに対してパッチaを作成していて
  2. 最新版を取り込んだらファイルAはファイルBに変更されていて
  3. 最新のソースにパッチaが簡単に適用できない

的な。こんなときはhg rebaseを使いましょう。

下準備

確認用のリポジトリを作成します

$ hg init mq+rebase
$ cd mq+rebase

ファイルを追加してコミット&編集してコミットします。

$ vi README
$ cat README
README
======

りーどみーです
$ hg add README
$ hg ci -m "add README"
$ hg mv README README.md
$ hg ci -m "rename README.md"

変更前に移動して、ファイルを変更してMQのパッチを作ります。

$ hg up 0
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ vi README 
$ hg qnew fix-readme.diff
$ hg qdiff
diff --git a/README b/README
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
 README
 ======

-りーどみーです
+READMEです

ここまでで、次のようなグラフになっています。

$ hg log -G --style compact
@  2[fix-readme.diff,qbase,qtip,tip]:0   6dd9b66a5c49   2013-12-14 18:09 +0900   trot
|    [mq]: fix-readme.diff
|
| o  1   fd9f6575c27b   2013-12-14 18:09 +0900   trot
|/     rename README.md
|
o  0[qparent]   a7b49ee46b61   2013-12-14 18:09 +0900   trot
     add README

MQに対してhg rebaseを行う

では適用済みのパッチであるrevision 2revision 1にrebaseしてみます。

$ hg rebase --source 2 --dest 1 --keep
merging README.md and README to README.md
patch fix-readme.diff finalized without changeset message

変更内容とグラフはこんな感じ。

% hg qdiff
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
 README
 ======

-りーどみーです
+READMEです
% hg log -G --style compact
@  3[fix-readme.diff,qbase,qtip,tip]:1   4cc4f45e60a3   2013-12-14 18:09 +0900   trot
|    [mq]: fix-readme.diff
|
| o  2:0   6dd9b66a5c49   2013-12-14 18:09 +0900   trot
| |    [mq]: fix-readme.diff
| |
o |  1[qparent]   fd9f6575c27b   2013-12-14 18:09 +0900   trot
|/     rename README.md
|
o  0   a7b49ee46b61   2013-12-14 18:09 +0900   trot
     add README

やりましたね!

パッチかリビジョンか

hg rebaseの対象にする適用済みパッチの範囲によってちょっと挙動が異なるので、説明しておきます。

  1. 対象が適用済みパッチすべての場合

    • hg rebase後の新しい変更はパッチになる
    • (--keepした場合)元の変更はリビジョンになる
  2. 対象が適用済みパッチの一部の場合

    • hg rebaseは失敗するので
    • hg rebase --abortで復旧する(このときゴミリビジョンが残る)

リビジョンの指定を誤り2のケースを行ってもパッチは壊れません。安心して使えますね。

追記:MQをバージョン管理している場合。

今回の例の様にhg rebaseはパッチの内容を変更する操作でもあります。MQをバージョン管理している場合、hg rebase実行後はhg st --mqhg ci --mqを忘れないようにしてください。

まとめ

  • MQの適用済みパッチに対してhg rebaseが行える。
  • hg rebaseするときは適用済みパッチすべてを対象にするよう気をつける。

hg cloneする時に利用できるリポジトリの指定方法について #mercurialjp

このエントリはMercurial Advent Calendar 2013 の7日目です。*1 hg cloneするときのURLについて書きます。

基本編

通常hg cloneに次のようなURLを渡すことでリポジトリをクローンすることができます。

$ hg clone path/to/local/repo
$ hg clone file:///absolute/path/to/local/repo
$ hg clone http://bitbucket.org/troter/home
$ hg clone https://bitbucket.org/troter/home
$ hg clone ssh://hg@bitbucket.org/troter/home

省略形を利用する

Schemes エクステンション*2を有効にすると、Mercurialホスティングサイトに向けの省略記法が利用できるようになります。

# .hgrc
[extensions]
schemes =

Schemes エクステンションを有効にすると、次の省略形が利用可能になります。

省略形 展開されるURL
py://cpython http://hg.python.org/cpython
bb://troter/home https://bitbucket.org/troter/home
bb+ssh://troter/home ssh://hg@bitbucket.org/troter/home
gcode://go https://go.googlecode.com/hg/ *3
kiln://hoge/bar https://hoge.kilnhg.com/Repo/bar

詳しくは次を参考にしてください。

省略形を定義する

schemesというセクションを利用することで自分で省略形を定義することもできます。定義してみましょう。

# .hgrc
[schemes]
codeplex = https://hg.codeplex.com/

この定義で、次の省略形が利用可能になります。

省略形 展開されるURL
codeplex://nakedobjects https://hg.codeplex.com/nakedobjects

社内リポジトリ用に設定すると便利です。

hg clone後に移動したいリビジョンを指定する

省略形を含めURLにフラグメントを使うとhg clone後に移動するリビジョンを指定できます。次の例ではリポジトリクローン後stableブランチに移動します。

$ hg clone http://hg.intevation.org/mercurial/crew/#stable
destination directory: crew
adding changesets
adding manifests
adding file changes
added 20047 changesets with 38585 changes to 2219 files
updating to branch stable
1032 files updated, 0 files merged, 0 files removed, 0 files unresolved

追記:この方法を利用するとhg pull時のリビジョン(ブランチ)もフラグメントのものが利用されます。特定のブランチのみ利用するリポジトリ(CIサーバーや、ステージング環境、など)で活用してください。 id:flying-foozyさんアドバイスありがとうございます。

まとめ

*1:大遅刻ですが。。

*2:Mercurial本体にバンドルされているエクステンンションです

*3:なぜか.にcloneしようとする。ディレクトリを指定するとよい。例: hg clone gcode://go go

最近のyard パーフェクトRuby Advent Calendar 2日目

このエントリは パーフェクトRuby Advent Calendar の2日目のエントリです。

1日目のエントリはパーフェクトRuby Advent Calendar 2013(1日目) - すがブロです。

yard diff

いきなりですが、パーフェクトRubyで知った最高に便利なコマンドは yard diff です。

開発中でも、運用中でも利用するライブラリのバージョンアップは必ず発生します。依存関係がたくさんあるライブラリを使っていていると次のようなことが起こりがちです。

  • ○○を更新したら、○○の使っている△△が更新されて今まで動いていたものが動かなくなった
  • ○○の使っている□□を更新したいけど、よくわかんないし、仕事増えそうだからやめよう

こんなときに yard diffを利用すると便利。変更内容を俯瞰できるので、ソースを追ってやるという気持ちになれます。yardのことを全然知らなかったので、一年前にこのコマンドを知っていれば、、、と悔やまれます。

最近のyard

せっかくyardに興味を持ったので、最近のyardの変更を調べてみました。パーフェクトRubyではyard-0.8.2.1を使っていて、現在はyard-0.8.7.3がリリースされています。この間に次のような機能追加がありました。

asciidoc の追加

マークアップの記法にasciidocが利用できるようになりました。利用するためには事前にgem install asciidoctorしておく必要があります。マニアックですね。

yard markupsコマンドの追加

yard docで利用できるドキュメントの形式が一覧できるようになりました。

% yard markups
Available markup types for `doc' command:

[asciidoc]
  Providers: asciidoctor
  Extensions: .asciidoc .ad .adoc .asc

[html]
  Extensions: .htm .html .shtml

[markdown]
  Providers: redcarpet rdiscount kramdown bluecloth maruku rpeg-markdown rdoc
  Extensions: .markdown .md .mdown .mkd

[none]

[pre]

[rdoc]
  Extensions: .rdoc

[ruby]
  Extensions: .rb .ru

[text]
  Extensions: .txt

[textile]
  Providers: redcloth
  Extensions: .textile .txtile

[textile_strict]
  Providers: redcloth

yard display コマンドの追加

1クラスだけドキュメントを表示します。利用するには事前にyard doc -n.yardocを作る必要があります。

% git clone https://github.com/rack/rack
% cd rack
% yard doc -n
Files:          64
Modules:        14 (    8 undocumented)
Classes:        82 (   34 undocumented)
Constants:      83 (   64 undocumented)
Methods:       464 (  249 undocumented)
 44.79% documented
% yard display Rack::Auth::Basic
----------------- Class: Rack::Auth::Basic < Rack::Auth::AbstractHandler

    Rack::Auth::Basic implements HTTP Basic Authentication, as per RFC
    2617.

    Initialize with the Rack application that you want protecting, and a
    block that checks if a username and password pair are valid.

    See also: <tt>example/protectedlobster.rb</tt>



------------------------------------------------------------------------

--layout onefileでHTMLを出力させると良い感じです

% yard display --layout onefile -f html Rack::Auth::Basic > rack-auth-basic.html

まとめ

yardなどのRubyで開発しているとまずインストールされているコマンド郡を、パーフェクトRubyはしっかり網羅してあります。調べるのをさぼっていた機能を勉強するのにとっても便利です。

次のアドベンターはid:t2osさんです!

自分用のRevsetsを定義する。 #mercurialjp

このエントリはMercurial Advent Calendar 2013 の1日目です。

MercurialにはRevsetsというリビジョン郡を指定するための条件を記述するDSLが組み込まれています。Revsetsに関しては過去のAdvent Calendarのエントリにわかりやすい解説があるのでそちらを参照してください。

Revsetsの弱点

Revsetsを利用すると次のようにわかりやすくリビジョン郡を指定できます。

# revsetsの例
# "bug" 又は "issue" に言及したリビジョン群のうち、 タグ付け時点の内容に含まれないもの
$ hg log -r "(keyword(bug) or keyword(issue)) and not ancestors(tag())"

とてもわかりやすいのですが、条件が長くなりがちで、条件が再利用しにくいという弱点があります。

自分用のRevsetsを定義する。

実はこの弱点を補うための機能はMercurialに組み込まれています。Revsetsは[revsetalias]というセクションを利用すると自分用の条件を定義することができるのです。 これにより、「可読性は高いが、再利用性が低い」という弱点を補うことができます。

次の例はhg help revsetsにある例です。

[revsetalias]
h = heads()
d($1) = sort($1, date)
rs($1, $2) = reverse(sort($1, $2))

実用的な例

僕は~/.hgrcに次のような定義をしています。

[revsetalias]
wip = (ancestors(.) and (not public()))
pulled = (tip:. - .)

このwippulledを利用すると、次のようにaliasがわかりやすく作成できます。

[alias]
# browse changesets.
pulled = log -vpr "pulled and (not merge())"
wip = log -vpr "wip"

# import all wip changesets to mq patch.
qimportwip = qimport -r 'wip and (not mq())'
qiwip = qimportwip

定義しているaliasの説明です。

  • hg pulled : hg pullで取り込んだ変更内容を確認する

  • hg wip : 作業中の変更内容を確認する

  • hg qimportwip, hg qiwip : 作業中の変更内容をすべてMQに取り込む

可読性と再利用性が両立していますね!

次回のMercurial Advent Calendarは?

次回の担当は id:cointoss1973 さんです。

GTUG Girls #14 でGitのハンズオンの講師を行いました

参加者の皆さん、主催者の @yanzm さん、会場提供のドワンゴさん、チューターとして手伝ってくれた @kana1 さん、 @sinsoku_listy さんお疲れ様でした。

当日の資料とtogetterのまとめです。

ハンズオンの最中にでた質問は良い感じでtogetterのまとめにまとまってるので、そちらを参考にしてください。

一応次のものは原稿の方に反映させました。

  • git config --list で設定項目が一覧できる
  • git fetchして更新されたorigin/masterとmasterをマージするときは基本--no-ffを指定しない
  • git pullの挙動について

ハンズオン参加者のみなさんも変更点を見てもらえると嬉しいです。 gistは左メニューのRevisionsで変更点が簡単に確認できるので、そちらもどうぞ。

Rhodecode Enterpriseのライセンス

Git/MercurialリポジトリホスティングするRhodecodeというWebアプリケーションが有ります。 WebUIでユーザ権限の設定やリポジトリの追加、Pull-Requestなどが行える OSSのアプリケーション です。

いままで、GPLv3で配布されていたRhodecodeですが、2013年8月にリリースされたRhodecode Enterprise(バージョンとしてはRhodecode-2.xです)から、名前の通り企業向けのソフトウェアとしてリリースされ、Webサイトもリニューアルし、ライセンスも一部変更されました。

新しいライセンスはRhodecodeを恒久的に商用ソフトウェアにするように見えますが、実はそういうライセンスではありません。

Rhodecode Enterprise(Rhodecode-2.x)とRhodecode-1.7.x

Rhodecode Enterprise(Rhodecode-2.x)はRhodecode-1.7.xをフォークして作られています。 Rhodecode-1.7.xはGPLv3でしたが、RhodeCode EnterpriseはGPLv3とBisiness Source Licenseの二つのライセンスが適応されています。

Business Source LicenseはRhodecode Enterpriseで新たに追加された画像、CSSに適応されます。GPLv3だったソースコード、ファイ ルのライセンスを変更する事は行っていません。

名前 対象 ライセンス
RhodeCode Enterprise Pythonのコード、HTMLなど GPLv3
新たに追加された画像、CSS Business Source License
Rhodecode-1.7.x すべて GPLv3

Business Source License

元はMySQLの作者がOSSでも商売をする為に考えたライセンスです。

英語得意じゃないので大まかに特徴だけ書きます。

  • ソースコードは公開する
    • 多人数で利用する場合は報酬を要求してもよい(コマーシャルライセンスを用意してよい)
  • 期日を決めOSS Licenseに移行する
  • Business Source LicenseはOSS Licenseではない

Rhodecode Enterpriseの場合、次のようになっています。

  • 20ユーザーまではBisiness Source Licenseが適用され無料。21名からコマーシャルライセンス。
  • 4年後の2017/09/01*1にBusiness Source LicenseからGPLv2 or laterに移行。

Rhodecode-1.7.x のサポートについて

作者はIRCで「しばらくはRhodecode-1.7.xのセキュリティフィックスは行う」と発言しています。 実際にRhodecode Enterpriseリリース後の2013/10/01にRhodecode-1.7.2がリリースされています。

今後Business Source Licenseは流行るのか?

GIFやMP3の様に後から特許料を要求するよりも穏やかなお金の取り方だとは思うのですが。。難しそうです。。。 RhodecodeがBusiness Source Licenseを採用したこと自体、かなり先進的な事例なので、Rhodecodeの成功次第でしょうか。

*1:以前は2年五の2015/09/01だった気がしたが。。

PyCon APAC 2013 開催期間中に勢いで作成したMercurial関連のスライド

twitterでも流しましたが、勢いで作成したスライドです。PyCon APAC 2013 Sprintの成果ということで。 英語はリリースノートからのコピペとかです。

Mercurial Update 2012/08-2013/09 PyCon APAC 2013 Sprint

Short Introduction of Mercurial Evolve Extension