Mercurial (hg) and SVN reference
hg and svn are the two revision control systems I use. Here is a summary of their use and differences.
Creating repository
- hg:
Doesn't have a global repository. Every copy is its own local repository. If desired, one copy can be designated as a global repository. Each project is its own repository.
- svn:
svnadmin create [--fs-type fsfs|bdb] url://to/repo
In svn, a repository is usually on a server somewhere, and contains multiple projects.
Creating a new project
- hg:
hg init proj
This creates proj directory if it doesn't exist, and makes it into a local repository. No files are added. hg does not impose any directory structure.
- svn:
Create new directory (e.g., in your home directory) to hold files, then import it. svn suggests (but doesn't require) the following directory structure for projects:
mkdir proj mkdir proj/trunk/ mkdir proj/branches/ mkdir proj/tags/ svn import /path/to/proj url://to/repo/proj
This imports proj to repository and adds any existing files in proj.
Checking out a project
- hg:
hg clone url://to/repo
hg clones an existing project repository. This can be any copy of the repository, as no global repository is imposed. Clone automatically sets the default push/pull path to the original repository, which is useful if the original repository is designated the “global repository”.
To set the default push/pull path, edit the file .hg/hrc and set the path as:
[paths] default = url://to/repo
URLs can be local files:
hg clone relative/path/to/project
or ssh:
hg clone ssh://hostname/relative/path/to/project
(also presumably http, but I've never used that.)
- svn:
svn co url://to/repo/proj/trunk
You can checkout any directory, but typically people checkout the trunk or some branch (see below). (I guess.)
URLs can be https:
svn co https://hostname/path/to/project
local files:
svn co file:///absolute/path/to/project
or ssh:
svn+ssh://hostname/absolute/path/to/project
File management
- Add files
hg add files
svn add [--parents] files
.Use
--parents
to automatically add parent directories.- Add all new files in directory, recursively
hg add [dir]
svn add --force dir
- Add directory
- hg does not put directories under revision control; add a file in that directory to add the directory.
svn mkdir dir
- Delete files
hg rm files
svn rm files
- Copy files
hg cp file1 file2
svn cp file1 file2
- Move files
hg mv file1 file2
svn mv file1 file2
- Revert file to previous version
hg revert {files|--all}
svn revert files
- Show status, compared to last update (i.e., local only)
hg st [--all] [files]
svn st [-v] [files]
- Show status, compared to remote repository
- n/a
svn st -u [files]
- Show diff, by default compared to last update
hg diff [-r rev] [files]
svn diff [-r rev] [files]
- Show diff, compared to another repository
hg {incoming | outgoing} [-p] url://to/repo
- n/a
- Update to changes from repository
hg pull [url://to/repo] && hg up
, orhg pull -u [url://to/repo]
svn up
- Resolve conflict after an update
- n/a
svn resolve --accept {mine-full | theirs-full | working} files
- Commit changes to repository
hg commit -m 'message' && hg push [url://to/repo]
svn commit -m 'message'
Ignoring files
- hg:
Store glob or regexp patterns, one per line, in file
proj/.hgignore
for the whole project.Global ignore patterns can be put in
~/.hgignore-global
- svn:
Store glob patterns, one per line, in property lists for each directory.
svn propset svn:ignore "file1dir svn propedit svn:ignore dir
Global ignore patterns can be set with the
global-ignores
option in~/.subversion/config
.
Branching and Merging
- hg:
Clone the project and merge changes as usual. I.e., there is nothing special about branching. In effect, every local repository is a branch.
- svn:
Make a light-weight copy on the server, check it out. Changes from the trunk can be merged into the branch. At the end, the branch can be reintegrated with the trunk.
svn copy url://to/repo/proj/trunk url://to/repo/proj/branches/my-branch svn co url://to/repo/proj/branches/my-branch # in copy of branch # merge changes from trunk into branch (can do many times) svn merge ^/proj/trunk # in copy of trunk # reintegrate branch into trunk (can do only once) svn merge --reintegrate ^/proj/branches/my-branch # test and verify, then commit svn commit -m msg
See note on relative URLs.
Properties
- hg:
Doesn't have the concept of properties (that I know of).
- svn:
Uses properties as metadata associated with files or directories.
svn propset <propname> 'text' files svn propset <propname> --file file files svn proplist files svn propget files svn propedit <propname> # starts $EDITOR svn propdel <propname>
propnames starting with svn: are reserved.
Text substitution
- hg
Doesn't generally support keywords. Their website explains why not and possible alternatives.
- svn:
Set svn:keywords property to which keywords to substitute, e.g., "Date Author".
svn propset svn:keywords "Date Author" files
svn supports these keywords in text:
$Date$ $Revision$ $Author$ $HeadURL$ $Id$ # combination of above, condensed $Header$ # combination of above, with full url