Managing independent patches

Christian Boos cboos at neuf.fr
Sat Apr 5 13:50:08 CDT 2008


Hello,

I've been quite interested by this discussion, as I also use MQ to 
manage mostly independent patches.
I'm adding some notes about hg qupdate, and I also propose an 
alternative solution, which is to address the problem by using multiple 
patch queues in the same working directory.


Jesse Glick wrote:
> Paul Moore wrote:
>   
>> 1. I would want my patches versioned
>>     
>
> So 'hg qinit -c' to get started...
>
>   
>> If I need to revert a patch
>>     
>
> Do you mean 'hg --cwd .hg/patches revert something.diff'? If you commit 
> after each patch you create, there wouldn't be anything else to revert. 
> Perhaps I misunderstand the question.
>
>   
>> 2. I think I'd spend a lot of time editing the series file to switch
>> the order of patches so that my "current" patch is the first one
>>     
>
> Someone recently posted a suggested patch to implement 'hg qup 
> something.diff' (or similar) which would make it particularly easy to do 
> this. (You would still need to 'hg qpop -a' first if you didn't want an 
> existing patch applied.) I'm sure you could write a simple shell script 
> to automate all this, or even a small Hg extension.
>
>   

Note that 'hg qupdate' is *already* an extension, just not yet a bundled 
one.
It works fine and I use it all the time, exactly for the same purpose as 
you..

See e.g. http://marc.info/?l=mercurial&m=120361309832542&w=2

For those wondering why this matters to edit the independent patch as 
the first one instead of simply doing an hg qgoto x or hg qpush x, it's 
because it's important to be able to have a clean diff against the base 
line when you're working in an "hybrid" checkout, like a svn checkout. 
So you can effectively work most of the time with Hg + MQ, and do "svn 
diff > x.diff" to produce patches, "svn up/ci" to pull from / push to 
upstream, etc.

There were already a few +1 votes for integrating that extension (I even 
counted one from Jesse ;-) ), but not follow-up... May I ask for it once 
again? The advantage of this extension over editing the series by hand 
is that it prevents you to mess up things with already applied patches.


>> 3. Each time I pull from upstream, I've got a lot of work to do to
>> rebase every patch.
>>     
>
> This is an active topic of discussion, and IMHO the greatest weakness of 
> MQ currently. I suggested 'hg qfetch' to do something akin to
>
> curr=`hg qtop`
> hg qpop -a
> hg fetch
> hg qpush $curr
>
> but with rebasing, use of merge tools rather than patch reject litter, 
> and of course error recovery. There have been various suggestions and I 
> think it's even a Google SoC project.
>   

The operations needed for rebasing MQ patches with merge support is 
described here:

http://hgbook.red-bean.com/hgbookch12.html#x16-28900012.8


Now, I had the idea that a somewhat different approach to solve the 
"Managing independent patches" issue could be to simply use *different 
queues*, in the same working directory, and have convenient ways to 
switch between them, list them, etc.
That way, you could address each different issue with one patch (or even 
multiple patches if really needed) in a dedicated queue, and version 
that queue if want, using qinit -c  and qcommit.

As I wanted to experiment a bit with this idea, that materialized into 
something that seemed so useful that I spent some time to polish it. I 
attached a proof-of-concept implementation for such a set of commands: 
mmq.sh

The main commands are:
  switchq [queuename]      -- switch to a named queue or create it
  listq                    -- list existing named queues
  whichq                   -- ask for the name of the active queue

And today I even added splitq, which is quite useful for splitting a 
existing big queue into smaller ones.

Here's a simple usage scenario:

Start working on feature 1:
  $ switchq feature1
  $ <work on feature 1>
  $ hg qref

Start working on feature 2
  $ switch feature2
  $ <work on feature 2>
  $ hg qref
  $ hg qnew test-case
  $ <add a test case for feature2>
  $ hg qref

Now go back working on feature1:
  $ switchq feature1
  $ <work more...>
  $ hg qref -m "done with feature1"

As feature1 is simply the active queue, you can do anything you would do 
with a Mercurial Queue, e.g. version it:
  $ hg qinit -c
  $ hg qcommit -m "save my first attempt for feature 1"
  $ <hack more on feature 1>
  $ hg qref
  $ hg qcommit -m "improved patch"

You have some ways to figure out where you stand:

  $ whichq
  feature1

  $ listq
  feature1
  feature2

  $ listq -v
  feature1: (active)
    * feature1
  feature2:
      feature2
    * test-case

As you can see from the above, a named queue will contain a first patch 
with the same name, and the patch at the top is remembered when 
switching off, so that it can be pushed again when switching on. This 
makes switching between queues quite convenient (even more so with 
command completion for switchq). If you already have lots of patches in 
your series, splitq can be used to move the applied patches in a queue 
of their own.

Hope you'll find that useful!

-- Christian
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: mmq.sh
Url: http://selenic.com/pipermail/mercurial/attachments/20080405/25aa4a3b/attachment.txt 


More information about the Mercurial mailing list