--- a/hgext/mq.py Fri May 28 16:01:57 2010 -0500
+++ b/hgext/mq.py Sat May 29 20:32:39 2010 +0200
@@ -234,7 +234,12 @@
class queue(object):
def __init__(self, ui, path, patchdir=None):
self.basepath = path
- self.path = patchdir or os.path.join(path, "patches")
+ try:
+ fh = open(os.path.join(path, '.queue'))
+ curpath = os.path.join(path, fh.read().rstrip())
+ except IOError:
+ curpath = os.path.join(path, 'patches')
+ self.path = patchdir or curpath
self.opener = util.opener(self.path)
self.ui = ui
self.applied_dirty = 0
@@ -2533,6 +2538,107 @@
q.save_dirty()
return 0
+def qqueue(ui, repo, name=None, **opts):
+ '''manage multiple patch queues
+
+ Supports switching between different patch queues, as well as creating
+ new patch queues and deleting existing ones.
+
+ Omitting a queue name or specifying -l/--list will show you the registered
+ queues - by default the "normal" patches queue is registered. The currently
+ active queue will be marked with "(active)".
+
+ To create a new queue, use -c/--create. The queue is automatically made
+ active, except in the case where there are applied patches from the
+ currently active queue in the repository. Then the queue will only be
+ created and switching will fail.
+
+ To delete an existing queue, use --delete. You cannot delete the currently
+ active queue.
+ '''
+
+ q = repo.mq
+
+ _defaultqueue = 'patches'
+ _allqueues = '.queues'
+ _activequeue = '.queue'
+
+ def _getcurrent():
+ return os.path.basename(q.path)
+
+ def _noqueues():
+ try:
+ fh = repo.opener(_allqueues, 'r')
+ fh.close()
+ except IOError:
+ return True
+
+ return False
+
+ def _getqueues():
+ current = _getcurrent()
+
+ try:
+ fh = repo.opener(_allqueues, 'r')
+ queues = [queue.strip() for queue in fh if queue.strip()]
+ if current not in queues:
+ queues.append(current)
+ except IOError:
+ queues = [_defaultqueue]
+
+ return sorted(queues)
+
+ def _setactive(name):
+ if q.applied:
+ raise util.Abort(_('patches applied - cannot set new queue active'))
+
+ fh = repo.opener(_activequeue, 'w')
+ fh.write(name)
+ fh.close()
+
+ def _addqueue(name):
+ fh = repo.opener(_allqueues, 'a')
+ fh.write('%s\n' % (name,))
+ fh.close()
+
+ if not name or opts.get('list'):
+ current = _getcurrent()
+ for queue in _getqueues():
+ ui.write('%s' % (queue,))
+ if queue == current:
+ ui.write(_(' (active)\n'))
+ else:
+ ui.write('\n')
+ return
+
+ existing = _getqueues()
+
+ if name not in existing and opts.get('delete'):
+ raise util.Abort(_('cannot delete queue that does not exist'))
+ elif name not in existing and not opts.get('create'):
+ raise util.Abort(_('use --create to create a new queue'))
+
+ if opts.get('create'):
+ if _noqueues():
+ _addqueue(_defaultqueue)
+ _addqueue(name)
+ _setactive(name)
+ elif opts.get('delete'):
+ current = _getcurrent()
+
+ if name == current:
+ raise util.Abort(_('cannot delete currently active queue'))
+
+ fh = repo.opener('.queues.new', 'w')
+ for queue in existing:
+ if queue == name:
+ continue
+ fh.write('%s\n' % (queue,))
+ fh.close()
+ util.rename(repo.join('.queues.new'), repo.join(_allqueues))
+ else:
+ _setactive(name)
+
def reposetup(ui, repo):
class mqrepo(repo.__class__):
@util.propertycache
@@ -2839,6 +2945,14 @@
(finish,
[('a', 'applied', None, _('finish all applied changesets'))],
_('hg qfinish [-a] [REV]...')),
+ 'qqueue':
+ (qqueue,
+ [
+ ('l', 'list', False, _('list all available queues')),
+ ('c', 'create', False, _('create new queue')),
+ ('', 'delete', False, _('delete reference to queue')),
+ ],
+ _('[OPTION] [QUEUE]')),
}
colortable = {'qguard.negative': 'red',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-qqueue Sat May 29 20:32:39 2010 +0200
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+echo "[extensions]" >> $HGRCPATH
+echo "mq=" >> $HGRCPATH
+
+hg init foo
+cd foo
+echo a > a
+hg ci -qAm a
+
+echo %% default queue
+hg qqueue
+
+echo b > a
+hg qnew -fgDU somestuff
+
+echo %% applied patches in default queue
+hg qap
+
+echo %% try to change patch \(create succeeds, switch fails\)
+hg qqueue foo --create
+hg qqueue
+
+echo %% empty default queue
+hg qpop
+
+echo %% switch queue
+hg qqueue foo
+hg qqueue
+
+echo %% unapplied patches
+hg qun
+echo c > a
+hg qnew -fgDU otherstuff
+
+echo %% fail switching back
+hg qqueue patches
+
+echo %% fail deleting current
+hg qqueue foo --delete
+
+echo %% switch back and delete foo
+hg qpop -a
+hg qqueue patches
+hg qqueue foo --delete
+hg qqueue
+cd ..
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-mq-qqueue.out Sat May 29 20:32:39 2010 +0200
@@ -0,0 +1,23 @@
+%% default queue
+patches (active)
+%% applied patches in default queue
+somestuff
+%% try to change patch (create succeeds, switch fails)
+abort: patches applied - cannot set new queue active
+foo
+patches (active)
+%% empty default queue
+popping somestuff
+patch queue now empty
+%% switch queue
+foo (active)
+patches
+%% unapplied patches
+%% fail switching back
+abort: patches applied - cannot set new queue active
+%% fail deleting current
+abort: cannot delete currently active queue
+%% switch back and delete foo
+popping otherstuff
+patch queue now empty
+patches (active)
--- a/tests/test-mq.out Fri May 28 16:01:57 2010 -0500
+++ b/tests/test-mq.out Sat May 29 20:32:39 2010 +0200
@@ -49,6 +49,7 @@
qpop pop the current patch off the stack
qprev print the name of the previous patch
qpush push the next patch onto the stack
+ qqueue manage multiple patch queues
qrefresh update the current patch
qrename rename a patch
qselect set or print guarded patches to push