Windows+TortoiseHgで始めるMercurial(hgコマンドをTortoiseHgで)

この記事は1.1.xを基準にしていて古いので、2.x対応版に書きなおした。

  1. 設定 => 2.x版はこちら
  2. hgコマンドをTortoiseHgで => 2.x版はこちら
  3. ブランチ・リポジトリ間の連携 => 2.x版はこちら
  4. 間違えたときのやり直し => 2.x版はこちら
  5. bitbucketの使い方(あとで書く)=>2.x版はこちら

リポジトリの作成

Mercurialリポジトリ作成方法には2通りあります。

空のリポジトリを作成

新しくバージョン管理を開始する場合に使います。リポジトリを置くディレクトリ上で右クリックして、

「TortoiseHg」->「ここにリポジトリを作成」

を選択します。

「TortoiseHgリポジトリ作成」ダイアログで、リポジトリ作成ディレクトリが入力されていることを確認したら、「作成」ボタンをクリックします。

この時、日本語を含むディレクトリを指定するのは止めましょう。Mercurialは日本語の扱いに不安点があるので、余計なトラブルを避けた方が得策です。

「.hg」ディレクトリと「.hgignore」が作成されれば成功です。

既存のリポジトリをクローン

既存のリポジトリがあり、それをもとにバージョン管理する場合に使います。リポジトリを置くディレクトリ上で右クリックして、

「TortoiseHg」->「リポジトリのクローン」

を選択します。

ダイアログが表示されるので、クローン元にリポジトリのURLまたはディレクトリを入力して、「クローン」ボタンをクリックしましょう。
ここでは例として、https://bitbucket.org/toruuetani/hglight-for-traclightning3 をターゲットにします。

図のようにコンテンツが生成されれば成功です。

.hgignoreとは何か?

バージョン管理の対象としないファイルを指定するものです。中間成果物や、環境依存のファイルなどを指定します。ワイルドカード正規表現を指定できるので、できるだけ無駄な記述を省きましょう。

syntax: glob
*.pyc
*.javac

最低限覚えること

Mercurialで最低限覚えておかなければならない操作には、以下のような操作があります。これだけ覚えておけばとりあえずバージョン管理が可能です。

  • 更新 / hg update
  • コミット/ hg commit
更新

ある特定の時点にファイルを更新します。ログビューアで更新したいリビジョンを右クリックして、更新を選択します。

表示されたダイアログで「更新」をクリックします。現時点行っている変更を破棄しても構わない場合、「ローカルの変更を破棄する」をチェックしてください。

ある程度変更を重ねてからやり直したくなった場合に便利です。

コミット

ファイルを変更したら、エクスプローラ上で右クリックして、「Hg コミット」を選択します。

コミットダイアログで、変更に含めるファイルを選択してコメントを記述しましょう。慣例として、1行目は変更の概要を記述します。必要であれば、3行目以降に詳細を記述してください。TracなどのITSが用意されいてるなら、関連するチケットの番号を記述しておくべきです。ITSの機能により、自動的にチケットにコメントが追記されます。もしそういう仕組みがないのなら、今すぐセットアップしましょう。

Windows+TortoiseHgで始めるMercurial(設定編)

ちょっとMercurialのHowToを書く必要が出てきたので書いてみる。

この記事は1.1.xを基準にしていて古いので、2.x対応版に書きなおした。

  1. 設定 => 2.x版はこちら
  2. hgコマンドをTortoiseHgで => 2.x版はこちら
  3. ブランチ・リポジトリ間の連携 => 2.x版はこちら
  4. 間違えたときのやり直し => 2.x版はこちら
  5. bitbucketの使い方 =>2.x版はこちら

TortoiseHgとは何か?

MercurialGUIツールです。Windows標準のファイラーであるエクスプローラを拡張して、GUIでバージョン管理が出来るようにしてくれます。
同時にhgコマンドも使えるようにしてくれるので、Mercurialをインストールするよりお勧めです。

 ダウンロードはこちらから -> TortoiseHg
 現在の最新版は tortoisehg-1.1.9.1-hg-1.7.5-x86.msi です。

 

TortoiseHgのインストール

 

