Extension to reorder mq patches

Andrei Vermel avermel at mail.ru
Thu Feb 21 10:32:38 CST 2008


-----Original Message-----
From: M.A. Williamson [mailto:maw48 at hermes.cam.ac.uk] On Behalf Of Mark
Williamson

> I was thinking it might be nice to be able to modify the patch 
> queue whilst patches are applied as long as it doesn't affect 
> the order of currently applied patches?  e.g.
Good point, I added this.

> If somebody had a really big patch queue then this might take a while, 
> especially if they're working over a network filesystem.  That's not a 
> problem as far as I'm concerned but what if you hit Ctrl-C for some reason

> during this process?  As far as I can see they could end up with a 
> truncated series file, which wouldn't be good.
> 
> Not entirely sure what would be the hg way of going about this but maybe
> you could write a new series file and then move it in place?

Rename is not atomic on windows, unfortunately, as file needs to be
deleted before rename. Still this makes a smaller lag period. 
I added this too.



# qup.py - move MQ patches to top of unapplied part of series
#
# Copyright 2008 Andrei Vermel <andrei.vermel at gmail.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.

from mercurial.i18n import _
from mercurial.node import *
from mercurial import commands, cmdutil, hg, node, util
import os, tempfile

def qup(ui, repo, *patches, **opts):
    '''move MQ patches to top of unapplied part of series.

Patches can be specified by unambiguous start substrings or indices.'''

    try:
        series = file(repo.path+'/patches/series', 'r')
    except:
        raise util.Abort(_('patch queue not found'))

    q = repo.mq

    if not patches:
        raise util.Abort(_('no patches specified'))

    old_num_patches = len(patches)
    patches = [q.lookup(patch) for patch in patches]
    patches_dict = dict.fromkeys(patches)
    if len(patches_dict.keys()) != old_num_patches:
        raise util.Abort(_(('same patch specified multiple times, %s') %
patches))

    series_dict = dict.fromkeys(q.series)
    for p in patches:
        if p not in series_dict:    
            raise util.Abort(_(('patch %s is not in series') % p))
   
    applied=[a.name for a in q.applied]
    for a in applied:
        if a in patches_dict:
            raise util.Abort(_(('patch %s is applied already, can\'t move')
% a))

    pending_applied = False
    if applied:
        top_applied = applied[-1]
        pending_applied = True
   
    tokeep = [] 
    tofront = {}
    toback = []
    for line in series:
        if line.strip().startswith('#'):
            toback.append(line)
        else:
            spl = line.split('#')
            firstword=''
            if spl:
                firstword = spl[0].strip()
            if pending_applied:
                tokeep.append(line)
                if firstword == top_applied:
                    pending_applied = False
            else:
                if firstword in patches_dict:
                    tofront[firstword]=line
                else:
                    toback.append(line)

    if pending_applied:
        raise util.Abort(_('top applied patch not found in the series?'))
    if not tofront:
        raise util.Abort(_('none of specified patches found in the series'))

    outfile = file(tempfile.mktemp(), 'w')
    outfile.writelines(tokeep)
    for patch in patches:
        outfile.write(tofront[patch].rstrip('\n')+'\n')
    outfile.writelines(toback)
    outfile.close()
    series.close()
    os.remove(series.name)
    os.rename(outfile.name, series.name)

cmdtable = {
    'qup':
        (qup, [],
        _('hg qup PATCH...')),
}
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: qup.py
Url: http://selenic.com/pipermail/mercurial/attachments/20080221/3312975a/attachment.txt 


More information about the Mercurial mailing list