Skip to content

Mercurial

Mercurial (hg) is a distributed version control system emphasizing ease-of-use and performance. It provides powerful branching, merging, and history management capabilities with extensive extension support for advanced workflows like evolve, topics, and interactive history editing.

Installation

# Ubuntu/Debian
sudo apt install mercurial

# macOS
brew install mercurial

# Fedora/RHEL
sudo dnf install mercurial

# From source
wget https://www.mercurial-scm.org/release/mercurial-6.7.tar.gz
tar xzf mercurial-6.7.tar.gz
cd mercurial-6.7
make install

# Verify installation
hg version

Initial Setup

# Configure user information
hg config --user user.name "Your Name"
hg config --user user.email "user@example.com"

# View configuration
hg config -l

# Set default push location
hg config paths.default = https://bitbucket.org/user/repo

# Enable useful extensions
hg config --user extensions.evolve =
hg config --user extensions.topic =
hg config --user extensions.histedit =

Basic Repository Operations

CommandDescription
hg initCreate new repository
hg clone URLClone existing repository
hg statusShow working directory status
hg logView commit history
hg diffShow file differences

Repository Initialization and Cloning

# Create new local repository
hg init myproject
cd myproject

# Clone remote repository
hg clone https://bitbucket.org/user/repo
hg clone ssh://hg@bitbucket.org/user/repo mylocal

# Clone specific revision
hg clone --rev 100 ssh://hg@server/repo

# Clone with limited history (shallow clone)
hg clone ssh://server/repo --noupdate

Commit Operations

# Add files to staging
hg add file.txt
hg add .

# Check status before committing
hg status

# Commit changes
hg commit -m "Feature: Add authentication system"

# Amend previous commit (evolve extension)
hg amend -m "Updated message"

# Create commit without working directory changes
hg commit --close-branch -m "Close old branch"

# View specific commit
hg log -r 5 -p
hg show 5

Branching and Workflow

# Create feature branch
hg branch feature/user-management
hg commit -m "Start user management feature"

# List all branches
hg branches

# Switch to different branch
hg update default

# List branch info
hg log -r "branch('feature/auth')" --template "{node|short} {desc}\n"

# Merge branches
hg update default
hg merge feature/auth
hg commit -m "Merge authentication feature"

# Close old branch
hg update feature/old
hg commit --close-branch -m "Closing old feature"

Advanced History Management

Using Evolve Extension

# Enable evolve extension
hg config --user extensions.evolve =

# Amend last commit (non-destructive)
hg amend

# Amend with new message
hg amend -m "Updated commit message"

# Update/modify older commits
hg log --template "{node|short} {desc}\n"
hg update -r <hash>
# Make changes
hg amend

# Rebase with evolve (automatic conflict resolution)
hg rebase -s <source> -d <dest>

# Obsolete commits without deleting
hg prune <revision>

# View hidden commits
hg log -r "hidden()" --template "{node|short} {desc}\n"

# Restore obsolete commits
hg evolve --all

Interactive History Editing

# Enable histedit extension
hg config --user extensions.histedit =

# Interactive history rebase
hg histedit -r "last(5)"

# Edit commits in list
# Commands: pick, edit, fold, drop, mess

# Auto-squash based on commit messages
hg histedit --commands <(hg log -r "::." --template "{node|short} {desc}\n")

Topic-Based Workflows

# Enable topic extension
hg config --user extensions.topic =

# Create topic (like local branch)
hg topic feature-redesign

# List topics
hg topic

# Switch topic
hg topic --switch auth-update

# Publish topic when ready
hg topic -p feature-redesign

# Clean up published topics
hg topic -d feature-redesign

# View changes in topic
hg log -r "topic(feature-redesign)" --graph

Pushing and Pulling

# Pull latest changes
hg pull

# Pull from specific URL
hg pull ssh://server/repo

# Pull specific revision
hg pull --rev 100 ssh://server/repo

# Push commits
hg push

# Push to specific URL
hg push ssh://hg@bitbucket.org/user/repo

# Push specific branch/topic
hg push -r feature/auth

# Force push (use carefully)
hg push --force

# Push new branch
hg push --new-branch

Patch and Diff Operations

# View unified diff
hg diff

# Diff specific file
hg diff filename.py

# Diff between revisions
hg diff -r 5:10

# Export changeset as patch
hg export tip > latest.patch
hg export 5:10 > range.patch