基本的にデフォルトインストールで構いません。エクスプローラ上で右クリックして、TortoiseHgと表示されたら成功です。
※1.1.8からメニューが自動的に日本語化されるようになりました。(参照)LANG環境変数なしで言語環境を検出してくれるようになったので、LANG環境変数の設定は必要ありません。

フォント設定の変更

インストールした状態だと、ログビューアのコミットログ表示部分の日本語部分が残念なことになります。

TortoiseHg(Mecrurial)は次のファイルに設定を保存します。

%USERPROFILE%\mercurial.ini

ここに以下のようにフォントを設定します(メイリオの場合)。

[gtools]
fontcomment = メイリオ 10
fontdiff = メイリオ 10
fontlist = メイリオ 9

以下のように設定したフォントでログビューアが表示されたら成功です。

マージツールの設定

標準ツールkdiffでもマージできますが、WinMerge 日本語版の方が使いやすいので設定しておきましょう。mercurial.iniに以下の設定を追加してください。

[merge-tools]
winmergeu.args=/e /ub /dl other /dr local $other $local $output
winmergeu.regkey=Software\Thingamahoochie\WinMerge
winmergeu.regname=Executable
winmergeu.fixeol=True
winmergeu.checkchanged=True
winmergeu.gui=True

[extdiff]
cmd.wmdiff = C:\Program Files\WinMerge\WinMergeU.exe
opts.wmdiff = /r /e /x /ub

[ui]
merge = winmergeu

[tortoisehg]
vdiff = wmdiff

次にTortoiseHgのグローバル設定を変更します。(エクスプローラ右クリック -> TortoiseHg -> グローバル設定)

以下のように設定してください。

  • 「3-way マージツール」=「winmergeu」
  • GUI差分表示ツール」=「wmdiff」

win32mbcsの設定

Mercurialは非常に使いやすいVCSですが、日本語ファイルパスの扱いだけはdisられています。
なぜかと言うと、Mercurialはファイルパスをバイナリで格納するため、日本語Windowsで格納した日本語ファイルをLinuxで取り出せません。逆も同じです。日本語WindowsでファイルパスはShiftJISでエンコードされ、LinuxではUTF8でエンコードされるからです。また、ShiftJISには0x5C問題があり、Mercurialは正しくパスを格納できません。
ただ、Windows環境だけに限定するなら回避策があり、win32mbcs拡張を有効にすることで問題なくなります。

win32mbcsを有効にするためには、mercurial.iniに次の設定を追加します。

[extensions]
win32mbcs = 

あるいはTortoiseHgのグローバル設定で、Extensions設定からwin32mbcsにチェックします。

プロキシ設定

プロキシもTortoiseHgのグローバル設定で設定できます。

django.db.transaction.commit_on_successデコレータの挙動はいまいち

ちょっとハマったのでメモしておく。

commit_on_successデコレータは、その名の通り関数が成功したらコミットする。その関数の開始時にトランザクションを開始したりはしない。既存のコネクションがあればそれを利用する。したがって、commit_on_successデコレータをネストさせても、意図したようには動かない。ネストした関数が失敗すると、ネストする前に行ったDB操作も一緒にロールバックされる。きちんとソース読んで、それでもわからないなら実際にコード書かないと駄目だな・・・
次のコードだと、test_rollback_nestedだけテストにパスしない。

# -*- encoding: utf-8 -*-
from django.db import models
from django.db import transaction


class Person(models.Model):
    name = models.CharField(u'名前', max_length=100, unique=True)

    def __unicode__(self):
        return self.name


def test_without_tran():
    """
    >>> Person.objects.all().delete()
    >>> test_without_tran()
    >>> Person.objects.all().order_by('name')
    [<Person: Test1>]
    """
    Person.objects.create(name="Test1")



def test_transaction():
    """
    >>> Person.objects.all().delete()
    >>> test_transaction()
    >>> Person.objects.all().order_by('name')
    [<Person: Test1>, <Person: Test2>]
    """
    @transaction.commit_on_success
    def _expect_commit():
        Person.objects.create(name="Test1")
        Person.objects.create(name="Test2")

    try:
        _expect_commit()
    except: pass


