Performing Common Tasks¶
Revive a Commit That Was Backed Out¶
Say your repository has the following history:
changeset: 263002:dfc93c68f9c7
user: Gijs Kruitbosch <gijskruitbosch@gmail.com>
date: Mon Dec 22 15:05:06 2014 +0000
summary: Bug 1113299 - hide tab mirroring feature if unavailable, r=jaws
changeset: 263001:268dfa4925ec
user: Brian Grinstead <bgrinstead@mozilla.com>
date: Tue Jan 13 12:25:57 2015 -0800
summary: Backed out changeset 291e3a83a122 (bug 1042619)
changeset: 263000:492134f929e2
user: Tim Nguyen <ntim.bugs@gmail.com>
date: Tue Jan 13 09:51:00 2015 -0500
summary: Bug 1121048 - Add back round corners on perf tool icon glyphs. r=jsantell
Commit 291e3a83a122
was backed out by 263001:268dfa4925ec
and
you want to revive it, either to reland it or to work on it again.
hg graft
should be used to revive old commits. In this case:
$ hg graft -f 291e3a83a122
grafting 262999:291e3a83a122 "Bug 1042619 - Change 'width x height' letter x to × in devtools frontend;r=bgrins"
merging browser/devtools/canvasdebugger/canvasdebugger.js
merging browser/devtools/layoutview/view.js
merging browser/devtools/responsivedesign/responsivedesign.jsm
$ hg log
changeset: 263004:3c6672d2df85
tag: tip
parent: 263002:dfc93c68f9c7
user: Aaron Raimist <aaronraimist@protonmail.ch>
date: Tue Jan 13 11:59:01 2015 -0800
summary: Bug 1042619 - Change 'width x height' letter x to × in devtools frontend;r=bgrins
As you can see, hg graft
recreated the original commit. The
merging
lines in the output above indicate that Mercurial invoked
its merge resolution algorithm to as part of grafting. What this means
is that the listed files were changed between when the commit was
originally performed and where the new commit resides. Mercurial was
able to automatically merge the differences. Had it not been able to do
so, it would entered the merge resolution workflow and asked you to run
hg graft --continue
to finish the graft.
Note
The -f
in this example is important: it allows grafting of commits
that are already ancestors of their destination. Without it, Mercurial
sees that you are attempting to recreate a commit that has already been
applied and will prevent you from probably shooting yourself in the
foot.
If you are familiar with Git, hg graft
is roughly equivalent to
git cherry-pick
.
Upgrading Repository Storage¶
Mercurial periodically makes changes to its on-disk storage that require a one-time upgrade of repository data to take advantage of the new storage format. Mercurial doesn’t do this automatically because the backwards compatibility guarantees of Mercurial say that the version of Mercurial that created a repo should always be able to read from it, even if common repo operations are performed by a newer version.
You have 2 options for upgrading repository storage:
- Re-clone the repo
- Run
hg debugupgraderepo
Upgrading Storage via Clone¶
A fresh Mercurial clone will usually use optimal/recommended storage for the Mercurial version being used. However, depending on how the clone is performed and where it is cloned from, this may not always work as expected.
To achieve an optimal clone with efficient storage, always clone from https://hg.mozilla.org/ - not from a local repo. By cloning from hg.mozilla.org, your clone will inherit the optimal storage used by the server. If you clone from anywhere else, you may inherit sub-optimal storage.
Say you have a copy of mozilla-central in a local mozilla-central directory. Perform a clone-based upgrade by running the following:
# Grab pristine copy of repo.
$ hg clone -U https://hg.mozilla.org/mozilla-central mozilla-central.new
# Copy over .hgrc
$ cp mozilla-central/.hg/hgrc mozilla-central.new/.hg/hgrc
# Pull your unpublished work from your local clone into the new clone.
$ hg --config phases.publish=false -R mozilla-central.new pull mozilla-central
# Now rename/remove your repos as appropriate.
Important
That config adjustment for phases.publish=false
is important. Without it,
draft changesets will become public and Mercurial won’t let you edit them.
To guard against, it is a good practice to add the following to your per-repo
.hg/hgrc
file immediately after a clone:
[phases]
publish = false
If you accidentally publish your draft changesets, you can reset phases by running the following commands:
# Reset all phases to draft.
$ hg phase --draft --force -r 0:tip
# Synchronize phases from a publishing repo.
$ hg pull https://hg.mozilla.org/...
Upgrading Storage via debugupgraderepo
¶
(Requires Mercurial 4.1 or newer)
Upgrading repository storage in-place is relatively easy: just use
hg debugupgraderepo
. This command (which is strictly still an
experimental command but shouldn’t corrupt your data) essentially
does an in-place hg clone
while applying various data and storage
optimizations along the way. The command doesn’t make any permanent
changes until the very end and makes a backup of your original data,
so there should be a low risk of data loss.
In its default mode of execution, hg debugupgraderepo
simply
converts storage to the latest storage format: it doesn’t heavily
process data to optimize it. So, to get the benefits of data optimization
(which will shrink the size of the repo and make operations faster),
you need to pass some flags to the command.
The first time you upgrade a repo, run as follows:
$ hg debugupgraderepo --optimize redeltaparent --optimize redeltamultibase --run
redeltaparent
tells Mercurial to recalculate the internal deltas
in storage so a logical parent is used. The first time this runs, it
will significantly slow down execution but it can result in significant
space savings on a Firefox repos. If you specify this on a repo where
data is already efficiently stored, it is almost a no-op.
redeltamultibase
tells Mercurial to calculate for merges against
both parents and to use the smallest. This always adds significant
processing time to repos with lots of merges. It can also drastically
reduce the repository size (by several hundred megabytes for Firefox
repos).
On a Firefox repository, it could take 2-3 hours to perform data optimizations if the repository isn’t already optimized. If you clone from hg.mozilla.org, you will get these optimizations automatically because the server performs them.
Analyzing Pushlog Data Offline¶
The mozext
extension replicates pushlog data to a local SQLite
database during hg pull
operations. The extension also exposes
some revsets and template features that allow querying and
formatting of pushlog data.
To enable mozext
, add the following to your hgrc:
[extensions]
firefoxtree = /path/to/version-control-tools/hgext/firefoxtree
mozext = /path/to/version-control-tools/hgext/mozext
Then, in a Firefox clone, run an hg pull
to grab pushlog data:
$ hg pull central
$ hg pull autoland
Now, you can run revsets to query pushlog data:
# Find all changesets initially pushed to autoland
$ hg log -r 'firstpushtree(autoland)' -T '{rev} {node|short} {desc|firstline}\n'
# Find revisions that were heads at time of push (this means they should have CI
# results available)
$ hg log -r 'pushhead(central)'