# Import patch
hg import latest.patch

# Create patch from uncommitted changes
hg diff > uncommitted.patch

# Apply patch without committing
hg import --no-commit latest.patch

Merging and Conflicts

# Merge another branch
hg merge feature/branch

# View merge status
hg status

# Resolve conflicts manually
# Edit conflicted files, remove conflict markers

# Mark conflicts as resolved
hg resolve -m filename.py

# View all merge conflicts
hg resolve --list

# Use external merge tool
hg merge --tool kdiff3

# Abort merge
hg update --clean .

Server Setup with hgweb

# Basic hgweb configuration
mkdir /var/hg
cd /var/hg

# Create hgweb.config
cat > hgweb.config << 'EOF'
[paths]
/ = /var/hg/repos/*

[web]
style = paper
allow_archive = gz zip bz2
push_ssl = false
allow_push = *
EOF

# Start hgweb server
hg serve -p 8080

# With WSGI (production)
hg serve --daemon -p 8000 --config server.web =

Hooks and Automation

# Configure commit hook
hg config --user hooks.precommit = echo "Checking before commit..."

# Update hook (on pull)
hg config --user hooks.update = echo "Repository updated"

# Push hook (remote validation)
hg config --user hooks.prepush = /path/to/validation.sh

# Change group hook
hg config --user hooks.changegroup = /path/to/notify.sh

# Example hook script
cat > /etc/mercurial/hooks/validate.sh << 'EOF'
#!/bin/bash
echo "Running commit validation..."
exit 0
EOF
chmod +x /etc/mercurial/hooks/validate.sh

Templates and Log Customization

# Custom log output
hg log --template "{node|short} {author} {desc}\n"

# Graph view
hg log --graph --template "{node|short} {desc}\n"

# Author statistics
hg log --template "{author}\n" | sort | uniq -c

# Commit count by author
hg log -r "all()" --template "{author}\n" | \
    sort | uniq -c | sort -rn

# View commits today
hg log -r "date('>=-2d')" --template "{node|short} {date|shortdate} {desc}\n"

# Find commits by author
hg log -r "author(john)" --template "{node|short} {desc}\n"

Rebasing and Cherry-Picking

# Enable rebase extension
hg config --user extensions.rebase =

# Rebase branch onto main
hg rebase -s feature/branch -d default

# Cherry-pick (graft) specific commit
hg graft 5

# Graft multiple commits
hg graft "5::10"

# Graft with conflict resolution
hg graft 5 --continue

# Abort graft
hg graft --abort

Backup and Recovery

# Create backup bundle
hg bundle --all backup.hg

# Restore from bundle
hg unbundle backup.hg

# Clone as backup
hg clone . ../backup_$(date +%Y%m%d)

# Export all changes
hg export --git -r 0:tip > full-history.patch

# Verify repository integrity
hg verify

# Rebuild repository
hg recover

Real-World Workflow Example

#!/bin/bash
# Complete feature development workflow

# 1. Update main branch
hg update default
hg pull

# 2. Create feature topic
hg topic feature/api-redesign

# 3. Make commits
hg add api.py
hg commit -m "Add new API endpoints"

# 4. Amend if needed (non-destructive)
# Make more changes
hg amend -m "Add endpoints with validation"

# 5. Rebase on latest main
hg rebase -d default

# 6. Push for review
hg push --new-branch

# 7. After approval, publish
hg topic -p feature/api-redesign

# 8. Merge to default
hg update default
hg merge feature/api-redesign
hg commit -m "Merge API redesign feature"

# 9. Push to remote
hg push

# 10. Clean up topic
hg topic -d feature/api-redesign

Troubleshooting

# Check repository status
hg status

# Verify repository integrity
hg verify

# Recover from corruption
hg recover

# View pending changes
hg status --change

# Find file history
hg log -f filename.py

# Show blame/annotate
hg annotate filename.py

# Reset to clean state
hg update -C .

# Remove uncommitted changes
hg revert --all

Best Practices

  • Use topics for local feature branches (publish when ready)
  • Enable evolve for safe history rewriting
  • Use meaningful commit messages with imperative mood
  • Squash commits before pushing with histedit
  • Test locally before pushing
  • Use hooks for validation and notifications
  • Regularly backup with bundles
  • Keep main/default branch stable
  • Review changes with graph view before merging
  • Document your workflow in project README

References


Last updated: 2026-03-30