##// END OF EJS Templates
Merge with stable
Merge with stable

File last commit:

r10264:d6512b3e merge default
r10264:d6512b3e merge default
Show More
mq.py
2739 lines | 100.0 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
commands: use minirst parser when displaying help
r9157 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 prepare repository to work with patches qinit
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.
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
Matt Mackall
mq: remove import of revlog
r7639 from mercurial import commands, cmdutil, hg, patch, util
Matt Mackall
error: move repo errors...
r7637 from mercurial import repair, extensions, url, error
Benoit Boissinot
use our urlopener (proxy handling, etc) instead of urllib
r7271 import os, sys, re, errno
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
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):
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 def __init__(self, rev, name=None):
if not name:
Brendan Cully
mq: handle patch names containing ":"
r3091 fields = rev.split(':', 1)
Brendan Cully
Update qsave to use StatusEntry; don't throw exception on bad status lines.
r2816 if len(fields) == 2:
self.rev, self.name = fields
else:
self.rev, self.name = None, None
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 else:
self.rev, self.name = rev, name
def __str__(self):
return self.rev + ':' + self.name
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 class patchheader(object):
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 def __init__(self, pf):
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:
l = lines[-1]
if re.match('\s*$', l):
del lines[-1]
else:
break
message = []
comments = []
user = None
date = None
format = None
subject = None
diffstart = 0
for line in file(pf):
line = line.rstrip()
if line.startswith('diff --git'):
diffstart = 2
break
if diffstart:
if line.startswith('+++ '):
diffstart = 2
break
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:]
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"
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)
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
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 self.haspatch = diffstart > 1
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:
Yann E. MORIN
mq: upgrade the patch to HG format when adding the author name with qrefresh...
r9336 if self._hasheader(['Date: ']):
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:
if self._hasheader(['From: ']):
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
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
Vadim Gelfer
mq: add join method
r2819 self.path = patchdir or os.path.join(path, "patches")
Thomas Arendsen Hein
Fix mq's usage of opener, which don't allow absolute paths now.
r1852 self.opener = util.opener(self.path)
mason@suse.com
Add mq extension
r1808 self.ui = ui
self.applied_dirty = 0
self.series_dirty = 0
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()
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)):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 lines = self.opener(self.status_path).read().splitlines()
Simon Heimberg
mq: only read files when needed...
r8524 return [statusentry(l) for l in lines]
return []
@util.propertycache
def full_series(self):
if os.path.exists(self.join(self.series_path)):
return self.opener(self.series_path).read().splitlines()
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):
diffopts = patch.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):
pre = re.compile("(\s*)([^#]+)")
index = 0
for l in self.full_series:
m = pre.match(l)
if m:
s = m.group(2)
s = s.rstrip()
if s == patch:
return index
index += 1
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:
guards = self.opener(self.guards_path).read().split()
except IOError, err:
if err.errno != errno.ENOENT: raise
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()
Vadim Gelfer
merge with brendan.
r2781 if self.applied_dirty: write_list(map(str, self.applied), self.status_path)
Vadim Gelfer
mq: simplify save_dirty
r2772 if self.series_dirty: write_list(self.full_series, self.series_path)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if self.guards_dirty: write_list(self.active_guards, self.guards_path)
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')
if stat:
opts['unified'] = '0'
Matt Mackall
walk: remove remaining users of cmdutils.matchpats
r6582 m = cmdutil.match(repo, files, opts)
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 chunks = patch.diff(repo, node1, node2, m, changes, diffopts)
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 write = fp is None and repo.ui.write or fp.write
Brodie Rao
diff: add --stat for diffstat output...
r9640 if stat:
width = self.ui.interactive() and util.termwidth() or 80
Brodie Rao
diffstat: with --git, mark binary files with Bin...
r9642 write(patch.diffstat(util.iterlines(chunks), width=width,
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 git=diffopts.git))
Brodie Rao
diff: add --stat for diffstat output...
r9640 else:
for chunk in chunks:
write(chunk)
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
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 (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)
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:
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 ph = patchheader(mergeq.join(patch))
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
if len(self.applied) == 0:
return None
Matt Mackall
mq: remove import of revlog
r7639 return bin(self.applied[-1].rev)
mason@suse.com
Add mq extension
r1808 pp = repo.changelog.parents(rev)
Matt Mackall
mq: remove import of revlog
r7639 if pp[1] != nullid:
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 arevs = [ x.rev for x in self.applied ]
Matt Mackall
mq: remove import of revlog
r7639 p0 = hex(pp[0])
p1 = hex(pp[1])
mason@suse.com
Add mq extension
r1808 if p0 in arevs:
return pp[0]
if p1 in arevs:
return pp[1]
return pp[0]
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 def mergepatch(self, repo, mergeq, series, diffopts):
mason@suse.com
Add mq extension
r1808 if len(self.applied) == 0:
# 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)
Matt Mackall
mq: remove import of revlog
r7639 self.applied.append(statusentry(hex(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)
Matt Mackall
mq: remove import of revlog
r7639 rev = bin(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:
Matt Mackall
mq: remove import of revlog
r7639 self.applied.append(statusentry(hex(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:
Brendan Cully
patch: return list of modified files even when an exception is raised...
r3465 fuzz = patch.patch(patchfile, self.ui, strip=1, cwd=repo.root,
Patrick Mezard
Make mq, record and transplant honor patch.eol
r8811 files=files, eolmode=None)
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"))
Brendan Cully
patch: return list of modified files even when an exception is raised...
r3465 return (False, files, False)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Brendan Cully
Teach mq about git patches
r2934 return (True, files, fuzz)
Benoit Boissinot
mq: codingstyle
r2796
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 def apply(self, repo, series, list=False, update_status=True,
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 strict=False, patchdir=None, merge=None, all_files={}):
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()
tr = repo.transaction()
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
switch lock releasing in the extensions from gc to explicit
r8112 del tr
release(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,
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 strict=False, patchdir=None, merge=None, all_files={}):
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:
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 ph = patchheader(self.join(patchname))
mason@suse.com
Add mq extension
r1808 except:
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
i18n: mark strings for translation in mq extension
r6960 message = _("imported patch %s\n") % patchname
mason@suse.com
Add mq extension
r1808 else:
if list:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 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)
all_files.update(files)
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:
Matt Mackall
dirstate: make wjoin function private
r4905 if os.path.exists(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
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 files = patch.updatedir(self.ui, repo, files)
Matt Mackall
match: remove files arg from repo.status and friends
r6603 match = cmdutil.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:
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 raise util.Abort(_("repo commit failed"))
mason@suse.com
Add mq extension
r1808
if update_status:
Matt Mackall
mq: remove import of revlog
r7639 self.applied.append(statusentry(hex(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:
r.remove(patches, True)
else:
for p in patches:
os.unlink(self.join(p))
if numrevs:
del self.applied[:numrevs]
self.applied_dirty = 1
Matt Mackall
replace util.sort with sorted built-in...
r8209 for i in sorted([self.find_series(p) for p in patches], reverse=True):
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 del self.full_series[i]
self.parse_series()
self.series_dirty = 1
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 def _revpatches(self, repo, revs):
Matt Mackall
util: add sort helper
r6762 firstrev = repo[self.applied[0].rev].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]
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 base = bin(self.applied[i].rev)
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
Brendan Cully
Allow qdel to delete multiple patches.
r2905 realpatches = []
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)
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 realpatches.append(patch)
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'))
Thomas Arendsen Hein
Removed unused ui parameter from revpair/revrange and fix its users.
r3707 revs = cmdutil.revrange(repo, opts['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)
realpatches += revpatches
numrevs = len(revpatches)
Brendan Cully
Allow qdel to delete multiple patches.
r2905
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 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):
if len(self.applied) > 0:
Matt Mackall
mq: remove import of revlog
r7639 top = bin(self.applied[-1].rev)
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
Vadim Gelfer
remove localrepository.changes....
r2875 def check_localchanges(self, repo, force=False, refresh=True):
m, a, r, d = repo.status()[:4]
if m or a or r or d:
if not force:
if refresh:
raise util.Abort(_("local changes found, refresh first"))
else:
raise util.Abort(_("local changes found"))
return m, a, r, d
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981 _reserved = ('series', 'status', 'guards')
def check_reserved_name(self, name):
if (name in self._reserved or name.startswith('.hg')
or name.startswith('.mq')):
raise util.Abort(_('"%s" cannot be used as the name of a patch')
% name)
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')
force = opts.get('force')
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')})
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 self.check_reserved_name(patchfn)
if os.path.exists(self.join(patchfn)):
raise util.Abort(_('patch "%s" already exists') % patchfn)
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 if opts.get('include') or opts.get('exclude') or pats:
Matt Mackall
walk: remove remaining users of cmdutils.matchpats
r6582 match = cmdutil.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):
raise util.Abort('%s: %s' % (f, msg))
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:
m, a, r, d = self.check_localchanges(repo, force)
Brendan Cully
mq: use cmdutil.matchfiles instead of match for qnew -f....
r7297 match = cmdutil.matchfiles(repo, m + a + r)
timeless
mq: qnew -f should reject merge working directories
r10114 if force:
p = repo[None].parents()
if len(p) > 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:
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 # if patch file write fails, abort early
p = self.opener(patchfn, "w")
try:
if date:
p.write("# HG changeset patch\n")
if user:
p.write("# User " + user + "\n")
p.write("# Date %d %d\n\n" % date)
elif user:
p.write("From: " + user + "\n\n")
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]
Matt Mackall
mq: remove import of revlog
r7639 self.applied.append(statusentry(hex(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)
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 chunks = patch.diff(repo, node1=parent, node2=n,
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()
if r: r.add([patchfn])
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
Dirkjan Ochtman
mq: add --force option to strip
r6472 def strip(self, repo, rev, 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)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 urev = self.qparents(repo, rev)
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)
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:
return (i, a.rev, 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]
Chris Mason
mq: patch naming shortcuts...
r2696 if len(self.series) > 0 and len(self.applied) > 0:
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)
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:
Thomas Arendsen Hein
Fixed python2.3 incompatibility (rsplit) in qpush/qpop with index.
r3082 off = int(patch[minus+1:] or 1)
Chris Mason
mq: patch naming shortcuts...
r2696 except(ValueError, OverflowError):
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:
Thomas Arendsen Hein
Fixed python2.3 incompatibility (rsplit) in qpush/qpop with index.
r3082 off = int(patch[plus+1:] or 1)
Chris Mason
mq: patch naming shortcuts...
r2696 except(ValueError, OverflowError):
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,
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 mergeq=None, all=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:
if repo.dirstate.parents()[0] not in repo.heads():
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)
if info:
if info[0] < len(self.applied) - 1:
raise util.Abort(
_("cannot push to a previous patch: %s") % patch)
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 self.ui.warn(
_('qpush: %s is already at the top\n') % patch)
return
pushable, reason = self.pushable(patch)
if not pushable:
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
if not force:
self.check_localchanges(repo)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
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]
all_files = {}
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...'))
node = repo.dirstate.parents()[0]
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 hg.revert(repo, node, None)
Matt Mackall
status: clean up all users for unknown files
r6760 unknown = repo.status(unknown=True)[4]
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
for f in unknown:
if f in all_files:
util.unlink(repo.wjoin(f))
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):
Bryan O'Sullivan
mq: teach qpop about symlinks
r5157 def getfile(f, rev, flags):
mason@suse.com
Add mq extension
r1808 t = repo.file(f).read(rev)
Bryan O'Sullivan
mq: teach qpop about symlinks
r5157 repo.wwrite(f, t, flags)
mason@suse.com
Add mq extension
r1808
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 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
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if len(self.applied) == 0:
# 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()
Matt Mackall
mq: remove import of revlog
r7639 rr = [ bin(x.rev) 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:
parents = [p.hex() for p in repo[None].parents()]
needupdate = False
for entry in self.applied[start:]:
if entry.rev in parents:
needupdate = True
break
update = needupdate
mason@suse.com
Add mq extension
r1808
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if not force and update:
self.check_localchanges(repo)
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)
Matt Mackall
mq: remove import of revlog
r7639 rev = bin(self.applied[start].rev)
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)
Matt Mackall
mq: remove import of revlog
r7639 if heads != [bin(self.applied[-1].rev)]:
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)
changes = repo.changelog.read(qp)
mmap = repo.manifest.read(changes[0])
Matt Mackall
status: clean up all users for unknown files
r6760 m, a, r, d = repo.status(qp, top)[:4]
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:
os.unlink(repo.wjoin(f))
except OSError, e:
if e.errno != errno.ENOENT:
raise
try: os.removedirs(os.path.dirname(repo.wjoin(f)))
except: pass
repo.dirstate.forget(f)
Nicolas Dumazet
mq: qpop: remove added files before re-adding removed files...
r10048 for f in m:
getfile(f, mmap[f], mmap.flags(f))
for f in r:
getfile(f, mmap[f], mmap.flags(f))
for f in m + r:
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]
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 self.strip(repo, rev, update=False, backup='strip')
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if len(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):
mason@suse.com
Add mq extension
r1808 if len(self.applied) == 0:
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()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
self.check_toppatch(repo)
(top, patchfn) = (self.applied[-1].rev, self.applied[-1].name)
Matt Mackall
mq: remove import of revlog
r7639 top = bin(top)
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"))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 cparents = repo.changelog.parents(top)
patchparent = self.qparents(repo, top)
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 ph = patchheader(self.join(patchfn))
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)
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
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 tip = repo.changelog.tip()
if top == tip:
# if the top of our patch queue is also the tip, there is an
# optimization here. We update the dirstate in place and strip
# off the tip commit. Then just commit the current directory
# tree. We can also send repo.commit the list of files
# changed to speed up the diff
#
# in short mode, we only diff the files included in the
Mads Kiilerich
mq: Fix --qrefresh --short to work with --exclude and --include...
r7177 # patch already plus specified files
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 #
# this should really read:
Matt Mackall
status: clean up all users for unknown files
r6760 # mm, dd, aa, aa2 = repo.status(tip, patchparent)[:4]
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # but we do it backwards to take advantage of manifest/chlog
# caching against the next repo.status call
#
Matt Mackall
status: clean up all users for unknown files
r6760 mm, aa, dd, aa2 = repo.status(patchparent, tip)[:4]
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 changes = repo.changelog.read(tip)
man = repo.manifest.read(changes[0])
aaa = aa[:]
Mads Kiilerich
mq: Fix --qrefresh --short to work with --exclude and --include...
r7177 matchfn = cmdutil.match(repo, pats, opts)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if opts.get('short'):
Mads Kiilerich
mq: Fix --qrefresh --short to work with --exclude and --include...
r7177 # if amending a patch, we start with existing
# files plus specified files - unfiltered
Mads Kiilerich
mq: Allow qrefresh --silent to take parameters...
r7113 match = cmdutil.matchfiles(repo, mm + aa + dd + matchfn.files())
Mads Kiilerich
mq: Fix --qrefresh --short to work with --exclude and --include...
r7177 # filter with inc/exl options
matchfn = cmdutil.match(repo, opts=opts)
mason@suse.com
Add mq extension
r1808 else:
Matt Mackall
status: use match helpers for various users
r6599 match = cmdutil.matchall(repo)
Matt Mackall
status: clean up all users for unknown files
r6760 m, a, r, d = repo.status(match=match)[:4]
mason@suse.com
Add mq extension
r1808
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # we might end up with files that were added between
# tip 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:
mm.append(x)
# 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:
del dd[dd.index(x)]
mm.append(x)
else:
aa.append(x)
# 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:
del aa[aa.index(x)]
forget.append(x)
continue
elif x in mm:
del mm[mm.index(x)]
dd.append(x)
mason@suse.com
Add mq extension
r1808
Martin Geisler
util: use built-in set instead of util.unique
r8151 m = list(set(mm))
r = list(set(dd))
a = list(set(aa))
Matt Mackall
status: clean up all users for unknown files
r6760 c = [filter(matchfn, l) for l in (m, a, r)]
Martin Geisler
util: use built-in set instead of util.unique
r8151 match = cmdutil.matchfiles(repo, set(c[0] + c[1] + c[2]))
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 chunks = patch.diff(repo, patchparent, match=match,
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 changes=c, opts=diffopts)
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 for chunk in chunks:
patchf.write(chunk)
mason@suse.com
Add mq extension
r1808
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 try:
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190 if diffopts.git or diffopts.upgrade:
Patrick Mezard
mq: drop copy records when refreshing regular patches (issue1441)...
r7566 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 tip
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 for dst in aaa:
f = repo.file(dst)
src = f.renamed(man[dst])
if src:
copies.setdefault(src[0], []).extend(copies.get(dst, []))
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]
Patrick Mezard
mq: drop copy records when refreshing regular patches (issue1441)...
r7566 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)
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 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
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 if not msg:
if not ph.message:
message = "[mq]: %s\n" % patchfn
else:
message = "\n".join(ph.message)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 message = msg
user = ph.user or changes[1]
"Mathieu Clabaut "
MQ: uniformise message and logfile option....
r2694
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 # assumes strip can roll itself back if interrupted
repo.dirstate.setparents(*cparents)
self.applied.pop()
self.applied_dirty = 1
self.strip(repo, top, update=False,
backup='strip')
except:
repo.dirstate.invalidate()
raise
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 try:
# might be nice to attempt to roll back strip after this
patchf.rename()
Matt Mackall
commit: drop the now-unused files parameter
r8706 n = repo.commit(message, user, ph.date, match=match,
force=True)
Matt Mackall
mq: remove import of revlog
r7639 self.applied.append(statusentry(hex(n), patchfn))
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 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 else:
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 self.printdiff(repo, diffopts, patchparent, fp=patchf)
Brendan Cully
mq: use atomictempfiles during patch refresh
r7400 patchf.rename()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 added = repo.status()[1]
for a in added:
f = repo.wjoin(a)
try:
os.unlink(f)
except OSError, e:
if e.errno != errno.ENOENT:
raise
try: os.removedirs(os.path.dirname(f))
except: pass
# forget the file copies in the dirstate
# push should readd the files later on
repo.dirstate.forget(a)
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 self.pop(repo, force=True)
self.push(repo, force=True)
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):
Dan Villiom Podlaski Christiansen
mq: align columns in verbose qseries output.
r9016 def displayname(pfx, patchname):
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 if summary:
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 ph = patchheader(self.join(patchname))
Dan Villiom Podlaski Christiansen
qseries: don't truncate the patch name (issue1912)...
r9874 msg = ph.message and ph.message[0] or ''
if self.ui.interactive():
width = util.termwidth() - len(pfx) - len(patchname) - 2
if width > 0:
msg = util.ellipsis(msg, width)
else:
msg = ''
msg = "%s%s: %s" % (pfx, patchname, msg)
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 else:
Dan Villiom Podlaski Christiansen
qseries: don't truncate the patch name (issue1912)...
r9874 msg = pfx + patchname
Dan Villiom Podlaski Christiansen
mq: align columns in verbose qseries output.
r9016 self.ui.write(msg + '\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:
idxwidth = len(str(start+length - 1))
Benoit Boissinot
use xrange instead of range
r3473 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:
stat = 'A'
elif self.pushable(i)[0]:
stat = 'U'
else:
stat = 'G'
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:
Dan Villiom Podlaski Christiansen
mq: align columns in verbose qseries output.
r9016 pfx = '%*d %s ' % (idxwidth, i, stat)
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 elif status and status != stat:
Thomas Arendsen Hein
Fix issue443: inconsistent output of "hg qunapplied -v"...
r4238 continue
Dan Villiom Podlaski Christiansen
mq: align columns in verbose qseries output.
r9016 displayname(pfx, patch)
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 ''
Dan Villiom Podlaski Christiansen
mq: align columns in verbose qseries output.
r9016 displayname(pfx, x)
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):
Vadim Gelfer
mq: add join method
r2819 if create or os.path.isdir(self.join(".hg")):
Thomas Arendsen Hein
Create local ui object per repository, so .hg/hgrc don't get mixed....
r1839 return hg.repository(self.ui, path=self.path, create=create)
mason@suse.com
Add mq extension
r1808
def restore(self, repo, rev, delete=None, qupdate=None):
c = repo.changelog.read(rev)
desc = c[4].strip()
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(' ')
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 qpp = [ bin(x) for x in l ]
mason@suse.com
Add mq extension
r1808 elif datastart != None:
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 l = line.rstrip()
Brendan Cully
Make mq camelcase consistent with the rest of hg.
r2818 se = statusentry(l)
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 file_ = se.name
if se.rev:
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 applied.append(se)
Brendan Cully
mq: don't write applied patches into series twice in restore
r3185 else:
series.append(file_)
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
self.strip(repo, rev, update=update, backup='strip')
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:
Matt Mackall
transform a bunch of print statements to appropriate ui calls
r5878 self.ui.status(_("queue directory updating\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):
if len(self.applied) == 0:
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 ar = [ ':' + x for x in self.full_series ]
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"
Brendan Cully
Update qsave to use StatusEntry; don't throw exception on bad status lines.
r2816 text = msg + "\n".join([str(x) for x in self.applied]) + '\n' + (ar and
"\n".join(ar) + '\n' or "")
Matt Mackall
commit: drop the now-unused files parameter
r8706 n = repo.commit(text, 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
Matt Mackall
mq: remove import of revlog
r7639 self.applied.append(statusentry(hex(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):
if len(self.applied) > 0:
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):
if all_patches:
return start
i = start
while i < len(self.series):
p, reason = self.pushable(i)
if p:
break
self.explain_pushable(i)
i += 1
return i
mason@suse.com
Add mq extension
r1808 if len(self.applied) > 0:
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)
def checkfile(patchname):
if not force and os.path.exists(self.join(patchname)):
raise util.Abort(_('patch "%s" already exists')
% patchname)
if rev:
if files:
raise util.Abort(_('option "-r" not valid when importing '
'files'))
Thomas Arendsen Hein
Removed unused ui parameter from revpair/revrange and fix its users.
r3707 rev = cmdutil.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'))
mason@suse.com
Add mq extension
r1808 i = 0
Vadim Gelfer
mq: add qimported patches if patch dir is a repo
r2488 added = []
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 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:
Matt Mackall
mq: remove import of revlog
r7639 base = hex(repo.changelog.node(rev[0]))
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 if base in [n.rev for n in self.applied]:
raise util.Abort(_('revision %d is already managed')
% rev[0])
Matt Mackall
mq: remove import of revlog
r7639 if heads != [bin(self.applied[-1].rev)]:
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])
Matt Mackall
mq: remove import of revlog
r7639 base = repo.changelog.rev(bin(self.applied[0].rev))
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)
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981 self.check_reserved_name(patchname)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 checkseries(patchname)
checkfile(patchname)
self.full_series.insert(0, patchname)
patchf = self.opener(patchname, "w")
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 patch.export(repo, [n], fp=patchf, opts=diffopts)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 patchf.close()
Matt Mackall
mq: remove import of revlog
r7639 se = statusentry(hex(n), patchname)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 self.applied.insert(0, se)
added.append(patchname)
patchname = None
self.parse_series()
self.applied_dirty = 1
mason@suse.com
Add mq extension
r1808 for filename in files:
if existing:
Brendan Cully
mq: support qimport -
r3547 if filename == '-':
raise util.Abort(_('-e is incompatible with import from -'))
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 if not patchname:
Patrick Mezard
Enforce unixish style for all generated patch names....
r4037 patchname = normname(filename)
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981 self.check_reserved_name(patchname)
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 if not os.path.isfile(self.join(patchname)):
raise util.Abort(_("patch %s does not exist") % patchname)
mason@suse.com
Add mq extension
r1808 else:
try:
Brendan Cully
mq: support qimport -
r3547 if filename == '-':
if not patchname:
raise util.Abort(_('need --name to import a patch from -'))
text = sys.stdin.read()
else:
Benoit Boissinot
use our urlopener (proxy handling, etc) instead of urllib
r7271 text = url.open(self.ui, filename).read()
Benoit Boissinot
Catch both IOError and OSError, fix regression introduced by 8046f0a070a6
r7421 except (OSError, IOError):
Martin Geisler
qimport: report filename in case of IOError...
r6940 raise util.Abort(_("unable to read %s") % filename)
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 if not patchname:
Patrick Mezard
Enforce unixish style for all generated patch names....
r4037 patchname = normname(os.path.basename(filename))
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981 self.check_reserved_name(patchname)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 checkfile(patchname)
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)
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()
Martin Geisler
mq, i18n: mark strings for translation
r7597 self.ui.warn(_("adding %s to series file\n") % patchname)
mason@suse.com
Add mq extension
r1808 i += 1
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 added.append(patchname)
patchname = None
mason@suse.com
Add mq extension
r1808 self.series_dirty = 1
Vadim Gelfer
mq: add qimported patches if patch dir is a repo
r2488 qrepo = self.qrepo()
if qrepo:
qrepo.add(added)
mason@suse.com
Add mq extension
r1808
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,
use the 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
def applied(ui, repo, patch=None, **opts):
"""print the patches already applied"""
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 l = len(q.applied)
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
return q.qseries(repo, length=end, start=start, status='A',
summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808
def unapplied(ui, repo, patch=None, **opts):
"""print the patches not yet applied"""
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
return q.qseries(repo, start=start, length=length, status='U',
summary=opts.get('summary'))
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
changes.
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.
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
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 q.qimport(repo, filename, patchname=opts['name'],
Brendan Cully
mq: add --git option to qimport -r
r3691 existing=opts['existing'], force=opts['force'], rev=opts['rev'],
git=opts['git'])
mason@suse.com
Add mq extension
r1808 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
def init(ui, repo, **opts):
Brendan Cully
Add more verbose help text to mq commands.
r2754 """init a new queue repository
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 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."""
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.init(repo, create=opts['create_repo'])
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()
mason@suse.com
Add mq extension
r1808 r.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
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
Brendan Cully
mq: improve qclone error handling when patch directory is not a repository.
r4862 would be created by qinit -c.
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
add cmdutil.remoteui...
r8188 sr = hg.repository(cmdutil.remoteui(ui, opts), ui.expandpath(source))
John Mulligan
mq: allow qclone's -p option to use path alias...
r7729 if opts['patches']:
patchespath = ui.expandpath(opts['patches'])
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'
' (see qinit -c)'))
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:
Matt Mackall
mq: remove import of revlog
r7639 qbase = bin(sr.mq.applied[0].rev)
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,
Vadim Gelfer
mq: add qclone command
r2720 pull=opts['pull'],
rev=destrev,
update=False,
stream=opts['uncompressed'])
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('cloning patch repository\n'))
Peter Arrenbrecht
cleanup: drop variables for unused return values...
r7874 hg.clone(ui, opts['patches'] or patchdir(sr), patchdir(dr),
pull=opts['pull'], update=not opts['noupdate'],
stream=opts['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'))
Vadim Gelfer
mq: update to handle repomap not longer used
r2725 dr.mq.strip(dr, qbase, update=False, backup=None)
Vadim Gelfer
mq: add qclone command
r2720 if not opts['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
mason@suse.com
Add mq extension
r1808 def commit(ui, repo, *pats, **opts):
Thomas Arendsen Hein
mq: Added help for qcommit, consistently talk about queue repository.
r2526 """commit changes in the queue repository"""
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()
if not r: raise util.Abort('no queue repository')
commands.commit(r.ui, r, *pats, **opts)
def series(ui, repo, **opts):
"""print the entire series file"""
Brendan Cully
Add -s option to qseries: display first line of patch header.
r2756 repo.mq.qseries(repo, missing=opts['missing'], summary=opts['summary'])
mason@suse.com
Add mq extension
r1808 return 0
def top(ui, repo, **opts):
"""print the name of the current patch"""
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:
return q.qseries(repo, start=t-1, length=1, status='A',
summary=opts.get('summary'))
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
def next(ui, repo, **opts):
"""print the name of the next patch"""
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
return q.qseries(repo, start=end, length=1, summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808
def prev(ui, repo, **opts):
"""print the name of the previous patch"""
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
return 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
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
any). It will refuse to run if there are any outstanding changes
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 unless -f/--force is specified, in which case the patch will be
initialized with them. You may also use -I/--include,
-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.
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)
def getmsg(): return ui.edit(msg, 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
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
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.
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)
Brendan Cully
Add option -e/--edit to qrefresh, to edit the existing header.
r2746 if opts['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
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 ph = patchheader(q.join(patch))
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 message = ui.edit('\n'.join(ph.message), ph.user or ui.username())
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
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
mq: word-wrap help texts at 70 characters
r7994 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
qrefresh.
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
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
current patch header, separated by a line of '* * *'."""
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]:
Thomas Arendsen Hein
Never apply string formatting to generated errors with util.Abort....
r3072 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)
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 if opts['edit']:
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:
ui.warn(_('Skipping already folded patch %s') % p)
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:
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 ph = patchheader(q.join(p))
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:
Brendan Cully
Fix qfold after recent changes
r2936 raise util.Abort(_('Error folding patch %s') % p)
patch.updatedir(ui, repo, files)
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:
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 ph = patchheader(q.join(parent))
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)
if opts['edit']:
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()
Bryan O'Sullivan
mq: add qgoto command.
r4432 def goto(ui, repo, patch, **opts):
'''push or pop patches until named patch is at top of stack'''
q = repo.mq
patch = q.lookup(patch)
if q.isapplied(patch):
ret = q.pop(repo, patch, force=opts['force'])
else:
ret = q.push(repo, patch, force=opts['force'])
q.save_dirty()
return ret
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
pushed only if the qselect command has activated it. A patch with
a negative guard ("-foo") is never pushed if the qselect command
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.
Augie Fackler
fancyopts: Parse options that occur after arguments....
r7772 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::
Augie Fackler
fancyopts: Parse options that occur after arguments....
r7772 hg qguard -- other.patch +2.6.17 -stable
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 '''
def status(idx):
guards = q.series_guards[idx] or ['unguarded']
ui.write('%s: %s\n' % (q.series[idx], ' '.join(guards)))
q = repo.mq
patch = None
args = list(args)
if opts['list']:
if args or opts['none']:
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'))
if args or opts['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)))
Brendan Cully
Add command qheader to display the header of a given patch.
r2747 def header(ui, repo, patch=None):
Martin Geisler
lowercase help output...
r7598 """print the header of the topmost or specified patch"""
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:
Martin Geisler
mq: lowercase output...
r7627 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')
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 ph = patchheader(repo.mq.join(patch))
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
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.
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
mason@suse.com
Add mq extension
r1808 if opts['merge']:
if opts['name']:
teki321@gmail.com
mq: qpush -n fix
r6627 newpath = repo.join(opts['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)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 ret = q.push(repo, patch, force=opts['force'], list=opts['list'],
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 mergeq=mergeq, all=opts.get('all'))
mason@suse.com
Add mq extension
r1808 return ret
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.
Dirkjan Ochtman
mq: add correct documentation for qpop
r6611 """
mason@suse.com
Add mq extension
r1808 localupdate = True
if opts['name']:
q = queue(ui, repo.join(""), repo.join(opts['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
Alexis S. L. Carvalho
mq: propagate the return error of pop
r4099 ret = q.pop(repo, patch, force=opts['force'], update=localupdate,
all=opts['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
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.
With two arguments, renames PATCH1 to PATCH2."""
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)
if os.path.exists(absdest):
raise util.Abort(_('%s already exists') % absdest)
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Brendan Cully
Make qrename handle directory targets; closes #333.
r3083 if name in q.series:
raise util.Abort(_('A patch named %s already exists in the series file') % name)
Brendan Cully
New self-explanatory command qrename.
r2750
if ui.verbose:
Martin Geisler
mq: lowercase output...
r7627 ui.write('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
Vadim Gelfer
mq: add join method
r2819 util.rename(q.join(patch), absdest)
Brendan Cully
New self-explanatory command qrename.
r2750 r = q.qrepo()
if r:
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':
r.undelete([name])
r.copy(patch, name)
r.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()
mason@suse.com
Add mq extension
r1808 def restore(ui, repo, rev, **opts):
Martin Geisler
expand "rev" to "revision" in help texts
r8028 """restore the queue state saved by a revision"""
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
mason@suse.com
Add mq extension
r1808 q.restore(repo, rev, delete=opts['delete'],
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 qupdate=opts['update'])
mason@suse.com
Add mq extension
r1808 q.save_dirty()
return 0
def save(ui, repo, **opts):
"""save current queue state"""
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()
if opts['copy']:
path = q.path
if opts['name']:
newpath = os.path.join(q.basepath, opts['name'])
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)
mason@suse.com
Add mq extension
r1808 if not opts['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)
if opts['empty']:
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
mason@suse.com
Add mq extension
r1808 def strip(ui, repo, rev, **opts):
Dirkjan Ochtman
mq: don't update the working copy on strip if parents aren't stripped...
r6635 """strip a revision and all its descendants from the repository
Martin Geisler
expand "dir" to "directory" in help texts
r8026 If one of the working directory's parent revisions is stripped, the
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 working directory will be updated to the parent of the stripped
revision.
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'
if opts['backup']:
backup = 'strip'
elif opts['nobackup']:
backup = 'none'
Dirkjan Ochtman
mq: don't update the working copy on strip if parents aren't stripped...
r6635
rev = repo.lookup(rev)
p = repo.dirstate.parents()
cl = repo.changelog
update = True
Matt Mackall
mq: remove import of revlog
r7639 if p[0] == nullid:
Dirkjan Ochtman
mq: don't update the working copy on strip if parents aren't stripped...
r6635 update = False
Matt Mackall
mq: remove import of revlog
r7639 elif p[1] == nullid and rev != cl.ancestor(p[0], rev):
Dirkjan Ochtman
mq: don't update the working copy on strip if parents aren't stripped...
r6635 update = False
elif rev not in (cl.ancestor(p[0], rev), cl.ancestor(p[1], rev)):
update = False
Dirkjan Ochtman
mq: add --force option to strip
r6472 repo.mq.strip(repo, rev, backup=backup, update=update, force=opts['force'])
mason@suse.com
Add mq extension
r1808 return 0
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def select(ui, repo, *args, **opts):
'''set or print guarded patches to push
Brendan Cully
mq help text updates and speling fixes
r2940 Use the 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
Brendan Cully
mq help text updates and speling fixes
r2940 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
(no other arguments needed). Use -v for more information.'''
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
q = repo.mq
guards = q.active()
if args or opts['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'))
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 if not opts['pop'] and not opts['reapply']:
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)))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 elif opts['series']:
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'))
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 reapply = opts['reapply'] and q.applied and q.appliedname(-1)
popped = False
if opts['pop'] or opts['reapply']:
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:
q.pop(repo, i-1)
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
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.
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 """
if not opts['applied'] and not revrange:
raise util.Abort(_('no revisions specified'))
elif opts['applied']:
revrange = ('qbase:qtip',) + revrange
q = repo.mq
if not q.applied:
ui.status(_('no patches applied\n'))
return 0
revs = cmdutil.revrange(repo, revrange)
q.finish(repo, revs)
q.save_dirty()
return 0
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:
Matt Mackall
mq: remove import of revlog
r7639 parent = hex(self.dirstate.parents()[0])
Vadim Gelfer
mq: do not allow to push from repo with patches applied
r2848 if parent in [s.rev for s in self.mq.applied]:
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
Vadim Gelfer
mq: do not allow to push from repo with patches applied
r2848 def push(self, remote, force=False, revs=None):
Brendan Cully
mq: allow push if -r is given explicitly
r4040 if self.mq.applied and not force and not revs:
Vadim Gelfer
mq: do not allow to push from repo with patches applied
r2848 raise util.Abort(_('source has mq patches applied'))
return super(mqrepo, self).push(remote, 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
Matt Mackall
mq: remove import of revlog
r7639 mqtags = [(bin(patch.rev), patch.name) for patch in q.applied]
Alexis S. L. Carvalho
mqrepo: don't abort if the status file has an unknown node
r5979
if mqtags[-1][0] not in self.changelog.nodemap:
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
Matt Mackall
mq: remove import of revlog
r7639 qbasenode = bin(q.applied[0].rev)
Alexis S. L. Carvalho
mqrepo: don't abort if the status file has an unknown node
r5979 if qbasenode not in cl.nodemap:
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
Alexis S. L. Carvalho
mqrepo: don't abort if the status file has an unknown node
r5979 qbase = cl.rev(qbasenode)
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
self._updatebranchcache(partial, lrev+1, qbase)
self._writebranchcache(partial, cl.node(qbase-1), qbase-1)
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
Matt Mackall
add __len__ and __iter__ methods to repo and revlog
r6750 self._updatebranchcache(partial, start, len(cl))
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):
Brendan Cully
Allow import --no-commit over an applied MQ patch....
r9867 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
Prevent import over an applied patch (closes issue795)
r7142 def uisetup(ui):
Matt Mackall
extensions: use new wrapper functions
r7216 extensions.wrapcommand(commands.table, 'import', mqimport)
Brendan Cully
Prevent import over an applied patch (closes issue795)
r7142
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
mason@suse.com
Add mq extension
r1808 cmdtable = {
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364 "qapplied":
(applied,
[('1', 'last', None, _('show only the last patch'))] + seriesopts,
Thomas Arendsen Hein
Add new flag [-1] to synopsis of qapplied/qunapplied
r9438 _('hg qapplied [-1] [-s] [PATCH]')),
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 "qclone":
(clone,
[('', '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)')),
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ('p', 'patches', '', _('location of source patch repository')),
Benoit Boissinot
refactor options from cmdtable...
r5147 ] + commands.remoteopts,
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 _('hg qclone [OPTION]... SOURCE [DEST]')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "qcommit|qci":
(commit,
Thomas Arendsen Hein
Better help for mq: Corrected synopses, get qcommit options from commands.py.
r2185 commands.table["^commit|ci"][1],
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 _('hg qcommit [OPTION]... [FILE]...')),
"^qdiff":
(diff,
Jason Orendorff
mq: qdiff: support all diffopts
r6668 commands.diffopts + commands.diffopts2 + commands.walkopts,
_('hg qdiff [OPTION]... [FILE]...')),
Brendan Cully
Replace qdel/qfold -f option with -k/--keep.
r2904 "qdelete|qremove|qrm":
Brendan Cully
Add -f option to qdelete, to remove patch file.
r2752 (delete,
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 [('k', 'keep', None, _('keep patch file')),
Cédric Duval
mq: no longer mention the deprecated qdelete's --revision option...
r8904 ('r', 'rev', [], _('stop managing a revision (DEPRECATED)'))],
Brendan Cully
mq: more qdelete help text tweaks
r4737 _('hg qdelete [-k] [-r REV]... [PATCH]...')),
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 'qfold':
(fold,
[('e', 'edit', None, _('edit patch header')),
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 ('k', 'keep', None, _('keep folded patch files')),
] + commands.commitopts,
_('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...')),
'qgoto':
(goto,
[('f', 'force', None, _('overwrite any local changes'))],
_('hg qgoto [OPTION]... PATCH')),
'qguard':
(guard,
[('l', 'list', None, _('list all patches and guards')),
('n', 'none', None, _('drop all guards'))],
Augie Fackler
fancyopts: Parse options that occur after arguments....
r7772 _('hg qguard [-l] [-n] -- [PATCH] [+GUARD]... [-GUARD]...')),
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 'qheader': (header, [], _('hg qheader [PATCH]')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "^qimport":
(qimport,
Martin Geisler
expand "dir" to "directory" in help texts
r8026 [('e', 'existing', None, _('import file in patch directory')),
timeless
Generally replace "file name" with "filename" in help and comments.
r8761 ('n', 'name', '', _('name of patch file')),
Martin Geisler
i18n, mq: mark command line options for translation
r7002 ('f', 'force', None, _('overwrite existing files')),
('r', 'rev', [], _('place existing revisions under mq control')),
Dirkjan Ochtman
mq: add -P/--push option to qimport
r8362 ('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...')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "^qinit":
(init,
Martin Geisler
i18n, mq: mark command line options for translation
r7002 [('c', 'create-repo', None, _('create queue repository'))],
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 _('hg qinit [-c]')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "qnew":
(new,
Brendan Cully
Add qnew -e option.
r2939 [('e', 'edit', None, _('edit commit message')),
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 ('f', 'force', None, _('import uncommitted changes into patch')),
Patrick Mezard
mq: add qnew --git option
r5025 ('g', 'git', None, _('use git extended diff format')),
Peter Arrenbrecht
mq: fix docs for qrefresh -D (issue1234)
r6915 ('U', 'currentuser', None, _('add "From: <current user>" to patch')),
('u', 'user', '', _('add "From: <given user>" to patch')),
('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
('d', 'date', '', _('add "Date: <given date>" to patch'))
] + commands.walkopts + commands.commitopts,
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 _('hg qnew [-e] [-m TEXT] [-l FILE] [-f] PATCH [FILE]...')),
"qnext": (next, [] + seriesopts, _('hg qnext [-s]')),
"qprev": (prev, [] + seriesopts, _('hg qprev [-s]')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "^qpop":
(pop,
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 [('a', 'all', None, _('pop all patches')),
Dirkjan Ochtman
Backed out changeset ff5ef3c0fe10 (fixes wrong documentation)
r6610 ('n', 'name', '', _('queue name to pop')),
Stephen Rasku
mq: changed help for qpop -f to reflect actual behaviour
r9588 ('f', 'force', None, _('forget any local changes to patched files'))],
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 _('hg qpop [-a] [-n NAME] [-f] [PATCH | INDEX]')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "^qpush":
(push,
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 [('f', 'force', None, _('apply if the patch has rejects')),
('l', 'list', None, _('list patch name in commit text')),
('a', 'all', None, _('apply all patches')),
('m', 'merge', None, _('merge from another queue')),
('n', 'name', '', _('merge queue name'))],
_('hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "^qrefresh":
(refresh,
Brendan Cully
Add option -e/--edit to qrefresh, to edit the existing header.
r2746 [('e', 'edit', None, _('edit commit message')),
Brendan Cully
mq: Add --git option to qrefresh
r3086 ('g', 'git', None, _('use git extended diff format')),
Mads Kiilerich
mq: Allow qrefresh --silent to take parameters...
r7113 ('s', 'short', None, _('refresh only files already in the patch and specified files')),
Yann E. MORIN
mq: re-phrase the qrefresh help about the user and date options
r9338 ('U', 'currentuser', None, _('add/update author field in patch with current user')),
('u', 'user', '', _('add/update author field in patch with given user')),
('D', 'currentdate', None, _('add/update date field in patch with current date')),
('d', 'date', '', _('add/update date field in patch with given date'))
Peter Arrenbrecht
mq: fix docs for qrefresh -D (issue1234)
r6915 ] + commands.walkopts + commands.commitopts,
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...')),
Vadim Gelfer
mq: add qmv as alias for qrename
r2751 'qrename|qmv':
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 (rename, [], _('hg qrename PATCH1 [PATCH2]')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "qrestore":
(restore,
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 [('d', 'delete', None, _('delete save entry')),
Martin Geisler
expand "dir" to "directory" in help texts
r8026 ('u', 'update', None, _('update queue working directory'))],
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 _('hg qrestore [-d] [-u] REV')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "qsave":
(save,
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 [('c', 'copy', None, _('copy patch directory')),
('n', 'name', '', _('copy directory 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]')),
"qselect":
(select,
[('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]...')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "qseries":
(series,
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 [('m', 'missing', None, _('print patches not in series')),
] + seriesopts,
_('hg qseries [-ms]')),
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 "^strip":
(strip,
Dirkjan Ochtman
mq: add --force option to strip
r6472 [('f', 'force', None, _('force removal with local changes')),
('b', 'backup', None, _('bundle unrelated changesets')),
Thomas Arendsen Hein
Updated command tables in commands.py and hgext extensions....
r4730 ('n', 'nobackup', None, _('no backups'))],
_('hg strip [-f] [-b] [-n] REV')),
"qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364 "qunapplied":
(unapplied,
[('1', 'first', None, _('show only the first patch'))] + seriesopts,
Thomas Arendsen Hein
Add new flag [-1] to synopsis of qapplied/qunapplied
r9438 _('hg qunapplied [-1] [-s] [PATCH]')),
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 "qfinish":
(finish,
[('a', 'applied', None, _('finish all applied changesets'))],
Martin Geisler
mq: standardize qfinish cmdline help string
r8948 _('hg qfinish [-a] [REV]...')),
mason@suse.com
Add mq extension
r1808 }