##// END OF EJS Templates
record: check patch name is valid before prompting in qrecord
record: check patch name is valid before prompting in qrecord

File last commit:

r14424:4eb88d29 default
r14424:4eb88d29 default
Show More
mq.py
3296 lines | 119.2 KiB | text/x-python | PythonLexer
Marti Raudsepp
mq: Cleanup: update outdated file header.
r6187 # mq.py - patch queues for mercurial
mason@suse.com
Add mq extension
r1808 #
Vadim Gelfer
update copyrights.
r2859 # Copyright 2005, 2006 Chris Mason <mason@suse.com>
mason@suse.com
Add mq extension
r1808 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
mason@suse.com
Add mq extension
r1808
Dirkjan Ochtman
extensions: fix up description lines some more
r8932 '''manage a stack of patches
Vadim Gelfer
help: add help to mq extension
r2554
This extension lets you work with a stack of patches in a Mercurial
Martin Geisler
Change double spaces to single spaces in help texts.
r7983 repository. It manages two stacks of patches - all known patches, and
Vadim Gelfer
help: add help to mq extension
r2554 applied patches (subset of known patches).
Known patches are represented as patch files in the .hg/patches
Martin Geisler
Change double spaces to single spaces in help texts.
r7983 directory. Applied patches are both patch files and changesets.
Vadim Gelfer
help: add help to mq extension
r2554
Martin Geisler
Use hg role in help strings
r10973 Common tasks (use :hg:`help command` for more details)::
Vadim Gelfer
help: add help to mq extension
r2554
Martin Geisler
commands: use minirst parser when displaying help
r9157 create new patch qnew
import existing patch qimport
Vadim Gelfer
help: add help to mq extension
r2554
Martin Geisler
commands: use minirst parser when displaying help
r9157 print patch series qseries
print applied patches qapplied
Vadim Gelfer
help: add help to mq extension
r2554
Martin Geisler
commands: use minirst parser when displaying help
r9157 add known patch to applied stack qpush
remove patch from applied stack qpop
refresh contents of top applied patch qrefresh
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190
By default, mq will automatically use git patches when required to
avoid losing file mode changes, copy records, binary files or empty
files creations or deletions. This behaviour can be configured with::
[mq]
git = auto/keep/yes/no
If set to 'keep', mq will obey the [diff] section configuration while
preserving existing git patches upon qrefresh. If set to 'yes' or
'no', mq will override the [diff] section and always generate git or
regular patches, possibly losing data in the second case.
Martin Geisler
mq: mention qqueue in module docstring
r11234
You will by default be managing a patch queue named "patches". You can
create other, independent patch queues with the :hg:`qqueue` command.
Vadim Gelfer
help: add help to mq extension
r2554 '''
Matt Mackall
Simplify i18n imports
r3891 from mercurial.i18n import _
Matt Mackall
mq: remove import of revlog
r7639 from mercurial.node import bin, hex, short, nullid, nullrev
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 from mercurial.lock import release
Idan Kamara
mq: don't hide the patch module
r14241 from mercurial import commands, cmdutil, hg, scmutil, util, revset
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 from mercurial import repair, extensions, url, error
Idan Kamara
mq: don't hide the patch module
r14241 from mercurial import patch as patchmod
"Yann E. MORIN"
mq/qqueue: add --purge option to delete a queue and its patch dir...
r11967 import os, sys, re, errno, shutil
mason@suse.com
Add mq extension
r1808
Peter Arrenbrecht
mq: drop obsolete reference to 'qversion'
r5645 commands.norepo += " qclone"
Vadim Gelfer
mq: add qclone command
r2720
Martin Geisler
mq: use cmdutil.command decorator
r14298 seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
cmdtable = {}
command = cmdutil.command(cmdtable)
Patrick Mezard
Enforce unixish style for all generated patch names....
r4037 # Patch names looks like unix-file names.
# They must be joinable with queue directory and result in the patch path.
normname = util.normpath
Benoit Boissinot
use new style classes
r8778 class statusentry(object):
Benoit Boissinot
mq: simplify statusentry(), fix restore broken by ee48e5ef8753
r10682 def __init__(self, node, name):
self.node, self.name = node, name
Dirkjan Ochtman
mq: __str__ falls back to __repr__
r11375 def __repr__(self):
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 return hex(self.node) + ':' + self.name
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 class patchheader(object):
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 def __init__(self, pf, plainmode=False):
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 def eatdiff(lines):
while lines:
l = lines[-1]
if (l.startswith("diff -") or
l.startswith("Index:") or
l.startswith("===========")):
del lines[-1]
else:
break
def eatempty(lines):
while lines:
Benoit Boissinot
mq: don't use regexp when not necessary
r10688 if not lines[-1].strip():
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 del lines[-1]
else:
break
message = []
comments = []
user = None
date = None
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 parent = None
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 format = None
subject = None
Steve Borho
mq: record more data in patchheader class (no behavior changes)...
r13229 branch = None
nodeid = None
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 diffstart = 0
for line in file(pf):
line = line.rstrip()
Benoit Boissinot
mq: allow lines starting with '--- ' in patch messages
r10730 if (line.startswith('diff --git')
or (diffstart and line.startswith('+++ '))):
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 diffstart = 2
break
Benoit Boissinot
mq: allow lines starting with '--- ' in patch messages
r10730 diffstart = 0 # reset
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 if line.startswith("--- "):
diffstart = 1
continue
elif format == "hgpatch":
# parse values when importing the result of an hg export
if line.startswith("# User "):
user = line[7:]
elif line.startswith("# Date "):
date = line[7:]
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 elif line.startswith("# Parent "):
Kevin Bullock
mq: strip extra whitespace from node ids in header (issue2790)...
r14170 parent = line[9:].lstrip()
Steve Borho
mq: record more data in patchheader class (no behavior changes)...
r13229 elif line.startswith("# Branch "):
branch = line[9:]
elif line.startswith("# Node ID "):
nodeid = line[10:]
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 elif not line.startswith("# ") and line:
message.append(line)
format = None
elif line == '# HG changeset patch':
David Soria Parra
mq: Parse commit message after we find start of changeset patch...
r9287 message = []
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 format = "hgpatch"
elif (format != "tagdone" and (line.startswith("Subject: ") or
line.startswith("subject: "))):
subject = line[9:]
format = "tag"
elif (format != "tagdone" and (line.startswith("From: ") or
line.startswith("from: "))):
user = line[6:]
format = "tag"
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 elif (format != "tagdone" and (line.startswith("Date: ") or
line.startswith("date: "))):
date = line[6:]
format = "tag"
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 elif format == "tag" and line == "":
# when looking for tags (subject: from: etc) they
# end once you find a blank line in the source
format = "tagdone"
elif message or line:
message.append(line)
comments.append(line)
eatdiff(message)
eatdiff(comments)
Steve Borho
mq: record more data in patchheader class (no behavior changes)...
r13229 # Remember the exact starting line of the patch diffs before consuming
# empty lines, for external use by TortoiseHg and others
self.diffstartline = len(comments)
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 eatempty(message)
eatempty(comments)
# make sure message isn't empty
if format and format.startswith("tag") and subject:
message.insert(0, "")
message.insert(0, subject)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 self.message = message
self.comments = comments
self.user = user
self.date = date
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 self.parent = parent
Steve Borho
mq: record more data in patchheader class (no behavior changes)...
r13229 # nodeid and branch are for external use by TortoiseHg and others
self.nodeid = nodeid
self.branch = branch
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 self.haspatch = diffstart > 1
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 self.plainmode = plainmode
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399
def setuser(self, user):
Cédric Duval
mq: rename setheader to updateheader and fix comment
r8654 if not self.updateheader(['From: ', '# User '], user):
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 try:
patchheaderat = self.comments.index('# HG changeset patch')
Yann E. MORIN
mq: fix coding style in qrefresh
r9334 self.comments.insert(patchheaderat + 1, '# User ' + user)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 except ValueError:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 if self.plainmode or self._hasheader(['Date: ']):
Yann E. MORIN
mq: upgrade the patch to HG format when adding the author name with qrefresh...
r9336 self.comments = ['From: ' + user] + self.comments
else:
tmp = ['# HG changeset patch', '# User ' + user, '']
self.comments = tmp + self.comments
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 self.user = user
def setdate(self, date):
Yann E. MORIN
mq: add the date with qrefresh, even if missing (issue1768)...
r9337 if not self.updateheader(['Date: ', '# Date '], date):
try:
patchheaderat = self.comments.index('# HG changeset patch')
self.comments.insert(patchheaderat + 1, '# Date ' + date)
except ValueError:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 if self.plainmode or self._hasheader(['From: ']):
Yann E. MORIN
mq: add the date with qrefresh, even if missing (issue1768)...
r9337 self.comments = ['Date: ' + date] + self.comments
else:
tmp = ['# HG changeset patch', '# Date ' + date, '']
self.comments = tmp + self.comments
self.date = date
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 def setparent(self, parent):
if not self.updateheader(['# Parent '], parent):
try:
patchheaderat = self.comments.index('# HG changeset patch')
self.comments.insert(patchheaderat + 1, '# Parent ' + parent)
except ValueError:
pass
self.parent = parent
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 def setmessage(self, message):
if self.comments:
self._delmsg()
self.message = [message]
self.comments += self.message
Cédric Duval
mq: rename setheader to updateheader and fix comment
r8654 def updateheader(self, prefixes, new):
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 '''Update all references to a field in the patch header.
Cédric Duval
mq: rename setheader to updateheader and fix comment
r8654 Return whether the field is present.'''
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 res = False
for prefix in prefixes:
for i in xrange(len(self.comments)):
if self.comments[i].startswith(prefix):
self.comments[i] = prefix + new
res = True
break
return res
Yann E. MORIN
mq: add function to check if a header exists in a patch
r9335 def _hasheader(self, prefixes):
'''Check if a header starts with any of the given prefixes.'''
for prefix in prefixes:
for comment in self.comments:
if comment.startswith(prefix):
return True
return False
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 def __str__(self):
if not self.comments:
return ''
return '\n'.join(self.comments) + '\n\n'
def _delmsg(self):
'''Remove existing message, keeping the rest of the comments fields.
If comments contains 'subject: ', message will prepend
the field and a blank line.'''
if self.message:
subj = 'subject: ' + self.message[0].lower()
for i in xrange(len(self.comments)):
if subj == self.comments[i].lower():
del self.comments[i]
self.message = self.message[2:]
break
ci = 0
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 for mi in self.message:
while mi != self.comments[ci]:
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 ci += 1
del self.comments[ci]
Benoit Boissinot
use new style classes
r8778 class queue(object):
mason@suse.com
Add mq extension
r1808 def __init__(self, ui, path, patchdir=None):
self.basepath = path
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 try:
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 fh = open(os.path.join(path, 'patches.queue'))
cur = fh.read().rstrip()
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 fh.close()
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 if not cur:
curpath = os.path.join(path, 'patches')
else:
curpath = os.path.join(path, 'patches-' + cur)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 except IOError:
curpath = os.path.join(path, 'patches')
self.path = patchdir or curpath
Adrian Buehlmann
move opener from util to scmutil
r13970 self.opener = scmutil.opener(self.path)
mason@suse.com
Add mq extension
r1808 self.ui = ui
self.applied_dirty = 0
self.series_dirty = 0
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 self.added = []
Thomas Arendsen Hein
Fix mq's usage of opener, which don't allow absolute paths now.
r1852 self.series_path = "series"
self.status_path = "status"
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 self.guards_path = "guards"
self.active_guards = None
self.guards_dirty = False
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190 # Handle mq.git as a bool with extended values
try:
gitmode = ui.configbool('mq', 'git', None)
if gitmode is None:
raise error.ConfigError()
self.gitmode = gitmode and 'yes' or 'no'
except error.ConfigError:
self.gitmode = ui.config('mq', 'git', 'auto').lower()
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 self.plainmode = ui.configbool('mq', 'plain', False)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Simon Heimberg
mq: only read files when needed...
r8524 @util.propertycache
def applied(self):
Vadim Gelfer
mq: add join method
r2819 if os.path.exists(self.join(self.status_path)):
Pierre-Yves David
mq: gracefully handle malformated status file...
r13507 def parselines(lines):
for l in lines:
entry = l.split(':', 1)
if len(entry) > 1:
n, name = entry
yield statusentry(bin(n), name)
elif l.strip():
self.ui.warn(_('malformated mq status line: %s\n') % entry)
# else we ignore empty lines
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 lines = self.opener.read(self.status_path).splitlines()
Pierre-Yves David
mq: gracefully handle malformated status file...
r13507 return list(parselines(lines))
Simon Heimberg
mq: only read files when needed...
r8524 return []
@util.propertycache
def full_series(self):
if os.path.exists(self.join(self.series_path)):
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 return self.opener.read(self.series_path).splitlines()
Simon Heimberg
mq: only read files when needed...
r8524 return []
@util.propertycache
def series(self):
self.parse_series()
return self.series
@util.propertycache
def series_guards(self):
self.parse_series()
return self.series_guards
mason@suse.com
Add mq extension
r1808
Simon Heimberg
mq: new method invalidate...
r8525 def invalidate(self):
for a in 'applied full_series series series_guards'.split():
if a in self.__dict__:
delattr(self, a)
self.applied_dirty = 0
self.series_dirty = 0
self.guards_dirty = False
self.active_guards = None
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 def diffopts(self, opts={}, patchfn=None):
Idan Kamara
mq: don't hide the patch module
r14241 diffopts = patchmod.diffopts(self.ui, opts)
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190 if self.gitmode == 'auto':
diffopts.upgrade = True
elif self.gitmode == 'keep':
pass
elif self.gitmode in ('yes', 'no'):
diffopts.git = self.gitmode == 'yes'
else:
raise util.Abort(_('mq.git option can be auto/keep/yes/no'
' got %s') % self.gitmode)
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 if patchfn:
Patrick Mezard
mq: preserve --git flag when merging patches...
r10185 diffopts = self.patchopts(diffopts, patchfn)
return diffopts
Patrick Mezard
mq: preserve --git flag when folding patches...
r10186 def patchopts(self, diffopts, *patches):
Patrick Mezard
mq: preserve --git flag when merging patches...
r10185 """Return a copy of input diff options with git set to true if
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190 referenced patch is a git patch and should be preserved as such.
Patrick Mezard
mq: preserve --git flag when merging patches...
r10185 """
diffopts = diffopts.copy()
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190 if not diffopts.git and self.gitmode == 'keep':
for patchfn in patches:
patchf = self.opener(patchfn, 'r')
# if the patch was a git patch, refresh it as a git patch
for line in patchf:
if line.startswith('diff --git'):
diffopts.git = True
break
patchf.close()
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 return diffopts
Vadim Gelfer
refactor text diff/patch code....
r2874
Vadim Gelfer
mq: add join method
r2819 def join(self, *p):
return os.path.join(self.path, *p)
mason@suse.com
Add mq extension
r1808 def find_series(self, patch):
Benoit Boissinot
mq: find_series() simplify and don't use regexps
r10685 def matchpatch(l):
l = l.split('#', 1)[0]
return l.strip() == patch
for index, l in enumerate(self.full_series):
if matchpatch(l):
return index
mason@suse.com
Add mq extension
r1808 return None
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 guard_re = re.compile(r'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
Vadim Gelfer
mq: rename read_series as parse_series, make simpler and faster
r2767 def parse_series(self):
mason@suse.com
Add mq extension
r1808 self.series = []
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 self.series_guards = []
Vadim Gelfer
mq: rename read_series as parse_series, make simpler and faster
r2767 for l in self.full_series:
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 h = l.find('#')
if h == -1:
patch = l
comment = ''
elif h == 0:
continue
else:
patch = l[:h]
comment = l[h:]
patch = patch.strip()
if patch:
Brendan Cully
mq: bail out if a patch appears more than once in the series file....
r3184 if patch in self.series:
raise util.Abort(_('%s appears more than once in %s') %
(patch, self.join(self.series_path)))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 self.series.append(patch)
self.series_guards.append(self.guard_re.findall(comment))
def check_guard(self, guard):
Patrick Mezard
mq: make qselect fail properly on an empty guard
r6607 if not guard:
return _('guard cannot be an empty string')
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 bad_chars = '# \t\r\n\f'
first = guard[0]
Simon Heimberg
mq: simpler check of first character of guard name
r8288 if first in '-+':
return (_('guard %r starts with invalid character: %r') %
(guard, first))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 for c in bad_chars:
if c in guard:
return _('invalid character in guard %r: %r') % (guard, c)
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def set_active(self, guards):
for guard in guards:
bad = self.check_guard(guard)
if bad:
raise util.Abort(bad)
Matt Mackall
replace util.sort with sorted built-in...
r8209 guards = sorted(set(guards))
Martin Geisler
do not attempt to translate ui.debug output
r9467 self.ui.debug('active guards: %s\n' % ' '.join(guards))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 self.active_guards = guards
self.guards_dirty = True
def active(self):
if self.active_guards is None:
self.active_guards = []
try:
Dan Villiom Podlaski Christiansen
prevent transient leaks of file handle by using new helper functions...
r14168 guards = self.opener.read(self.guards_path).split()
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 except IOError, err:
Matt Mackall
many, many trivial check-code fixups
r10282 if err.errno != errno.ENOENT:
raise
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 guards = []
for i, guard in enumerate(guards):
bad = self.check_guard(guard)
if bad:
self.ui.warn('%s:%d: %s\n' %
(self.join(self.guards_path), i + 1, bad))
else:
self.active_guards.append(guard)
return self.active_guards
def set_guards(self, idx, guards):
for g in guards:
if len(g) < 2:
raise util.Abort(_('guard %r too short') % g)
if g[0] not in '-+':
raise util.Abort(_('guard %r starts with invalid char') % g)
bad = self.check_guard(g[1:])
if bad:
raise util.Abort(bad)
drop = self.guard_re.sub('', self.full_series[idx])
self.full_series[idx] = drop + ''.join([' #' + g for g in guards])
self.parse_series()
self.series_dirty = True
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def pushable(self, idx):
if isinstance(idx, str):
idx = self.series.index(idx)
patchguards = self.series_guards[idx]
if not patchguards:
return True, None
guards = self.active()
exactneg = [g for g in patchguards if g[0] == '-' and g[1:] in guards]
if exactneg:
return False, exactneg[0]
pos = [g for g in patchguards if g[0] == '+']
Vadim Gelfer
mq: apply patch is any posative guard matches...
r2850 exactpos = [g for g in pos if g[1:] in guards]
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if pos:
Vadim Gelfer
mq: apply patch is any posative guard matches...
r2850 if exactpos:
return True, exactpos[0]
return False, pos
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 return True, ''
def explain_pushable(self, idx, all_patches=False):
write = all_patches and self.ui.write or self.ui.warn
if all_patches or self.ui.verbose:
if isinstance(idx, str):
idx = self.series.index(idx)
pushable, why = self.pushable(idx)
if all_patches and pushable:
if why is None:
write(_('allowing %s - no guards in effect\n') %
self.series[idx])
else:
if not why:
write(_('allowing %s - no matching negative guards\n') %
self.series[idx])
else:
write(_('allowing %s - guarded by %r\n') %
(self.series[idx], why))
if not pushable:
Vadim Gelfer
mq: make guards more strict, add tests
r2829 if why:
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 write(_('skipping %s - guarded by %r\n') %
Brendan Cully
mq: fix explain_pushable for negative guards
r3870 (self.series[idx], why))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 else:
write(_('skipping %s - no matching guards\n') %
self.series[idx])
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808 def save_dirty(self):
Vadim Gelfer
mq: simplify save_dirty
r2772 def write_list(items, path):
fp = self.opener(path, 'w')
for i in items:
Matt Mackall
transform a bunch of print statements to appropriate ui calls
r5878 fp.write("%s\n" % i)
Vadim Gelfer
mq: simplify save_dirty
r2772 fp.close()
Matt Mackall
many, many trivial check-code fixups
r10282 if self.applied_dirty:
write_list(map(str, self.applied), self.status_path)
if self.series_dirty:
write_list(self.full_series, self.series_path)
if self.guards_dirty:
write_list(self.active_guards, self.guards_path)
Nicolas Dumazet
mq: qrepo.add(mq.added) inside save_dirty inside of doing it manually...
r11546 if self.added:
qrepo = self.qrepo()
if qrepo:
Dan Villiom Podlaski Christiansen
mq: silence spurious output....
r12658 qrepo[None].add(f for f in self.added if f not in qrepo[None])
Nicolas Dumazet
mq: qrepo.add(mq.added) inside save_dirty inside of doing it manually...
r11546 self.added = []
mason@suse.com
Add mq extension
r1808
Brendan Cully
Remove undo log after mq operations that rollback would break
r4207 def removeundo(self, repo):
undo = repo.sjoin('undo')
if not os.path.exists(undo):
return
try:
os.unlink(undo)
except OSError, inst:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_('error removing undo: %s\n') % str(inst))
Brendan Cully
Remove undo log after mq operations that rollback would break
r4207
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 def printdiff(self, repo, diffopts, node1, node2=None, files=None,
Brendan Cully
Fix test-mq-qdiff; add -I and -X options to qdiff
r2937 fp=None, changes=None, opts={}):
Brodie Rao
diff: add --stat for diffstat output...
r9640 stat = opts.get('stat')
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 m = scmutil.match(repo, files, opts)
Yuya Nishihara
commands: refactor diff --stat and qdiff --stat...
r11050 cmdutil.diffordiffstat(self.ui, repo, diffopts, node1, node2, m,
changes, stat, fp)
Vadim Gelfer
refactor text diff/patch code....
r2874
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 def mergeone(self, repo, mergeq, head, patch, rev, diffopts):
mason@suse.com
Add mq extension
r1808 # first try just applying the patch
Matt Mackall
many, many trivial check-code fixups
r10282 (err, n) = self.apply(repo, [patch], update_status=False,
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 strict=True, merge=rev)
mason@suse.com
Add mq extension
r1808
if err == 0:
return (err, n)
if n is None:
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_("apply failed for patch %s") % patch)
mason@suse.com
Add mq extension
r1808
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("patch didn't work out, merging %s\n") % patch)
mason@suse.com
Add mq extension
r1808
# apply failed, strip away that rev and merge.
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 hg.clean(repo, head)
Nicolas Dumazet
strip: support multiple revisions
r11789 self.strip(repo, [n], update=False, backup='strip')
mason@suse.com
Add mq extension
r1808
Matt Mackall
use repo[changeid] to get a changectx
r6747 ctx = repo[rev]
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 ret = hg.merge(repo, rev)
mason@suse.com
Add mq extension
r1808 if ret:
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_("update returned %d") % ret)
Matt Mackall
commit: drop the now-unused files parameter
r8706 n = repo.commit(ctx.description(), ctx.user(), force=True)
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if n is None:
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_("repo commit failed"))
mason@suse.com
Add mq extension
r1808 try:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(mergeq.join(patch), self.plainmode)
mason@suse.com
Add mq extension
r1808 except:
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_("unable to read %s") % patch)
mason@suse.com
Add mq extension
r1808
Patrick Mezard
mq: preserve --git flag when merging patches...
r10185 diffopts = self.patchopts(diffopts, patch)
Thomas Arendsen Hein
Fix mq's usage of opener, which don't allow absolute paths now.
r1852 patchf = self.opener(patch, "w")
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 comments = str(ph)
mason@suse.com
Add mq extension
r1808 if comments:
patchf.write(comments)
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 self.printdiff(repo, diffopts, head, n, fp=patchf)
mason@suse.com
Add mq extension
r1808 patchf.close()
Brendan Cully
Remove undo log after mq operations that rollback would break
r4207 self.removeundo(repo)
mason@suse.com
Add mq extension
r1808 return (0, n)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808 def qparents(self, repo, rev=None):
if rev is None:
(p1, p2) = repo.dirstate.parents()
Matt Mackall
mq: remove import of revlog
r7639 if p2 == nullid:
mason@suse.com
Add mq extension
r1808 return p1
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
mason@suse.com
Add mq extension
r1808 return None
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 return self.applied[-1].node
p1, p2 = repo.changelog.parents(rev)
Benoit Boissinot
mq: simplify qparents calculation
r10680 if p2 != nullid and p2 in [x.node for x in self.applied]:
return p2
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 return p1
mason@suse.com
Add mq extension
r1808
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 def mergepatch(self, repo, mergeq, series, diffopts):
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
mason@suse.com
Add mq extension
r1808 # each of the patches merged in will have two parents. This
# can confuse the qrefresh, qdiff, and strip code because it
# needs to know which parent is actually in the patch queue.
# so, we insert a merge marker with only one parent. This way
# the first patch in the queue is never a merge patch
#
pname = ".hg.patches.merge.marker"
Matt Mackall
commit: drop the now-unused files parameter
r8706 n = repo.commit('[mq]: merge marker', force=True)
Brendan Cully
Remove undo log after mq operations that rollback would break
r4207 self.removeundo(repo)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(n, pname))
mason@suse.com
Add mq extension
r1808 self.applied_dirty = 1
head = self.qparents(repo)
for patch in series:
Chris Mason
mq: patch naming shortcuts...
r2696 patch = mergeq.lookup(patch, strict=True)
mason@suse.com
Add mq extension
r1808 if not patch:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("patch %s does not exist\n") % patch)
mason@suse.com
Add mq extension
r1808 return (1, None)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 pushable, reason = self.pushable(patch)
if not pushable:
self.explain_pushable(patch, all_patches=True)
continue
mason@suse.com
Add mq extension
r1808 info = mergeq.isapplied(patch)
if not info:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("patch %s is not applied\n") % patch)
mason@suse.com
Add mq extension
r1808 return (1, None)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 rev = info[1]
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 err, head = self.mergeone(repo, mergeq, head, patch, rev, diffopts)
mason@suse.com
Add mq extension
r1808 if head:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(head, patch))
mason@suse.com
Add mq extension
r1808 self.applied_dirty = 1
if err:
return (err, head)
Brendan Cully
Make mergepatch save queue now that qpush isn't.
r4437 self.save_dirty()
mason@suse.com
Add mq extension
r1808 return (0, head)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 def patch(self, repo, patchfile):
'''Apply patchfile to the working directory.
timeless
Generally replace "file name" with "filename" in help and comments.
r8761 patchfile: name of patch file'''
Brendan Cully
patch: return list of modified files even when an exception is raised...
r3465 files = {}
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 try:
Patrick Mezard
patch: make patch()/internalpatch() always update the dirstate
r14260 fuzz = patchmod.patch(self.ui, repo, patchfile, strip=1,
Patrick Mezard
patch: remove patch.patch() cwd argument
r14382 files=files, eolmode=None)
Patrick Mezard
patch: make patch()/internalpatch() always update the dirstate
r14260 return (True, list(files), fuzz)
Brendan Cully
Unify mq and hg patch invocation....
r2919 except Exception, inst:
self.ui.note(str(inst) + '\n')
if not self.ui.verbose:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("patch failed, unable to continue (try -v)\n"))
Patrick Mezard
patch: make patch()/internalpatch() always update the dirstate
r14260 return (False, list(files), False)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 def apply(self, repo, series, list=False, update_status=True,
Benoit Boissinot
mq: all_files can be a set, remove dangerous default values
r10661 strict=False, patchdir=None, merge=None, all_files=None):
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 wlock = lock = tr = None
Bryan O'Sullivan
MQ: tidy up if a qpush is interrupted....
r4418 try:
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 wlock = repo.wlock()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 lock = repo.lock()
Steve Borho
localrepo: add desc parameter to transaction...
r10881 tr = repo.transaction("qpush")
Bryan O'Sullivan
MQ: tidy up if a qpush is interrupted....
r4418 try:
Matt Mackall
transactions: avoid late tear-down (issue641)...
r4970 ret = self._apply(repo, series, list, update_status,
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 strict, patchdir, merge, all_files=all_files)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 tr.close()
self.save_dirty()
return ret
except:
try:
tr.abort()
finally:
repo.invalidate()
repo.dirstate.invalidate()
raise
finally:
Ronny Pfannschmidt
make transactions work on non-refcounted python implementations
r11230 release(tr, lock, wlock)
Alexis S. L. Carvalho
mq: really remove undo after a qpush (and after a strip)...
r5527 self.removeundo(repo)
Bryan O'Sullivan
MQ: tidy up if a qpush is interrupted....
r4418
Matt Mackall
transactions: avoid late tear-down (issue641)...
r4970 def _apply(self, repo, series, list=False, update_status=True,
Benoit Boissinot
mq: all_files can be a set, remove dangerous default values
r10661 strict=False, patchdir=None, merge=None, all_files=None):
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875 '''returns (error, hash)
error = 1 for unable to read, 2 for patch failed, 3 for patch fuzz'''
mason@suse.com
Add mq extension
r1808 # TODO unify with commands.py
if not patchdir:
patchdir = self.path
err = 0
n = None
Brendan Cully
Teach mq about git patches
r2934 for patchname in series:
pushable, reason = self.pushable(patchname)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if not pushable:
Brendan Cully
Teach mq about git patches
r2934 self.explain_pushable(patchname, all_patches=True)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 continue
Martin Geisler
mq: use ui.status when pushing and popping patches
r9111 self.ui.status(_("applying %s\n") % patchname)
Brendan Cully
Teach mq about git patches
r2934 pf = os.path.join(patchdir, patchname)
mason@suse.com
Add mq extension
r1808
try:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(self.join(patchname), self.plainmode)
Idan Kamara
mq: loosen except clause when reading patch headers
r14239 except IOError:
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875 self.ui.warn(_("unable to read %s\n") % patchname)
mason@suse.com
Add mq extension
r1808 err = 1
break
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 message = ph.message
mason@suse.com
Add mq extension
r1808 if not message:
Martin Geisler
mq: mark strings that should not be translated
r12849 # The commit message should not be translated
David Soria Parra
mq: Do not translate import message that are appended to commits....
r10274 message = "imported patch %s\n" % patchname
mason@suse.com
Add mq extension
r1808 else:
if list:
Martin Geisler
mq: mark strings that should not be translated
r12849 # The commit message should not be translated
David Soria Parra
mq: Do not translate import message that are appended to commits....
r10274 message.append("\nimported patch %s" % patchname)
mason@suse.com
Add mq extension
r1808 message = '\n'.join(message)
Matt Mackall
mq: handle empty patches more gracefully (issue1501)
r7782 if ph.haspatch:
(patcherr, files, fuzz) = self.patch(repo, pf)
Benoit Boissinot
mq: all_files can be a set, remove dangerous default values
r10661 if all_files is not None:
all_files.update(files)
Matt Mackall
mq: handle empty patches more gracefully (issue1501)
r7782 patcherr = not patcherr
else:
self.ui.warn(_("patch %s is empty\n") % patchname)
patcherr, files, fuzz = 0, [], 0
mason@suse.com
Add mq extension
r1808
Brendan Cully
Teach mq about git patches
r2934 if merge and files:
Alexis S. L. Carvalho
mq: don't abort when merging a patch that removes files
r4332 # Mark as removed/merged and update dirstate parent info
removed = []
merged = []
for f in files:
Patrick Mezard
Use lexists() instead of exists() where appropriate
r12344 if os.path.lexists(repo.wjoin(f)):
Alexis S. L. Carvalho
mq: don't abort when merging a patch that removes files
r4332 merged.append(f)
else:
removed.append(f)
Matt Mackall
dirstate: break update into separate functions
r4904 for f in removed:
repo.dirstate.remove(f)
for f in merged:
repo.dirstate.merge(f)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 p1, p2 = repo.dirstate.parents()
repo.dirstate.setparents(p1, merge)
Matt Mackall
match: remove files arg from repo.status and friends
r6603
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 match = scmutil.matchfiles(repo, files or [])
Matt Mackall
commit: drop the now-unused files parameter
r8706 n = repo.commit(message, ph.user, ph.date, match=match, force=True)
mason@suse.com
Add mq extension
r1808
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if n is None:
Martin Geisler
mq: expand 'repo' -> 'repository' in error message
r12850 raise util.Abort(_("repository commit failed"))
mason@suse.com
Add mq extension
r1808
if update_status:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(n, patchname))
mason@suse.com
Add mq extension
r1808
if patcherr:
Matt Mackall
mq: handle empty patches more gracefully (issue1501)
r7782 self.ui.warn(_("patch failed, rejects left in working dir\n"))
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875 err = 2
mason@suse.com
Add mq extension
r1808 break
if fuzz and strict:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("fuzz found when applying patch, stopping\n"))
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875 err = 3
mason@suse.com
Add mq extension
r1808 break
return (err, n)
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 def _cleanup(self, patches, numrevs, keep=False):
if not keep:
r = self.qrepo()
if r:
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 r[None].remove(patches, True)
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 else:
for p in patches:
os.unlink(self.join(p))
if numrevs:
Pierre-Yves David
mq: prevent traceback when qfinish patches not in series....
r14010 qfinished = self.applied[:numrevs]
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 del self.applied[:numrevs]
self.applied_dirty = 1
Pierre-Yves David
mq: prevent traceback when qfinish patches not in series....
r14010 unknown = []
for (i, p) in sorted([(self.find_series(p), p) for p in patches],
reverse=True):
if i is not None:
del self.full_series[i]
else:
unknown.append(p)
if unknown:
if numrevs:
rev = dict((entry.name, entry.node) for entry in qfinished)
for p in unknown:
msg = _('revision %s refers to unknown patches: %s\n')
self.ui.warn(msg % (short(rev[p]), p))
else:
msg = _('unknown patches: %s\n')
raise util.Abort(''.join(msg % p for p in unknown))
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 self.parse_series()
self.series_dirty = 1
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 def _revpatches(self, repo, revs):
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 firstrev = repo[self.applied[0].node].rev()
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 patches = []
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 for i, rev in enumerate(revs):
Dirkjan Ochtman
mq: warn about finalizing patches without cset message
r8832
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 if rev < firstrev:
raise util.Abort(_('revision %d is not managed') % rev)
Dirkjan Ochtman
mq: warn about finalizing patches without cset message
r8832
ctx = repo[rev]
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 base = self.applied[i].node
Dirkjan Ochtman
mq: warn about finalizing patches without cset message
r8832 if ctx.node() != base:
msg = _('cannot delete revision %d above applied patches')
raise util.Abort(msg % rev)
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 patch = self.applied[i].name
Dirkjan Ochtman
mq: warn about finalizing patches without cset message
r8832 for fmt in ('[mq]: %s', 'imported patch %s'):
if ctx.description() == fmt % patch:
msg = _('patch %s finalized without changeset message\n')
repo.ui.status(msg % patch)
break
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 patches.append(patch)
return patches
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 def finish(self, repo, revs):
patches = self._revpatches(repo, sorted(revs))
self._cleanup(patches, len(patches))
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
Brendan Cully
mq: add qdelete --forget option...
r3088 def delete(self, repo, patches, opts):
Brendan Cully
mq: require patch argument or revision for qdelete
r4736 if not patches and not opts.get('rev'):
Brendan Cully
mq: more qdelete help text tweaks
r4737 raise util.Abort(_('qdelete requires at least one revision or '
'patch name'))
Brendan Cully
mq: require patch argument or revision for qdelete
r4736
Greg Ward
mq: make 'qdelete <patchidx>' work again....
r11365 realpatches = []
Brendan Cully
Allow qdel to delete multiple patches.
r2905 for patch in patches:
patch = self.lookup(patch, strict=True)
info = self.isapplied(patch)
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 if info:
Brendan Cully
Allow qdel to delete multiple patches.
r2905 raise util.Abort(_("cannot delete applied patch %s") % patch)
if patch not in self.series:
raise util.Abort(_("patch %s not in series file") % patch)
Dan Villiom Podlaski Christiansen
mq: handle deleting the same patch twice in one command (issue2427)
r12655 if patch not in realpatches:
realpatches.append(patch)
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 numrevs = 0
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 if opts.get('rev'):
if not self.applied:
raise util.Abort(_('no patches applied'))
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 revs = scmutil.revrange(repo, opts.get('rev'))
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 if len(revs) > 1 and revs[0] > revs[1]:
revs.reverse()
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 revpatches = self._revpatches(repo, revs)
Greg Ward
mq: make 'qdelete <patchidx>' work again....
r11365 realpatches += revpatches
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 numrevs = len(revpatches)
Brendan Cully
Allow qdel to delete multiple patches.
r2905
Greg Ward
mq: make 'qdelete <patchidx>' work again....
r11365 self._cleanup(realpatches, numrevs, opts.get('keep'))
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808 def check_toppatch(self, repo):
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.applied:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 top = self.applied[-1].node
Patrick Mezard
mq: qdiff with the same diff options than qrefresh (issue1350)...
r10191 patch = self.applied[-1].name
mason@suse.com
Add mq extension
r1808 pp = repo.dirstate.parents()
if top not in pp:
Matt Mackall
mq: clarify queue top message
r5432 raise util.Abort(_("working directory revision is not qtip"))
Patrick Mezard
mq: qdiff with the same diff options than qrefresh (issue1350)...
r10191 return top, patch
return None, None
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 def check_substate(self, repo):
'''return list of subrepos at a different revision than substate.
Abort if any subrepos have uncommitted changes.'''
inclsubs = []
wctx = repo[None]
for s in wctx.substate:
if wctx.sub(s).dirty(True):
raise util.Abort(
_("uncommitted changes in subrepository %s") % s)
elif wctx.sub(s).dirty():
inclsubs.append(s)
return inclsubs
Idan Kamara
mq: allow to qpop/push with a dirty working copy (issue2780)...
r14256 def localchangesfound(self, refresh=True):
if refresh:
raise util.Abort(_("local changes found, refresh first"))
else:
raise util.Abort(_("local changes found"))
Vadim Gelfer
remove localrepository.changes....
r2875 def check_localchanges(self, repo, force=False, refresh=True):
m, a, r, d = repo.status()[:4]
Augie Fackler
qnew: ignore force option...
r10372 if (m or a or r or d) and not force:
Idan Kamara
mq: allow to qpop/push with a dirty working copy (issue2780)...
r14256 self.localchangesfound(refresh)
Vadim Gelfer
remove localrepository.changes....
r2875 return m, a, r, d
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713
Idan Kamara
mq: add '.' and '..' to list of forbidden patch names...
r14051 _reserved = ('series', 'status', 'guards', '.', '..')
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981 def check_reserved_name(self, name):
Idan Kamara
mq: be more explicit on invalid patch name message
r14054 if name in self._reserved:
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981 raise util.Abort(_('"%s" cannot be used as the name of a patch')
% name)
Idan Kamara
mq: be more explicit on invalid patch name message
r14054 for prefix in ('.hg', '.mq'):
if name.startswith(prefix):
raise util.Abort(_('patch name cannot begin with "%s"')
% prefix)
for c in ('#', ':'):
if c in name:
raise util.Abort(_('"%s" cannot be used in the name of a patch')
% c)
Idan Kamara
mq: wrap patch file name checks in a function
r14422 def checkpatchname(self, name, force=False):
self.check_reserved_name(name)
if not force and os.path.exists(self.join(name)):
if os.path.isdir(self.join(name)):
raise util.Abort(_('"%s" already exists as a directory')
% name)
else:
raise util.Abort(_('patch "%s" already exists') % name)
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 def new(self, repo, patchfn, *pats, **opts):
Brendan Cully
mq: do not invoke editor until just before patch creation. Closes issue1346.
r7157 """options:
msg: a string or a no-argument function returning a string
"""
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 msg = opts.get('msg')
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673 user = opts.get('user')
Peter Arrenbrecht
mq: add --currentdate and --date options to qnew and qrefresh...
r5788 date = opts.get('date')
Thomas Arendsen Hein
Fix bad behaviour when specifying an invalid date (issue700)...
r6139 if date:
date = util.parsedate(date)
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 diffopts = self.diffopts({'git': opts.get('git')})
Idan Kamara
record: check patch name is valid before prompting in qrecord
r14424 if opts.get('checkname', True):
self.checkpatchname(patchfn)
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 inclsubs = self.check_substate(repo)
if inclsubs:
inclsubs.append('.hgsubstate')
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 if opts.get('include') or opts.get('exclude') or pats:
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 if inclsubs:
pats = list(pats or []) + inclsubs
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 match = scmutil.match(repo, pats, opts)
Brendan Cully
mq: abort qnew -f if any file in an explicit list cannot be read
r7161 # detect missing files in pats
def badfn(f, msg):
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 if f != '.hgsubstate': # .hgsubstate is auto-created
raise util.Abort('%s: %s' % (f, msg))
Brendan Cully
mq: abort qnew -f if any file in an explicit list cannot be read
r7161 match.bad = badfn
Matt Mackall
match: remove files arg from repo.status and friends
r6603 m, a, r, d = repo.status(match=match)[:4]
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 else:
Augie Fackler
qnew: ignore force option...
r10372 m, a, r, d = self.check_localchanges(repo, force=True)
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 match = scmutil.matchfiles(repo, m + a + r + inclsubs)
Augie Fackler
qnew: ignore force option...
r10372 if len(repo[None].parents()) > 1:
raise util.Abort(_('cannot manage merge changesets'))
Vadim Gelfer
remove localrepository.changes....
r2875 commitfiles = m + a + r
mason@suse.com
Add mq extension
r1808 self.check_toppatch(repo)
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 insert = self.full_series_end()
mason@suse.com
Add mq extension
r1808 wlock = repo.wlock()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Martin Geisler
qnew: give better feedback when doing 'hg qnew foo/' (issue2464)
r12878 try:
# if patch file write fails, abort early
p = self.opener(patchfn, "w")
except IOError, e:
raise util.Abort(_('cannot write patch "%s": %s')
% (patchfn, e.strerror))
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 try:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 if self.plainmode:
if user:
p.write("From: " + user + "\n")
if not date:
p.write("\n")
if date:
p.write("Date: %d %d\n\n" % date)
else:
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 p.write("# HG changeset patch\n")
Matt Mackall
fix up a bunch of check-code warnings
r10413 p.write("# Parent "
Matt Mackall
misc: replace .parents()[0] with p1()
r13878 + hex(repo[None].p1().node()) + "\n")
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 if user:
p.write("# User " + user + "\n")
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 if date:
p.write("# Date %s %s\n\n" % date)
Dirkjan Ochtman
some modernization cleanups, forward compatibility
r8366 if hasattr(msg, '__call__'):
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 msg = msg()
commitmsg = msg and msg or ("[mq]: %s" % patchfn)
Matt Mackall
commit: drop the now-unused files parameter
r8706 n = repo.commit(commitmsg, user, date, match=match, force=True)
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if n is None:
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 raise util.Abort(_("repo commit failed"))
try:
self.full_series[insert:insert] = [patchfn]
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(n, patchfn))
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 self.parse_series()
self.series_dirty = 1
self.applied_dirty = 1
if msg:
Bernhard Leiner
mq: make qnew patch format consistent with qrefresh (issue1457)
r7614 msg = msg + "\n\n"
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 p.write(msg)
if commitfiles:
parent = self.qparents(repo, n)
Idan Kamara
mq: don't hide the patch module
r14241 chunks = patchmod.diff(repo, node1=parent, node2=n,
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 match=match, opts=diffopts)
for chunk in chunks:
p.write(chunk)
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 p.close()
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 wlock.release()
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 wlock = None
r = self.qrepo()
Matt Mackall
many, many trivial check-code fixups
r10282 if r:
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 r[None].add([patchfn])
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 except:
repo.rollback()
raise
Benoit Boissinot
remove unused variables
r7280 except Exception:
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 patchpath = self.join(patchfn)
try:
os.unlink(patchpath)
except:
self.ui.warn(_('error unlinking %s\n') % patchpath)
raise
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.removeundo(repo)
finally:
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 release(wlock)
mason@suse.com
Add mq extension
r1808
Nicolas Dumazet
strip: support multiple revisions
r11789 def strip(self, repo, revs, update=True, backup="all", force=None):
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 wlock = lock = None
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
mason@suse.com
Add mq extension
r1808 wlock = repo.wlock()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 lock = repo.lock()
mason@suse.com
Add mq extension
r1808
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if update:
Dirkjan Ochtman
mq: add --force option to strip
r6472 self.check_localchanges(repo, force=force, refresh=False)
Nicolas Dumazet
strip: support multiple revisions
r11789 urev = self.qparents(repo, revs[0])
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 hg.clean(repo, urev)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 repo.dirstate.write()
mason@suse.com
Add mq extension
r1808
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.removeundo(repo)
Nicolas Dumazet
strip: support multiple revisions
r11789 for rev in revs:
repair.strip(self.ui, repo, rev, backup)
Alexis S. L. Carvalho
mq: really remove undo after a qpush (and after a strip)...
r5527 # strip may have unbundled a set of backed up revisions after
# the actual strip
self.removeundo(repo)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 release(lock, wlock)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808 def isapplied(self, patch):
"""returns (index, rev, patch)"""
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 for i, a in enumerate(self.applied):
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 if a.name == patch:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 return (i, a.node, a.name)
mason@suse.com
Add mq extension
r1808 return None
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223 # if the exact patch name does not exist, we try a few
Chris Mason
mq: patch naming shortcuts...
r2696 # variations. If strict is passed, we try only #1
#
# 1) a number to indicate an offset in the series file
# 2) a unique substring of the patch name was given
# 3) patchname[-+]num to indicate an offset in the series file
def lookup(self, patch, strict=False):
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 patch = patch and str(patch)
Chris Mason
mq: patch naming shortcuts...
r2696 def partial_name(s):
if s in self.series:
return s
Vadim Gelfer
mq: print matches if patch name not unique
r2765 matches = [x for x in self.series if s in x]
if len(matches) > 1:
self.ui.warn(_('patch name "%s" is ambiguous:\n') % s)
for m in matches:
self.ui.warn(' %s\n' % m)
return None
if matches:
return matches[0]
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.series and self.applied:
Chris Mason
mq: patch naming shortcuts...
r2696 if s == 'qtip':
Brendan Cully
mq: fix qheader without args when guards are applied after qtop
r3874 return self.series[self.series_end(True)-1]
Chris Mason
mq: patch naming shortcuts...
r2696 if s == 'qbase':
return self.series[0]
return None
Jason Orendorff
mq: don't warn about ambiguous patch name when using patch index (issue1439)
r7568
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if patch is None:
mason@suse.com
Add mq extension
r1808 return None
Jason Orendorff
mq: don't warn about ambiguous patch name when using patch index (issue1439)
r7568 if patch in self.series:
return patch
Chris Mason
mq: patch naming shortcuts...
r2696
Vadim Gelfer
mq: add join method
r2819 if not os.path.isfile(self.join(patch)):
mason@suse.com
Add mq extension
r1808 try:
sno = int(patch)
Matt Mackall
many, many trivial check-code fixups
r10282 except (ValueError, OverflowError):
Chris Mason
mq: patch naming shortcuts...
r2696 pass
else:
Jason Orendorff
mq: don't warn about ambiguous patch name when using patch index (issue1439)
r7568 if -len(self.series) <= sno < len(self.series):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 return self.series[sno]
Jason Orendorff
mq: don't warn about ambiguous patch name when using patch index (issue1439)
r7568
Chris Mason
mq: patch naming shortcuts...
r2696 if not strict:
Jason Orendorff
mq: don't warn about ambiguous patch name when using patch index (issue1439)
r7568 res = partial_name(patch)
Chris Mason
mq: patch naming shortcuts...
r2696 if res:
return res
Thomas Arendsen Hein
Fixed python2.3 incompatibility (rsplit) in qpush/qpop with index.
r3082 minus = patch.rfind('-')
if minus >= 0:
res = partial_name(patch[:minus])
Chris Mason
mq: patch naming shortcuts...
r2696 if res:
i = self.series.index(res)
try:
Matt Mackall
many, many trivial check-code fixups
r10282 off = int(patch[minus + 1:] or 1)
except (ValueError, OverflowError):
Chris Mason
mq: patch naming shortcuts...
r2696 pass
else:
if i - off >= 0:
return self.series[i - off]
Thomas Arendsen Hein
Fixed python2.3 incompatibility (rsplit) in qpush/qpop with index.
r3082 plus = patch.rfind('+')
if plus >= 0:
res = partial_name(patch[:plus])
Chris Mason
mq: patch naming shortcuts...
r2696 if res:
i = self.series.index(res)
try:
Matt Mackall
many, many trivial check-code fixups
r10282 off = int(patch[plus + 1:] or 1)
except (ValueError, OverflowError):
Chris Mason
mq: patch naming shortcuts...
r2696 pass
else:
if i + off < len(self.series):
return self.series[i + off]
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_("patch %s not in series") % patch)
mason@suse.com
Add mq extension
r1808
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 def push(self, repo, patch=None, force=False, list=False,
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 mergeq=None, all=False, move=False, exact=False):
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 diffopts = self.diffopts()
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 wlock = repo.wlock()
Adrian Buehlmann
mq: eliminate warning on qpush with empty series...
r8795 try:
Dirkjan Ochtman
mq: don't warn on qpush against a branch head
r10362 heads = []
for b, ls in repo.branchmap().iteritems():
heads += ls
if not heads:
heads = [nullid]
Matt Mackall
misc: replace .parents()[0] with p1()
r13878 if repo.dirstate.p1() not in heads and not exact:
Adrian Buehlmann
mq: eliminate warning on qpush with empty series...
r8795 self.ui.status(_("(working directory not at a head)\n"))
Matt Mackall
mq: warn when applying a patch to somewhere other than tip
r6340
Adrian Buehlmann
mq: eliminate warning on qpush with empty series...
r8795 if not self.series:
self.ui.warn(_('no patches in series\n'))
return 0
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 patch = self.lookup(patch)
# Suppose our series file is: A B C and the current 'top'
# patch is B. qpush C should be performed (moving forward)
# qpush B is a NOP (no change) qpush A is an error (can't
# go backwards with qpush)
if patch:
info = self.isapplied(patch)
Afuna
mq: catch attempt to qpush to an earlier patch (issue2587)...
r13369 if info and info[0] >= len(self.applied) - 1:
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 self.ui.warn(
_('qpush: %s is already at the top\n') % patch)
Gilles Moris
mq: explicit exit code when patch is already on top
r11439 return 0
Afuna
mq: catch attempt to qpush to an earlier patch (issue2587)...
r13369
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 pushable, reason = self.pushable(patch)
Afuna
mq: catch attempt to qpush to an earlier patch (issue2587)...
r13369 if pushable:
if self.series.index(patch) < self.series_end():
raise util.Abort(
_("cannot push to a previous patch: %s") % patch)
else:
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 if reason:
reason = _('guarded by %r') % reason
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 reason = _('no matching guards')
self.ui.warn(_("cannot push '%s' - %s\n") % (patch, reason))
return 1
elif all:
patch = self.series[-1]
if self.isapplied(patch):
self.ui.warn(_('all patches are currently applied\n'))
return 0
Ben Thomas
Modify qpush/qpop idempotent operations to return success...
r4100
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # Following the above example, starting at 'top' of B:
# qpush should be performed (pushes C), but a subsequent
# qpush without an argument is an error (nothing to
# apply). This allows a loop of "...while hg qpush..." to
# work as it detects an error when done
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 start = self.series_end()
if start == len(self.series):
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.ui.warn(_('patch series already fully applied\n'))
return 1
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 if exact:
if move:
raise util.Abort(_("cannot use --exact and --move together"))
if self.applied:
raise util.Abort(_("cannot push --exact with applied patches"))
root = self.series[start]
target = patchheader(self.join(root), self.plainmode).parent
if not target:
raise util.Abort(_("%s does not have a parent recorded" % root))
if not repo[target] == repo['.']:
hg.update(repo, target)
Mads Kiilerich
mq: qpush --move, reorder patch series and apply only the patch...
r11064 if move:
Gilles Moris
qpush --move: move the right patch even with comment lines...
r11715 if not patch:
Thomas Arendsen Hein
coding style: fix gratuitous whitespace after Python keywords
r13075 raise util.Abort(_("please specify the patch to move"))
Gilles Moris
qpush --move: move the right patch even with comment lines...
r11715 for i, rpn in enumerate(self.full_series[start:]):
# strip markers for patch guards
if self.guard_re.split(rpn, 1)[0] == patch:
break
index = start + i
assert index < len(self.full_series)
fullpatch = self.full_series[index]
del self.full_series[index]
Gilles Moris
mq: fix qpush --move for selected guarded patches...
r11438 self.full_series.insert(start, fullpatch)
Mads Kiilerich
mq: qpush --move, reorder patch series and apply only the patch...
r11064 self.parse_series()
self.series_dirty = 1
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 self.applied_dirty = 1
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if start > 0:
self.check_toppatch(repo)
if not patch:
patch = self.series[start]
end = start + 1
Bryan O'Sullivan
MQ: tidy up if a qpush is interrupted....
r4418 else:
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 end = self.series.index(patch, start) + 1
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 s = self.series[start:end]
Idan Kamara
mq: allow to qpop/push with a dirty working copy (issue2780)...
r14256
if not force:
mm, aa, rr, dd = repo.status()[:4]
wcfiles = set(mm + aa + rr + dd)
if wcfiles:
for patchname in s:
pf = os.path.join(self.path, patchname)
Patrick Mezard
patch: add lexists() to backends, use it in selectfile()...
r14351 patchfiles = patchmod.changedfiles(self.ui, repo, pf)
Matt Mackall
check-code: complain about set.isdisjoint
r14267 if wcfiles.intersection(patchfiles):
Idan Kamara
mq: allow to qpop/push with a dirty working copy (issue2780)...
r14256 self.localchangesfound(self.applied)
elif mergeq:
self.check_localchanges(refresh=self.applied)
Benoit Boissinot
mq: all_files can be a set, remove dangerous default values
r10661 all_files = set()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
if mergeq:
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 ret = self.mergepatch(repo, mergeq, s, diffopts)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 ret = self.apply(repo, s, list, all_files=all_files)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 except:
self.ui.warn(_('cleaning up working directory...'))
Matt Mackall
misc: replace .parents()[0] with p1()
r13878 node = repo.dirstate.p1()
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 hg.revert(repo, node, None)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # only remove unknown files that we know we touched or
# created while patching
Benoit Boissinot
mq: avoid a (potentially expensive) repo.status(unknown=True) call
r10662 for f in all_files:
if f not in repo.dirstate:
Benoit Boissinot
mq: do not try to delete non-existent files (regression from e8e56d8377ab)
r10693 try:
Adrian Buehlmann
rename util.unlink to unlinkpath
r13235 util.unlinkpath(repo.wjoin(f))
Benoit Boissinot
mq: do not try to delete non-existent files (regression from e8e56d8377ab)
r10693 except OSError, inst:
if inst.errno != errno.ENOENT:
raise
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.ui.warn(_('done\n'))
raise
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875
Benoit Allard
mq: fix traceback for qpush inexistant-patch with no patch applied
r9590 if not self.applied:
return ret[0]
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 top = self.applied[-1].name
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875 if ret[0] and ret[0] > 1:
msg = _("errors during apply, please fix and refresh %s\n")
self.ui.write(msg % top)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Martin Geisler
mq: lowercase output...
r7627 self.ui.write(_("now at: %s\n") % top)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 return ret[0]
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 wlock.release()
mason@suse.com
Add mq extension
r1808
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 def pop(self, repo, patch=None, force=False, update=True, all=False):
wlock = repo.wlock()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
if patch:
# index, rev, patch
info = self.isapplied(patch)
if not info:
patch = self.lookup(patch)
info = self.isapplied(patch)
if not info:
raise util.Abort(_("patch %s is not applied") % patch)
Ben Thomas
Modify qpush/qpop idempotent operations to return success...
r4100
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # Allow qpop -a to work repeatedly,
# but not qpop without an argument
self.ui.warn(_("no patches applied\n"))
return not all
mason@suse.com
Add mq extension
r1808
Dirkjan Ochtman
mq: refactor the pop code to be more readable and allow more changes
r7620 if all:
start = 0
elif patch:
start = info[0] + 1
else:
start = len(self.applied) - 1
if start >= len(self.applied):
self.ui.warn(_("qpop: %s is already at the top\n") % patch)
return
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if not update:
parents = repo.dirstate.parents()
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 rr = [x.node for x in self.applied]
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 for p in parents:
if p in rr:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("qpop: forcing dirstate update\n"))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 update = True
Dirkjan Ochtman
mq: allow qpop if popped revisions are not working dir parents
r7621 else:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 parents = [p.node() for p in repo[None].parents()]
Dirkjan Ochtman
mq: allow qpop if popped revisions are not working dir parents
r7621 needupdate = False
for entry in self.applied[start:]:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 if entry.node in parents:
Dirkjan Ochtman
mq: allow qpop if popped revisions are not working dir parents
r7621 needupdate = True
break
update = needupdate
mason@suse.com
Add mq extension
r1808
Dirkjan Ochtman
mq: refactor the pop code to be more readable and allow more changes
r7620 self.applied_dirty = 1
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 end = len(self.applied)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 rev = self.applied[start].node
Alexis S. L. Carvalho
mq: pop/refresh: avoid losing revisions not managed by mq...
r5980 if update:
Patrick Mezard
mq: qdiff with the same diff options than qrefresh (issue1350)...
r10191 top = self.check_toppatch(repo)[0]
Alexis S. L. Carvalho
mq: pop/refresh: avoid losing revisions not managed by mq...
r5980
Dirkjan Ochtman
mq: allow qpop if popped revisions are not working dir parents
r7621 try:
heads = repo.changelog.heads(rev)
Matt Mackall
mq: remove import of revlog
r7639 except error.LookupError:
Dirkjan Ochtman
mq: allow qpop if popped revisions are not working dir parents
r7621 node = short(rev)
raise util.Abort(_('trying to pop unknown node %s') % node)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 if heads != [self.applied[-1].node]:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 raise util.Abort(_("popping would remove a revision not "
"managed by this patch queue"))
Alexis S. L. Carvalho
mq: pop/refresh: avoid losing revisions not managed by mq...
r5980
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # we know there are no local changes, so we can make a simplified
# form of hg.update.
if update:
qp = self.qparents(repo, rev)
Benoit Boissinot
mq: simplify and use context API
r10663 ctx = repo[qp]
Matt Mackall
status: clean up all users for unknown files
r6760 m, a, r, d = repo.status(qp, top)[:4]
Idan Kamara
mq: allow to qpop/push with a dirty working copy (issue2780)...
r14256 parentfiles = set(m + a + r + d)
if not force and parentfiles:
mm, aa, rr, dd = repo.status()[:4]
wcfiles = set(mm + aa + rr + dd)
Matt Mackall
check-code: complain about set.isdisjoint
r14267 if wcfiles.intersection(parentfiles):
Idan Kamara
mq: allow to qpop/push with a dirty working copy (issue2780)...
r14256 self.localchangesfound()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if d:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 raise util.Abort(_("deletions found between repo revs"))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 for f in a:
try:
Adrian Buehlmann
rename util.unlink to unlinkpath
r13235 util.unlinkpath(repo.wjoin(f))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 except OSError, e:
if e.errno != errno.ENOENT:
raise
repo.dirstate.forget(f)
Nicolas Dumazet
mq: qpop: remove added files before re-adding removed files...
r10048 for f in m + r:
Benoit Boissinot
mq: simplify and use context API
r10663 fctx = ctx[f]
repo.wwrite(f, fctx.data(), fctx.flags())
Nicolas Dumazet
mq: qpop: remove added files before re-adding removed files...
r10048 repo.dirstate.normal(f)
Matt Mackall
mq: remove import of revlog
r7639 repo.dirstate.setparents(qp, nullid)
Mads Kiilerich
mq: qpop now tells which patches are popped...
r9110 for patch in reversed(self.applied[start:end]):
Martin Geisler
mq: use ui.status when pushing and popping patches
r9111 self.ui.status(_("popping %s\n") % patch.name)
Alexis S. L. Carvalho
qpop/qrefresh: update self.applied before calling strip...
r5987 del self.applied[start:end]
Nicolas Dumazet
strip: support multiple revisions
r11789 self.strip(repo, [rev], update=False, backup='strip')
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.applied:
Martin Geisler
mq: lowercase output...
r7627 self.ui.write(_("now at: %s\n") % self.applied[-1].name)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Martin Geisler
mq: lowercase output...
r7627 self.ui.write(_("patch queue now empty\n"))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 wlock.release()
mason@suse.com
Add mq extension
r1808
Brendan Cully
Fix test-mq-qdiff; add -I and -X options to qdiff
r2937 def diff(self, repo, pats, opts):
Patrick Mezard
mq: qdiff with the same diff options than qrefresh (issue1350)...
r10191 top, patch = self.check_toppatch(repo)
mason@suse.com
Add mq extension
r1808 if not top:
Martin Geisler
mq: lowercase output...
r7627 self.ui.write(_("no patches applied\n"))
mason@suse.com
Add mq extension
r1808 return
qp = self.qparents(repo, top)
Martin Geisler
diff: change --inverse to --reverse...
r9857 if opts.get('reverse'):
Yannick Gingras
diff: add --inverse option...
r9725 node1, node2 = None, qp
else:
node1, node2 = qp, None
Patrick Mezard
mq: qdiff with the same diff options than qrefresh (issue1350)...
r10191 diffopts = self.diffopts(opts, patch)
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 self.printdiff(repo, diffopts, node1, node2, files=pats, opts=opts)
mason@suse.com
Add mq extension
r1808
Brendan Cully
allow qrefresh to take a list of files; closes #96.
r2938 def refresh(self, repo, pats=None, **opts):
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
Martin Geisler
mq: lowercase output...
r7627 self.ui.write(_("no patches applied\n"))
Bryan O'Sullivan
qrefresh: exit with status 1 if no patches applied.
r3004 return 1
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 msg = opts.get('msg', '').rstrip()
newuser = opts.get('user')
Thomas Arendsen Hein
Fix bad behaviour when specifying an invalid date (issue700)...
r6139 newdate = opts.get('date')
if newdate:
newdate = '%d %d' % util.parsedate(newdate)
mason@suse.com
Add mq extension
r1808 wlock = repo.wlock()
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
self.check_toppatch(repo)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 (top, patchfn) = (self.applied[-1].node, self.applied[-1].name)
Alexis S. L. Carvalho
mq: pop/refresh: avoid losing revisions not managed by mq...
r5980 if repo.changelog.heads(top) != [top]:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 raise util.Abort(_("cannot refresh a revision with children"))
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 inclsubs = self.check_substate(repo)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 cparents = repo.changelog.parents(top)
patchparent = self.qparents(repo, top)
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(self.join(patchfn), self.plainmode)
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 diffopts = self.diffopts({'git': opts.get('git')}, patchfn)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 if msg:
ph.setmessage(msg)
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673 if newuser:
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 ph.setuser(newuser)
Peter Arrenbrecht
mq: add --currentdate and --date options to qnew and qrefresh...
r5788 if newdate:
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 ph.setdate(newdate)
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph.setparent(hex(patchparent))
Brendan Cully
mq: truncate patch just before rewriting header
r5180
Brendan Cully
mq: use atomictempfiles during patch refresh
r7400 # only commit new patch when write is complete
patchf = self.opener(patchfn, 'w', atomictemp=True)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 comments = str(ph)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if comments:
patchf.write(comments)
mason@suse.com
Add mq extension
r1808
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # update the dirstate in place, strip off the qtip commit
# and then commit.
#
# this should really read:
Martin Geisler
mq: fix comment to reflect change in efbee27415ab
r13005 # mm, dd, aa = repo.status(top, patchparent)[:3]
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # but we do it backwards to take advantage of manifest/chlog
# caching against the next repo.status call
Kevin Bullock
mq: clean up unused variable in qrefresh...
r13004 mm, aa, dd = repo.status(patchparent, top)[:3]
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 changes = repo.changelog.read(top)
man = repo.manifest.read(changes[0])
aaa = aa[:]
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 matchfn = scmutil.match(repo, pats, opts)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # in short mode, we only diff the files included in the
# patch already plus specified files
if opts.get('short'):
# if amending a patch, we start with existing
# files plus specified files - unfiltered
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 match = scmutil.matchfiles(repo, mm + aa + dd + matchfn.files())
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # filter with inc/exl options
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 matchfn = scmutil.match(repo, opts=opts)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 else:
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 match = scmutil.matchall(repo)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 m, a, r, d = repo.status(match=match)[:4]
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 mm = set(mm)
aa = set(aa)
dd = set(dd)
mason@suse.com
Add mq extension
r1808
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # we might end up with files that were added between
# qtip and the dirstate parent, but then changed in the
# local dirstate. in this case, we want them to only
# show up in the added section
for x in m:
if x not in aa:
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 mm.add(x)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # we might end up with files added by the local dirstate that
# were deleted by the patch. In this case, they should only
# show up in the changed section.
for x in a:
if x in dd:
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 dd.remove(x)
mm.add(x)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 else:
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 aa.add(x)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # make sure any files deleted in the local dirstate
# are not in the add or change column of the patch
forget = []
for x in d + r:
if x in aa:
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 aa.remove(x)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 forget.append(x)
continue
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 else:
mm.discard(x)
dd.add(x)
m = list(mm)
r = list(dd)
a = list(aa)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 c = [filter(matchfn, l) for l in (m, a, r)]
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 match = scmutil.matchfiles(repo, set(c[0] + c[1] + c[2] + inclsubs))
Idan Kamara
mq: don't hide the patch module
r14241 chunks = patchmod.diff(repo, patchparent, match=match,
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 changes=c, opts=diffopts)
for chunk in chunks:
patchf.write(chunk)
mason@suse.com
Add mq extension
r1808
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 try:
Patrick Mezard
Merge with crew-stable
r10368 if diffopts.git or diffopts.upgrade:
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 copies = {}
for dst in a:
src = repo.dirstate.copied(dst)
# during qfold, the source file for copies may
# be removed. Treat this as a simple add.
if src is not None and src in repo.dirstate:
copies.setdefault(src, []).append(dst)
repo.dirstate.add(dst)
# remember the copies between patchparent and qtip
for dst in aaa:
f = repo.file(dst)
src = f.renamed(man[dst])
if src:
Patrick Mezard
Merge with crew-stable
r10368 copies.setdefault(src[0], []).extend(
copies.get(dst, []))
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 if dst in a:
copies[src[0]].append(dst)
# we can't copy a file created by the patch itself
if dst in copies:
del copies[dst]
for src, dsts in copies.iteritems():
for dst in dsts:
repo.dirstate.copy(src, dst)
else:
for dst in a:
repo.dirstate.add(dst)
# Drop useless copy information
for f in list(repo.dirstate.copies()):
repo.dirstate.copy(None, f)
for f in r:
repo.dirstate.remove(f)
# if the patch excludes a modified file, mark that
# file with mtime=0 so status can see it.
mm = []
for i in xrange(len(m)-1, -1, -1):
if not matchfn(m[i]):
mm.append(m[i])
del m[i]
for f in m:
repo.dirstate.normal(f)
for f in mm:
repo.dirstate.normallookup(f)
for f in forget:
repo.dirstate.forget(f)
mason@suse.com
Add mq extension
r1808
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 if not msg:
if not ph.message:
message = "[mq]: %s\n" % patchfn
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 message = "\n".join(ph.message)
else:
message = msg
"Mathieu Clabaut "
MQ: uniformise message and logfile option....
r2694
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 user = ph.user or changes[1]
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # assumes strip can roll itself back if interrupted
repo.dirstate.setparents(*cparents)
self.applied.pop()
self.applied_dirty = 1
Nicolas Dumazet
strip: support multiple revisions
r11789 self.strip(repo, [top], update=False,
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 backup='strip')
except:
repo.dirstate.invalidate()
raise
try:
# might be nice to attempt to roll back strip after this
n = repo.commit(message, user, ph.date, match=match,
force=True)
Martin Geisler
mq: do not let qrefresh write bad patch
r13632 # only write patch after a successful commit
patchf.rename()
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(n, patchfn))
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 except:
ctx = repo[cparents[0]]
repo.dirstate.rebuild(ctx.node(), ctx.manifest())
self.save_dirty()
self.ui.warn(_('refresh interrupted while patch was popped! '
'(revert --all, qpush to recover)\n'))
raise
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 wlock.release()
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 self.removeundo(repo)
mason@suse.com
Add mq extension
r1808
def init(self, repo, create=False):
Alexis S. L. Carvalho
mq: qinit -c creates a repo even after a regular qinit
r4071 if not create and os.path.isdir(self.path):
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_("patch queue directory already exists"))
Alexis S. L. Carvalho
mq: qinit -c creates a repo even after a regular qinit
r4071 try:
os.mkdir(self.path)
except OSError, inst:
if inst.errno != errno.EEXIST or not create:
raise
mason@suse.com
Add mq extension
r1808 if create:
return self.qrepo(create=True)
def unapplied(self, repo, patch=None):
if patch and patch not in self.series:
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_("patch %s is not in series file") % patch)
mason@suse.com
Add mq extension
r1808 if not patch:
start = self.series_end()
else:
start = self.series.index(patch) + 1
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 unapplied = []
for i in xrange(start, len(self.series)):
pushable, reason = self.pushable(i)
if pushable:
unapplied.append((i, self.series[i]))
self.explain_pushable(i)
return unapplied
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 def qseries(self, repo, missing=None, start=0, length=None, status=None,
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 summary=False):
Brodie Rao
qseries: make use of output labeling
r10824 def displayname(pfx, patchname, state):
Dan Villiom Podlaski Christiansen
mq: only highlight/label patch name for qseries....
r10932 if pfx:
self.ui.write(pfx)
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 if summary:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(self.join(patchname), self.plainmode)
Dan Villiom Podlaski Christiansen
qseries: don't truncate the patch name (issue1912)...
r9874 msg = ph.message and ph.message[0] or ''
Dan Villiom Podlaski Christiansen
mq: use ui.formatted() instead of ui.plain().
r11327 if self.ui.formatted():
Augie Fackler
termwidth: move to ui.ui from util
r12689 width = self.ui.termwidth() - len(pfx) - len(patchname) - 2
Dan Villiom Podlaski Christiansen
qseries: don't truncate the patch name (issue1912)...
r9874 if width > 0:
msg = util.ellipsis(msg, width)
else:
msg = ''
Dan Villiom Podlaski Christiansen
mq: only highlight/label patch name for qseries....
r10932 self.ui.write(patchname, label='qseries.' + state)
self.ui.write(': ')
self.ui.write(msg, label='qseries.message.' + state)
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 else:
Dan Villiom Podlaski Christiansen
mq: only highlight/label patch name for qseries....
r10932 self.ui.write(patchname, label='qseries.' + state)
self.ui.write('\n')
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183
Martin Geisler
replace set-like dictionaries with real sets...
r8152 applied = set([p.name for p in self.applied])
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 if length is None:
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 length = len(self.series) - start
mason@suse.com
Add mq extension
r1808 if not missing:
Dan Villiom Podlaski Christiansen
mq: align columns in verbose qseries output.
r9016 if self.ui.verbose:
Matt Mackall
many, many trivial check-code fixups
r10282 idxwidth = len(str(start + length - 1))
for i in xrange(start, start + length):
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 patch = self.series[i]
if patch in applied:
Brodie Rao
qseries: make use of output labeling
r10824 char, state = 'A', 'applied'
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 elif self.pushable(i)[0]:
Brodie Rao
qseries: make use of output labeling
r10824 char, state = 'U', 'unapplied'
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 else:
Brodie Rao
qseries: make use of output labeling
r10824 char, state = 'G', 'guarded'
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 pfx = ''
mason@suse.com
Add mq extension
r1808 if self.ui.verbose:
Brodie Rao
qseries: make use of output labeling
r10824 pfx = '%*d %s ' % (idxwidth, i, char)
elif status and status != char:
Thomas Arendsen Hein
Fix issue443: inconsistent output of "hg qunapplied -v"...
r4238 continue
Brodie Rao
qseries: make use of output labeling
r10824 displayname(pfx, patch, state)
mason@suse.com
Add mq extension
r1808 else:
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 msng_list = []
mason@suse.com
Add mq extension
r1808 for root, dirs, files in os.walk(self.path):
d = root[len(self.path) + 1:]
for f in files:
fl = os.path.join(d, f)
Thomas Arendsen Hein
Fix mq's usage of opener, which don't allow absolute paths now.
r1852 if (fl not in self.series and
Thomas Arendsen Hein
hg qseries -m: guards file was not ignored
r4241 fl not in (self.status_path, self.series_path,
self.guards_path)
Thomas Arendsen Hein
Fix mq's usage of opener, which don't allow absolute paths now.
r1852 and not fl.startswith('.')):
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 msng_list.append(fl)
Matt Mackall
replace util.sort with sorted built-in...
r8209 for x in sorted(msng_list):
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 pfx = self.ui.verbose and ('D ') or ''
Brodie Rao
qseries: make use of output labeling
r10824 displayname(pfx, x, 'missing')
mason@suse.com
Add mq extension
r1808
def issaveline(self, l):
Brendan Cully
Update qsave to use StatusEntry; don't throw exception on bad status lines.
r2816 if l.name == '.hg.patches.save.line':
mason@suse.com
Add mq extension
r1808 return True
def qrepo(self, create=False):
Mads Kiilerich
mq: don't inherit default and default-push paths with --mq (issue2333)...
r11965 ui = self.ui.copy()
ui.setconfig('paths', 'default', '', overlay=False)
ui.setconfig('paths', 'default-push', '', overlay=False)
Vadim Gelfer
mq: add join method
r2819 if create or os.path.isdir(self.join(".hg")):
Mads Kiilerich
mq: don't inherit default and default-push paths with --mq (issue2333)...
r11965 return hg.repository(ui, path=self.path, create=create)
mason@suse.com
Add mq extension
r1808
def restore(self, repo, rev, delete=None, qupdate=None):
Benoit Boissinot
mq: use context API
r10681 desc = repo[rev].description().strip()
mason@suse.com
Add mq extension
r1808 lines = desc.splitlines()
i = 0
datastart = None
series = []
applied = []
qpp = None
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 for i, line in enumerate(lines):
if line == 'Patch Data:':
mason@suse.com
Add mq extension
r1808 datastart = i + 1
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 elif line.startswith('Dirstate:'):
l = line.rstrip()
mason@suse.com
Add mq extension
r1808 l = l[10:].split(' ')
Matt Mackall
many, many trivial check-code fixups
r10282 qpp = [bin(x) for x in l]
Martin Geisler
code style: prefer 'is' and 'is not' tests with singletons
r13031 elif datastart is not None:
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 l = line.rstrip()
Benoit Boissinot
mq: qsave creates entries with the left part empty (':patchname')
r10683 n, name = l.split(':', 1)
if n:
applied.append(statusentry(bin(n), name))
Brendan Cully
mq: don't write applied patches into series twice in restore
r3185 else:
Benoit Boissinot
mq: simplify statusentry(), fix restore broken by ee48e5ef8753
r10682 series.append(l)
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if datastart is None:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("No saved patch data found\n"))
mason@suse.com
Add mq extension
r1808 return 1
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("restoring status: %s\n") % lines[0])
mason@suse.com
Add mq extension
r1808 self.full_series = series
self.applied = applied
Vadim Gelfer
mq: rename read_series as parse_series, make simpler and faster
r2767 self.parse_series()
mason@suse.com
Add mq extension
r1808 self.series_dirty = 1
self.applied_dirty = 1
heads = repo.changelog.heads()
if delete:
if rev not in heads:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("save entry has children, leaving it alone\n"))
mason@suse.com
Add mq extension
r1808 else:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("removing save entry %s\n") % short(rev))
mason@suse.com
Add mq extension
r1808 pp = repo.dirstate.parents()
if rev in pp:
update = True
else:
update = False
Nicolas Dumazet
strip: support multiple revisions
r11789 self.strip(repo, [rev], update=update, backup='strip')
mason@suse.com
Add mq extension
r1808 if qpp:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("saved queue repository parents: %s %s\n") %
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 (short(qpp[0]), short(qpp[1])))
mason@suse.com
Add mq extension
r1808 if qupdate:
timeless
qrestore: trying to improve the English
r12848 self.ui.status(_("updating queue directory\n"))
mason@suse.com
Add mq extension
r1808 r = self.qrepo()
if not r:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("Unable to load queue repository\n"))
mason@suse.com
Add mq extension
r1808 return 1
Matt Mackall
Introduce update helper functions: update, merge, clean, and revert
r2808 hg.clean(r, qpp[0])
mason@suse.com
Add mq extension
r1808
def save(self, repo, msg=None):
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("save: no patches applied, exiting\n"))
mason@suse.com
Add mq extension
r1808 return 1
if self.issaveline(self.applied[-1]):
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("status is already saved\n"))
mason@suse.com
Add mq extension
r1808 return 1
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808 if not msg:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 msg = _("hg patches saved state")
mason@suse.com
Add mq extension
r1808 else:
msg = "hg patches: " + msg.rstrip('\r\n')
r = self.qrepo()
if r:
pp = r.dirstate.parents()
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
mason@suse.com
Add mq extension
r1808 msg += "\n\nPatch Data:\n"
Benoit Boissinot
mq: simplify commit message generation
r10679 msg += ''.join('%s\n' % x for x in self.applied)
msg += ''.join(':%s\n' % x for x in self.full_series)
n = repo.commit(msg, force=True)
mason@suse.com
Add mq extension
r1808 if not n:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("repo commit failed\n"))
mason@suse.com
Add mq extension
r1808 return 1
Benoit Boissinot
mq: fix coding style (missing space)
r10684 self.applied.append(statusentry(n, '.hg.patches.save.line'))
mason@suse.com
Add mq extension
r1808 self.applied_dirty = 1
Matt Mackall
Merge with -stable, fix small test failure
r4209 self.removeundo(repo)
mason@suse.com
Add mq extension
r1808
Chris Mason
mq: fix qnew and qimport to deal with series file comments...
r2698 def full_series_end(self):
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.applied:
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 p = self.applied[-1].name
Chris Mason
mq: fix qnew and qimport to deal with series file comments...
r2698 end = self.find_series(p)
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if end is None:
Chris Mason
mq: fix qnew and qimport to deal with series file comments...
r2698 return len(self.full_series)
return end + 1
return 0
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def series_end(self, all_patches=False):
Patrick Mezard
mq: fix qtop failure when the series ends with guarded patches.
r4406 """If all_patches is False, return the index of the next pushable patch
in the series, or the series length. If all_patches is True, return the
index of the first patch past the last applied one.
"""
mason@suse.com
Add mq extension
r1808 end = 0
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def next(start):
Benoit Boissinot
mq: use xrange/enumerate instead of += 1
r10687 if all_patches or start >= len(self.series):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 return start
Benoit Boissinot
mq: use xrange/enumerate instead of += 1
r10687 for i in xrange(start, len(self.series)):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 p, reason = self.pushable(i)
if p:
break
self.explain_pushable(i)
return i
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.applied:
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 p = self.applied[-1].name
mason@suse.com
Add mq extension
r1808 try:
end = self.series.index(p)
except ValueError:
return 0
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 return next(end + 1)
return next(end)
mason@suse.com
Add mq extension
r1808
def appliedname(self, index):
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 pname = self.applied[index].name
mason@suse.com
Add mq extension
r1808 if not self.ui.verbose:
"Mathieu Clabaut "
mq: uniform verbose display of patche[s]....
r2677 p = pname
else:
Brendan Cully
mq: fix appliedname
r2941 p = str(self.series.index(pname)) + " " + pname
mason@suse.com
Add mq extension
r1808 return p
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 def qimport(self, repo, files, patchname=None, rev=None, existing=None,
Brendan Cully
mq: add --git option to qimport -r
r3691 force=None, git=False):
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 def checkseries(patchname):
if patchname in self.series:
raise util.Abort(_('patch %s is already in the series file')
% patchname)
if rev:
if files:
raise util.Abort(_('option "-r" not valid when importing '
'files'))
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 rev = scmutil.revrange(repo, rev)
Alejandro Santos
compat: use 'key' argument instead of 'cmp' when sorting a list
r9032 rev.sort(reverse=True)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 if (len(files) > 1 or len(rev) > 1) and patchname:
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_('option "-n" not valid when importing multiple '
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 'patches'))
if rev:
# If mq patches are applied, we can only import revisions
# that form a linear path to qbase.
# Otherwise, they should form a linear path to a head.
heads = repo.changelog.heads(repo.changelog.node(rev[-1]))
if len(heads) > 1:
raise util.Abort(_('revision %d is the root of more than one '
'branch') % rev[-1])
if self.applied:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 base = repo.changelog.node(rev[0])
if base in [n.node for n in self.applied]:
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 raise util.Abort(_('revision %d is already managed')
% rev[0])
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 if heads != [self.applied[-1].node]:
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 raise util.Abort(_('revision %d is not the parent of '
'the queue') % rev[0])
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 base = repo.changelog.rev(self.applied[0].node)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 lastparent = repo.changelog.parentrevs(base)[0]
else:
if heads != [repo.changelog.node(rev[0])]:
raise util.Abort(_('revision %d has unmanaged children')
% rev[0])
lastparent = None
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 diffopts = self.diffopts({'git': git})
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 for r in rev:
p1, p2 = repo.changelog.parentrevs(r)
n = repo.changelog.node(r)
Matt Mackall
mq: remove import of revlog
r7639 if p2 != nullrev:
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 raise util.Abort(_('cannot import merge revision %d') % r)
if lastparent and lastparent != r:
raise util.Abort(_('revision %d is not the parent of %d')
% (r, lastparent))
lastparent = p1
if not patchname:
Patrick Mezard
Enforce unixish style for all generated patch names....
r4037 patchname = normname('%d.diff' % r)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 checkseries(patchname)
Idan Kamara
mq: use checkpatchname...
r14423 self.checkpatchname(patchname, force)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 self.full_series.insert(0, patchname)
patchf = self.opener(patchname, "w")
Benoit Boissinot
patch/diff: move patch.export() to cmdutil.export()...
r10611 cmdutil.export(repo, [n], fp=patchf, opts=diffopts)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 patchf.close()
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 se = statusentry(n, patchname)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 self.applied.insert(0, se)
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 self.added.append(patchname)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 patchname = None
self.parse_series()
self.applied_dirty = 1
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 self.series_dirty = True
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141
Benoit Boissinot
mq: use xrange/enumerate instead of += 1
r10687 for i, filename in enumerate(files):
mason@suse.com
Add mq extension
r1808 if existing:
Brendan Cully
mq: support qimport -
r3547 if filename == '-':
raise util.Abort(_('-e is incompatible with import from -'))
Nicolas Dumazet
mq: support "qimport --existing --name renametothis thatexistingpatch"...
r11699 filename = normname(filename)
self.check_reserved_name(filename)
originpath = self.join(filename)
if not os.path.isfile(originpath):
raise util.Abort(_("patch %s does not exist") % filename)
if patchname:
Idan Kamara
mq: use checkpatchname...
r14423 self.checkpatchname(patchname, force)
Nicolas Dumazet
mq: support "qimport --existing --name renametothis thatexistingpatch"...
r11699
self.ui.write(_('renaming %s to %s\n')
% (filename, patchname))
Patrick Mezard
mq: fix qimport --name --existing --force on win32...
r11701 util.rename(originpath, self.join(patchname))
Nicolas Dumazet
mq: support "qimport --existing --name renametothis thatexistingpatch"...
r11699 else:
patchname = filename
mason@suse.com
Add mq extension
r1808 else:
Idan Kamara
mq: check patch name is valid before reading imported file
r14395 if filename == '-' and not patchname:
raise util.Abort(_('need --name to import a patch from -'))
elif not patchname:
Idan Kamara
mq: strip all leading slashes from url when importing...
r14396 patchname = normname(os.path.basename(filename.rstrip('/')))
Idan Kamara
mq: use checkpatchname...
r14423 self.checkpatchname(patchname, force)
mason@suse.com
Add mq extension
r1808 try:
Brendan Cully
mq: support qimport -
r3547 if filename == '-':
text = sys.stdin.read()
else:
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 fp = url.open(self.ui, filename)
text = fp.read()
fp.close()
Benoit Boissinot
Catch both IOError and OSError, fix regression introduced by 8046f0a070a6
r7421 except (OSError, IOError):
Nicolas Dumazet
mq: clarify the fact that qimport is trying to read a file...
r11709 raise util.Abort(_("unable to read file %s") % filename)
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 patchf = self.opener(patchname, "w")
mason@suse.com
Add mq extension
r1808 patchf.write(text)
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 patchf.close()
Brendan Cully
mq: make qimport -f work properly. Closes issue1255....
r7160 if not force:
checkseries(patchname)
if patchname not in self.series:
index = self.full_series_end() + i
self.full_series[index:index] = [patchname]
Vadim Gelfer
mq: rename read_series as parse_series, make simpler and faster
r2767 self.parse_series()
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 self.series_dirty = True
Martin Geisler
mq, i18n: mark strings for translation
r7597 self.ui.warn(_("adding %s to series file\n") % patchname)
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 self.added.append(patchname)
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 patchname = None
mason@suse.com
Add mq extension
r1808
André Sintzoff
mq: remove undo after a qimport
r13409 self.removeundo(repo)
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qdelete|qremove|qrm",
[('k', 'keep', None, _('keep patch file')),
('r', 'rev', [],
_('stop managing a revision (DEPRECATED)'), _('REV'))],
_('hg qdelete [-k] [PATCH]...'))
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 def delete(ui, repo, *patches, **opts):
Brendan Cully
Allow qdel to delete multiple patches.
r2905 """remove patches from queue
Brendan Cully
Add -f option to qdelete, to remove patch file.
r2752
Dirkjan Ochtman
mq: compact & rewrap documentation for qdelete command
r8929 The patches must not be applied, and at least one patch is required. With
-k/--keep, the patch files are preserved in the patch directory.
Cédric Duval
mq: no longer mention the deprecated qdelete's --revision option...
r8904
To stop managing a patch and move it into permanent history,
Martin Geisler
mq: use hg reST role some more
r11307 use the :hg:`qfinish` command."""
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 q.delete(repo, patches, opts)
mason@suse.com
Add mq extension
r1808 q.save_dirty()
return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qapplied",
[('1', 'last', None, _('show only the last patch'))
] + seriesopts,
_('hg qapplied [-1] [-s] [PATCH]'))
mason@suse.com
Add mq extension
r1808 def applied(ui, repo, patch=None, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the patches already applied
Returns 0 on success."""
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 if patch:
if patch not in q.series:
raise util.Abort(_("patch %s is not in series file") % patch)
end = q.series.index(patch) + 1
else:
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 end = q.series_end(True)
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
if opts.get('last') and not end:
ui.write(_("no patches applied\n"))
return 1
elif opts.get('last') and end == 1:
ui.write(_("only one patch applied\n"))
return 1
elif opts.get('last'):
start = end - 2
end = 1
else:
start = 0
Erik Zielke
mq: removed return from callers to patchheader.qseries...
r12539 q.qseries(repo, length=end, start=start, status='A',
summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qunapplied",
[('1', 'first', None, _('show only the first patch'))] + seriesopts,
_('hg qunapplied [-1] [-s] [PATCH]'))
mason@suse.com
Add mq extension
r1808 def unapplied(ui, repo, patch=None, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the patches not yet applied
Returns 0 on success."""
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
if patch:
if patch not in q.series:
raise util.Abort(_("patch %s is not in series file") % patch)
start = q.series.index(patch) + 1
else:
Thomas Arendsen Hein
Fix issue443: inconsistent output of "hg qunapplied -v"...
r4238 start = q.series_end(True)
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
if start == len(q.series) and opts.get('first'):
ui.write(_("all patches applied\n"))
return 1
length = opts.get('first') and 1 or None
Erik Zielke
mq: removed return from callers to patchheader.qseries...
r12539 q.qseries(repo, start=start, length=length, status='U',
summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qimport",
[('e', 'existing', None, _('import file in patch directory')),
('n', 'name', '',
_('name of patch file'), _('NAME')),
('f', 'force', None, _('overwrite existing files')),
('r', 'rev', [],
_('place existing revisions under mq control'), _('REV')),
('g', 'git', None, _('use git extended diff format')),
('P', 'push', None, _('qpush after importing'))],
_('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... FILE...'))
mason@suse.com
Add mq extension
r1808 def qimport(ui, repo, *filename, **opts):
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 """import a patch
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 The patch is inserted into the series after the last applied
patch. If no patches have been applied, qimport prepends the patch
Adrian Buehlmann
mq: qimport: explain insertion point in doc string
r6634 to the series.
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 The patch will have the same name as its source file unless you
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 give it a new one with -n/--name.
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 You can register an existing patch inside the patch directory with
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 the -e/--existing flag.
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 With -f/--force, an existing patch of the same name will be
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 overwritten.
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 An existing changeset may be placed under mq control with -r/--rev
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 (e.g. qimport --rev tip -n patch will place tip under mq control).
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 With -g/--git, patches imported with --rev will use the git diff
Matt Mackall
update help on git diffs
r7387 format. See the diffs help topic for information on why this is
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 important for preserving rename/copy information and permission
Patrick Mezard
mq: mention qfinish in qimport help
r13528 changes. Use :hg:`qfinish` to remove changesets from mq control.
David Frey
Update qimport help explaining how to read a patch from stdin (Issue371)
r8075
To import a patch from standard input, pass - as the patch file.
When importing from standard input, a patch name must be specified
using the --name flag.
Nicolas Dumazet
mq: document possible combination of -e and -n for qimport
r11700
Nicolas Dumazet
mq: correct qimport documentation
r11706 To import an existing patch while renaming it::
Nicolas Dumazet
mq: document possible combination of -e and -n for qimport
r11700
hg qimport -e existing-patch -n new-name
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 if import succeeded.
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 """
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 try:
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 q.qimport(repo, filename, patchname=opts.get('name'),
existing=opts.get('existing'), force=opts.get('force'),
rev=opts.get('rev'), git=opts.get('git'))
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 finally:
q.save_dirty()
Dirkjan Ochtman
mq: add -P/--push option to qimport
r8362
if opts.get('push') and not opts.get('rev'):
return q.push(repo, None)
mason@suse.com
Add mq extension
r1808 return 0
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 def qinit(ui, repo, create):
"""initialize a new queue repository
Brendan Cully
Add more verbose help text to mq commands.
r2754
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 This command also creates a series file for ordering patches, and
an mq-specific .hgignore file in the queue repository, to exclude
Erik Zielke
mq: added return 0 on success...
r12538 the status and guards files (these contain mostly transient state).
Returns 0 if initialization succeeded."""
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 r = q.init(repo, create)
mason@suse.com
Add mq extension
r1808 q.save_dirty()
if r:
Alexis S. L. Carvalho
mq: qinit -c creates a repo even after a regular qinit
r4071 if not os.path.exists(r.wjoin('.hgignore')):
fp = r.wopener('.hgignore', 'w')
Alexis S. L. Carvalho
qinit -c: add ^\.hg and ^\.mq to .hgignore
r6034 fp.write('^\\.hg\n')
fp.write('^\\.mq\n')
Alexis S. L. Carvalho
mq: qinit -c creates a repo even after a regular qinit
r4071 fp.write('syntax: glob\n')
fp.write('status\n')
fp.write('guards\n')
fp.close()
if not os.path.exists(r.wjoin('series')):
r.wopener('series', 'w').close()
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 r[None].add(['.hgignore', 'series'])
Alexis S. L. Carvalho
mq: qinit -c creates a repo even after a regular qinit
r4071 commands.add(ui, r)
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qinit",
[('c', 'create-repo', None, _('create queue repository'))],
_('hg qinit [-c]'))
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 def init(ui, repo, **opts):
"""init a new queue repository (DEPRECATED)
The queue repository is unversioned by default. If
-c/--create-repo is specified, qinit will create a separate nested
repository for patches (qinit -c may also be run later to convert
an unversioned patch repository into a versioned one). You can use
qcommit to commit changes to this queue repository.
This command is deprecated. Without -c, it's implied by other relevant
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 commands. With -c, use :hg:`init --mq` instead."""
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 return qinit(ui, repo, create=opts.get('create_repo'))
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qclone",
[('', 'pull', None, _('use pull protocol to copy metadata')),
('U', 'noupdate', None, _('do not update the new working directories')),
('', 'uncompressed', None,
_('use uncompressed transfer (fast over LAN)')),
('p', 'patches', '',
_('location of source patch repository'), _('REPO')),
] + commands.remoteopts,
_('hg qclone [OPTION]... SOURCE [DEST]'))
Vadim Gelfer
mq: add qclone command
r2720 def clone(ui, source, dest=None, **opts):
'''clone main and patch repository at same time
Martin Geisler
Change double spaces to single spaces in help texts.
r7983 If source is local, destination will have no patches applied. If
Vadim Gelfer
mq: add qclone command
r2720 source is remote, this command can not check if patches are
applied in source, so cannot guarantee that patches are not
Martin Geisler
Change double spaces to single spaces in help texts.
r7983 applied in destination. If you clone remote repository, be sure
Vadim Gelfer
mq: add qclone command
r2720 before that it has no patches applied.
Source patch repository is looked for in <src>/.hg/patches by
Martin Geisler
Change double spaces to single spaces in help texts.
r7983 default. Use -p <url> to change.
Brendan Cully
mq: improve qclone error handling when patch directory is not a repository.
r4862
timeless
Spell Mercurial as a proper noun
r8760 The patch directory must be a nested Mercurial repository, as
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 would be created by :hg:`init --mq`.
Erik Zielke
mq: added return 0 on success...
r12538
Return 0 on success.
Vadim Gelfer
mq: add qclone command
r2720 '''
Alexis S. L. Carvalho
avoid double slash problem mentioned in issue695
r5226 def patchdir(repo):
url = repo.url()
if url.endswith('/'):
url = url[:-1]
return url + '/.hg/patches'
Vadim Gelfer
mq: add qclone command
r2720 if dest is None:
dest = hg.defaultdest(source)
Matt Mackall
remoteui: move from cmdutil to hg
r11273 sr = hg.repository(hg.remoteui(ui, opts), ui.expandpath(source))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('patches'):
patchespath = ui.expandpath(opts.get('patches'))
John Mulligan
mq: allow qclone's -p option to use path alias...
r7729 else:
patchespath = patchdir(sr)
Brendan Cully
mq: improve qclone error handling when patch directory is not a repository.
r4862 try:
Peter Arrenbrecht
cleanup: drop variables for unused return values...
r7874 hg.repository(ui, patchespath)
Matt Mackall
error: move repo errors...
r7637 except error.RepoError:
Brendan Cully
mq: improve qclone error handling when patch directory is not a repository.
r4862 raise util.Abort(_('versioned patch repository not found'
Cédric Duval
mq: no longer refer to deprecated qinit -c command
r10690 ' (see init --mq)'))
Vadim Gelfer
mq: add qclone command
r2720 qbase, destrev = None, None
if sr.local():
Vadim Gelfer
mq: update to handle repomap not longer used
r2725 if sr.mq.applied:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 qbase = sr.mq.applied[0].node
Vadim Gelfer
mq: add qclone command
r2720 if not hg.islocal(dest):
Martin Geisler
replace set-like dictionaries with real sets...
r8152 heads = set(sr.heads())
destrev = list(heads.difference(sr.heads(qbase)))
Alexis S. L. Carvalho
fix qclone to a remote repo...
r4171 destrev.append(sr.changelog.parents(qbase)[0])
Peter Arrenbrecht
mq: make qclone ask remote source repo for qbase using lookup protocol
r6164 elif sr.capable('lookup'):
Alexis S. L. Carvalho
qclone: do not abort if remote hasn't enabled mq (issue1040)
r6380 try:
qbase = sr.lookup('qbase')
Matt Mackall
error: move repo errors...
r7637 except error.RepoError:
Alexis S. L. Carvalho
qclone: do not abort if remote hasn't enabled mq (issue1040)
r6380 pass
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('cloning main repository\n'))
Matt Mackall
mq: pass a URL to clone
r4476 sr, dr = hg.clone(ui, sr.url(), dest,
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 pull=opts.get('pull'),
Vadim Gelfer
mq: add qclone command
r2720 rev=destrev,
update=False,
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 stream=opts.get('uncompressed'))
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('cloning patch repository\n'))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 hg.clone(ui, opts.get('patches') or patchdir(sr), patchdir(dr),
pull=opts.get('pull'), update=not opts.get('noupdate'),
stream=opts.get('uncompressed'))
Vadim Gelfer
mq: add qclone command
r2720 if dr.local():
if qbase:
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('stripping applied patches from destination '
'repository\n'))
Nicolas Dumazet
strip: support multiple revisions
r11789 dr.mq.strip(dr, [qbase], update=False, backup=None)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if not opts.get('noupdate'):
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('updating destination repository\n'))
Matt Mackall
Move merge code to its own module...
r2775 hg.update(dr, dr.changelog.tip())
Vadim Gelfer
mq: add qclone command
r2720
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qcommit|qci",
commands.table["^commit|ci"][1],
_('hg qcommit [OPTION]... [FILE]...'))
mason@suse.com
Add mq extension
r1808 def commit(ui, repo, *pats, **opts):
Dirkjan Ochtman
mq: deprecate qinit and qcommit
r10361 """commit changes in the queue repository (DEPRECATED)
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 This command is deprecated; use :hg:`commit --mq` instead."""
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
mason@suse.com
Add mq extension
r1808 r = q.qrepo()
Matt Mackall
many, many trivial check-code fixups
r10282 if not r:
raise util.Abort('no queue repository')
mason@suse.com
Add mq extension
r1808 commands.commit(r.ui, r, *pats, **opts)
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qseries",
[('m', 'missing', None, _('print patches not in series')),
] + seriesopts,
_('hg qseries [-ms]'))
mason@suse.com
Add mq extension
r1808 def series(ui, repo, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the entire series file
Returns 0 on success."""
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 repo.mq.qseries(repo, missing=opts.get('missing'), summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qtop", [] + seriesopts, _('hg qtop [-s]'))
mason@suse.com
Add mq extension
r1808 def top(ui, repo, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the name of the current patch
Returns 0 on success."""
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
Patrick Mezard
mq: fix qtop failure when the series ends with guarded patches.
r4406 t = q.applied and q.series_end(True) or 0
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 if t:
Erik Zielke
mq: removed return from callers to patchheader.qseries...
r12539 q.qseries(repo, start=t - 1, length=1, status='A',
summary=opts.get('summary'))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 else:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_("no patches applied\n"))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 return 1
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qnext", [] + seriesopts, _('hg qnext [-s]'))
mason@suse.com
Add mq extension
r1808 def next(ui, repo, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the name of the next patch
Returns 0 on success."""
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
end = q.series_end()
if end == len(q.series):
Martin Geisler
mq: lowercase output...
r7627 ui.write(_("all patches applied\n"))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 return 1
Erik Zielke
mq: removed return from callers to patchheader.qseries...
r12539 q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qprev", [] + seriesopts, _('hg qprev [-s]'))
mason@suse.com
Add mq extension
r1808 def prev(ui, repo, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the name of the previous patch
Returns 0 on success."""
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
l = len(q.applied)
if l == 1:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_("only one patch applied\n"))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 return 1
if not l:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_("no patches applied\n"))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 return 1
Erik Zielke
mq: removed return from callers to patchheader.qseries...
r12539 q.qseries(repo, start=l - 2, length=1, status='A',
summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673 def setupheaderopts(ui, opts):
Martin Geisler
mq: do not call ui.username unless it is necessary...
r9733 if not opts.get('user') and opts.get('currentuser'):
opts['user'] = ui.username()
if not opts.get('date') and opts.get('currentdate'):
opts['date'] = "%d %d" % util.makedate()
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qnew",
[('e', 'edit', None, _('edit commit message')),
('f', 'force', None, _('import uncommitted changes (DEPRECATED)')),
('g', 'git', None, _('use git extended diff format')),
('U', 'currentuser', None, _('add "From: <current user>" to patch')),
('u', 'user', '',
_('add "From: <USER>" to patch'), _('USER')),
('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
('d', 'date', '',
_('add "Date: <DATE>" to patch'), _('DATE'))
] + commands.walkopts + commands.commitopts,
_('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...'))
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 def new(ui, repo, patch, *args, **opts):
Brendan Cully
Add more verbose help text to mq commands.
r2754 """create a new patch
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 qnew creates a new patch on top of the currently-applied patch (if
Wagner Bruna
mq: remove reference for deprecated -f option...
r10808 any). The patch will be initialized with any outstanding changes
in the working directory. You may also use -I/--include,
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 -X/--exclude, and/or a list of files after the patch name to add
only changes to matching files to the new patch, leaving the rest
as uncommitted modifications.
Brendan Cully
Add more verbose help text to mq commands.
r2754
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 -u/--user and -d/--date can be used to set the (given) user and
date, respectively. -U/--currentuser and -D/--currentdate set user
to current user and date to current date.
Dirkjan Ochtman
mq: reflow qnew help, add help for options
r7306
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 -e/--edit, -m/--message or -l/--logfile set the patch header as
well as the commit message. If none is specified, the header is
empty and the commit message is '[mq]: PATCH'.
Dirkjan Ochtman
help: commands supporting --git point to the gitdiffs topic (issue1352)
r7307
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 Use the -g/--git option to keep the patch in the git extended diff
Matt Mackall
update help on git diffs
r7387 format. Read the diffs help topic for more information on why this
is important for preserving permission changes and copy/rename
information.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on successful creation of a new patch.
Dirkjan Ochtman
mq: reflow qnew help, add help for options
r7306 """
Brendan Cully
mq: do not invoke editor until just before patch creation. Closes issue1346.
r7157 msg = cmdutil.logmessage(opts)
Matt Mackall
many, many trivial check-code fixups
r10282 def getmsg():
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 return ui.edit(msg, opts.get('user') or ui.username())
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Brendan Cully
mq: do not invoke editor until just before patch creation. Closes issue1346.
r7157 opts['msg'] = msg
if opts.get('edit'):
opts['msg'] = getmsg
else:
opts['msg'] = msg
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673 setupheaderopts(ui, opts)
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 q.new(repo, patch, *args, **opts)
mason@suse.com
Add mq extension
r1808 q.save_dirty()
return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qrefresh",
[('e', 'edit', None, _('edit commit message')),
('g', 'git', None, _('use git extended diff format')),
('s', 'short', None,
_('refresh only files already in the patch and specified files')),
('U', 'currentuser', None,
_('add/update author field in patch with current user')),
('u', 'user', '',
_('add/update author field in patch with given user'), _('USER')),
('D', 'currentdate', None,
_('add/update date field in patch with current date')),
('d', 'date', '',
_('add/update date field in patch with given date'), _('DATE'))
] + commands.walkopts + commands.commitopts,
_('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...'))
Brendan Cully
allow qrefresh to take a list of files; closes #96.
r2938 def refresh(ui, repo, *pats, **opts):
Brendan Cully
mq help text updates and speling fixes
r2940 """update the current patch
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 If any file patterns are provided, the refreshed patch will
contain only the modifications that match those patterns; the
remaining modifications will remain in the working directory.
Thomas Arendsen Hein
mq: Mention usage of hg add/remove/copy/rename in qrefresh help text.
r4048
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 If -s/--short is specified, files currently included in the patch
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 will be refreshed just like matched files and remain in the patch.
Mads Kiilerich
mq: Allow qrefresh --silent to take parameters...
r7113
Renato Cunha
mq: save qrefresh message for easy recovery in case it fails (issue2062)...
r11947 If -e/--edit is specified, Mercurial will start your configured editor for
you to enter a message. In case qrefresh fails, you will find a backup of
your message in ``.hg/last-message.txt``.
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 hg add/remove/copy/rename work as usual, though you might want to
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 use git-style patches (-g/--git or [diff] git=1) to track copies
and renames. See the diffs help topic for more information on the
git diff format.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Brendan Cully
mq help text updates and speling fixes
r2940 """
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 message = cmdutil.logmessage(opts)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('edit'):
Alexis S. L. Carvalho
mq: fix qrefresh -e with no patches applied
r5334 if not q.applied:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_("no patches applied\n"))
Alexis S. L. Carvalho
mq: fix qrefresh -e with no patches applied
r5334 return 1
Brendan Cully
Add option -e/--edit to qrefresh, to edit the existing header.
r2746 if message:
raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 patch = q.applied[-1].name
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(q.join(patch), q.plainmode)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 message = ui.edit('\n'.join(ph.message), ph.user or ui.username())
Renato Cunha
mq: save qrefresh message for easy recovery in case it fails (issue2062)...
r11947 # We don't want to lose the patch message if qrefresh fails (issue2062)
msgfile = repo.opener('last-message.txt', 'wb')
msgfile.write(message)
msgfile.close()
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673 setupheaderopts(ui, opts)
Bryan O'Sullivan
qrefresh: exit with status 1 if no patches applied.
r3004 ret = q.refresh(repo, pats, msg=message, **opts)
mason@suse.com
Add mq extension
r1808 q.save_dirty()
Bryan O'Sullivan
qrefresh: exit with status 1 if no patches applied.
r3004 return ret
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qdiff",
commands.diffopts + commands.diffopts2 + commands.walkopts,
_('hg qdiff [OPTION]... [FILE]...'))
Brendan Cully
Fix test-mq-qdiff; add -I and -X options to qdiff
r2937 def diff(ui, repo, *pats, **opts):
Dirkjan Ochtman
mq: expand help text for qdiff...
r6606 """diff of the current patch and subsequent modifications
Dirkjan Ochtman
mq: lose the trailing whitespace
r6621
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 Shows a diff which includes the current patch as well as any
changes which have been made in the working directory since the
last refresh (thus showing what the current patch would become
after a qrefresh).
Dirkjan Ochtman
mq: lose the trailing whitespace
r6621
Martin Geisler
Use hg role in help strings
r10973 Use :hg:`diff` if you only want to see the changes made since the
last qrefresh, or :hg:`export qtip` if you want to see changes
made by the current patch without including changes made since the
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 qrefresh.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Dirkjan Ochtman
mq: expand help text for qdiff...
r6606 """
Brendan Cully
Fix test-mq-qdiff; add -I and -X options to qdiff
r2937 repo.mq.diff(repo, pats, opts)
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command('qfold',
[('e', 'edit', None, _('edit patch header')),
('k', 'keep', None, _('keep folded patch files')),
] + commands.commitopts,
_('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...'))
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 def fold(ui, repo, *files, **opts):
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 """fold the named patches into the current patch
Brendan Cully
Add -m, -l, -e options to qfold.
r2753
Brendan Cully
Add -f option to qfold; improve qfold documentation.
r2771 Patches must not yet be applied. Each patch will be successively
applied to the current patch in the order given. If all the
patches apply successfully, the current patch will be refreshed
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 with the new cumulative patch, and the folded patches will be
deleted. With -k/--keep, the folded patch files will not be
removed afterwards.
Brendan Cully
Add -f option to qfold; improve qfold documentation.
r2771
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 The header for each folded patch will be concatenated with the
Erik Zielke
mq: switched to `` around * * *...
r12755 current patch header, separated by a line of ``* * *``.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success."""
Brendan Cully
Add -m, -l, -e options to qfold.
r2753
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 q = repo.mq
if not files:
raise util.Abort(_('qfold requires at least one patch name'))
Patrick Mezard
mq: qdiff with the same diff options than qrefresh (issue1350)...
r10191 if not q.check_toppatch(repo)[0]:
Martin Geisler
Lowercase error messages
r12067 raise util.Abort(_('no patches applied'))
David Frey
mq: abort qfold upon local changes (issue1662)
r8425 q.check_localchanges(repo)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 message = cmdutil.logmessage(opts)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('edit'):
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 if message:
raise util.Abort(_('option "-e" incompatible with "-m" or "-l"'))
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 parent = q.lookup('qtip')
patches = []
messages = []
for f in files:
Brendan Cully
Fix qfold after recent changes
r2936 p = q.lookup(f)
if p in patches or p == parent:
Patrick Mezard
mq: add newline after qfold warning
r12208 ui.warn(_('Skipping already folded patch %s\n') % p)
Brendan Cully
Fix qfold after recent changes
r2936 if q.isapplied(p):
raise util.Abort(_('qfold cannot fold already applied patch %s') % p)
patches.append(p)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Brendan Cully
Fix qfold after recent changes
r2936 for p in patches:
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 if not message:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(q.join(p), q.plainmode)
Brendan Cully
mq: filter out empty commit messages in qfold
r7454 if ph.message:
messages.append(ph.message)
Brendan Cully
Fix qfold after recent changes
r2936 pf = q.join(p)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 (patchsuccess, files, fuzz) = q.patch(repo, pf)
if not patchsuccess:
Martin Geisler
Lowercase error messages
r12067 raise util.Abort(_('error folding patch %s') % p)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 if not message:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(q.join(parent), q.plainmode)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 message, user = ph.message, ph.user
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 for msg in messages:
message.append('* * *')
message.extend(msg)
message = '\n'.join(message)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('edit'):
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 message = ui.edit(message, user or ui.username())
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Patrick Mezard
mq: preserve --git flag when folding patches...
r10186 diffopts = q.patchopts(q.diffopts(), *patches)
q.refresh(repo, msg=message, git=diffopts.git)
Brendan Cully
mq: update qfold to call delete correctly
r3243 q.delete(repo, patches, opts)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 q.save_dirty()
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qgoto",
[('f', 'force', None, _('overwrite any local changes'))],
_('hg qgoto [OPTION]... PATCH'))
Bryan O'Sullivan
mq: add qgoto command.
r4432 def goto(ui, repo, patch, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 '''push or pop patches until named patch is at top of stack
Returns 0 on success.'''
Bryan O'Sullivan
mq: add qgoto command.
r4432 q = repo.mq
patch = q.lookup(patch)
if q.isapplied(patch):
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 ret = q.pop(repo, patch, force=opts.get('force'))
Bryan O'Sullivan
mq: add qgoto command.
r4432 else:
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 ret = q.push(repo, patch, force=opts.get('force'))
Bryan O'Sullivan
mq: add qgoto command.
r4432 q.save_dirty()
return ret
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qguard",
[('l', 'list', None, _('list all patches and guards')),
('n', 'none', None, _('drop all guards'))],
_('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]'))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def guard(ui, repo, *args, **opts):
'''set or print guards for a patch
Brendan Cully
mq help text updates and speling fixes
r2940 Guards control whether a patch can be pushed. A patch with no
guards is always pushed. A patch with a positive guard ("+foo") is
Martin Geisler
mq: use hg reST role some more
r11307 pushed only if the :hg:`qselect` command has activated it. A patch with
a negative guard ("-foo") is never pushed if the :hg:`qselect` command
Brendan Cully
mq help text updates and speling fixes
r2940 has activated it.
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Brendan Cully
mq help text updates and speling fixes
r2940 With no arguments, print the currently active guards.
With arguments, set guards for the named patch.
Erik Zielke
Use note admonition
r12389
.. note::
Specifying negative guards now requires '--'.
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Martin Geisler
mq: fix literal blocks in docstrings
r9824 To set guards on another patch::
Martin Geisler
mq: more instructive use of "--" in qguard help (issue2040)
r10476 hg qguard other.patch -- +2.6.17 -stable
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 '''
def status(idx):
guards = q.series_guards[idx] or ['unguarded']
Dan Villiom Podlaski Christiansen
qguard: label patch names by status when listing guards
r11819 if q.series[idx] in applied:
state = 'applied'
elif q.pushable(idx)[0]:
state = 'unapplied'
else:
state = 'guarded'
label = 'qguard.patch qguard.%s qseries.%s' % (state, state)
ui.write('%s: ' % ui.label(q.series[idx], label))
Brodie Rao
qguard: make use of output labeling
r10822 for i, guard in enumerate(guards):
if guard.startswith('+'):
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(guard, label='qguard.positive')
Brodie Rao
qguard: make use of output labeling
r10822 elif guard.startswith('-'):
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(guard, label='qguard.negative')
Brodie Rao
qguard: make use of output labeling
r10822 else:
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(guard, label='qguard.unguarded')
Brodie Rao
qguard: make use of output labeling
r10822 if i != len(guards) - 1:
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(' ')
ui.write('\n')
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 q = repo.mq
Dan Villiom Podlaski Christiansen
qguard: label patch names by status when listing guards
r11819 applied = set(p.name for p in q.applied)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 patch = None
args = list(args)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('list'):
if args or opts.get('none'):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 raise util.Abort(_('cannot mix -l/--list with options or arguments'))
for i in xrange(len(q.series)):
status(i)
return
if not args or args[0][0:1] in '-+':
if not q.applied:
raise util.Abort(_('no patches applied'))
patch = q.applied[-1].name
if patch is None and args[0][0:1] not in '-+':
patch = args.pop(0)
if patch is None:
raise util.Abort(_('no patch to work with'))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if args or opts.get('none'):
Christian Ebert
mq: abort cleanly when invalid patch name is given to qguard
r4133 idx = q.find_series(patch)
if idx is None:
raise util.Abort(_('no patch named %s') % patch)
q.set_guards(idx, args)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 q.save_dirty()
else:
status(q.series.index(q.lookup(patch)))
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qheader", [], _('hg qheader [PATCH]'))
Brendan Cully
Add command qheader to display the header of a given patch.
r2747 def header(ui, repo, patch=None):
Erik Zielke
mq: added return 0 on success...
r12538 """print the header of the topmost or specified patch
Returns 0 on success."""
Brendan Cully
Add command qheader to display the header of a given patch.
r2747 q = repo.mq
if patch:
patch = q.lookup(patch)
else:
if not q.applied:
Benoit Boissinot
i18n: mark more strings for translation
r10510 ui.write(_('no patches applied\n'))
Bryan O'Sullivan
qheader: exit withh meaningful error code.
r3008 return 1
Brendan Cully
Add command qheader to display the header of a given patch.
r2747 patch = q.lookup('qtip')
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(q.join(patch), q.plainmode)
Brendan Cully
Add command qheader to display the header of a given patch.
r2747
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 ui.write('\n'.join(ph.message) + '\n')
Brendan Cully
Add command qheader to display the header of a given patch.
r2747
mason@suse.com
Add mq extension
r1808 def lastsavename(path):
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 (directory, base) = os.path.split(path)
names = os.listdir(directory)
mason@suse.com
Add mq extension
r1808 namere = re.compile("%s.([0-9]+)" % base)
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 maxindex = None
mason@suse.com
Add mq extension
r1808 maxname = None
for f in names:
m = namere.match(f)
if m:
index = int(m.group(1))
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if maxindex is None or index > maxindex:
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 maxindex = index
mason@suse.com
Add mq extension
r1808 maxname = f
if maxname:
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 return (os.path.join(directory, maxname), maxindex)
mason@suse.com
Add mq extension
r1808 return (None, None)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808 def savename(path):
(last, index) = lastsavename(path)
if last is None:
index = 0
newpath = path + ".%d" % (index + 1)
return newpath
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qpush",
[('f', 'force', None, _('apply on top of local changes')),
('e', 'exact', None, _('apply the target patch to its recorded parent')),
('l', 'list', None, _('list patch name in commit text')),
('a', 'all', None, _('apply all patches')),
('m', 'merge', None, _('merge from another queue (DEPRECATED)')),
('n', 'name', '',
_('merge queue name (DEPRECATED)'), _('NAME')),
('', 'move', None, _('reorder patch series and apply only the patch'))],
_('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]'))
mason@suse.com
Add mq extension
r1808 def push(ui, repo, patch=None, **opts):
Dirkjan Ochtman
mq: add a little documentation on qpush -f
r6552 """push the next patch onto the stack
Dirkjan Ochtman
remove trailing spaces
r6553
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 When -f/--force is applied, all local changes in patched files
will be lost.
Erik Zielke
mq: added return 0 on success...
r12538
Stefano Tortarolo
mq: fix typo in docstring
r13725 Return 0 on success.
Dirkjan Ochtman
mq: add a little documentation on qpush -f
r6552 """
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
mason@suse.com
Add mq extension
r1808 mergeq = None
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('merge'):
if opts.get('name'):
newpath = repo.join(opts.get('name'))
mason@suse.com
Add mq extension
r1808 else:
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 newpath, i = lastsavename(q.path)
mason@suse.com
Add mq extension
r1808 if not newpath:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 ui.warn(_("no saved queues found, please use -n\n"))
mason@suse.com
Add mq extension
r1808 return 1
mergeq = queue(ui, repo.join(""), newpath)
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 ui.warn(_("merging with queue at: %s\n") % mergeq.path)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
exact=opts.get('exact'))
mason@suse.com
Add mq extension
r1808 return ret
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qpop",
[('a', 'all', None, _('pop all patches')),
('n', 'name', '',
_('queue name to pop (DEPRECATED)'), _('NAME')),
('f', 'force', None, _('forget any local changes to patched files'))],
_('hg qpop [-a] [-f] [PATCH | INDEX]'))
mason@suse.com
Add mq extension
r1808 def pop(ui, repo, patch=None, **opts):
Dirkjan Ochtman
mq: add correct documentation for qpop
r6611 """pop the current patch off the stack
Dirkjan Ochtman
mq: lose the trailing whitespace
r6621
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 By default, pops off the top of the patch stack. If given a patch
name, keeps popping off patches until the named patch is at the
top of the stack.
Erik Zielke
mq: added return 0 on success...
r12538
Return 0 on success.
Dirkjan Ochtman
mq: add correct documentation for qpop
r6611 """
mason@suse.com
Add mq extension
r1808 localupdate = True
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('name'):
q = queue(ui, repo.join(""), repo.join(opts.get('name')))
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 ui.warn(_('using patch queue: %s\n') % q.path)
mason@suse.com
Add mq extension
r1808 localupdate = False
else:
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate,
all=opts.get('all'))
mason@suse.com
Add mq extension
r1808 q.save_dirty()
Alexis S. L. Carvalho
mq: propagate the return error of pop
r4099 return ret
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qrename|qmv", [], _('hg qrename PATCH1 [PATCH2]'))
Brendan Cully
New self-explanatory command qrename.
r2750 def rename(ui, repo, patch, name=None, **opts):
"""rename a patch
With one argument, renames the current patch to PATCH1.
Erik Zielke
mq: added return 0 on success...
r12538 With two arguments, renames PATCH1 to PATCH2.
Returns 0 on success."""
Brendan Cully
New self-explanatory command qrename.
r2750
q = repo.mq
if not name:
name = patch
patch = None
if patch:
patch = q.lookup(patch)
else:
if not q.applied:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_('no patches applied\n'))
Brendan Cully
New self-explanatory command qrename.
r2750 return
patch = q.lookup('qtip')
Brendan Cully
Make qrename handle directory targets; closes #333.
r3083 absdest = q.join(name)
if os.path.isdir(absdest):
Patrick Mezard
Enforce unixish style for all generated patch names....
r4037 name = normname(os.path.join(name, os.path.basename(patch)))
Brendan Cully
Make qrename handle directory targets; closes #333.
r3083 absdest = q.join(name)
Idan Kamara
mq: use checkpatchname...
r14423 q.checkpatchname(name)
Brendan Cully
New self-explanatory command qrename.
r2750
Benoit Boissinot
i18n: mark more strings for translation
r10510 ui.note(_('renaming %s to %s\n') % (patch, name))
Brendan Cully
New self-explanatory command qrename.
r2750 i = q.find_series(patch)
Mathieu Clabaut
Issue424: mq patch loses guard when qrenamed
r3685 guards = q.guard_re.findall(q.full_series[i])
q.full_series[i] = name + ''.join([' #' + g for g in guards])
Vadim Gelfer
mq: rename read_series as parse_series, make simpler and faster
r2767 q.parse_series()
Brendan Cully
New self-explanatory command qrename.
r2750 q.series_dirty = 1
info = q.isapplied(patch)
if info:
Brendan Cully
Make mq camelcase consistent with the rest of hg.
r2818 q.applied[info[0]] = statusentry(info[1], name)
Brendan Cully
New self-explanatory command qrename.
r2750 q.applied_dirty = 1
Yuya Nishihara
mq: fixed ENOENT when qrename to new/directory.patch...
r11513 destdir = os.path.dirname(absdest)
if not os.path.isdir(destdir):
os.makedirs(destdir)
Vadim Gelfer
mq: add join method
r2819 util.rename(q.join(patch), absdest)
Brendan Cully
New self-explanatory command qrename.
r2750 r = q.qrepo()
Patrick Mezard
mq: qrename should not touch the dirstate if src is untracked (issue2460)
r12875 if r and patch in r.dirstate:
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 wctx = r[None]
Brendan Cully
New self-explanatory command qrename.
r2750 wlock = r.wlock()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Weijun Wang
mq: handle added patch renaming correctly
r6648 if r.dirstate[patch] == 'a':
r.dirstate.forget(patch)
r.dirstate.add(name)
else:
if r.dirstate[name] == 'r':
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 wctx.undelete([name])
wctx.copy(patch, name)
wctx.remove([patch], False)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 wlock.release()
Brendan Cully
New self-explanatory command qrename.
r2750
q.save_dirty()
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qrestore",
[('d', 'delete', None, _('delete save entry')),
('u', 'update', None, _('update queue working directory'))],
_('hg qrestore [-d] [-u] REV'))
mason@suse.com
Add mq extension
r1808 def restore(ui, repo, rev, **opts):
Dirkjan Ochtman
mq: deprecate qsave, qrestore and related options
r10360 """restore the queue state saved by a revision (DEPRECATED)
Dan Villiom Podlaski Christiansen
mq: fix the deprecation comment for qsave & qrestore....
r12352 This command is deprecated, use :hg:`rebase` instead."""
mason@suse.com
Add mq extension
r1808 rev = repo.lookup(rev)
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 q.restore(repo, rev, delete=opts.get('delete'),
qupdate=opts.get('update'))
mason@suse.com
Add mq extension
r1808 q.save_dirty()
return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qsave",
[('c', 'copy', None, _('copy patch directory')),
('n', 'name', '',
_('copy directory name'), _('NAME')),
('e', 'empty', None, _('clear queue status file')),
('f', 'force', None, _('force copy'))] + commands.commitopts,
_('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'))
mason@suse.com
Add mq extension
r1808 def save(ui, repo, **opts):
Dirkjan Ochtman
mq: deprecate qsave, qrestore and related options
r10360 """save current queue state (DEPRECATED)
Dan Villiom Podlaski Christiansen
mq: fix the deprecation comment for qsave & qrestore....
r12352 This command is deprecated, use :hg:`rebase` instead."""
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Matt Mackall
dispatch: move dispatching code to cmdutil
r4549 message = cmdutil.logmessage(opts)
"Mathieu Clabaut "
MQ: uniformise message and logfile option....
r2694 ret = q.save(repo, msg=message)
mason@suse.com
Add mq extension
r1808 if ret:
return ret
q.save_dirty()
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('copy'):
mason@suse.com
Add mq extension
r1808 path = q.path
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('name'):
newpath = os.path.join(q.basepath, opts.get('name'))
mason@suse.com
Add mq extension
r1808 if os.path.exists(newpath):
if not os.path.isdir(newpath):
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_('destination %s exists and is not '
'a directory') % newpath)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if not opts.get('force'):
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_('destination %s exists, '
'use -f to force') % newpath)
mason@suse.com
Add mq extension
r1808 else:
newpath = savename(path)
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 ui.warn(_("copy %s to %s\n") % (path, newpath))
mason@suse.com
Add mq extension
r1808 util.copyfiles(path, newpath)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('empty'):
mason@suse.com
Add mq extension
r1808 try:
Vadim Gelfer
mq: add join method
r2819 os.unlink(q.join(q.status_path))
mason@suse.com
Add mq extension
r1808 except:
pass
return 0
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("strip",
[('f', 'force', None, _('force removal of changesets, discard '
'uncommitted changes (no backup)')),
('b', 'backup', None, _('bundle only changesets with local revision'
' number greater than REV which are not'
' descendants of REV (DEPRECATED)')),
('n', 'no-backup', None, _('no backups')),
('', 'nobackup', None, _('no backups (DEPRECATED)')),
('k', 'keep', None, _("do not modify working copy during strip"))],
_('hg strip [-k] [-f] [-n] REV...'))
Nicolas Dumazet
strip: support multiple revisions
r11789 def strip(ui, repo, *revs, **opts):
"""strip changesets and all their descendants from the repository
The strip command removes the specified changesets and all their
Patrick Mezard
strip: make it clear that --force discards changes (issue310)
r14026 descendants. If the working directory has uncommitted changes, the
operation is aborted unless the --force flag is supplied, in which
case changes will be discarded.
Dirkjan Ochtman
mq: don't update the working copy on strip if parents aren't stripped...
r6635
Faheem Mitha
mq: rewrite strip docstrings...
r11073 If a parent of the working directory is stripped, then the working
directory will automatically be updated to the most recent
available ancestor of the stripped parent after the operation
completes.
Any stripped changesets are stored in ``.hg/strip-backup`` as a
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 bundle (see :hg:`help bundle` and :hg:`help unbundle`). They can
be restored by running :hg:`unbundle .hg/strip-backup/BUNDLE`,
Faheem Mitha
mq: rewrite strip docstrings...
r11073 where BUNDLE is the bundle file created by the strip. Note that
the local revision numbers will in general be different after the
restore.
Christian Ebert
mq: rename strip --nobackup option to --no-backup (issue2377)...
r12282 Use the --no-backup option to discard the backup bundle once the
Faheem Mitha
mq: rewrite strip docstrings...
r11073 operation completes.
Erik Zielke
mq: added return 0 on success...
r12538
Return 0 on success.
Dirkjan Ochtman
mq: don't update the working copy on strip if parents aren't stripped...
r6635 """
mason@suse.com
Add mq extension
r1808 backup = 'all'
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('backup'):
mason@suse.com
Add mq extension
r1808 backup = 'strip'
Jacek Sowiński
strip: typo bugfix related to '--nobackup -> --no-backup' rename (issue2377)...
r13224 elif opts.get('no_backup') or opts.get('nobackup'):
mason@suse.com
Add mq extension
r1808 backup = 'none'
Dirkjan Ochtman
mq: don't update the working copy on strip if parents aren't stripped...
r6635
cl = repo.changelog
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 revs = set(scmutil.revrange(repo, revs))
Wagner Bruna
strip: support revision sets
r12767 if not revs:
Wagner Bruna
mq: mark string for i18n
r12775 raise util.Abort(_('empty revision set'))
Nicolas Dumazet
strip: support multiple revisions
r11789
descendants = set(cl.descendants(*revs))
strippedrevs = revs.union(descendants)
roots = revs.difference(descendants)
update = False
# if one of the wdir parent is stripped we'll need
# to update away to an earlier revision
for p in repo.dirstate.parents():
if p != nullid and cl.rev(p) in strippedrevs:
update = True
break
rootnodes = set(cl.node(r) for r in roots)
Dirkjan Ochtman
mq: don't update the working copy on strip if parents aren't stripped...
r6635
Vishakh H
mq: cleanup status if applied mq is stripped (issue1881)...
r11637 q = repo.mq
if q.applied:
Nicolas Dumazet
strip: support multiple revisions
r11789 # refresh queue state if we're about to strip
# applied patches
if cl.rev(repo.lookup('qtip')) in strippedrevs:
Vishakh H
mq: cleanup status if applied mq is stripped (issue1881)...
r11637 q.applied_dirty = True
start = 0
end = len(q.applied)
Nicolas Dumazet
strip: support multiple revisions
r11789 for i, statusentry in enumerate(q.applied):
if statusentry.node in rootnodes:
# if one of the stripped roots is an applied
# patch, only part of the queue is stripped
start = i
break
Vishakh H
mq: cleanup status if applied mq is stripped (issue1881)...
r11637 del q.applied[start:end]
q.save_dirty()
Augie Fackler
strip: add --keep flag to avoid modifying wc during strip...
r12682 revs = list(rootnodes)
if update and opts.get('keep'):
wlock = repo.wlock()
try:
urev = repo.mq.qparents(repo, revs[0])
repo.dirstate.rebuild(urev, repo[urev].manifest())
repo.dirstate.write()
update = False
finally:
wlock.release()
repo.mq.strip(repo, revs, backup=backup, update=update,
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 force=opts.get('force'))
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qselect",
[('n', 'none', None, _('disable all guards')),
('s', 'series', None, _('list all guards in series file')),
('', 'pop', None, _('pop to before first guarded applied patch')),
('', 'reapply', None, _('pop, then reapply patches'))],
_('hg qselect [OPTION]... [GUARD]...'))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def select(ui, repo, *args, **opts):
'''set or print guarded patches to push
Martin Geisler
mq: use hg reST role some more
r11307 Use the :hg:`qguard` command to set or print guards on patch, then use
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 qselect to tell mq which guards to use. A patch will be pushed if
it has no guards or any positive guards match the currently
selected guard, but will not be pushed if any negative guards
Martin Geisler
mq: fix literal blocks in docstrings
r9824 match the current guard. For example::
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
timeless@gmail.com
mq: fix qselect help for qguard
r13791 qguard foo.patch -- -stable (negative guard)
qguard bar.patch +stable (positive guard)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 qselect stable
Brendan Cully
mq help text updates and speling fixes
r2940 This activates the "stable" guard. mq will skip foo.patch (because
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 it has a negative match) but push bar.patch (because it has a
positive match).
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Brendan Cully
mq help text updates and speling fixes
r2940 With no arguments, prints the currently active guards.
With one argument, sets the active guard.
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Brendan Cully
mq help text updates and speling fixes
r2940 Use -n/--none to deactivate guards (no other arguments needed).
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 When no guards are active, patches with positive guards are
skipped and patches with negative guards are pushed.
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Brendan Cully
mq help text updates and speling fixes
r2940 qselect can change the guards on applied patches. It does not pop
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 guarded patches by default. Use --pop to pop back to the last
applied patch that is not guarded. Use --reapply (which implies
--pop) to push back to the current patch afterwards, but skip
guarded patches.
Vadim Gelfer
qselect: add --pop, --reapply options
r2844
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 Use -s/--series to print a list of all guards in the series file
Erik Zielke
mq: added return 0 on success...
r12538 (no other arguments needed). Use -v for more information.
Returns 0 on success.'''
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
q = repo.mq
guards = q.active()
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if args or opts.get('none'):
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 old_unapplied = q.unapplied(repo)
old_guarded = [i for i in xrange(len(q.applied)) if
not q.pushable(i)[0]]
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 q.set_active(args)
q.save_dirty()
if not args:
ui.status(_('guards deactivated\n'))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if not opts.get('pop') and not opts.get('reapply'):
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 unapplied = q.unapplied(repo)
guarded = [i for i in xrange(len(q.applied))
if not q.pushable(i)[0]]
if len(unapplied) != len(old_unapplied):
ui.status(_('number of unguarded, unapplied patches has '
'changed from %d to %d\n') %
(len(old_unapplied), len(unapplied)))
if len(guarded) != len(old_guarded):
ui.status(_('number of guarded, applied patches has changed '
'from %d to %d\n') %
(len(old_guarded), len(guarded)))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 elif opts.get('series'):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 guards = {}
noguards = 0
for gs in q.series_guards:
if not gs:
noguards += 1
for g in gs:
guards.setdefault(g, 0)
guards[g] += 1
if ui.verbose:
guards['NONE'] = noguards
guards = guards.items()
Alejandro Santos
compat: use 'key' argument instead of 'cmp' when sorting a list
r9032 guards.sort(key=lambda x: x[0][1:])
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if guards:
ui.note(_('guards in series file:\n'))
for guard, count in guards:
ui.note('%2d ' % count)
ui.write(guard, '\n')
else:
ui.note(_('no guards in series file\n'))
else:
if guards:
ui.note(_('active guards:\n'))
for g in guards:
ui.write(g, '\n')
else:
ui.write(_('no active guards\n'))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 reapply = opts.get('reapply') and q.applied and q.appliedname(-1)
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 popped = False
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('pop') or opts.get('reapply'):
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 for i in xrange(len(q.applied)):
pushable, reason = q.pushable(i)
if not pushable:
ui.status(_('popping guarded patches\n'))
popped = True
if i == 0:
q.pop(repo, all=True)
else:
Matt Mackall
many, many trivial check-code fixups
r10282 q.pop(repo, i - 1)
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 break
if popped:
try:
if reapply:
ui.status(_('reapplying unguarded patches\n'))
q.push(repo, reapply)
finally:
q.save_dirty()
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qfinish",
[('a', 'applied', None, _('finish all applied changesets'))],
_('hg qfinish [-a] [REV]...'))
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 def finish(ui, repo, *revrange, **opts):
"""move applied patches into repository history
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 Finishes the specified revisions (corresponding to applied
patches) by moving them out of mq control into regular repository
history.
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 Accepts a revision range or the -a/--applied option. If --applied
is specified, all applied mq revisions are removed from mq
control. Otherwise, the given revisions must be at the base of the
stack of applied patches.
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 This can be especially useful if your changes have been applied to
an upstream repository, or if you are about to push your changes
to upstream.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 """
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if not opts.get('applied') and not revrange:
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 raise util.Abort(_('no revisions specified'))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 elif opts.get('applied'):
Matt Mackall
qfinish: fix range logic for --applied...
r11730 revrange = ('qbase::qtip',) + revrange
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
q = repo.mq
if not q.applied:
ui.status(_('no patches applied\n'))
return 0
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 revs = scmutil.revrange(repo, revrange)
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 q.finish(repo, revs)
q.save_dirty()
return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qqueue",
[('l', 'list', False, _('list all available queues')),
('c', 'create', False, _('create new queue')),
('', 'rename', False, _('rename active queue')),
('', 'delete', False, _('delete reference to queue')),
('', 'purge', False, _('delete queue, and remove patch dir')),
],
_('[OPTION] [QUEUE]'))
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 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.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 '''
q = repo.mq
_defaultqueue = 'patches'
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 _allqueues = 'patches.queues'
_activequeue = 'patches.queue'
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229
def _getcurrent():
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 cur = os.path.basename(q.path)
if cur.startswith('patches-'):
cur = cur[8:]
return cur
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229
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()]
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 fh.close()
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 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'))
"Yann E. MORIN"
mq/qqueue: split _setactive...
r11938 _setactivenocheck(name)
def _setactivenocheck(name):
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 fh = repo.opener(_activequeue, 'w')
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 if name != 'patches':
fh.write(name)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 fh.close()
def _addqueue(name):
fh = repo.opener(_allqueues, 'a')
fh.write('%s\n' % (name,))
fh.close()
"Yann E. MORIN"
mq/qqueue: enable renaming of active queue
r11939 def _queuedir(name):
if name == 'patches':
return repo.join('patches')
else:
return repo.join('patches-' + name)
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 def _validname(name):
for n in name:
if n in ':\\/.':
return False
return True
"Yann E. MORIN"
mq/qqueue: commonalise the queue deletion code
r11966 def _delete(name):
if name not in existing:
raise util.Abort(_('cannot delete queue that does not exist'))
current = _getcurrent()
if name == current:
raise util.Abort(_('cannot delete currently active queue'))
fh = repo.opener('patches.queues.new', 'w')
for queue in existing:
if queue == name:
continue
fh.write('%s\n' % (queue,))
fh.close()
util.rename(repo.join('patches.queues.new'), repo.join(_allqueues))
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 if not name or opts.get('list'):
current = _getcurrent()
for queue in _getqueues():
ui.write('%s' % (queue,))
"Yann E. MORIN"
mq/qqueue: --list does not print (active) with --quiet...
r11767 if queue == current and not ui.quiet:
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 ui.write(_(' (active)\n'))
else:
ui.write('\n')
return
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 if not _validname(name):
raise util.Abort(
_('invalid queue name, may not contain the characters ":\\/."'))
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 existing = _getqueues()
if opts.get('create'):
Cédric Duval
mq: prevent the creation of a queue whose name is already taken...
r11271 if name in existing:
raise util.Abort(_('queue "%s" already exists') % name)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 if _noqueues():
_addqueue(_defaultqueue)
_addqueue(name)
_setactive(name)
"Yann E. MORIN"
mq/qqueue: enable renaming of active queue
r11939 elif opts.get('rename'):
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 current = _getcurrent()
if name == current:
"Yann E. MORIN"
mq/qqueue: enable renaming of active queue
r11939 raise util.Abort(_('can\'t rename "%s" to its current name') % name)
if name in existing:
raise util.Abort(_('queue "%s" already exists') % name)
olddir = _queuedir(current)
newdir = _queuedir(name)
if os.path.exists(newdir):
raise util.Abort(_('non-queue directory "%s" already exists') %
newdir)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 fh = repo.opener('patches.queues.new', 'w')
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 for queue in existing:
"Yann E. MORIN"
mq/qqueue: enable renaming of active queue
r11939 if queue == current:
fh.write('%s\n' % (name,))
if os.path.exists(olddir):
util.rename(olddir, newdir)
else:
fh.write('%s\n' % (queue,))
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 fh.close()
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 util.rename(repo.join('patches.queues.new'), repo.join(_allqueues))
"Yann E. MORIN"
mq/qqueue: enable renaming of active queue
r11939 _setactivenocheck(name)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 elif opts.get('delete'):
"Yann E. MORIN"
mq/qqueue: commonalise the queue deletion code
r11966 _delete(name)
"Yann E. MORIN"
mq/qqueue: add --purge option to delete a queue and its patch dir...
r11967 elif opts.get('purge'):
if name in existing:
_delete(name)
qdir = _queuedir(name)
if os.path.exists(qdir):
shutil.rmtree(qdir)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 else:
Cédric Duval
mq: prevent the creation of a queue whose name is already taken...
r11271 if name not in existing:
raise util.Abort(_('use --create to create a new queue'))
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 _setactive(name)
mason@suse.com
Add mq extension
r1808 def reposetup(ui, repo):
Brendan Cully
Make mq camelcase consistent with the rest of hg.
r2818 class mqrepo(repo.__class__):
Simon Heimberg
mq: only read files when needed...
r8524 @util.propertycache
def mq(self):
return queue(self.ui, self.join(""))
Vadim Gelfer
mq: do not allow to push from repo with patches applied
r2848 def abort_if_wdir_patched(self, errmsg, force=False):
if self.mq.applied and not force:
Martin Geisler
mq: forbid commit of merge involving mq patches
r13520 parents = self.dirstate.parents()
patches = [s.node for s in self.mq.applied]
if parents[0] in patches or parents[1] in patches:
Vadim Gelfer
mq: do not allow to push from repo with patches applied
r2848 raise util.Abort(errmsg)
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Matt Mackall
mq: fix commit prototype
r8711 def commit(self, text="", user=None, date=None, match=None,
force=False, editor=False, extra={}):
Vadim Gelfer
mq: do not allow to push from repo with patches applied
r2848 self.abort_if_wdir_patched(
_('cannot commit over an applied mq patch'),
force)
Brendan Cully
Disallow commit over an applied mq patch.
r2845
Matt Mackall
mq: fix commit prototype
r8711 return super(mqrepo, self).commit(text, user, date, match, force,
editor, extra)
Brendan Cully
Disallow commit over an applied mq patch.
r2845
Patrick Mezard
mq: factor out push conditions checks...
r13327 def checkpush(self, force, revs):
Patrick Mezard
mq: always require --force when pushing patches (issue2363)...
r12378 if self.mq.applied and not force:
haspatches = True
if revs:
# Assume applied patches have no non-patch descendants
# and are not on remote already. If they appear in the
# set of resolved 'revs', bail out.
applied = set(e.node for e in self.mq.applied)
haspatches = bool([n for n in revs if n in applied])
if haspatches:
raise util.Abort(_('source has mq patches applied'))
Patrick Mezard
mq: factor out push conditions checks...
r13327 super(mqrepo, self).checkpush(force, revs)
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 def _findtags(self):
'''augment tags from base class with patch tags'''
result = super(mqrepo, self)._findtags()
Brendan Cully
Add mq patch names to tagscache instead of overriding lookup....
r2682
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = self.mq
Brendan Cully
mq: do not hold a reference to repo in tags override...
r2723 if not q.applied:
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 return result
Brendan Cully
Mq: modify repo.lookup to resolve applied patches too.
r2663
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 mqtags = [(patch.node, patch.name) for patch in q.applied]
Alexis S. L. Carvalho
mqrepo: don't abort if the status file has an unknown node
r5979
Matt Mackall
mq: fix qpush recursion in _findtags when status file is wrong (issue2664)...
r13508 try:
timeless
remove unused variables
r14174 self.changelog.rev(mqtags[-1][0])
Matt Mackall
mq: fix qpush recursion in _findtags when status file is wrong (issue2664)...
r13508 except error.RepoLookupError:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_('mq status file refers to unknown node %s\n')
Matt Mackall
mq: remove import of revlog
r7639 % short(mqtags[-1][0]))
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 return result
Alexis S. L. Carvalho
mqrepo: don't abort if the status file has an unknown node
r5979
Brendan Cully
mq: do not hold a reference to repo in tags override...
r2723 mqtags.append((mqtags[-1][0], 'qtip'))
mqtags.append((mqtags[0][0], 'qbase'))
Brendan Cully
mq: add qparent tag (first parent of qbase)
r4219 mqtags.append((self.changelog.parents(mqtags[0][0])[0], 'qparent'))
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 tags = result[0]
Brendan Cully
mq: do not hold a reference to repo in tags override...
r2723 for patch in mqtags:
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 if patch[1] in tags:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_('Tag %s overrides mq patch of the same name\n')
% patch[1])
Brendan Cully
mq: do not hold a reference to repo in tags override...
r2723 else:
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 tags[patch[1]] = patch[0]
Brendan Cully
Add mq patch names to tagscache instead of overriding lookup....
r2682
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 return result
Brendan Cully
Add qtip and qbase to mq qlookup.
r2664
Alexis S. L. Carvalho
move the reading of branch.cache from _branchtags to branchtags
r6120 def _branchtags(self, partial, lrev):
Alexis S. L. Carvalho
make mq play nicely with the branch cache...
r3492 q = self.mq
if not q.applied:
Alexis S. L. Carvalho
move the reading of branch.cache from _branchtags to branchtags
r6120 return super(mqrepo, self)._branchtags(partial, lrev)
Alexis S. L. Carvalho
make mq play nicely with the branch cache...
r3492
Alexis S. L. Carvalho
mqrepo: don't abort if the status file has an unknown node
r5979 cl = self.changelog
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 qbasenode = q.applied[0].node
Matt Mackall
mq: fix qpush recursion in _findtags when status file is wrong (issue2664)...
r13508 try:
qbase = cl.rev(qbasenode)
except error.LookupError:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_('mq status file refers to unknown node %s\n')
Matt Mackall
mq: remove import of revlog
r7639 % short(qbasenode))
Alexis S. L. Carvalho
move the reading of branch.cache from _branchtags to branchtags
r6120 return super(mqrepo, self)._branchtags(partial, lrev)
Alexis S. L. Carvalho
make mq play nicely with the branch cache...
r3492
start = lrev + 1
if start < qbase:
# update the cache (excluding the patches) and save it
Sune Foldager
localrepo: change _updatebranchcache to use a context generator
r10770 ctxgen = (self[r] for r in xrange(lrev + 1, qbase))
self._updatebranchcache(partial, ctxgen)
Matt Mackall
many, many trivial check-code fixups
r10282 self._writebranchcache(partial, cl.node(qbase - 1), qbase - 1)
Alexis S. L. Carvalho
make mq play nicely with the branch cache...
r3492 start = qbase
# if start = qbase, the cache is as updated as it should be.
# if start > qbase, the cache includes (part of) the patches.
# we might as well use it, but we won't save it.
# update the cache up to the tip
Sune Foldager
localrepo: change _updatebranchcache to use a context generator
r10770 ctxgen = (self[r] for r in xrange(start, len(cl)))
self._updatebranchcache(partial, ctxgen)
Alexis S. L. Carvalho
make mq play nicely with the branch cache...
r3492
Alexis S. L. Carvalho
fix encoding conversion of branch names when mq is loaded
r3826 return partial
Alexis S. L. Carvalho
make mq play nicely with the branch cache...
r3492
Vadim Gelfer
mq: only add mq attribute to local repo
r2851 if repo.local():
repo.__class__ = mqrepo
mason@suse.com
Add mq extension
r1808
Matt Mackall
extensions: use new wrapper functions
r7216 def mqimport(orig, ui, repo, *args, **kwargs):
Matt Mackall
many, many trivial check-code fixups
r10282 if (hasattr(repo, 'abort_if_wdir_patched')
and not kwargs.get('no_commit', False)):
Matt Mackall
extensions: use new wrapper functions
r7216 repo.abort_if_wdir_patched(_('cannot import over an applied patch'),
kwargs.get('force'))
return orig(ui, repo, *args, **kwargs)
Brendan Cully
mq: make init -Q do what qinit -c did
r10402 def mqinit(orig, ui, *args, **kwargs):
Benoit Boissinot
mq: simplify --mq handling / keep compatibility with other extensions...
r10558 mq = kwargs.pop('mq', None)
Brendan Cully
mq: make init -Q do what qinit -c did
r10402
if not mq:
return orig(ui, *args, **kwargs)
Cédric Duval
mq: fix init with nonexistent or non-local repository
r10691 if args:
repopath = args[0]
if not hg.islocal(repopath):
raise util.Abort(_('only a local queue repository '
'may be initialized'))
else:
repopath = cmdutil.findrepo(os.getcwd())
if not repopath:
Martin Geisler
Lowercase error messages
r12067 raise util.Abort(_('there is no Mercurial repository here '
Cédric Duval
mq: fix init with nonexistent or non-local repository
r10691 '(.hg not found)'))
Brendan Cully
mq: make init -Q do what qinit -c did
r10402 repo = hg.repository(ui, repopath)
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 return qinit(ui, repo, True)
Brendan Cully
mq: make init -Q do what qinit -c did
r10402
Brendan Cully
mq: add --mq option to some commands...
r10359 def mqcommand(orig, ui, repo, *args, **kwargs):
"""Add --mq option to operate on patch repository instead of main"""
# some commands do not like getting unknown options
Benoit Boissinot
mq: simplify --mq handling / keep compatibility with other extensions...
r10558 mq = kwargs.pop('mq', None)
Brendan Cully
mq: add --mq option to some commands...
r10359
if not mq:
return orig(ui, repo, *args, **kwargs)
q = repo.mq
r = q.qrepo()
if not r:
Martin Geisler
mq: mark error message for translation
r11120 raise util.Abort(_('no queue repository'))
Brendan Cully
mq: incorporate mq repo config when using --mq...
r10407 return orig(r.ui, r, *args, **kwargs)
Brendan Cully
mq: add --mq option to some commands...
r10359
Matt Mackall
mq: add a line to hg summary
r11107 def summary(orig, ui, repo, *args, **kwargs):
r = orig(ui, repo, *args, **kwargs)
q = repo.mq
m = []
a, u = len(q.applied), len(q.unapplied(repo))
if a:
Eric Eisner
mq: make use of output labeling for summary
r11121 m.append(ui.label(_("%d applied"), 'qseries.applied') % a)
Matt Mackall
mq: add a line to hg summary
r11107 if u:
Eric Eisner
mq: make use of output labeling for summary
r11121 m.append(ui.label(_("%d unapplied"), 'qseries.unapplied') % u)
Matt Mackall
mq: add a line to hg summary
r11107 if m:
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write("mq: %s\n" % ', '.join(m))
Matt Mackall
mq: add a line to hg summary
r11107 else:
Martin Geisler
mq: mark string for translation
r11119 ui.note(_("mq: (empty queue)\n"))
Matt Mackall
mq: add a line to hg summary
r11107 return r
Idan Kamara
mq: add a 'mq()' revset predicate that returns applied mq csets
r14210 def revsetmq(repo, subset, x):
"""``mq()``
Changesets managed by MQ.
"""
revset.getargs(x, 0, 0, _("mq takes no arguments"))
applied = set([repo[r.node].rev() for r in repo.mq.applied])
return [r for r in subset if r in applied]
def extsetup(ui):
revset.symbols['mq'] = revsetmq
# tell hggettext to extract docstrings from these functions:
i18nfunctions = [revsetmq]
Brendan Cully
Prevent import over an applied patch (closes issue795)
r7142 def uisetup(ui):
Matt Mackall
mq: drop -Q in favor of --mq only
r10591 mqopt = [('', 'mq', None, _("operate on patch repository"))]
Brendan Cully
mq: make init -Q do what qinit -c did
r10402
Matt Mackall
extensions: use new wrapper functions
r7216 extensions.wrapcommand(commands.table, 'import', mqimport)
Matt Mackall
mq: add a line to hg summary
r11107 extensions.wrapcommand(commands.table, 'summary', summary)
Brendan Cully
mq: make init -Q do what qinit -c did
r10402
entry = extensions.wrapcommand(commands.table, 'init', mqinit)
entry[1].extend(mqopt)
Dan Villiom Podlaski Christiansen
mq: extend support for the --mq argument to extension commands...
r12036 nowrap = set(commands.norepo.split(" ") + ['qrecord'])
def dotable(cmdtable):
for cmd in cmdtable.keys():
cmd = cmdutil.parsealiases(cmd)[0]
if cmd in nowrap:
continue
entry = extensions.wrapcommand(cmdtable, cmd, mqcommand)
entry[1].extend(mqopt)
dotable(commands.table)
for extname, extmodule in extensions.extensions():
if extmodule.__file__ != __file__:
dotable(getattr(extmodule, 'cmdtable', {}))
Brendan Cully
Prevent import over an applied patch (closes issue795)
r7142
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826
colortable = {'qguard.negative': 'red',
'qguard.positive': 'yellow',
'qguard.unguarded': 'green',
'qseries.applied': 'blue bold underline',
'qseries.guarded': 'black bold',
'qseries.missing': 'red bold',
'qseries.unapplied': 'black bold'}