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
| Command | Description |
|---|---|
hg init | Create new repository |
hg clone URL | Clone existing repository |
hg status | Show working directory status |
hg log | View commit history |
hg diff | Show 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
- Mercurial Official Documentation
- Bitbucket Mercurial Guide
- Evolve Extension Docs
- Topic Extension Docs
Last updated: 2026-03-30