Mercurial
バージョン管理ツール
Mercurial
概要
Mercurial(コマンド名:hg)は、Matt Mackallによって2005年に開発されたオープンソースの分散型バージョン管理システムです。Pythonで実装され、「シンプルで直感的な操作」を設計理念とし、Git と同時期に開発されました。分散型アーキテクチャによる高いパフォーマンスと柔軟性を持ちながら、Gitよりも学習しやすいコマンド体系を提供します。プラットフォーム非依存性とPythonエコシステムとの親和性により、科学計算・研究開発分野で特に支持されており、Pythonベースの拡張機能により高度なカスタマイズが可能です。
詳細
Mercurial 2025年版は、0.3%の小さなマーケットシェアながら、Python開発者や研究機関を中心に根強い支持を獲得しています。GPL v2ライセンスの下でオープンソースとして提供され、安定性と信頼性を重視した開発が継続されています。主要実装言語がPythonであることにより、拡張機能の開発が容易で、科学計算分野でのワークフローにシームレスに統合できます。分散型でありながらGitほど複雑ではない設計により、ブランチ概念が Named Branch と Anonymous Branch(Bookmark)に分かれ、シンプルなワークフローを実現します。
主な特徴
- Python実装: 拡張性の高いアーキテクチャとPythonエコシステム統合
- シンプルな操作: 直感的なコマンド体系と学習コストの低さ
- プラットフォーム独立性: Windows、Linux、macOSでの一貫した動作
- 効率的なブランチ管理: Named BranchとBookmarkによる柔軟なワークフロー
- 強力な拡張システム: Pythonによるカスタム機能の実装
- Web インターフェース: 内蔵Webサーバーによるリポジトリブラウジング
メリット・デメリット
メリット
- 0.3%の小さなマーケットシェアながらPython開発者に高い支持
- シンプルなコマンドとPythonベースの実装による拡張性
- Gitよりも学習しやすい一貫したコマンド体系
- 科学計算・研究分野でのワークフロー統合実績
- プラットフォーム独立性による高い互換性
- 内蔵Webサーバーによる簡単なリポジトリ共有
デメリット
- 小さなマーケットシェアによる情報・ツールの限定性
- GitHubやGitLabとの互換性なし(専用ホスティング必要)
- 新規チームメンバーの学習コストとツール習得
- モダンなDevOpsエコシステムとの統合がGitに劣る
- エンタープライズレベルのホスティング選択肢の少なさ
- コミュニティとエコシステムの縮小傾向
参考ページ
- Mercurial 公式サイト
- Mercurial: The Definitive Guide
- Mercurial Wiki
- Python.org Mercurial リポジトリ
- Learn Mercurial in Y Minutes
書き方の例
インストールと初期設定
# Mercurialのインストール
# Ubuntu/Debian
sudo apt-get install mercurial
# macOS (Homebrew)
brew install mercurial
# Windows (公式インストーラー使用)
# https://www.mercurial-scm.org/downloads
# バージョン確認
hg version
# グローバル設定
hg config --edit
# または直接設定
hg config --global --edit
# 設定例(~/.hgrc)
[ui]
username = Your Name <[email protected]>
editor = vim
merge = vimdiff
[extensions]
color =
purge =
rebase =
shelve =
リポジトリの初期化と基本操作
# 新しいリポジトリを初期化
hg init my-project
cd my-project
# 既存リポジトリをクローン
hg clone https://hg.example.com/repository
hg clone ssh://[email protected]/user/repository
# 浅いクローン(--depth オプションはない代わりに)
hg clone --rev tip https://hg.example.com/repository
# ファイルの追加
echo "Hello Mercurial" > hello.txt
hg add hello.txt
# すべてのファイルを追加
hg add .
# ファイルの状態確認
hg status
# M = modified, A = added, R = removed, ? = untracked, ! = missing
# 変更差分の確認
hg diff
hg diff hello.txt
hg diff --rev 0:1 # リビジョン間の差分
# コミット実行
hg commit -m "Initial commit with hello.txt"
hg commit -A -m "Add all files and commit" # add + commit
ブランチとブックマーク管理
# Named Branchの作成と管理
hg branch feature-authentication
echo "auth module" > auth.py
hg add auth.py
hg commit -m "Add authentication module"
# ブランチ一覧表示
hg branches
hg branches --active
# ブランチの切り替え
hg update default
hg update feature-authentication
# Bookmarkの作成(軽量ブランチ)
hg bookmark experimental-feature
hg commit -m "Experimental changes"
# ブックマーク一覧
hg bookmarks
# ブックマークの切り替え
hg update experimental-feature
hg update -r default
# ブランチのマージ
hg update default
hg merge feature-authentication
hg commit -m "Merge feature-authentication branch"
# グラフィカルなログ表示
hg log --graph
hg glog # 短縮形
リモートリポジトリ操作
# リモートリポジトリの設定確認
hg paths
# デフォルトパスの設定
echo "[paths]" >> .hg/hgrc
echo "default = https://hg.example.com/repository" >> .hg/hgrc
# 変更をプッシュ
hg push
hg push -b feature-branch # 特定ブランチのみ
hg push --new-branch # 新しいブランチを含む
# 変更をプル
hg pull
hg pull -u # pull + update
# インカミング変更の確認
hg incoming
# アウトゴーイング変更の確認
hg outgoing
# 特定リビジョンからプル
hg pull -r 123
高度な操作とワークフロー
# リビジョンの巻き戻し
hg rollback # 最後のトランザクションを取り消し
# 変更の一時保存(shelve拡張必要)
hg shelve
hg shelve --list
hg unshelve
# ファイルの履歴確認
hg log filename.txt
hg log --follow filename.txt # リネーム追跡
# 特定リビジョンのファイル表示
hg cat -r 123 filename.txt
# 注釈付きファイル表示(blame)
hg annotate filename.txt
hg blame filename.txt # エイリアス
# リベース操作(rebase拡張必要)
hg rebase -s source_rev -d dest_rev
# チェリーピック(transplant拡張使用)
hg transplant 123
# パッチの作成と適用
hg export -r 123 > patch.diff
hg import patch.diff
# バンドルファイルでの変更セット交換
hg bundle --base 100 changes.hg
hg unbundle changes.hg
設定とカスタマイズ
# .hgrc設定ファイルの詳細設定
[ui]
username = Developer <[email protected]>
editor = code --wait
merge = vscode
ssh = ssh -C
[defaults]
log = --graph
status = --all
[alias]
ll = log --graph --template '{rev}: {desc|firstline}\n'
st = status
ci = commit
co = update
[extensions]
color =
pager =
progress =
rebase =
shelve =
purge =
histedit =
[color]
status.modified = cyan
status.added = green
status.removed = red
status.unknown = magenta
Webインターフェースとサーバー
# 内蔵Webサーバーの起動
hg serve
hg serve --port 8080 --address 0.0.0.0
# 設定ファイルでWebサーバー設定
[web]
port = 8080
address = localhost
name = My Repository
description = Project repository
contact = [email protected]
allow_push = *
allow_read = *
# hgwebを使用したマルチリポジトリホスティング
# /etc/mercurial/hgweb.config
[collections]
/repos = /path/to/repositories
[web]
style = gitweb
allow_push = *
フック機能とカスタマイズ
# .hg/hgrc でのフック設定
[hooks]
# pre-commit フック
pre-commit = python scripts/check-style.py
# commit メッセージフック
commit = echo "Committed changeset $HG_NODE"
# プッシュ後フック
post-push = curl -X POST https://api.example.com/webhook
# Python フックスクリプトの例
[hooks]
pre-commit.style = python:scripts.hooks.check_style
# scripts/hooks.py
def check_style(ui, repo, **kwargs):
# スタイルチェックロジック
if style_check_failed():
ui.warn("Style check failed\n")
return True # コミットを拒否
return False
プロジェクト固有のワークフロー
# 機能開発ワークフロー
hg update default
hg pull -u
hg branch feature/new-api
# 開発作業
hg commit -m "Implement new API endpoint"
hg update default
hg merge feature/new-api
hg commit -m "Merge feature/new-api"
hg push
# リリース管理ワークフロー
hg update default
hg branch release/v1.2.0
# リリース準備作業
hg commit -m "Prepare release v1.2.0"
hg tag v1.2.0
hg update default
hg merge release/v1.2.0
hg commit -m "Merge release v1.2.0"
# ホットフィックスワークフロー
hg update v1.1.0 # タグから開始
hg branch hotfix/critical-bug
# バグ修正
hg commit -m "Fix critical security bug"
hg tag v1.1.1
hg update default
hg merge hotfix/critical-bug
hg commit -m "Merge hotfix v1.1.1"
Python統合とスクリプト
# Python script での Mercurial操作
from mercurial import ui, hg, commands
from mercurial.context import workingctx
# リポジトリを開く
repo_ui = ui.ui()
repo = hg.repository(repo_ui, '.')
# ワーキングディレクトリの状態取得
wctx = workingctx(repo)
status = wctx.status()
print(f"Modified files: {status.modified}")
print(f"Added files: {status.added}")
# ログの取得
def get_recent_commits(repo, count=10):
commits = []
for i in range(min(count, len(repo))):
ctx = repo[len(repo) - 1 - i]
commits.append({
'rev': ctx.rev(),
'node': ctx.hex(),
'desc': ctx.description(),
'user': ctx.user(),
'date': ctx.date(),
})
return commits
# プログラマティックコミット
def auto_commit(repo, message):
repo_ui = repo.ui
commands.commit(repo_ui, repo, message=message, addremove=True)
移行とインポート
# Gitリポジトリからの変換(hg-git拡張使用)
hg clone git://github.com/user/repo.git
# SVNリポジトリからの変換
hg convert --source-type svn https://svn.example.com/repo ./hg-repo
# FastExportを使用したGitからの移行
git fast-export --all | hg fastimport -
# 設定ファイルを使用した詳細変換
# convert.conf
[convert]
git.similarity = 90
# マップファイルでの作者変換
# authormap.txt
[email protected] = New Name <[email protected]>
hg convert --config convert.git.similarity=90 \
--authormap authormap.txt \
git-repo hg-repo