[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Mercurial is the distributed version control system used to
manage the XEmacs core code. We plan to migrate the packages as well in
the near future. The command used is hg
; the entire system is
implemented as subcommands of the hg
command.
• Mercurial Basics | ||
13.1 Preserving Existing Changes with Mercurial Queues |
Most people have some kind of package manager to help install free software. Invariably a reasonably fresh version of Mercurial is available. XEmacs doesn’t do anything particularly tricky in its repositories, so unless you’re one of those folks who likes to spend more time fiddling with your infrastructure than developing, the packaged Mercurial should be more than sufficient. Somewhat fresher versions may be available in prepackaged form from the Mercurial Project, if you like to stay on the leading edge.
The primary online command for getting help on Mercurial is hg
help
.
For up-to-date information about this, other information about accessing the repository including making your first clone of the repository, and availability of branches, please refer to our website, http://www.xemacs.org/Develop/hgaccess.html.
Very little, for occasional contributors. So don’t worry about it; the commands are you used to with CVS or Subversion will work pretty much as is. There are two important differences:
In version control, update means to refresh the versions of files in your workspace. In a distributed system, however, there are two possible sources: the project repository, and your own clone (local repository) which is a more or less up-to-date copy of the project repository, including all the history information and historical revisions.
update is taken to mean refresh from the clone, and a new command pull is defined to mean copy history from the project repository to the clone. Thus, to get new work from other contributors applied to your repository, you need to pull, then update. Normally the source for pull defaults to the project repository you cloned from, and the version to update to defaults to the tip (latest version in the clone), so in principle you can abbreviate to
hg pull hg update |
In fact, Mercurial allows a further abbreviation, to hg pull -u
.
The other direction is similar. The commit command refers to the
clone. A new command, push is used to copy local history
to the project repository. Unlike the pull
command, however,
there is no very short way to say “command and push.”
Third parties provide many extensions to Mercurial. (In fact, the
Mercurial Project often distributes new functionality as extensions,
until the UI has stabilized.) Extensions are just as easy to use as
core commands, and well-written extensions provide their documentation
via hg help
just like the core. The main difference is that core
commands are always available, but extensions must be enabled. This is
done in the extensions section of ‘~/.hgrc’. Here’s one of mine:
[ui] username = Stephen J. Turnbull <stephen@xemacs.org> ignore = ~/.hgglobalignore [extensions] hgext.hgk = hgext.mq = hgext.rebase = |
All of the extensions mentioned above are distributed with Mercurial
itself, so enabing them is particularly simple. A locally written or
third-party extension would have a path-to-module after the equal sign.
The first two extensions above are recommended for all contributors.
Some contributors may like to use the rebase extension as well, and
sometimes it’s a good way to dig yourself out of a hole. Others hate
it; if you are thinking about using it, you should be careful, and you
should never push
a rebased branch without coordinating with the
project.
hgk
A browser for the history graph, showing relationships among versions.
Provides the view
command.
mq
Mercurial queues are a way of managing sequences of patches, similar to the “quilt” program made famous by some Linux maintainers. It allows you to distinguish between your local changes and “official” ones. Provides many commands beginning with the letter “q”.
rebase
Rebasing is an alternative technique for managing sequences of patches.
However, it uses branches rather than patches, and can produce a very
confusing public history if used indiscriminately. Provides the
rebase
command.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
When first working with a distributed VCS, you may find yourself creating a series of unrelated changes in the workspace. Now you feel stuck: you worry that you if you commit now, you’ll pull in unrelated changes. But Mercurial won’t let you merge until you have committed? Here’s how to use Mercurial queues to push “just this fix” without also pushing unrelated, uncommited changes also present in the workspace. This will also set you up for more effective workflow in the future.
First, mq is an extension, which must be enabled before use. Edit ‘$HOME/.hgrc’ and add these two lines:
[extensions] hgext.mq = |
If you already have an [extensions] section, omit the first line.
Suppose the change that you are ready to push is a check for a valid drive letter on the Windows platform. It affects ‘src/nt.c’, and of course ‘src/ChangeLog’. Assume you have no other changes to these files. It is important to do this step now, before handling other changes! (In general, it’s a good idea to create your mq patches in approximately the order you will submit them. There are ways to override that order, using “guards,” but that’s a little tedious. Recent versions of Mercurial queues have an option to reorder patches when applying them: ‘hg qpush --move patch-name’.)
Initialize an mq patch for this change:
hg qnew -f -m "Check first whether drive is valid." valid-drive \ src/ChangeLog src/nt.c |
View ‘.hg/patches/valid-drive’ and make sure it is the patch you want to push.
Now make patches for other changes. For a change to ‘foo.el’, ‘foo-msw.el’, and ‘lisp/ChangeLog’ it would look like
hg qnew -f -m "Frob foo." frob-foo lisp/foo.el lisp/foo-msw.el \ lisp/ChangeLog |
Do this until there are no changes left (hg status reports no modified files).
I strongly recommend that you do this now. This is probably the best way to organize your work when you make many small changes. However, if you have overlapping changes that you can’t easily sort out, or just don’t feel like doing that, you can just
hg qnew -f -m "DON'T COMMIT ME!" big-ball-of-mud |
instead.
Now let’s commit the patch you want to push. If you feel paranoid, you can view all the patches in ‘.hg/patches’ to make sure they look OK.
hg qpop --all # unapply --all patches hg status # should report no modified files hg qpush # note, no argument needed hg qapplied # will report "valid-drive" because that was # the first patch you created (it's a queue!!) hg qfinish --applied # convert valid-drive from a patch to a commit # Make sure it's OK. hg log -r tip # message you gave in 'qnew -m' is the # log message |
Update and push.
hg pull -u # should work without complaint since you # don't say you have any commits hg push # Yay! |
That looks like a lot of work, but it’s actually not too inconvenient.
After this, whenever you have something that could turn into a commitable change, do "hg qnew ...". Make the ‘ChangeLog’ right away (it can even just be a placeholder to fill in later). That allows you to isolate this change from other changes, even if they touch the same files.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Aidan Kehoe on December 27, 2016 using texi2html 1.82.