def test_rollback():
    """
    >>> Person.objects.all().delete()
    >>> test_rollback()
    >>> Person.objects.all().order_by('name')
    []
    """
    @transaction.commit_on_success
    def _expect_rollback():
        Person.objects.create(name="Test1")
        Person.objects.create(name="Test1")

    try:
        _expect_rollback()
    except: pass


def test_rollback_nested():
    """
    >>> Person.objects.all().delete()
    >>> test_rollback_nested()
    >>> Person.objects.all().order_by('name')
    [<Person: Test10>, <Person: Test11>]
    """
    @transaction.commit_on_success
    def _expect_rollback():
        Person.objects.create(name="Test1")
        Person.objects.create(name="Test1")

    @transaction.commit_on_success
    def _expect_commit():
        Person.objects.create(name="Test10")
        try:
            _expect_rollback()
        except: pass
        Person.objects.create(name="Test11")

    try:
        _expect_commit()
    except: pass

hglightをTracLightning 3.0に対応してみた。

自己流でTracMercurialをセットアップするのも面倒なので、hglightをforkしてTracLightning 3.0に対応してみた。こちらからどうぞ。インストール手順とかは本家と同じです。

本家と違うのはこれくらい。

今後やってみたいのはこれくらい。

  • trac-post-commit-hook対応
    • ないと結構やってられない。
    • trac 0.11だと、チケットの更新日時がミリ秒まで持ってない?から多数のチェンジセットをpushすると、たまにフックに失敗してコメントが付与されないことがある。 trac 0.12でミリ秒まで持つようになったらしいので、それはなくなるはず。
  • プロジェクト生成時、既存リポジトリからcloneできるようにする。

bitbucketの使い方メモ

基本的なこと、サインインとかpush/pull/forkは大抵書いてあるけど、forkしてから先の事とかを書いてるサイトが見つからなかったので、メモしておく。

fork元の変更をpullする。

bitbucket上でやるのかと思ってたけど、違うみたい。

まずはforkしたリポジトリのローカルリポジトリで、fork元のURLを指定してpullする。その後pushするだけ。

CD WORK_DIR
hg pull https://yourname@bitbucket.org/fork_source
hg push

もちろんローカルだけに変更を留めておきたいなら、pushしなければいい。

trac-post-commit-hookみたいなことをやる。

デフォルト設定だとできないので、以下のURLを参考にする。

http://confluence.atlassian.com/display/BITBUCKET/Setting+Up+the+Bitbucket+Issues+Service

まずはリポジトリのadminタブwクリックする。そうすると「Additional options/settings」というブロックが表示されるので、「Services」をクリックする。

「Services Administration」というブロックで、コンボボックスから「Issues」を選択して「Add service」をクリックする。

これでコミットログに以下のように記述すればいい。はずなんだけど、たまに失敗してる?

fixes #4711 #チケットのクローズ
reopening #4711 #チケットの再オープン
refs #4711 #チケットへの参照

どっかに分散バージョン管理に対応したITSはないものか

最近はTrac&Mercurialで開発管理して、さらにSphinxにも手を出し始めたんだけども、いまいち使いにくい。

理由は主にTracが分散バージョン管理に対応してないから。リポジトリを複数に分けて管理したいけど、対応してないから一つしか使えない。おまけにリボジトリブラウザがUnicodeDecodeErrorをスローしてまともにソースが見れない。なので最近はチケットとマイルストーンくらいしか使わなくなった。

あと、Sphinxを始めたからか、wiki記法が嫌いになった。ドキュメントもreSTで書きたい。それが出来ればまとめてSphinxでビルドしてPDFにしたりしたい。HTMLで公開出来るだけでもいいかな。

などなどいろいろTracに不満を感じるようになってきた。昔ほどTracを追いかけられないのはそのせいだろうか。TracLightningは便利だけども、肥大化しすぎてて使いこなせない。眠らせてる機能が山程あるんだろうな…

redmineに浮気しようかと思ったけど、Mercurialに対応してる訳でもなさそうだ。

どっかにないかなあ。

  • Mercurialに対応してて、複数リボジトリを表示できる。
  • ドキュメントはreSTで書けて、Sphinxでビルドできる。もちろんGraphvizで図も書ける。
  • チケットはテンプレートを指定できて、既存のチケットを複製できたりする。

Djangoで作れたりしないかな…