mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
439 lines
14 KiB
Plaintext
439 lines
14 KiB
Plaintext
|
|
Mercurial(hg) Cheatsheet for Xen
|
|
================================
|
|
|
|
Written by Andrew Warfield, extended by Michael Fetterman and Ian Pratt
|
|
June 29, 2005, extended by Grzegorz Milos 04 July 2005.
|
|
|
|
Overview
|
|
--------
|
|
The Xen project has moved from BitKeeper to Mercurial for source
|
|
control. This note aims to provide a quick guide to getting up and
|
|
running with the new tools as quickly as possible, and is written from
|
|
the perspective of someone who has been using BK.
|
|
|
|
For a more detailed exposition, see the mecurial tutorial:
|
|
http://www.serpentine.com/mercurial/index.cgi?Tutorial
|
|
|
|
The Hg manpage is available at:
|
|
http://www.selenic.com/mercurial/hg.1.html
|
|
|
|
There's also a very useful FAQ that explains the terminology:
|
|
http://www.selenic.com/mercurial/FAQ.html
|
|
|
|
There's also a good README:
|
|
http://www.selenic.com/mercurial/README
|
|
|
|
Necessary software
|
|
------------------
|
|
Mercurial is available at:
|
|
http://www.selenic.com/mercurial/
|
|
|
|
You will also need a Python version >= 2.3
|
|
|
|
How Mercurial is different from BK
|
|
----------------------------------
|
|
There are several pertinent differences between hg and bk. This
|
|
section aims to give an overview of the conceptual differences between
|
|
the two SCMs -- if you just want examples to get going, skip ahead to
|
|
"Getting Xen". The key differences are:
|
|
|
|
- No explicit per-file locking. You do not need to explicitly
|
|
check a file out before editing it.
|
|
- No notion (currently) of file renames.
|
|
- A repository can have multiple active heads.
|
|
- Automatic merge support is currently inferior to BK's.
|
|
- No graphical tools.
|
|
- No per-file revision history, only per-changeset (we never really used this anyhow)
|
|
- Hg repositories tend to be rather bigger than Bk ones, but Hg does seem faster.
|
|
|
|
Mercurial is based on the notion of changesets as complete, immutable,
|
|
versions of the repository. You make changes to a working version of
|
|
the repository that is based on a particular changeset. When you
|
|
commit, you will generate a new child changeset with whatever changes
|
|
you choose to apply.
|
|
|
|
A major difference between Hg and BK is that you aren't forced to
|
|
resolve conflicts immediately: BK forced you to resolve conflicts
|
|
immediately on any merge, and it then immediately created a changeset
|
|
with those conflicts' resolutions. Frequently, you then had to add
|
|
yet another changeset to fixup the things for which the automatic
|
|
merge yielded bad results. Hg puts the results of the merge into your
|
|
work directory, and remembers what you merged with (so that it can
|
|
later record both of the merge parents, if you decide to make a
|
|
changeset), but it doesn't immediately create a changeset.
|
|
|
|
A further feature of Hg is that it allows a repository to have
|
|
multiple heads. This means that you can have changesets with no common
|
|
descendent in one repository -- something BK won't allow. This is
|
|
actually pretty neat. For example, it would in principle enable you to
|
|
have both the 2.0-testing and unstable trees in a single
|
|
repository. We shyed away from doing this as we thought the risk of
|
|
commiting to the wrong head was too great.
|
|
|
|
One slightly confusing aspect of Hg is that many of the commands have
|
|
aliases, and hence when looking things up in the man page its not
|
|
always obvious what the underlying command is. For example 'co' is
|
|
actually an alias for the 'update' command, but 'co' seems to make
|
|
more sense, at least to RCS refugees like me.
|
|
|
|
|
|
Getting Xen
|
|
-----------
|
|
|
|
The URL for the mainline Xen mercurial respository is:
|
|
|
|
http://xenbits.xensource.com/xen-unstable.hg
|
|
(similarly for xen-2.0 and xen-2.0-testing)
|
|
|
|
You can point a browser and this and use Hg's web interface to view
|
|
revision history, or use it as the nominated source when issuing
|
|
"hg init" or "hg pull" commands.
|
|
|
|
However, to avoid taxing the Mercurial server with a complete pull of
|
|
the Xen repository, it is best to download a tarball of a seed
|
|
repository from:
|
|
|
|
http://www.cl.cam.ac.uk/Research/SRG/netos/xen/downloads/xen-unstable.hg.tar.gz
|
|
|
|
(or copy from /usr/groups/netos/html/xen/downloads/xen-unstable.hg.tar.gz)
|
|
|
|
Untar the repository on your disk, cd into it, and then pull the most
|
|
recent changes:
|
|
|
|
hg pull -u
|
|
|
|
By default hg does not automatically checkout ('update') files from
|
|
the repository as used to happen with bk. The above is equivalent to
|
|
"hg pull; hg co"
|
|
|
|
The repository parent is stored in a repository configuration file,
|
|
.hg/hgrc, from the repository root. If you look at this file, you
|
|
will see:
|
|
|
|
| [paths]
|
|
| default = http://xenbits.xensource.com/xen-unstable.hg
|
|
|
|
"default" specifies the appropriate parent repository for hg to pull
|
|
from. Hg allows you to pull additional repositories, for instance if
|
|
you want to work between unstable and testing concurrently.
|
|
|
|
The command "hg pull" simply adds changesets to your repository,
|
|
without any merging of any kind. "hg pull -u" implies merging with
|
|
the current state of your working directory. If you weren't already
|
|
"updated" to your local repository's tip, you might be surprised to
|
|
find yourself merging the results of the pull with a non-tip node in
|
|
your local repository.
|
|
|
|
|
|
Revision History
|
|
----------------
|
|
|
|
You can view the repository revision history with:
|
|
|
|
hg history
|
|
|
|
In practice, you'll probably want to use pipe the output through
|
|
'head' or 'more' as it prints the entire history.
|
|
|
|
Looking at the first few lines of output, you can see the changeset at
|
|
the head of the current branch, known as the 'tip' (the tip is
|
|
automatically given a special tag to make it easy to refer to):
|
|
|
|
| changeset: 5599:6cbf9ec05cd9e05c0c46a85df7fc00262633cd3d
|
|
| tag: tip
|
|
| user: kaf24@firebug.cl.cam.ac.uk
|
|
| date: Tue Jun 28 18:47:14 2005
|
|
| summary: bitkeeper revision 1.1768 (42c18d2259NPELcGV7ohyZNh72ufSw)
|
|
|
|
By default, Hg just shows the first line of the changset comments. You
|
|
can find further information with "hg -v history".
|
|
|
|
The changeset identifier has two parts, a _local_ monotonically
|
|
increasing changeset id, 5599 above, and a _global_ hash, which
|
|
follows the colon on the changeset line. The hash uniquely identifies
|
|
the changeset and its lineage back to the root of the changeset tree
|
|
-- it is useful for distributed management and so on. However, as it
|
|
is a bit unruly, the local id will allow you to work easily with the
|
|
local repo. Hg commands will take either identifier. Additionally, a
|
|
tags mechanism lets you give common names to specific changesets.
|
|
|
|
You should always use the global hash when referring to versions of
|
|
the mainline Xen respoitory. With Bk you could often get away with
|
|
using the shortform version, but with Hg the local ids are pretty much
|
|
guaranteed to be different.
|
|
|
|
|
|
Creating a child repository from an existing repository
|
|
-------------------------------------------------------
|
|
If you wanted to create additional local child repositories,
|
|
|
|
hg init [path or url]
|
|
|
|
is effectively equivalent to bk clone. The major difference is that
|
|
it should be run from the root of your new repository. So:
|
|
|
|
bk clone /foo/bar
|
|
|
|
would be replaced with:
|
|
|
|
mkdir bar
|
|
cd bar
|
|
hg init /foo/bar
|
|
|
|
NB: newer version of Hg support a 'clone' command that works in the
|
|
same manner as bk.
|
|
|
|
Editing files
|
|
-------------
|
|
|
|
Normal edits may be made in place. File creation needs explicit
|
|
marking, though deletes should be picked up automatically
|
|
|
|
creation:
|
|
|
|
touch a.txt (or otherwise created a file)
|
|
hg add a.txt
|
|
|
|
You can see what has changed using:
|
|
|
|
hg status
|
|
|
|
| C foo/foo.c
|
|
| R foo/bar.c
|
|
| ? a.txt
|
|
|
|
This shows that in the current repo, foo.c has been changed, bar.c has
|
|
been deleted, and a.txt is new, but has not been added. '?' changes
|
|
to 'A' after "hg add a.txt". There is a .hgignore file which contains
|
|
regexps of files that should be ignored when scanning for new
|
|
files. We try to ensure that all the generated files in a build are
|
|
covered by the regexps.
|
|
|
|
You can add all the new files in a repository with "hg addremove". If
|
|
you discover that you've added a file you didn't want, you can remove
|
|
it from the list of files to be included in the next commit using
|
|
"hg forget".
|
|
|
|
Committing changes
|
|
-----------------
|
|
|
|
After you've checked that hg knows about any new files you've created,
|
|
you probably want to see a diff of what you're about to commit. You
|
|
can do this with:
|
|
|
|
hg diff
|
|
|
|
Once you're happy with what you have, invoke:
|
|
|
|
hg commit
|
|
|
|
This will pop up an editor with a list of files to be committed to the
|
|
repository. It will look vaguely like this:
|
|
|
|
|
|
|
| HG: manifest hash 6397b04bd5c2a992482d973b685a7e5e498788e7
|
|
| HG: changed doc/thesis/new.tex
|
|
| HG: removed doc/2005-hotdep-protection/paper.tex
|
|
|
|
Your comments can go anywhere in this file. The first line is the
|
|
most important, as it will show as the changeset description in
|
|
non-verbose-mode history listings.
|
|
|
|
You can do commits without the editor and of partial sets of files
|
|
using command-line switches. See:
|
|
|
|
hg help commit
|
|
|
|
You can use the -A (--addremove) flag to commit e.g. "hg -A commit" to
|
|
ask mercurial to scan the tree looking for newly created files to add
|
|
in to the changeset. This avoids having to explicitly use "hg add",
|
|
but you probably want to be careful of adding any new generated files
|
|
too.
|
|
|
|
|
|
Generating a patch
|
|
------------------
|
|
Generating a patch is easy,
|
|
|
|
hg export [changeset]
|
|
|
|
will generate a patch describing the diff between that changeset and
|
|
its parent.
|
|
|
|
To generate a patch between two specified revisions use:
|
|
hg diff -r A -r B [files]
|
|
NB: BK syntax -rA..B isn't supported by Hg.
|
|
|
|
|
|
Pushing changesets to a parent repository
|
|
-----------------------------------------
|
|
|
|
hg push
|
|
|
|
Pushes changes up to a parent. You can't push if you pulled the
|
|
repository off the web interface. In fact, you can currently only push
|
|
to an ssh target -- filesystem drectory targets don't work, but this
|
|
will be fixed soon.
|
|
For now it is possible to set up assymetric pull/push paths. Pulls can
|
|
be done via web interface while pushes via ssh. Example of .hg/hgrc config
|
|
file:
|
|
| [paths]
|
|
| default = http://your.server/repository_name
|
|
| default-push = ssh://[username@]your.server//repository_location
|
|
|
|
|
|
Repository history
|
|
------------------
|
|
|
|
Here are a collection of common commands to get you started:
|
|
|
|
hg history | less
|
|
|
|
shows the history of changesets, starting from the most recent. You
|
|
want to pipe it to some sort of pager. For more complete details,
|
|
|
|
hg -v history | less
|
|
|
|
will include files modified and full (not just first-line) comments.
|
|
|
|
Additionally, you can see just the tip (head of the current
|
|
branch) of the repository by typing:
|
|
|
|
hg [-v] tip
|
|
|
|
|
|
Moving to a specific changeset
|
|
------------------------------
|
|
|
|
The co command lets you change the working version of the repository
|
|
to a different changeset.
|
|
|
|
hg co [changeset]
|
|
|
|
NB: 'co' is an alias for 'update'
|
|
|
|
This command enables you to rewind the working repository to previous
|
|
changesets, for example to isolate the changeset in which a bug is
|
|
introduced.
|
|
|
|
If you try and do a 'co' but have modified files in your repository Hg
|
|
won't let you unless you ask it explicitly to merge the checked out
|
|
version into the current tree using the "-m" option. The "-C"
|
|
(--clean) option will force overwrite any locally modified files.
|
|
|
|
Any commits that are made to non-head changesets will obviously fork
|
|
the tree, creating a new head. You can see all the heads in a tree with
|
|
"hg heads".
|
|
|
|
In general, "hg co" does the right thing, although it doesn't
|
|
currently seem to clean up unused directories that have been created
|
|
by other checked-out versions. This can confuse the Xen build
|
|
system. Hg will probably get fixed soon, but in the meantime you can
|
|
cleanup with "find -depth -type d -print | xargs -r rmdir".
|
|
|
|
You can return to the tip by ommiting an explicit changeset id.
|
|
|
|
The manifest command lets you see the contents of the repository for
|
|
the current changeset.
|
|
|
|
hg manifest
|
|
|
|
This will print a bunch of records of the form:
|
|
|
|
| 98856c45c35a504bc6da06a62b7787ddfdfd1c8b 644 COPYING
|
|
| f28971eedc5b54e7a9b26dd18d52992955354981 644 Config.mk
|
|
| a3575cc4db59e50bbac8a039a0c74f081a8dfc4f 644 Makefile
|
|
| 7fc869aae2945a9f4626fad96552db3103e61cb9 644 README
|
|
| ...
|
|
|
|
This lists the hash of each file, its 1-bit 'executable' atribute
|
|
(either file permission mode 644 or 755), and the file name. So, to
|
|
determine the files that change across two changesets, you would dump
|
|
the respective manifests to files, and use diff.
|
|
|
|
|
|
Managing changeset tags
|
|
-----------------------
|
|
To create a tag to the current changeset:
|
|
|
|
hg tag tagname
|
|
|
|
This will _immediately_ generate a changeset with a change to the file
|
|
.hgtags in the repository root. The new tag in this file will look
|
|
something like:
|
|
|
|
| 35159ed4b30538e7a52c60ad0a63f7e9af156e4c tagname
|
|
|
|
and may be used to identify that changeset throughout the repo.
|
|
Storing tags in this file and generating changesets immediately
|
|
forces people to merge and keep tags up to date across the repository.
|
|
|
|
Note that tags are resolved by searching .hgtags in each of the
|
|
repository heads, sequentially, and using the first match. "hg heads"
|
|
lists the current heads.
|
|
|
|
The "hg tags" command, will lists all the currently valid tags.
|
|
|
|
|
|
Hg server and source browser
|
|
----------------------------
|
|
|
|
hg serve -p port
|
|
|
|
Launches a web server on the specified port, serving a source browser
|
|
for the repository. This browser may be used to examine the
|
|
changeset history, view annotated source files, generate diffs.
|
|
Additionally "hg pull" may be run against it.
|
|
|
|
Additional useful commands
|
|
(that probably only need one-line descriptions)
|
|
-----------------------------------------------
|
|
|
|
(Slightly) more detail on all of these is available with
|
|
|
|
hg help [command]
|
|
|
|
Shows the differences between whatever changeset you most recently
|
|
checked out, and your current working directory:
|
|
|
|
hg diff
|
|
|
|
View an annotated version of a source file:
|
|
|
|
hg annotate
|
|
|
|
Get a historical version of a file:
|
|
|
|
hg cat
|
|
|
|
NB: Most commands accepting a version number want the changeset's
|
|
version number. "hg cat" is different in that it wants the
|
|
*file*'s version number.
|
|
|
|
Unadd a file to the current commit:
|
|
|
|
hg forget
|
|
|
|
List all heads in the current repository:
|
|
|
|
hg heads
|
|
|
|
Undo exactly one (and ONLY one) changeset:
|
|
|
|
hg undo
|
|
|
|
Show the parents of a changeset:
|
|
|
|
hg parents
|
|
|
|
NB: Changesets have either one or two parent changesets. If your
|
|
working directory contains the uncommitted results of a merge, then
|
|
you have two parents. Otherwise, the single parent is the changeset
|
|
which you most recently checked out.
|
|
|
|
Show the revision history for a single file
|
|
|
|
hg [-v] log <filename>
|
|
|