Managing Local Changes with Mercurial Queues
From gem5
Contents
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.
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