Some Mercurial Queues tips: hg qcrecord, qfold, and qpush –move

Recently I’ve come across some good solutions for common tasks with Mercurial Queues (MQ). I’ve updated our MDC page on this subject, and for greater visibility I’d like to copy that stuff here.

Splitting a patch, the easy case: per-file splitting

If you have a patch that modifies file1 and file2, and you want to split it into two patches each modifying only one file, do:

$ hg qgoto my-patch
$ hg qref -X path/to/first/file            # take changes out of current patch and back into `hg diff`
$ hg qnew -f patch-modifying-first-file    # and take that into a new MQ patch

Here, the qref -X command takes the changes to the first file out of the patch, so that they now show up in hg diff and therefore get picked up by the hg qnew -f.

Splitting a patch, the general case, including per-hunk and per-line splitting

If you need to perform finer patch splitting, for example per-hunk or even per-line, there’s a great tool for that: hg qcrecord. It’s provided by the Crecord extension. Follow the instructions on that page to install it. This extension works on your current `hg diff`. So if you had your patch as a MQ patch, you first need to take the changes out of it, using hg qref -X.

$ hg qref -X .             # take changes out of current patch and back into `hg diff`
$ hg qcrecord new-patch 

This will open a console-based dialog allowing you to select file-by-file, hunk-by-hunk, and even line-by-line, what changes you want to record into new-patch. When you first launch hg qcrecord, shows you a list of modified files:

SELECT CHUNKS: (j/k/up/dn/pgup/pgdn) move cursor; (space/A) toggle hunk/all
 (f)old/unfold; (c)ommit applied; (q)uit; (?) help | [X]=hunk applied **=folded
[X]**M hello.cpp

Let’s now press ‘f’ to unfold hello.cpp:

SELECT CHUNKS: (j/k/up/dn/pgup/pgdn) move cursor; (space/A) toggle hunk/all
 (f)old/unfold; (c)ommit applied; (q)uit; (?) help | [X]=hunk applied **=folded
[X]    diff --git a/hello.cpp b/hello.cpp
       2 hunks, 4 lines changed

   [X]     @@ -1,4 +1,5 @@
            #include <iostrea>
      [X]  +#include <cmath>
           #include <cstdlib>

           double square(double x)

   [X]     @@ -8,5 +9,6 @@

            int main()
            {
      [X]  -  std::cout << square(3.2) << std::endl;
      [X]  +  double x = 2.0;
      [X]  +  std::cout << std::sqrt(square(x)) << std::endl;
           }

Folding multiple patches into one

The hg qfold command allows you to merge a patch into another one:

$ hg qgoto my-first-patch      # go to first patch
$ hg qfold my-second-patch     # fold second patch into it

Pushing only one patch, reordering as needed

Mercurial 1.6 introduced the new hg qpush --move command, doing exactly that. This allows to reorder one’s patch queue without resorting to manually editing the series file.

3 Responses to “Some Mercurial Queues tips: hg qcrecord, qfold, and qpush –move”

  1. I’ve never tried hg qpush –move, since I did not know if it’s reliable. How reliable has it been for you?

  2. bjacob says:

    I use it frequently and it’s never failed me. Using hg 1.6.4.

  3. Jason Duell says:

    Nice post–very helpful! Thanks. qcrecord will save me some time once of these days…

    Jason