Managing Local Changes with Mercurial Queues

From gem5
Revision as of 14:07, 9 March 2013 by Atgutier (talk | contribs) (Creating and handling patches)
Jump to: navigation, search

Repository Management Problem

gem5 users typically opt to freeze their repository at a particular changeset when starting a new research project. This approach has several downsides:

  • It discourages users from contributing back any useful changes they may develop.
  • If a useful change is added upstream, it's a long, tedious process to update.

If a user chooses to keep their local repository up-to-date with the source tree they typically use named branches and merge any upstream changes into their branches. This approach also has its downsides:

  • If any local change needs to be updated, it requires a separate commit.
  • If you have several small, unrelated changes, separate branches must be maintained.
  • Upstream changes must be merged into the local branches.

A powerful tool that overcomes these problems is the mercurial queue extension.

Mercurial Queues

The mercurial queue extension is a powerful tool that allows you to:

  • Manage small changes easily as a set of well-defined patches.
  • Edit previous patches without having a new commit.
  • Keep your local changes cleanly separated from upstream changes.
  • Prevent changes from being recorded in the project history until they are ready.

Basic MQ commands

Help Command
  • hg help mq --- Gives a list of mercurial queue commands and a brief description of each.
Creating and handling patches
  • hg qnew change1.patch -m "commit message" --- Create a new patch named "change1.patch" with a commit message.
  • hg qpop --- Pop topmost patch off the queue.
  • hg qpush --- Push next patch in the series onto the queue.
  • hg qrefresh --- Add any local changes to the topmost patch.
  • hg qfinish --- Remove patch from the queue and make a permanent part of the repo history.
Checking the status of patches in the queue
  • hg qapplied --- List all applied patches in the queue.
  • hg qseries --- List all patches in the current series (this includes even patches that aren't applied).
  • hg qdiff --- Display the diff for the applied patch at the top of the queue
Adding patches from other queues
  • hg qimport -e pre_existing.patch --- Adds a pre-existing patch called "pre_existing.patch" to the local queue.

Rebase Extension

Example Mercurial Queue Use

Enable the MQ extension

To enable the mercurial queue extension, simply add the following to your .hgrc file:

[extensions]
hgext.mq =

Simple workflow with MQs

Here is a simple example outlining basic MQ usage:

# clone a clean copy of gem5
hg clone http://repo.gem5.org/gem5

# initialize a new mercurial queue
cd ./gem5
hg init --mq

# make some local changes and turn them into a patch
hg qnew change1.patch -m "cpu: made some changes to the cpu model"

# we have some more changes that we want to turn into a separate patch
hg qnew change2.patch -m "cache: made some changes to the cache"

# now you want to make some more changes and include them in change1
# make sure change1 is at the top of the queue
hg qtop

>>> change2.patch

# it's not, so we have to pop change2 off the queue
hg qpop
hg qtop

>>> change1.patch

# now it's the top patch. make the necessary changes and update
hg qrefresh

# re-apply change2
hg qpush

# let's check that all of our patches are applied
hg qapplied

>>> change1.patch
>>> change2.patch