##// END OF EJS Templates
treediscovery: use progress helper...
treediscovery: use progress helper Differential Revision: https://phab.mercurial-scm.org/D3801

File last commit:

r38061:558e5504 default
r38419:2f5c622f @47 default
Show More
mq.py
3668 lines | 134.6 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
Yuya Nishihara
help: uppercase command placeholder...
r30879 Common tasks (use :hg:`help COMMAND` for more details)::
Vadim Gelfer
help: add help to mq extension
r2554
Martin Geisler
commands: use minirst parser when displaying help
r9157 create new patch qnew
import existing patch qimport
Vadim Gelfer
help: add help to mq extension
r2554
Martin Geisler
commands: use minirst parser when displaying help
r9157 print patch series qseries
print applied patches qapplied
Vadim Gelfer
help: add help to mq extension
r2554
Martin Geisler
commands: use minirst parser when displaying help
r9157 add known patch to applied stack qpush
remove patch from applied stack qpop
refresh contents of top applied patch qrefresh
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190
By default, mq will automatically use git patches when required to
avoid losing file mode changes, copy records, binary files or empty
timeless@mozdev.org
spelling: behaviour -> behavior
r26098 files creations or deletions. This behavior can be configured with::
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190
[mq]
git = auto/keep/yes/no
If set to 'keep', mq will obey the [diff] section configuration while
preserving existing git patches upon qrefresh. If set to 'yes' or
'no', mq will override the [diff] section and always generate git or
regular patches, possibly losing data in the second case.
Martin Geisler
mq: mention qqueue in module docstring
r11234
Matt Mackall
mq: fix secret description in help
r16040 It may be desirable for mq changesets to be kept in the secret phase (see
Matt Mackall
mq: add secret setting
r16017 :hg:`help phases`), which can be enabled with the following setting::
[mq]
secret = True
Martin Geisler
mq: mention qqueue in module docstring
r11234 You will by default be managing a patch queue named "patches". You can
create other, independent patch queues with the :hg:`qqueue` command.
Patrick Mezard
mq: introduce mq.check setting...
r16656
If the working directory contains uncommitted files, qpush, qpop and
qgoto abort immediately. If -f/--force is used, the changes are
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 discarded. Setting::
Patrick Mezard
mq: introduce mq.check setting...
r16656
[mq]
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 keepchanges = True
make them behave as if --keep-changes were passed, and non-conflicting
Patrick Mezard
mq: introduce mq.check setting...
r16656 local changes will be tolerated and preserved. If incompatible options
such as -f/--force or --exact are passed, this setting is ignored.
Pierre-Yves David
mq: extract strip function as its standalone extension (issue3824)...
r19826
This extension used to provide a strip command. This command now lives
in the strip extension.
Vadim Gelfer
help: add help to mq extension
r2554 '''
Yuya Nishihara
doctest: use print_function and convert bytes to unicode where needed
r34139 from __future__ import absolute_import, print_function
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127
import errno
import os
import re
import shutil
Matt Mackall
Simplify i18n imports
r3891 from mercurial.i18n import _
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127 from mercurial.node import (
bin,
hex,
nullid,
nullrev,
short,
)
from mercurial import (
cmdutil,
commands,
Augie Fackler
mq: refer to dirstateguard by its new name
r30489 dirstateguard,
Augie Fackler
python3: wrap all uses of <exception>.strerror with strtolocal...
r34024 encoding,
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127 error,
extensions,
hg,
localrepo,
lock as lockmod,
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 logcmdutil,
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127 patch as patchmod,
phases,
Pulkit Goyal
py3: use pycompat.getcwd() instead of os.getcwd()...
r30519 pycompat,
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127 registrar,
Yuya Nishihara
revset: split language services to revsetlang module (API)...
r31024 revsetlang,
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127 scmutil,
Yuya Nishihara
revset: import set classes directly from smartset module...
r31023 smartset,
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 subrepoutil,
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127 util,
Pierre-Yves David
vfs: use 'vfs' module directly in 'hgext.mq'...
r31243 vfs as vfsmod,
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127 )
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 from mercurial.utils import (
dateutil,
stringutil,
)
Pulkit Goyal
py3: make hgext/mq.py use absolute_import
r29127
release = lockmod.release
Martin Geisler
mq: use cmdutil.command decorator
r14298 seriesopts = [('s', 'summary', None, _('print first line of patch header'))]
cmdtable = {}
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 command = registrar.command(cmdtable)
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
Augie Fackler
extensions: document that `testedwith = 'internal'` is special...
r25186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 testedwith = 'ships-with-hg-core'
Martin Geisler
mq: use cmdutil.command decorator
r14298
Boris Feld
configitems: register the 'mq.git' config
r34182 configtable = {}
configitem = registrar.configitem(configtable)
configitem('mq', 'git',
default='auto',
)
Boris Feld
configitems: register the 'mq.keepchanges' config
r34183 configitem('mq', 'keepchanges',
default=False,
)
Boris Feld
configitems: register the 'mq.plain' config
r34184 configitem('mq', 'plain',
default=False,
)
Boris Feld
configitems: register the 'mq.secret' config
r34185 configitem('mq', 'secret',
default=False,
)
Boris Feld
configitems: register the 'mq.git' config
r34182
Mads Kiilerich
spelling: random spell checker fixes
r19951 # force load strip extension formerly included in mq and import some utility
Pierre-Yves David
mq: prepare a strip extension for extraction...
r19822 try:
stripext = extensions.find('strip')
except KeyError:
# note: load is lazy so we could avoid the try-except,
Mads Kiilerich
spelling: random spell checker fixes
r19951 # but I (marmoute) prefer this explicit code.
Pierre-Yves David
mq: prepare a strip extension for extraction...
r19822 class dummyui(object):
def debug(self, msg):
pass
stripext = extensions.load(dummyui(), 'strip', '')
Pierre-Yves David
strip: move the strip helper function for mq to strip...
r19825 strip = stripext.strip
Pierre-Yves David
strip: move checksubstate from mq to strip...
r19823 checksubstate = stripext.checksubstate
Pierre-Yves David
strip: move checklocalchanges from mq to strip...
r19824 checklocalchanges = stripext.checklocalchanges
Pierre-Yves David
strip: move checksubstate from mq to strip...
r19823
Patrick Mezard
Enforce unixish style for all generated patch names....
r4037 # Patch names looks like unix-file names.
# They must be joinable with queue directory and result in the patch path.
normname = util.normpath
Benoit Boissinot
use new style classes
r8778 class statusentry(object):
Benoit Boissinot
mq: simplify statusentry(), fix restore broken by ee48e5ef8753
r10682 def __init__(self, node, name):
self.node, self.name = node, name
Augie Fackler
mq: fix up statusentry to be both repr()-able and bytes()-able...
r35860
def __bytes__(self):
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 return hex(self.node) + ':' + self.name
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780
Augie Fackler
mq: fix up statusentry to be both repr()-able and bytes()-able...
r35860 __str__ = encoding.strmethod(__bytes__)
__repr__ = encoding.strmethod(__bytes__)
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 # The order of the headers in 'hg export' HG patches:
HGHEADERS = [
# '# HG changeset patch',
'# User ',
'# Date ',
'# ',
'# Branch ',
'# Node ID ',
'# Parent ', # can occur twice for merges - but that is not relevant for mq
]
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 # The order of headers in plain 'mail style' patches:
PLAINHEADERS = {
'from': 0,
'date': 1,
'subject': 2,
}
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546
def inserthgheader(lines, header, value):
"""Assuming lines contains a HG patch header, add a header line with value.
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> try: inserthgheader([], b'# Date ', b'z')
Yuya Nishihara
doctest: upgrade old-style "except" clause
r34140 ... except ValueError as inst: print("oops")
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 oops
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> inserthgheader([b'# HG changeset patch'], b'# Date ', b'z')
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 ['# HG changeset patch', '# Date z']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> inserthgheader([b'# HG changeset patch', b''], b'# Date ', b'z')
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 ['# HG changeset patch', '# Date z', '']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> inserthgheader([b'# HG changeset patch', b'# User y'], b'# Date ', b'z')
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 ['# HG changeset patch', '# User y', '# Date z']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> inserthgheader([b'# HG changeset patch', b'# Date x', b'# User y'],
... b'# User ', b'z')
Mads Kiilerich
mq: fix update of headers that occur in the "wrong" order...
r23412 ['# HG changeset patch', '# Date x', '# User z']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> inserthgheader([b'# HG changeset patch', b'# Date y'], b'# Date ', b'z')
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 ['# HG changeset patch', '# Date z']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> inserthgheader([b'# HG changeset patch', b'', b'# Date y'],
... b'# Date ', b'z')
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 ['# HG changeset patch', '# Date z', '', '# Date y']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> inserthgheader([b'# HG changeset patch', b'# Parent y'],
... b'# Date ', b'z')
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 ['# HG changeset patch', '# Date z', '# Parent y']
"""
start = lines.index('# HG changeset patch') + 1
newindex = HGHEADERS.index(header)
Mads Kiilerich
mq: fix update of headers that occur in the "wrong" order...
r23412 bestpos = len(lines)
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 for i in range(start, len(lines)):
line = lines[i]
Mads Kiilerich
mq: fix update of headers that occur in the "wrong" order...
r23412 if not line.startswith('# '):
bestpos = min(bestpos, i)
break
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 for lineindex, h in enumerate(HGHEADERS):
if line.startswith(h):
if lineindex == newindex:
lines[i] = header + value
Mads Kiilerich
mq: fix update of headers that occur in the "wrong" order...
r23412 return lines
if lineindex > newindex:
bestpos = min(bestpos, i)
break # next line
lines.insert(bestpos, header + value)
Mads Kiilerich
mq: refactor patchheader header ordering to match export (BC)...
r22546 return lines
Mads Kiilerich
mq: introduce insertplainheader - same naive implementation as before
r23345 def insertplainheader(lines, header, value):
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 """For lines containing a plain patch header, add a header line with value.
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> insertplainheader([], b'Date', b'z')
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 ['Date: z']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> insertplainheader([b''], b'Date', b'z')
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 ['Date: z', '']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> insertplainheader([b'x'], b'Date', b'z')
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 ['Date: z', '', 'x']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> insertplainheader([b'From: y', b'x'], b'Date', b'z')
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 ['From: y', 'Date: z', '', 'x']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> insertplainheader([b' date : x', b' from : y', b''], b'From', b'z')
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 [' date : x', 'From: z', '']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> insertplainheader([b'', b'Date: y'], b'Date', b'z')
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 ['Date: z', '', 'Date: y']
Yuya Nishihara
doctest: bulk-replace string literals with b'' for Python 3...
r34133 >>> insertplainheader([b'foo: bar', b'DATE: z', b'x'], b'From', b'y')
Mads Kiilerich
mq: smarter handling of plain headers...
r23442 ['From: y', 'foo: bar', 'DATE: z', '', 'x']
"""
newprio = PLAINHEADERS[header.lower()]
bestpos = len(lines)
for i, line in enumerate(lines):
if ':' in line:
lheader = line.split(':', 1)[0].strip().lower()
lprio = PLAINHEADERS.get(lheader, newprio + 1)
if lprio == newprio:
lines[i] = '%s: %s' % (header, value)
return lines
if lprio > newprio and i < bestpos:
bestpos = i
else:
if line:
lines.insert(i, '')
if i < bestpos:
bestpos = i
break
lines.insert(bestpos, '%s: %s' % (header, value))
Mads Kiilerich
mq: introduce insertplainheader - same naive implementation as before
r23345 return lines
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 class patchheader(object):
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 def __init__(self, pf, plainmode=False):
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 def eatdiff(lines):
while lines:
l = lines[-1]
if (l.startswith("diff -") or
l.startswith("Index:") or
l.startswith("===========")):
del lines[-1]
else:
break
def eatempty(lines):
while lines:
Benoit Boissinot
mq: don't use regexp when not necessary
r10688 if not lines[-1].strip():
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 del lines[-1]
else:
break
message = []
comments = []
user = None
date = None
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 parent = None
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 format = None
subject = None
Steve Borho
mq: record more data in patchheader class (no behavior changes)...
r13229 branch = None
nodeid = None
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 diffstart = 0
Pulkit Goyal
py3: use open() instead of file()...
r35936 for line in open(pf, 'rb'):
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 line = line.rstrip()
Benoit Boissinot
mq: allow lines starting with '--- ' in patch messages
r10730 if (line.startswith('diff --git')
or (diffstart and line.startswith('+++ '))):
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 diffstart = 2
break
Benoit Boissinot
mq: allow lines starting with '--- ' in patch messages
r10730 diffstart = 0 # reset
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 if line.startswith("--- "):
diffstart = 1
continue
elif format == "hgpatch":
# parse values when importing the result of an hg export
if line.startswith("# User "):
user = line[7:]
elif line.startswith("# Date "):
date = line[7:]
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 elif line.startswith("# Parent "):
Mads Kiilerich
mq: write '# Parent ' lines with two spaces like export does (BC)...
r22521 parent = line[9:].lstrip() # handle double trailing space
Steve Borho
mq: record more data in patchheader class (no behavior changes)...
r13229 elif line.startswith("# Branch "):
branch = line[9:]
elif line.startswith("# Node ID "):
nodeid = line[10:]
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 elif not line.startswith("# ") and line:
message.append(line)
format = None
elif line == '# HG changeset patch':
David Soria Parra
mq: Parse commit message after we find start of changeset patch...
r9287 message = []
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 format = "hgpatch"
elif (format != "tagdone" and (line.startswith("Subject: ") or
line.startswith("subject: "))):
subject = line[9:]
format = "tag"
elif (format != "tagdone" and (line.startswith("From: ") or
line.startswith("from: "))):
user = line[6:]
format = "tag"
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 elif (format != "tagdone" and (line.startswith("Date: ") or
line.startswith("date: "))):
date = line[6:]
format = "tag"
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 elif format == "tag" and line == "":
# when looking for tags (subject: from: etc) they
# end once you find a blank line in the source
format = "tagdone"
elif message or line:
message.append(line)
comments.append(line)
eatdiff(message)
eatdiff(comments)
Steve Borho
mq: record more data in patchheader class (no behavior changes)...
r13229 # Remember the exact starting line of the patch diffs before consuming
# empty lines, for external use by TortoiseHg and others
self.diffstartline = len(comments)
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 eatempty(message)
eatempty(comments)
# make sure message isn't empty
if format and format.startswith("tag") and subject:
message.insert(0, subject)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 self.message = message
self.comments = comments
self.user = user
self.date = date
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 self.parent = parent
Steve Borho
mq: record more data in patchheader class (no behavior changes)...
r13229 # nodeid and branch are for external use by TortoiseHg and others
self.nodeid = nodeid
self.branch = branch
Cédric Duval
mq: initializing patchheader class directly from patch content...
r8653 self.haspatch = diffstart > 1
Mads Kiilerich
mq: make patchheader .plainmode more reliable...
r22544 self.plainmode = (plainmode or
'# HG changeset patch' not in self.comments and
Augie Fackler
cleanup: use __builtins__.any instead of util.any...
r25149 any(c.startswith('Date: ') or
Mads Kiilerich
mq: make patchheader .plainmode more reliable...
r22544 c.startswith('From: ')
for c in self.comments))
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399
def setuser(self, user):
Mads Kiilerich
mq: drop updateheader - inserthgheader and insertplainheader is enough
r23443 try:
inserthgheader(self.comments, '# User ', user)
except ValueError:
if self.plainmode:
insertplainheader(self.comments, 'From', user)
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):
Mads Kiilerich
mq: drop updateheader - inserthgheader and insertplainheader is enough
r23443 try:
inserthgheader(self.comments, '# Date ', date)
except ValueError:
if self.plainmode:
insertplainheader(self.comments, 'Date', date)
else:
tmp = ['# HG changeset patch', '# Date ' + date]
self.comments = tmp + self.comments
Yann E. MORIN
mq: add the date with qrefresh, even if missing (issue1768)...
r9337 self.date = date
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 def setparent(self, parent):
Mads Kiilerich
mq: drop updateheader - inserthgheader and insertplainheader is enough
r23443 try:
inserthgheader(self.comments, '# Parent ', parent)
except ValueError:
if not self.plainmode:
tmp = ['# HG changeset patch', '# Parent ' + parent]
self.comments = tmp + self.comments
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 self.parent = parent
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 def setmessage(self, message):
if self.comments:
self._delmsg()
self.message = [message]
Mads Kiilerich
mq: when setting message in plain mode, separate it from header (issue4453)...
r23344 if message:
if self.plainmode and self.comments and self.comments[-1]:
self.comments.append('')
self.comments.append(message)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399
Pulkit Goyal
py3: add __bytes__() for mq.patchheader and make sure __str__ returns str...
r35934 def __bytes__(self):
Mads Kiilerich
mq: simplify patchheader handling of the empty line before the diff...
r22522 s = '\n'.join(self.comments).rstrip()
if not s:
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 return ''
Mads Kiilerich
mq: simplify patchheader handling of the empty line before the diff...
r22522 return s + '\n\n'
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399
Pulkit Goyal
py3: add __bytes__() for mq.patchheader and make sure __str__ returns str...
r35934 __str__ = encoding.strmethod(__bytes__)
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 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]
Matt Mackall
merge with stable
r16102 def newcommit(repo, phase, *args, **kwargs):
Pierre-Yves David
mq: rename secretcommit to newcommit...
r16057 """helper dedicated to ensure a commit respect mq.secret setting
It should be used instead of repo.commit inside the mq source for operation
creating new changeset.
Pierre-Yves David
mq: have mq create secret changeset only
r15926 """
Pierre-Yves David
clfilter: ensure that mq performs commits on unfiltered repos
r18010 repo = repo.unfiltered()
Patrick Mezard
mq: ensure all mq commits are made with secretcommit()...
r16100 if phase is None:
Boris Feld
configitems: register the 'mq.secret' config
r34185 if repo.ui.configbool('mq', 'secret'):
Patrick Mezard
mq: ensure all mq commits are made with secretcommit()...
r16100 phase = phases.secret
Jun Wu
mq: get rid of ui.backupconfig
r31460 overrides = {('ui', 'allowemptycommit'): True}
Patrick Mezard
mq: ensure all mq commits are made with secretcommit()...
r16100 if phase is not None:
Jun Wu
mq: get rid of ui.backupconfig
r31460 overrides[('phases', 'new-commit')] = phase
with repo.ui.configoverride(overrides, 'mq'):
Durham Goode
mq: use ui.allowemptycommit to allow empty commits...
r25019 repo.ui.setconfig('ui', 'allowemptycommit', True)
Pierre-Yves David
mq: have mq create secret changeset only
r15926 return repo.commit(*args, **kwargs)
Patrick Mezard
mq: introduce qpush --check...
r16654 class AbortNoCleanup(error.Abort):
pass
Benoit Boissinot
use new style classes
r8778 class queue(object):
Simon Heimberg
mq: do not inherit settings form base repo in mqrepo (Fixes issue2358)...
r19064 def __init__(self, ui, baseui, path, patchdir=None):
mason@suse.com
Add mq extension
r1808 self.basepath = path
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 try:
Gregory Szorc
py3: open patches.queue in binary mode...
r36124 with open(os.path.join(path, 'patches.queue'), r'rb') as fh:
cur = fh.read().rstrip()
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 if not cur:
curpath = os.path.join(path, 'patches')
else:
curpath = os.path.join(path, 'patches-' + cur)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 except IOError:
curpath = os.path.join(path, 'patches')
self.path = patchdir or curpath
Pierre-Yves David
vfs: use 'vfs' module directly in 'hgext.mq'...
r31243 self.opener = vfsmod.vfs(self.path)
mason@suse.com
Add mq extension
r1808 self.ui = ui
Simon Heimberg
mq: do not inherit settings form base repo in mqrepo (Fixes issue2358)...
r19064 self.baseui = baseui
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.applieddirty = False
self.seriesdirty = False
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 self.added = []
Adrian Buehlmann
mq: rename series_path to seriespath
r14587 self.seriespath = "series"
Adrian Buehlmann
mq: rename status_path to statuspath
r14588 self.statuspath = "status"
Adrian Buehlmann
mq: rename guards_path to guardspath
r14589 self.guardspath = "guards"
Adrian Buehlmann
mq: rename active_guards to activeguards
r14590 self.activeguards = None
Adrian Buehlmann
mq: rename guards_dirty to guardsdirty
r14591 self.guardsdirty = False
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190 # Handle mq.git as a bool with extended values
Boris Feld
configitems: register the 'mq.git' config
r34182 gitmode = ui.config('mq', 'git').lower()
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 boolmode = stringutil.parsebool(gitmode)
Boris Feld
configitems: register the 'mq.git' config
r34182 if boolmode is not None:
if boolmode:
gitmode = 'yes'
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 else:
Boris Feld
configitems: register the 'mq.git' config
r34182 gitmode = 'no'
self.gitmode = gitmode
Matt Mackall
mq: tweak config reading to make check-config happy...
r25827 # deprecated config: mq.plain
Boris Feld
configitems: register the 'mq.plain' config
r34184 self.plainmode = ui.configbool('mq', 'plain')
David Soria Parra
shelve: allow shelving of a change with an mq patch applied...
r19856 self.checkapplied = True
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):
Idan Kamara
mq: eliminate explicit checks for file existence
r15258 def parselines(lines):
for l in lines:
entry = l.split(':', 1)
if len(entry) > 1:
n, name = entry
yield statusentry(bin(n), name)
elif l.strip():
Pulkit Goyal
py3: use stringutil.pprint() to format a list to print...
r38061 self.ui.warn(_('malformated mq status line: %s\n') %
stringutil.pprint(entry))
Idan Kamara
mq: eliminate explicit checks for file existence
r15258 # else we ignore empty lines
try:
Adrian Buehlmann
mq: rename status_path to statuspath
r14588 lines = self.opener.read(self.statuspath).splitlines()
Pierre-Yves David
mq: gracefully handle malformated status file...
r13507 return list(parselines(lines))
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as e:
Idan Kamara
mq: eliminate explicit checks for file existence
r15258 if e.errno == errno.ENOENT:
return []
raise
Simon Heimberg
mq: only read files when needed...
r8524
@util.propertycache
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 def fullseries(self):
Idan Kamara
mq: eliminate explicit checks for file existence
r15258 try:
Mads Kiilerich
mq: minor cleanup
r15878 return self.opener.read(self.seriespath).splitlines()
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as e:
Idan Kamara
mq: eliminate explicit checks for file existence
r15258 if e.errno == errno.ENOENT:
return []
raise
Simon Heimberg
mq: only read files when needed...
r8524
@util.propertycache
def series(self):
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 self.parseseries()
Simon Heimberg
mq: only read files when needed...
r8524 return self.series
@util.propertycache
Adrian Buehlmann
mq: rename series_guards to seriesguards
r14573 def seriesguards(self):
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 self.parseseries()
Adrian Buehlmann
mq: rename series_guards to seriesguards
r14573 return self.seriesguards
mason@suse.com
Add mq extension
r1808
Simon Heimberg
mq: new method invalidate...
r8525 def invalidate(self):
Adrian Buehlmann
mq: rename series_guards to seriesguards
r14573 for a in 'applied fullseries series seriesguards'.split():
Simon Heimberg
mq: new method invalidate...
r8525 if a in self.__dict__:
delattr(self, a)
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.applieddirty = False
self.seriesdirty = False
Adrian Buehlmann
mq: rename guards_dirty to guardsdirty
r14591 self.guardsdirty = False
Adrian Buehlmann
mq: rename active_guards to activeguards
r14590 self.activeguards = None
Simon Heimberg
mq: new method invalidate...
r8525
Mads Kiilerich
mq: create non-lossy patches, also with custom global diff configuration...
r34092 def diffopts(self, opts=None, patchfn=None, plain=False):
"""Return diff options tweaked for this mq use, possibly upgrading to
git format, and possibly plain and without lossy options."""
diffopts = patchmod.difffeatureopts(self.ui, opts,
git=True, whitespace=not plain, formatchanging=not plain)
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:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('mq.git option can be auto/keep/yes/no'
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190 ' 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
Martin von Zweigbergk
mq: don't reimplement any()...
r36360 diffopts.git = any(line.startswith('diff --git')
for line in patchf)
Patrick Mezard
mq: upgrade to git patch when necessary (issue767)
r10190 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)
Adrian Buehlmann
mq: rename find_series to findseries
r14574 def findseries(self, patch):
Benoit Boissinot
mq: find_series() simplify and don't use regexps
r10685 def matchpatch(l):
l = l.split('#', 1)[0]
return l.strip() == patch
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 for index, l in enumerate(self.fullseries):
Benoit Boissinot
mq: find_series() simplify and don't use regexps
r10685 if matchpatch(l):
return index
mason@suse.com
Add mq extension
r1808 return None
Pulkit Goyal
py3: add b'' to regular expressions which are raw strings...
r35145 guard_re = re.compile(br'\s?#([-+][^-+# \t\r\n\f][^# \t\r\n\f]*)')
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 def parseseries(self):
mason@suse.com
Add mq extension
r1808 self.series = []
Adrian Buehlmann
mq: rename series_guards to seriesguards
r14573 self.seriesguards = []
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 for l in self.fullseries:
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:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('%s appears more than once in %s') %
Adrian Buehlmann
mq: rename series_path to seriespath
r14587 (patch, self.join(self.seriespath)))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 self.series.append(patch)
Adrian Buehlmann
mq: rename series_guards to seriesguards
r14573 self.seriesguards.append(self.guard_re.findall(comment))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Adrian Buehlmann
mq: rename check_guard to checkguard
r14576 def checkguard(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
Adrian Buehlmann
mq: rename set_active to setactive
r14578 def setactive(self, guards):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 for guard in guards:
Adrian Buehlmann
mq: rename check_guard to checkguard
r14576 bad = self.checkguard(guard)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if bad:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.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))
Adrian Buehlmann
mq: rename active_guards to activeguards
r14590 self.activeguards = guards
Adrian Buehlmann
mq: rename guards_dirty to guardsdirty
r14591 self.guardsdirty = True
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
def active(self):
Adrian Buehlmann
mq: rename active_guards to activeguards
r14590 if self.activeguards is None:
self.activeguards = []
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 try:
Adrian Buehlmann
mq: rename guards_path to guardspath
r14589 guards = self.opener.read(self.guardspath).split()
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as err:
Matt Mackall
many, many trivial check-code fixups
r10282 if err.errno != errno.ENOENT:
raise
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 guards = []
for i, guard in enumerate(guards):
Adrian Buehlmann
mq: rename check_guard to checkguard
r14576 bad = self.checkguard(guard)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if bad:
self.ui.warn('%s:%d: %s\n' %
Adrian Buehlmann
mq: rename guards_path to guardspath
r14589 (self.join(self.guardspath), i + 1, bad))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 else:
Adrian Buehlmann
mq: rename active_guards to activeguards
r14590 self.activeguards.append(guard)
return self.activeguards
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Adrian Buehlmann
mq: rename set_guards to setguards
r14577 def setguards(self, idx, guards):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 for g in guards:
if len(g) < 2:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('guard %r too short') % g)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if g[0] not in '-+':
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('guard %r starts with invalid char') % g)
Adrian Buehlmann
mq: rename check_guard to checkguard
r14576 bad = self.checkguard(g[1:])
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if bad:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(bad)
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 drop = self.guard_re.sub('', self.fullseries[idx])
self.fullseries[idx] = drop + ''.join([' #' + g for g in guards])
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 self.parseseries()
Adrian Buehlmann
mq: rename series_dirty to seriesdirty
r14593 self.seriesdirty = True
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def pushable(self, idx):
Gregory Szorc
py3: compare against bytes instead of str...
r36123 if isinstance(idx, bytes):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 idx = self.series.index(idx)
Adrian Buehlmann
mq: rename series_guards to seriesguards
r14573 patchguards = self.seriesguards[idx]
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if not patchguards:
return True, None
guards = self.active()
Pulkit Goyal
py3: use .startswith() instead of bytes[0]...
r37538 exactneg = [g for g in patchguards
if g.startswith('-') and g[1:] in guards]
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if exactneg:
Pulkit Goyal
py3: use pycompat.byterepr() instead of repr()...
r37540 return False, pycompat.byterepr(exactneg[0])
Pulkit Goyal
py3: use .startswith() instead of bytes[0]...
r37538 pos = [g for g in patchguards if g.startswith('+')]
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:
Pulkit Goyal
py3: use pycompat.byterepr() instead of repr()...
r37540 return True, pycompat.byterepr(exactpos[0])
return False, ' '.join([pycompat.byterepr(p) for p in pos])
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 return True, ''
Adrian Buehlmann
mq: rename explain_pushable to explainpushable
r14579 def explainpushable(self, idx, all_patches=False):
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if all_patches:
write = self.ui.write
else:
write = self.ui.warn
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if all_patches or self.ui.verbose:
Pulkit Goyal
py3: use bytes instead of str in isinstance()...
r37539 if isinstance(idx, bytes):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 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:
Martin Geisler
mq: print "'foo' 'bar'", not "['foo', 'bar']" when showing guards...
r14464 write(_('allowing %s - guarded by %s\n') %
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 (self.series[idx], why))
if not pushable:
Vadim Gelfer
mq: make guards more strict, add tests
r2829 if why:
Martin Geisler
mq: print "'foo' 'bar'", not "['foo', 'bar']" when showing guards...
r14464 write(_('skipping %s - guarded by %s\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
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 def savedirty(self):
Adrian Buehlmann
mq: rename write_list to writelist
r14594 def writelist(items, path):
Augie Fackler
mq: open status file et al in bytes mode...
r35861 fp = self.opener(path, 'wb')
Vadim Gelfer
mq: simplify save_dirty
r2772 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()
Adrian Buehlmann
mq: rename applied_dirty to applieddirty
r14592 if self.applieddirty:
Augie Fackler
mq: use bytes() instead of str() to encode statusentries for writing...
r35862 writelist(map(bytes, self.applied), self.statuspath)
Mads Kiilerich
mq: only save dirty files once when savedirty is called multiple times
r15883 self.applieddirty = False
Adrian Buehlmann
mq: rename series_dirty to seriesdirty
r14593 if self.seriesdirty:
Adrian Buehlmann
mq: rename write_list to writelist
r14594 writelist(self.fullseries, self.seriespath)
Mads Kiilerich
mq: only save dirty files once when savedirty is called multiple times
r15883 self.seriesdirty = False
Adrian Buehlmann
mq: rename guards_dirty to guardsdirty
r14591 if self.guardsdirty:
Adrian Buehlmann
mq: rename write_list to writelist
r14594 writelist(self.activeguards, self.guardspath)
Mads Kiilerich
mq: only save dirty files once when savedirty is called multiple times
r15883 self.guardsdirty = False
Nicolas Dumazet
mq: qrepo.add(mq.added) inside save_dirty inside of doing it manually...
r11546 if self.added:
qrepo = self.qrepo()
if qrepo:
Dan Villiom Podlaski Christiansen
mq: silence spurious output....
r12658 qrepo[None].add(f for f in self.added if f not in qrepo[None])
Nicolas Dumazet
mq: qrepo.add(mq.added) inside save_dirty inside of doing it manually...
r11546 self.added = []
mason@suse.com
Add mq extension
r1808
Brendan Cully
Remove undo log after mq operations that rollback would break
r4207 def removeundo(self, repo):
undo = repo.sjoin('undo')
if not os.path.exists(undo):
return
try:
os.unlink(undo)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except OSError as inst:
Pulkit Goyal
py3: use util.forcevytestr to convert error to bytes...
r36650 self.ui.warn(_('error removing undo: %s\n') %
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 stringutil.forcebytestr(inst))
Brendan Cully
Remove undo log after mq operations that rollback would break
r4207
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 def backup(self, repo, files, copy=False):
Patrick Mezard
mq: backup local changes in qpop --force (issue3433)
r16633 # backup local changes in --force case
for f in sorted(files):
absf = repo.wjoin(f)
if os.path.lexists(absf):
self.ui.note(_('saving current version of %s as %s\n') %
Siddharth Agarwal
origpath: move from cmdutil to scmutil...
r27651 (f, scmutil.origpath(self.ui, repo, f)))
absorig = scmutil.origpath(self.ui, repo, absf)
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 if copy:
Christian Delahousse
mq: let the user choose where .orig files are kept...
r26943 util.copyfile(absf, absorig)
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 else:
Christian Delahousse
mq: let the user choose where .orig files are kept...
r26943 util.rename(absf, absorig)
Patrick Mezard
mq: backup local changes in qpop --force (issue3433)
r16633
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 def printdiff(self, repo, diffopts, node1, node2=None, files=None,
Gregory Szorc
mq: don't use mutable default argument value
r31394 fp=None, changes=None, opts=None):
Pierre-Yves David
mq: explicitly tests for None...
r31432 if opts is None:
opts = {}
Brodie Rao
diff: add --stat for diffstat output...
r9640 stat = opts.get('stat')
Matt Mackall
scmutil: switch match users to supplying contexts...
r14671 m = scmutil.match(repo[node1], files, opts)
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 logcmdutil.diffordiffstat(self.ui, repo, diffopts, node1, node2, m,
changes, stat, fp)
Vadim Gelfer
refactor text diff/patch code....
r2874
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 def mergeone(self, repo, mergeq, head, patch, rev, diffopts):
mason@suse.com
Add mq extension
r1808 # first try just applying the patch
Matt Mackall
many, many trivial check-code fixups
r10282 (err, n) = self.apply(repo, [patch], update_status=False,
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 strict=True, merge=rev)
mason@suse.com
Add mq extension
r1808
if err == 0:
return (err, n)
if n is None:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.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)
Jordi Gutiérrez Hermoso
strip: remove -b/--backup codepaths...
r22057 strip(self.ui, repo, [n], update=False, backup=False)
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:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("update returned %d") % ret)
Matt Mackall
merge with stable
r16102 n = newcommit(repo, None, ctx.description(), ctx.user(), force=True)
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if n is None:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("repo commit failed"))
mason@suse.com
Add mq extension
r1808 try:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(mergeq.join(patch), self.plainmode)
Brodie Rao
cleanup: replace naked excepts with except Exception: ...
r16689 except Exception:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.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")
Pulkit Goyal
py3: use bytes() instead of str()...
r36685 comments = bytes(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):
Pierre-Yves David
mq: document repo.mq.qparents...
r19816 """return the mq handled parent or p1
In some case where mq get himself in being the parent of a merge the
Mads Kiilerich
spelling: random spell checker fixes
r19951 appropriate parent may be p2.
Pierre-Yves David
mq: document repo.mq.qparents...
r19816 (eg: an in progress merge started with mq disabled)
If no parent are managed by mq, p1 is returned.
"""
mason@suse.com
Add mq extension
r1808 if rev is None:
(p1, p2) = repo.dirstate.parents()
Matt Mackall
mq: remove import of revlog
r7639 if p2 == nullid:
mason@suse.com
Add mq extension
r1808 return p1
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
mason@suse.com
Add mq extension
r1808 return None
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 return self.applied[-1].node
p1, p2 = repo.changelog.parents(rev)
Benoit Boissinot
mq: simplify qparents calculation
r10680 if p2 != nullid and p2 in [x.node for x in self.applied]:
return p2
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 return p1
mason@suse.com
Add mq extension
r1808
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 def mergepatch(self, repo, mergeq, series, diffopts):
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
mason@suse.com
Add mq extension
r1808 # each of the patches merged in will have two parents. This
# can confuse the qrefresh, qdiff, and strip code because it
# needs to know which parent is actually in the patch queue.
# so, we insert a merge marker with only one parent. This way
# the first patch in the queue is never a merge patch
#
pname = ".hg.patches.merge.marker"
Matt Mackall
merge with stable
r16102 n = newcommit(repo, None, '[mq]: merge marker', force=True)
Brendan Cully
Remove undo log after mq operations that rollback would break
r4207 self.removeundo(repo)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(n, pname))
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.applieddirty = True
mason@suse.com
Add mq extension
r1808
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:
Adrian Buehlmann
mq: rename explain_pushable to explainpushable
r14579 self.explainpushable(patch, all_patches=True)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 continue
mason@suse.com
Add mq extension
r1808 info = mergeq.isapplied(patch)
if not info:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("patch %s is not applied\n") % patch)
mason@suse.com
Add mq extension
r1808 return (1, None)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 rev = info[1]
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 err, head = self.mergeone(repo, mergeq, head, patch, rev, diffopts)
mason@suse.com
Add mq extension
r1808 if head:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(head, patch))
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.applieddirty = True
mason@suse.com
Add mq extension
r1808 if err:
return (err, head)
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 self.savedirty()
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'''
Patrick Mezard
patch: turn patch() touched files dict into a set
r14564 files = set()
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 try:
Patrick Mezard
patch: make patch()/internalpatch() always update the dirstate
r14260 fuzz = patchmod.patch(self.ui, repo, patchfile, strip=1,
Patrick Mezard
patch: remove patch.patch() cwd argument
r14382 files=files, eolmode=None)
Patrick Mezard
patch: make patch()/internalpatch() always update the dirstate
r14260 return (True, list(files), fuzz)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except Exception as inst:
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 self.ui.note(stringutil.forcebytestr(inst) + '\n')
Brendan Cully
Unify mq and hg patch invocation....
r2919 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"))
Dan Villiom Podlaski Christiansen
mq: don't suppress patch tracebacks when applying patches
r15085 self.ui.traceback()
Patrick Mezard
patch: make patch()/internalpatch() always update the dirstate
r14260 return (False, list(files), False)
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,
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 strict=False, patchdir=None, merge=None, all_files=None,
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 tobackup=None, keepchanges=False):
FUJIWARA Katsunori
dirstate: remove meaningless dirstateguard...
r26578 wlock = lock = tr = None
Bryan O'Sullivan
MQ: tidy up if a qpush is interrupted....
r4418 try:
Matt Mackall
Make repo locks recursive, eliminate all passing of lock/wlock
r4917 wlock = repo.wlock()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 lock = repo.lock()
Steve Borho
localrepo: add desc parameter to transaction...
r10881 tr = repo.transaction("qpush")
Bryan O'Sullivan
MQ: tidy up if a qpush is interrupted....
r4418 try:
Matt Mackall
transactions: avoid late tear-down (issue641)...
r4970 ret = self._apply(repo, series, list, update_status,
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 strict, patchdir, merge, all_files=all_files,
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 tobackup=tobackup, keepchanges=keepchanges)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 tr.close()
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 self.savedirty()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 return ret
Patrick Mezard
mq: introduce qpush --check...
r16654 except AbortNoCleanup:
tr.close()
self.savedirty()
Matt Mackall
mq: avoid silent failure when single patch doesn't apply (issue4604)...
r24826 raise
Brodie Rao
check-code: ignore naked excepts with a "re-raise" comment...
r16705 except: # re-raises
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
tr.abort()
finally:
Mads Kiilerich
mq: use .invalidate to cancel dirty mq state when cancelling transaction...
r15881 self.invalidate()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 raise
finally:
FUJIWARA Katsunori
dirstate: remove meaningless dirstateguard...
r26578 release(tr, lock, wlock)
Alexis S. L. Carvalho
mq: really remove undo after a qpush (and after a strip)...
r5527 self.removeundo(repo)
Bryan O'Sullivan
MQ: tidy up if a qpush is interrupted....
r4418
Matt Mackall
transactions: avoid late tear-down (issue641)...
r4970 def _apply(self, repo, series, list=False, update_status=True,
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 strict=False, patchdir=None, merge=None, all_files=None,
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 tobackup=None, keepchanges=False):
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 """returns (error, hash)
error = 1 for unable to read, 2 for patch failed, 3 for patch
fuzz. tobackup is None or a set of files to backup before they
are modified by a patch.
"""
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:
Adrian Buehlmann
mq: rename explain_pushable to explainpushable
r14579 self.explainpushable(patchname, all_patches=True)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 continue
Martin Geisler
mq: use ui.status when pushing and popping patches
r9111 self.ui.status(_("applying %s\n") % patchname)
Brendan Cully
Teach mq about git patches
r2934 pf = os.path.join(patchdir, patchname)
mason@suse.com
Add mq extension
r1808
try:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(self.join(patchname), self.plainmode)
Idan Kamara
mq: loosen except clause when reading patch headers
r14239 except IOError:
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875 self.ui.warn(_("unable to read %s\n") % patchname)
mason@suse.com
Add mq extension
r1808 err = 1
break
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 message = ph.message
mason@suse.com
Add mq extension
r1808 if not message:
Martin Geisler
mq: mark strings that should not be translated
r12849 # The commit message should not be translated
David Soria Parra
mq: Do not translate import message that are appended to commits....
r10274 message = "imported patch %s\n" % patchname
mason@suse.com
Add mq extension
r1808 else:
if list:
Martin Geisler
mq: mark strings that should not be translated
r12849 # The commit message should not be translated
David Soria Parra
mq: Do not translate import message that are appended to commits....
r10274 message.append("\nimported patch %s" % patchname)
mason@suse.com
Add mq extension
r1808 message = '\n'.join(message)
Matt Mackall
mq: handle empty patches more gracefully (issue1501)
r7782 if ph.haspatch:
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 if tobackup:
touched = patchmod.changedfiles(self.ui, repo, pf)
touched = set(touched) & tobackup
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 if touched and keepchanges:
Patrick Mezard
mq: introduce qpush --check...
r16654 raise AbortNoCleanup(
Matt Mackall
mq: avoid silent failure when single patch doesn't apply (issue4604)...
r24826 _("conflicting local changes found"),
hint=_("did you forget to qrefresh?"))
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 self.backup(repo, touched, copy=True)
tobackup = tobackup - touched
Matt Mackall
mq: handle empty patches more gracefully (issue1501)
r7782 (patcherr, files, fuzz) = self.patch(repo, pf)
Benoit Boissinot
mq: all_files can be a set, remove dangerous default values
r10661 if all_files is not None:
all_files.update(files)
Matt Mackall
mq: handle empty patches more gracefully (issue1501)
r7782 patcherr = not patcherr
else:
self.ui.warn(_("patch %s is empty\n") % patchname)
patcherr, files, fuzz = 0, [], 0
mason@suse.com
Add mq extension
r1808
Brendan Cully
Teach mq about git patches
r2934 if merge and files:
Alexis S. L. Carvalho
mq: don't abort when merging a patch that removes files
r4332 # Mark as removed/merged and update dirstate parent info
removed = []
merged = []
for f in files:
Patrick Mezard
Use lexists() instead of exists() where appropriate
r12344 if os.path.lexists(repo.wjoin(f)):
Alexis S. L. Carvalho
mq: don't abort when merging a patch that removes files
r4332 merged.append(f)
else:
removed.append(f)
Augie Fackler
mq: migrate to context manager for changing dirstate parents
r32347 with repo.dirstate.parentchange():
for f in removed:
repo.dirstate.remove(f)
for f in merged:
repo.dirstate.merge(f)
p1, p2 = repo.dirstate.parents()
repo.setparents(p1, merge)
Matt Mackall
match: remove files arg from repo.status and friends
r6603
Angel Ezquerra
mq: update subrepos when applying / unapplying patches that change .hgsubstate...
r19638 if all_files and '.hgsubstate' in all_files:
Mads Kiilerich
mq: repo['.'] is not a wctx, repo[None] is...
r20959 wctx = repo[None]
pctx = repo['.']
Angel Ezquerra
mq: update subrepos when applying / unapplying patches that change .hgsubstate...
r19638 overwrite = False
Yuya Nishihara
subrepo: split non-core functions to new module...
r36026 mergedsubstate = subrepoutil.submerge(repo, pctx, wctx, wctx,
overwrite)
Angel Ezquerra
mq: update subrepos when applying / unapplying patches that change .hgsubstate...
r19638 files += mergedsubstate.keys()
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 match = scmutil.matchfiles(repo, files or [])
Matt Mackall
qpush: avoid trying to manage existing history (issue2218)
r16043 oldtip = repo['tip']
Matt Mackall
merge with stable
r16102 n = newcommit(repo, None, message, ph.user, ph.date, match=match,
force=True)
Matt Mackall
qpush: avoid trying to manage existing history (issue2218)
r16043 if repo['tip'] == oldtip:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("qpush exactly duplicates child changeset"))
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if n is None:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("repository commit failed"))
mason@suse.com
Add mq extension
r1808
if update_status:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(n, patchname))
mason@suse.com
Add mq extension
r1808
if patcherr:
Yuya Nishihara
commands: say "working directory" in full spelling
r24365 self.ui.warn(_("patch failed, rejects left in working "
"directory\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:
Matt Mackall
context: make forget work like commands.forget...
r14435 r[None].forget(patches)
for p in patches:
Mads Kiilerich
mq: don't fail when removing a patch without patch file from series file
r18067 try:
os.unlink(self.join(p))
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except OSError as inst:
Mads Kiilerich
mq: don't fail when removing a patch without patch file from series file
r18067 if inst.errno != errno.ENOENT:
raise
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833
Pierre-Yves David
mq: turn changeset draft on qfinish (except if qparent is secret)...
r15920 qfinished = []
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 if numrevs:
Pierre-Yves David
mq: prevent traceback when qfinish patches not in series....
r14010 qfinished = self.applied[:numrevs]
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 del self.applied[:numrevs]
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.applieddirty = True
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833
Pierre-Yves David
mq: prevent traceback when qfinish patches not in series....
r14010 unknown = []
Pulkit Goyal
py3: workaround comparing NoneType and integers...
r37543 sortedseries = []
for p in patches:
idx = self.findseries(p)
if idx is None:
sortedseries.append((-1, p))
else:
sortedseries.append((idx, p))
sortedseries.sort(reverse=True)
for (i, p) in sortedseries:
if i != -1:
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 del self.fullseries[i]
Pierre-Yves David
mq: prevent traceback when qfinish patches not in series....
r14010 else:
unknown.append(p)
if unknown:
if numrevs:
rev = dict((entry.name, entry.node) for entry in qfinished)
for p in unknown:
msg = _('revision %s refers to unknown patches: %s\n')
self.ui.warn(msg % (short(rev[p]), p))
else:
msg = _('unknown patches: %s\n')
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(''.join(msg % p for p in unknown))
Pierre-Yves David
mq: prevent traceback when qfinish patches not in series....
r14010
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 self.parseseries()
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.seriesdirty = True
Pierre-Yves David
mq: turn changeset draft on qfinish (except if qparent is secret)...
r15920 return [entry.node for entry in qfinished]
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 def _revpatches(self, repo, revs):
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 firstrev = repo[self.applied[0].node].rev()
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 patches = []
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 for i, rev in enumerate(revs):
Dirkjan Ochtman
mq: warn about finalizing patches without cset message
r8832
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 if rev < firstrev:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('revision %d is not managed') % rev)
Dirkjan Ochtman
mq: warn about finalizing patches without cset message
r8832
ctx = repo[rev]
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 base = self.applied[i].node
Dirkjan Ochtman
mq: warn about finalizing patches without cset message
r8832 if ctx.node() != base:
msg = _('cannot delete revision %d above applied patches')
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(msg % rev)
Dirkjan Ochtman
mq: warn about finalizing patches without cset message
r8832
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):
Pierre-Yves David
qfinish: do not set secret changeset to draft if mq.secret=false...
r16029 # Manually trigger phase computation to ensure phasedefaults is
# executed before we remove the patches.
Patrick Mezard
phases: introduce phasecache...
r16657 repo._phasecache
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 patches = self._revpatches(repo, sorted(revs))
Pierre-Yves David
mq: turn changeset draft on qfinish (except if qparent is secret)...
r15920 qfinished = self._cleanup(patches, len(patches))
Boris Feld
configitems: register the 'mq.secret' config
r34185 if qfinished and repo.ui.configbool('mq', 'secret'):
Pierre-Yves David
qfinish: do not set secret changeset to draft if mq.secret=false...
r16029 # only use this logic when the secret option is added
Pierre-Yves David
mq: turn changeset draft on qfinish (except if qparent is secret)...
r15920 oldqbase = repo[qfinished[0]]
Boris Feld
mq: use the newcommitphase utility...
r34563 tphase = phases.newcommitphase(repo.ui)
Pierre-Yves David
qfinish: comply with the phases.new-commit option in secret mode (issue3335)...
r16290 if oldqbase.phase() > tphase and oldqbase.p1().phase() <= tphase:
Bryan O'Sullivan
with: use context manager for transaction in qfinish
r27864 with repo.transaction('qfinish') as tr:
Pierre-Yves David
phase: add a transaction argument to advanceboundary...
r22069 phases.advanceboundary(repo, tr, tphase, qfinished)
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'):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('qdelete requires at least one revision or '
Brendan Cully
mq: more qdelete help text tweaks
r4737 'patch name'))
Brendan Cully
mq: require patch argument or revision for qdelete
r4736
Greg Ward
mq: make 'qdelete <patchidx>' work again....
r11365 realpatches = []
Brendan Cully
Allow qdel to delete multiple patches.
r2905 for patch in patches:
patch = self.lookup(patch, strict=True)
info = self.isapplied(patch)
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 if info:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("cannot delete applied patch %s") % patch)
Brendan Cully
Allow qdel to delete multiple patches.
r2905 if patch not in self.series:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("patch %s not in series file") % patch)
Dan Villiom Podlaski Christiansen
mq: handle deleting the same patch twice in one command (issue2427)
r12655 if patch not in realpatches:
realpatches.append(patch)
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 numrevs = 0
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 if opts.get('rev'):
if not self.applied:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no patches applied'))
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 revs = scmutil.revrange(repo, opts.get('rev'))
Pierre-Yves David
mq: use `revs.sort()` to ensure the set is ascending...
r22803 revs.sort()
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 revpatches = self._revpatches(repo, revs)
Greg Ward
mq: make 'qdelete <patchidx>' work again....
r11365 realpatches += revpatches
Dirkjan Ochtman
mq: unify code for qdel -r and qfin
r8833 numrevs = len(revpatches)
Brendan Cully
Allow qdel to delete multiple patches.
r2905
Greg Ward
mq: make 'qdelete <patchidx>' work again....
r11365 self._cleanup(realpatches, numrevs, opts.get('keep'))
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Adrian Buehlmann
mq: rename check_toppatch to checktoppatch
r14581 def checktoppatch(self, repo):
Mads Kiilerich
mq: checktoppatch should only check if p1 is qtip...
r18343 '''check that working directory is at qtip'''
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.applied:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 top = self.applied[-1].node
Patrick Mezard
mq: qdiff with the same diff options than qrefresh (issue1350)...
r10191 patch = self.applied[-1].name
Mads Kiilerich
mq: checktoppatch should only check if p1 is qtip...
r18343 if repo.dirstate.p1() != top:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.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
FUJIWARA Katsunori
mq: create patch file after commit to import diff of ".hgsubstate" at qrefresh...
r17152 def putsubstate2changes(self, substatestate, changes):
for files in changes[:3]:
if '.hgsubstate' in files:
return # already listed up
# not yet listed up
if substatestate in 'a?':
changes[1].append('.hgsubstate')
elif substatestate in 'r':
changes[2].append('.hgsubstate')
else: # modified
changes[0].append('.hgsubstate')
Pierre-Yves David
mq: simplifies the refresh hint in checklocalchanges...
r19812 def checklocalchanges(self, repo, force=False, refresh=True):
excsuffix = ''
Idan Kamara
mq: allow to qpop/push with a dirty working copy (issue2780)...
r14256 if refresh:
timeless@mozdev.org
mq: consistently use qrefresh
r26780 excsuffix = ', qrefresh first'
Pierre-Yves David
mq: simplifies the refresh hint in checklocalchanges...
r19812 # plain versions for i18n tool to detect them
timeless@mozdev.org
mq: consistently use qrefresh
r26780 _("local changes found, qrefresh first")
_("local changed subrepos found, qrefresh first")
Pierre-Yves David
mq: extract checklocalchanges from `mq.queue`...
r19814 return checklocalchanges(repo, force, excsuffix)
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713
Idan Kamara
mq: add '.' and '..' to list of forbidden patch names...
r14051 _reserved = ('series', 'status', 'guards', '.', '..')
Adrian Buehlmann
mq: rename check_reserved_name to checkreservedname
r14584 def checkreservedname(self, name):
Idan Kamara
mq: be more explicit on invalid patch name message
r14054 if name in self._reserved:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('"%s" cannot be used as the name of a patch')
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981 % name)
Yuya Nishihara
mq: reject new patch name containing leading/trailing whitespace...
r31556 if name != name.strip():
# whitespace is stripped by parseseries()
raise error.Abort(_('patch name cannot begin or end with '
'whitespace'))
Idan Kamara
mq: be more explicit on invalid patch name message
r14054 for prefix in ('.hg', '.mq'):
if name.startswith(prefix):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('patch name cannot begin with "%s"')
Idan Kamara
mq: be more explicit on invalid patch name message
r14054 % prefix)
Augie Fackler
mq: ban \r and \n in patch names (issue4711)...
r25454 for c in ('#', ':', '\r', '\n'):
Idan Kamara
mq: be more explicit on invalid patch name message
r14054 if c in name:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('%r cannot be used in the name of a patch')
Pulkit Goyal
py3: use pycompat.bytestr() where repr in involved...
r37577 % pycompat.bytestr(c))
Idan Kamara
mq: be more explicit on invalid patch name message
r14054
Idan Kamara
mq: wrap patch file name checks in a function
r14422 def checkpatchname(self, name, force=False):
Adrian Buehlmann
mq: rename check_reserved_name to checkreservedname
r14584 self.checkreservedname(name)
Idan Kamara
mq: wrap patch file name checks in a function
r14422 if not force and os.path.exists(self.join(name)):
if os.path.isdir(self.join(name)):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('"%s" already exists as a directory')
Idan Kamara
mq: wrap patch file name checks in a function
r14422 % name)
else:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('patch "%s" already exists') % name)
Alexis S. L. Carvalho
mq: don't allow patches with some reserved names...
r5981
Mads Kiilerich
mq: refactor makepatchname into class method
r27918 def makepatchname(self, title, fallbackname):
"""Return a suitable filename for title, adding a suffix to make
it unique in the existing list"""
namebase = re.sub('[\s\W_]+', '_', title.lower()).strip('_')
Pierre-Yves David
mq: restrict generated patch name to 75 characters (issue5117)...
r28388 namebase = namebase[:75] # avoid too long name (issue5117)
Mads Kiilerich
mq: check for reserved patch name with qimport -r (issue5033)...
r27919 if namebase:
try:
self.checkreservedname(namebase)
except error.Abort:
namebase = fallbackname
else:
Mads Kiilerich
mq: refactor makepatchname into class method
r27918 namebase = fallbackname
name = namebase
i = 0
Mads Kiilerich
mq: check for reserved patch name with qimport -r (issue5033)...
r27919 while True:
if name not in self.fullseries:
try:
self.checkpatchname(name)
break
except error.Abort:
pass
Mads Kiilerich
mq: refactor makepatchname into class method
r27918 i += 1
Pulkit Goyal
py3: use "%d" instead of "%s" for integers...
r36049 name = '%s__%d' % (namebase, i)
Mads Kiilerich
mq: refactor makepatchname into class method
r27918 return name
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 def checkkeepchanges(self, keepchanges, force):
if force and keepchanges:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot use both --force and --keep-changes'))
Patrick Mezard
mq: introduce qpush --check...
r16654
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
"""
Pulkit Goyal
py3: use pycompat.byteskwargs() to fix keyword arguments handling...
r36405 opts = pycompat.byteskwargs(opts)
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 msg = opts.get('msg')
FUJIWARA Katsunori
mq: fold the code path to invoke editor into specific logic (qnew)...
r21420 edit = opts.get('edit')
FUJIWARA Katsunori
mq: pass 'editform' argument to 'cmdutil.getcommiteditor'...
r22003 editform = opts.get('editform', 'mq.qnew')
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:
Boris Feld
util: extract all date-related utils in utils/dateutil module...
r36625 date = dateutil.parsedate(date)
Mads Kiilerich
mq: create non-lossy patches, also with custom global diff configuration...
r34092 diffopts = self.diffopts({'git': opts.get('git')}, plain=True)
Idan Kamara
record: check patch name is valid before prompting in qrecord
r14424 if opts.get('checkname', True):
self.checkpatchname(patchfn)
Pierre-Yves David
mq: extract checksubstate from the queue class...
r19813 inclsubs = checksubstate(repo)
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 if inclsubs:
FUJIWARA Katsunori
mq: use list of already known target files instead of matching object for diff...
r16366 substatestate = repo.dirstate['.hgsubstate']
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 if opts.get('include') or opts.get('exclude') or pats:
Brendan Cully
mq: abort qnew -f if any file in an explicit list cannot be read
r7161 # detect missing files in pats
def badfn(f, msg):
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174 if f != '.hgsubstate': # .hgsubstate is auto-created
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort('%s: %s' % (f, msg))
Matt Harbison
mq: use the optional badfn argument when building a matcher
r25469 match = scmutil.match(repo[None], pats, opts, badfn=badfn)
FUJIWARA Katsunori
mq: use list of already known target files instead of matching object for diff...
r16366 changes = repo.status(match=match)
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 else:
FUJIWARA Katsunori
mq: use list of already known target files instead of matching object for diff...
r16366 changes = self.checklocalchanges(repo, force=True)
FUJIWARA Katsunori
mq: omit ".hgsubstate" from qnew/qrefresh target list for consistent node hash...
r20786 commitfiles = list(inclsubs)
for files in changes[:3]:
FUJIWARA Katsunori
localrepo: omit ".hgsubstate" also from "added" files...
r20827 commitfiles.extend(files)
FUJIWARA Katsunori
mq: omit ".hgsubstate" from qnew/qrefresh target list for consistent node hash...
r20786 match = scmutil.matchfiles(repo, commitfiles)
Augie Fackler
qnew: ignore force option...
r10372 if len(repo[None].parents()) > 1:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot manage merge changesets'))
Adrian Buehlmann
mq: rename check_toppatch to checktoppatch
r14581 self.checktoppatch(repo)
Adrian Buehlmann
mq: rename full_series_end to fullseriesend
r14585 insert = self.fullseriesend()
Bryan O'Sullivan
with: use context manager for wlock in qnew
r27827 with repo.wlock():
Martin Geisler
qnew: give better feedback when doing 'hg qnew foo/' (issue2464)
r12878 try:
# if patch file write fails, abort early
p = self.opener(patchfn, "w")
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except IOError as e:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot write patch "%s": %s')
Augie Fackler
python3: wrap all uses of <exception>.strerror with strtolocal...
r34024 % (patchfn, encoding.strtolocal(e.strerror)))
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 try:
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 defaultmsg = "[mq]: %s" % patchfn
FUJIWARA Katsunori
mq: pass 'editform' argument to 'cmdutil.getcommiteditor'...
r22003 editor = cmdutil.getcommiteditor(editform=editform)
FUJIWARA Katsunori
mq: fold the code path to invoke editor into specific logic (qnew)...
r21420 if edit:
FUJIWARA Katsunori
mq: use the editor gotten by "getcommiteditor()" instead of "ui.edit()" (qnew)...
r21421 def finishdesc(desc):
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 if desc.rstrip():
return desc
else:
return defaultmsg
FUJIWARA Katsunori
mq: use the editor gotten by "getcommiteditor()" instead of "ui.edit()" (qnew)...
r21421 # i18n: this message is shown in editor with "HG: " prefix
extramsg = _('Leave message empty to use default message.')
editor = cmdutil.getcommiteditor(finishdesc=finishdesc,
FUJIWARA Katsunori
mq: pass 'editform' argument to 'cmdutil.getcommiteditor'...
r22003 extramsg=extramsg,
editform=editform)
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 commitmsg = msg
else:
commitmsg = msg or defaultmsg
Matt Mackall
merge with stable
r16102 n = newcommit(repo, None, commitmsg, user, date, match=match,
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 force=True, editor=editor)
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if n is None:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("repo commit failed"))
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 try:
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 self.fullseries[insert:insert] = [patchfn]
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 self.applied.append(statusentry(n, patchfn))
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 self.parseseries()
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.seriesdirty = True
self.applieddirty = True
FUJIWARA Katsunori
qnew: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21234 nctx = repo[n]
Mads Kiilerich
mq: write headers of new patches using patchheader
r22547 ph = patchheader(self.join(patchfn), self.plainmode)
if user:
ph.setuser(user)
if date:
Pulkit Goyal
py3: use "%d" for integers instead of "%s"...
r36407 ph.setdate('%d %d' % date)
Mads Kiilerich
mq: write headers of new patches using patchheader
r22547 ph.setparent(hex(nctx.p1().node()))
msg = nctx.description().strip()
if msg == defaultmsg.strip():
msg = ''
ph.setmessage(msg)
Pulkit Goyal
py3: use bytes instead of str...
r35966 p.write(bytes(ph))
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 if commitfiles:
parent = self.qparents(repo, n)
FUJIWARA Katsunori
mq: use list of already known target files instead of matching object for diff...
r16366 if inclsubs:
FUJIWARA Katsunori
mq: create patch file after commit to import diff of ".hgsubstate" at qrefresh...
r17152 self.putsubstate2changes(substatestate, changes)
Idan Kamara
mq: don't hide the patch module
r14241 chunks = patchmod.diff(repo, node1=parent, node2=n,
FUJIWARA Katsunori
mq: use list of already known target files instead of matching object for diff...
r16366 changes=changes, opts=diffopts)
Dirkjan Ochtman
patch: turn patch.diff() into a generator...
r7308 for chunk in chunks:
p.write(chunk)
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 p.close()
r = self.qrepo()
Matt Mackall
many, many trivial check-code fixups
r10282 if r:
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 r[None].add([patchfn])
Brodie Rao
check-code: ignore naked excepts with a "re-raise" comment...
r16705 except: # re-raises
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 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)
Brodie Rao
cleanup: replace naked excepts with more specific ones
r16688 except OSError:
Brendan Cully
mq: heavy rearrangement of qnew to make it recover reliably from errors....
r7162 self.ui.warn(_('error unlinking %s\n') % patchpath)
raise
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.removeundo(repo)
mason@suse.com
Add mq extension
r1808
def isapplied(self, patch):
"""returns (index, rev, patch)"""
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 for i, a in enumerate(self.applied):
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 if a.name == patch:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 return (i, a.node, a.name)
mason@suse.com
Add mq extension
r1808 return None
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223 # if the exact patch name does not exist, we try a few
Chris Mason
mq: patch naming shortcuts...
r2696 # variations. If strict is passed, we try only #1
#
Mads Kiilerich
mq: fix corner cases for handling of patch 0 in qselect...
r15256 # 1) a number (as string) to indicate an offset in the series file
Chris Mason
mq: patch naming shortcuts...
r2696 # 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):
Adrian Buehlmann
mq: rename partial_name to partialname
r14595 def partialname(s):
Chris Mason
mq: patch naming shortcuts...
r2696 if s in self.series:
return s
Vadim Gelfer
mq: print matches if patch name not unique
r2765 matches = [x for x in self.series if s in x]
if len(matches) > 1:
self.ui.warn(_('patch name "%s" is ambiguous:\n') % s)
for m in matches:
self.ui.warn(' %s\n' % m)
return None
if matches:
return matches[0]
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.series and self.applied:
Chris Mason
mq: patch naming shortcuts...
r2696 if s == 'qtip':
Mads Kiilerich
check-code: there must also be whitespace between ')' and operator...
r18054 return self.series[self.seriesend(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
if patch in self.series:
return patch
Chris Mason
mq: patch naming shortcuts...
r2696
Vadim Gelfer
mq: add join method
r2819 if not os.path.isfile(self.join(patch)):
mason@suse.com
Add mq extension
r1808 try:
sno = int(patch)
Matt Mackall
many, many trivial check-code fixups
r10282 except (ValueError, OverflowError):
Chris Mason
mq: patch naming shortcuts...
r2696 pass
else:
Jason Orendorff
mq: don't warn about ambiguous patch name when using patch index (issue1439)
r7568 if -len(self.series) <= sno < len(self.series):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 return self.series[sno]
Jason Orendorff
mq: don't warn about ambiguous patch name when using patch index (issue1439)
r7568
Chris Mason
mq: patch naming shortcuts...
r2696 if not strict:
Adrian Buehlmann
mq: rename partial_name to partialname
r14595 res = partialname(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:
Adrian Buehlmann
mq: rename partial_name to partialname
r14595 res = partialname(patch[:minus])
Chris Mason
mq: patch naming shortcuts...
r2696 if res:
i = self.series.index(res)
try:
Matt Mackall
many, many trivial check-code fixups
r10282 off = int(patch[minus + 1:] or 1)
except (ValueError, OverflowError):
Chris Mason
mq: patch naming shortcuts...
r2696 pass
else:
if i - off >= 0:
return self.series[i - off]
Thomas Arendsen Hein
Fixed python2.3 incompatibility (rsplit) in qpush/qpop with index.
r3082 plus = patch.rfind('+')
if plus >= 0:
Adrian Buehlmann
mq: rename partial_name to partialname
r14595 res = partialname(patch[:plus])
Chris Mason
mq: patch naming shortcuts...
r2696 if res:
i = self.series.index(res)
try:
Matt Mackall
many, many trivial check-code fixups
r10282 off = int(patch[plus + 1:] or 1)
except (ValueError, OverflowError):
Chris Mason
mq: patch naming shortcuts...
r2696 pass
else:
if i + off < len(self.series):
return self.series[i + off]
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("patch %s not in series") % patch)
mason@suse.com
Add mq extension
r1808
Patrick Mezard
mq: introduce qpush --check...
r16654 def push(self, repo, patch=None, force=False, list=False, mergeq=None,
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 all=False, move=False, exact=False, nobackup=False,
keepchanges=False):
self.checkkeepchanges(keepchanges, force)
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 diffopts = self.diffopts()
Bryan O'Sullivan
with: use context manager for wlock in qpush
r27828 with repo.wlock():
Kevin Bullock
mq: prefer a loop to a double-for list comprehension...
r20119 heads = []
for hs in repo.branchmap().itervalues():
heads.extend(hs)
Dirkjan Ochtman
mq: don't warn on qpush against a branch head
r10362 if not heads:
heads = [nullid]
Matt Mackall
misc: replace .parents()[0] with p1()
r13878 if repo.dirstate.p1() not in heads and not exact:
Adrian Buehlmann
mq: eliminate warning on qpush with empty series...
r8795 self.ui.status(_("(working directory not at a head)\n"))
Matt Mackall
mq: warn when applying a patch to somewhere other than tip
r6340
Adrian Buehlmann
mq: eliminate warning on qpush with empty series...
r8795 if not self.series:
self.ui.warn(_('no patches in series\n'))
return 0
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # 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:
Mads Kiilerich
mq: cleanup of lookup - handling of None is not relevant...
r15257 patch = self.lookup(patch)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 info = self.isapplied(patch)
Afuna
mq: catch attempt to qpush to an earlier patch (issue2587)...
r13369 if info and info[0] >= len(self.applied) - 1:
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 self.ui.warn(
_('qpush: %s is already at the top\n') % patch)
Gilles Moris
mq: explicit exit code when patch is already on top
r11439 return 0
Afuna
mq: catch attempt to qpush to an earlier patch (issue2587)...
r13369
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 pushable, reason = self.pushable(patch)
Afuna
mq: catch attempt to qpush to an earlier patch (issue2587)...
r13369 if pushable:
Adrian Buehlmann
mq: rename series_end to seriesend
r14586 if self.series.index(patch) < self.seriesend():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Afuna
mq: catch attempt to qpush to an earlier patch (issue2587)...
r13369 _("cannot push to a previous patch: %s") % patch)
else:
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 if reason:
Martin Geisler
mq: print "'foo' 'bar'", not "['foo', 'bar']" when showing guards...
r14464 reason = _('guarded by %s') % 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
Adrian Buehlmann
mq: rename series_end to seriesend
r14586 start = self.seriesend()
Brendan Cully
mq: gracefully abort qpush/qgoto to guarded patch (issue1186)
r7398 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
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 if not force and not keepchanges:
Idan Kamara
backout of d04ba50e104d: allow to qpop/push with a dirty working copy...
r14732 self.checklocalchanges(repo, refresh=self.applied)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 if exact:
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 if keepchanges:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 _("cannot use --exact and --keep-changes together"))
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 if move:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot use --exact and --move '
Brodie Rao
cleanup: eradicate long lines
r16683 'together'))
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 if self.applied:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot push --exact with applied '
Brodie Rao
cleanup: eradicate long lines
r16683 'patches'))
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 root = self.series[start]
target = patchheader(self.join(root), self.plainmode).parent
if not target:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Matt Mackall
i18n: fix all remaining uses of % inside _()
r16231 _("%s does not have a parent recorded") % root)
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 if not repo[target] == repo['.']:
hg.update(repo, target)
Mads Kiilerich
mq: qpush --move, reorder patch series and apply only the patch...
r11064 if move:
Gilles Moris
qpush --move: move the right patch even with comment lines...
r11715 if not patch:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("please specify the patch to move"))
Mads Kiilerich
mq: fix qpush --move with comments in series file between applied patches...
r16303 for fullstart, rpn in enumerate(self.fullseries):
# strip markers for patch guards
if self.guard_re.split(rpn, 1)[0] == self.series[start]:
break
for i, rpn in enumerate(self.fullseries[fullstart:]):
Gilles Moris
qpush --move: move the right patch even with comment lines...
r11715 # strip markers for patch guards
if self.guard_re.split(rpn, 1)[0] == patch:
break
Mads Kiilerich
mq: fix qpush --move with comments in series file between applied patches...
r16303 index = fullstart + i
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 assert index < len(self.fullseries)
fullpatch = self.fullseries[index]
del self.fullseries[index]
Mads Kiilerich
mq: fix qpush --move with comments in series file between applied patches...
r16303 self.fullseries.insert(fullstart, fullpatch)
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 self.parseseries()
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.seriesdirty = True
self.applieddirty = True
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if start > 0:
Adrian Buehlmann
mq: rename check_toppatch to checktoppatch
r14581 self.checktoppatch(repo)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 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
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 tobackup = set()
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 if (not nobackup and force) or keepchanges:
Martin von Zweigbergk
strip: make checklocalchanges() return full status tuple...
r22925 status = self.checklocalchanges(repo, force=True)
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 if keepchanges:
Martin von Zweigbergk
strip: make checklocalchanges() return full status tuple...
r22925 tobackup.update(status.modified + status.added +
status.removed + status.deleted)
Patrick Mezard
mq: introduce qpush --check...
r16654 else:
Martin von Zweigbergk
strip: make checklocalchanges() return full status tuple...
r22925 tobackup.update(status.modified + status.added)
Patrick Mezard
mq: backup local changes in qpush --force...
r16634
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 s = self.series[start:end]
Benoit Boissinot
mq: all_files can be a set, remove dangerous default values
r10661 all_files = set()
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
if mergeq:
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 ret = self.mergepatch(repo, mergeq, s, diffopts)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Patrick Mezard
mq: backup local changes in qpush --force...
r16634 ret = self.apply(repo, s, list, all_files=all_files,
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 tobackup=tobackup, keepchanges=keepchanges)
Matt Mackall
mq: avoid silent failure when single patch doesn't apply (issue4604)...
r24826 except AbortNoCleanup:
raise
Brodie Rao
check-code: ignore naked excepts with a "re-raise" comment...
r16705 except: # re-raises
Matt Mackall
mq: use cmdutil.revert instead of hg.revert...
r26654 self.ui.warn(_('cleaning up working directory...\n'))
cmdutil.revert(self.ui, repo, repo['.'],
repo.dirstate.parents(), no_backup=True)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # only remove unknown files that we know we touched or
# created while patching
Benoit Boissinot
mq: avoid a (potentially expensive) repo.status(unknown=True) call
r10662 for f in all_files:
if f not in repo.dirstate:
Mads Kiilerich
vfs: use repo.wvfs.unlinkpath
r31309 repo.wvfs.unlinkpath(f, ignoremissing=True)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 self.ui.warn(_('done\n'))
raise
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875
Benoit Allard
mq: fix traceback for qpush inexistant-patch with no patch applied
r9590 if not self.applied:
return ret[0]
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 top = self.applied[-1].name
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875 if ret[0] and ret[0] > 1:
timeless@mozdev.org
mq: consistently use qrefresh
r26780 msg = _("errors during apply, please fix and qrefresh %s\n")
Dirkjan Ochtman
mq: fix error message for qpush inexistent-patch (issue1702)
r8875 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
Patrick Mezard
mq: add --no-backup for qpush/qpop/qgoto
r16635 def pop(self, repo, patch=None, force=False, update=True, all=False,
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 nobackup=False, keepchanges=False):
self.checkkeepchanges(keepchanges, force)
Bryan O'Sullivan
with: use context manager for wlock in qpop
r27829 with repo.wlock():
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if patch:
# index, rev, patch
info = self.isapplied(patch)
if not info:
patch = self.lookup(patch)
info = self.isapplied(patch)
if not info:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("patch %s is not applied") % patch)
Ben Thomas
Modify qpush/qpop idempotent operations to return success...
r4100
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # Allow qpop -a to work repeatedly,
# but not qpop without an argument
self.ui.warn(_("no patches applied\n"))
return not all
mason@suse.com
Add mq extension
r1808
Dirkjan Ochtman
mq: refactor the pop code to be more readable and allow more changes
r7620 if all:
start = 0
elif patch:
start = info[0] + 1
else:
start = len(self.applied) - 1
if start >= len(self.applied):
self.ui.warn(_("qpop: %s is already at the top\n") % patch)
return
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if not update:
parents = repo.dirstate.parents()
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 rr = [x.node for x in self.applied]
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 for p in parents:
if p in rr:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("qpop: forcing dirstate update\n"))
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 update = True
Dirkjan Ochtman
mq: allow qpop if popped revisions are not working dir parents
r7621 else:
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 parents = [p.node() for p in repo[None].parents()]
Martin von Zweigbergk
mq: don't reimplement any()...
r36361 update = any(entry.node in parents
for entry in self.applied[start:])
mason@suse.com
Add mq extension
r1808
Patrick Mezard
mq: backup local changes in qpop --force (issue3433)
r16633 tobackup = set()
if update:
Martin von Zweigbergk
strip: make checklocalchanges() return full status tuple...
r22925 s = self.checklocalchanges(repo, force=force or keepchanges)
Patrick Mezard
mq: introduce qpop --check...
r16653 if force:
if not nobackup:
Martin von Zweigbergk
strip: make checklocalchanges() return full status tuple...
r22925 tobackup.update(s.modified + s.added)
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 elif keepchanges:
Martin von Zweigbergk
strip: make checklocalchanges() return full status tuple...
r22925 tobackup.update(s.modified + s.added +
s.removed + s.deleted)
Idan Kamara
backout of d04ba50e104d: allow to qpop/push with a dirty working copy...
r14732
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.applieddirty = True
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 end = len(self.applied)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 rev = self.applied[start].node
Alexis S. L. Carvalho
mq: pop/refresh: avoid losing revisions not managed by mq...
r5980
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)
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('trying to pop unknown node %s') % node)
Dirkjan Ochtman
mq: allow qpop if popped revisions are not working dir parents
r7621
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 if heads != [self.applied[-1].node]:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("popping would remove a revision not "
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 "managed by this patch queue"))
Pierre-Yves David
mq: prevent rewriting operation on public changeset...
r16048 if not repo[self.applied[-1].node].mutable():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Jordi Gutiérrez Hermoso
phases: rewrite "immutable changeset" to "public changeset"...
r25411 _("popping would remove a public revision"),
timeless
mq: use single quotes in use warning
r29968 hint=_("see 'hg help phases' for details"))
Alexis S. L. Carvalho
mq: pop/refresh: avoid losing revisions not managed by mq...
r5980
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 # we know there are no local changes, so we can make a simplified
# form of hg.update.
if update:
qp = self.qparents(repo, rev)
Benoit Boissinot
mq: simplify and use context API
r10663 ctx = repo[qp]
Mads Kiilerich
mq: fix qpop of working directory parent patch when not at qtip...
r18342 m, a, r, d = repo.status(qp, '.')[:4]
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 if d:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("deletions found between repo revs"))
Patrick Mezard
mq: backup local changes in qpop --force (issue3433)
r16633
Patrick Mezard
mq: introduce qpop --check...
r16653 tobackup = set(a + m + r) & tobackup
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 if keepchanges and tobackup:
timeless@mozdev.org
mq: consistently use qrefresh
r26780 raise error.Abort(_("local changes found, qrefresh first"))
Patrick Mezard
mq: introduce qpop --check...
r16653 self.backup(repo, tobackup)
Augie Fackler
mq: migrate to context manager for changing dirstate parents
r32347 with repo.dirstate.parentchange():
for f in a:
repo.wvfs.unlinkpath(f, ignoremissing=True)
repo.dirstate.drop(f)
for f in m + r:
fctx = ctx[f]
repo.wwrite(f, fctx.data(), fctx.flags())
repo.dirstate.normal(f)
repo.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]
Jordi Gutiérrez Hermoso
strip: remove -b/--backup codepaths...
r22057 strip(self.ui, repo, [rev], update=False, backup=False)
Angel Ezquerra
mq: update subrepos when applying / unapplying patches that change .hgsubstate...
r19638 for s, state in repo['.'].substate.items():
repo['.'].sub(s).get(state)
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.applied:
Martin Geisler
mq: lowercase output...
r7627 self.ui.write(_("now at: %s\n") % self.applied[-1].name)
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 else:
Martin Geisler
mq: lowercase output...
r7627 self.ui.write(_("patch queue now empty\n"))
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):
Adrian Buehlmann
mq: rename check_toppatch to checktoppatch
r14581 top, patch = self.checktoppatch(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):
Pulkit Goyal
py3: use pycompat.byteskwargs() to fix keyword arguments handling...
r36405 opts = pycompat.byteskwargs(opts)
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
Martin Geisler
mq: lowercase output...
r7627 self.ui.write(_("no patches applied\n"))
Bryan O'Sullivan
qrefresh: exit with status 1 if no patches applied.
r3004 return 1
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 msg = opts.get('msg', '').rstrip()
FUJIWARA Katsunori
mq: fold the code paths to invoke editor into specific logic (qrefresh/qfold)...
r21422 edit = opts.get('edit')
FUJIWARA Katsunori
mq: pass 'editform' argument to 'cmdutil.getcommiteditor'...
r22003 editform = opts.get('editform', 'mq.qrefresh')
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 newuser = opts.get('user')
Thomas Arendsen Hein
Fix bad behaviour when specifying an invalid date (issue700)...
r6139 newdate = opts.get('date')
if newdate:
Boris Feld
util: extract all date-related utils in utils/dateutil module...
r36625 newdate = '%d %d' % dateutil.parsedate(newdate)
mason@suse.com
Add mq extension
r1808 wlock = repo.wlock()
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 try:
Adrian Buehlmann
mq: rename check_toppatch to checktoppatch
r14581 self.checktoppatch(repo)
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 (top, patchfn) = (self.applied[-1].node, self.applied[-1].name)
Alexis S. L. Carvalho
mq: pop/refresh: avoid losing revisions not managed by mq...
r5980 if repo.changelog.heads(top) != [top]:
timeless@mozdev.org
mq: consistently use qrefresh
r26780 raise error.Abort(_("cannot qrefresh a revision with children"))
Pierre-Yves David
mq: prevent rewriting operation on public changeset...
r16048 if not repo[top].mutable():
timeless@mozdev.org
mq: consistently use qrefresh
r26780 raise error.Abort(_("cannot qrefresh public revision"),
timeless
mq: use single quotes in use warning
r29968 hint=_("see 'hg help phases' for details"))
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366
FUJIWARA Katsunori
mq: check subrepo synchronizations against parent of workdir or other appropriate context...
r17153 cparents = repo.changelog.parents(top)
patchparent = self.qparents(repo, top)
Martin von Zweigbergk
mq: avoid a silly conversion from binary nodeid to hex...
r37399 inclsubs = checksubstate(repo, patchparent)
FUJIWARA Katsunori
mq: create patch file after commit to import diff of ".hgsubstate" at qrefresh...
r17152 if inclsubs:
substatestate = repo.dirstate['.hgsubstate']
Kevin Bullock
mq: update .hgsubstate if subrepos are clean (issue2499)...
r13174
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(self.join(patchfn), self.plainmode)
Mads Kiilerich
mq: create non-lossy patches, also with custom global diff configuration...
r34092 diffopts = self.diffopts({'git': opts.get('git')}, patchfn,
plain=True)
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673 if newuser:
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 ph.setuser(newuser)
Peter Arrenbrecht
mq: add --currentdate and --date options to qnew and qrefresh...
r5788 if newdate:
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 ph.setdate(newdate)
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph.setparent(hex(patchparent))
Brendan Cully
mq: truncate patch just before rewriting header
r5180
Brendan Cully
mq: use atomictempfiles during patch refresh
r7400 # only commit new patch when write is complete
patchf = self.opener(patchfn, 'w', atomictemp=True)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # update the dirstate in place, strip off the qtip commit
# and then commit.
#
# this should really read:
Martin Geisler
mq: fix comment to reflect change in efbee27415ab
r13005 # mm, dd, aa = repo.status(top, patchparent)[:3]
Mads Kiilerich
fix wording and not-completely-trivial spelling errors and bad docstrings
r17425 # but we do it backwards to take advantage of manifest/changelog
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # caching against the next repo.status call
Kevin Bullock
mq: clean up unused variable in qrefresh...
r13004 mm, aa, dd = repo.status(patchparent, top)[:3]
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 changes = repo.changelog.read(top)
Durham Goode
manifest: remove usages of manifest.read...
r30369 man = repo.manifestlog[changes[0]].read()
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 aaa = aa[:]
Martin von Zweigbergk
cleanup: rename "matchfn" to "match" where obviously a matcher...
r34085 match1 = scmutil.match(repo[None], pats, opts)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # in short mode, we only diff the files included in the
# patch already plus specified files
if opts.get('short'):
# if amending a patch, we start with existing
# files plus specified files - unfiltered
Martin von Zweigbergk
cleanup: rename "matchfn" to "match" where obviously a matcher...
r34085 match = scmutil.matchfiles(repo, mm + aa + dd + match1.files())
Mads Kiilerich
fix trivial spelling errors
r17424 # filter with include/exclude options
Martin von Zweigbergk
cleanup: rename "matchfn" to "match" where obviously a matcher...
r34085 match1 = scmutil.match(repo[None], opts=opts)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 else:
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 match = scmutil.matchall(repo)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 m, a, r, d = repo.status(match=match)[:4]
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 mm = set(mm)
aa = set(aa)
dd = set(dd)
mason@suse.com
Add mq extension
r1808
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # we might end up with files that were added between
# qtip and the dirstate parent, but then changed in the
# local dirstate. in this case, we want them to only
# show up in the added section
for x in m:
if x not in aa:
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 mm.add(x)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # we might end up with files added by the local dirstate that
# were deleted by the patch. In this case, they should only
# show up in the changed section.
for x in a:
if x in dd:
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 dd.remove(x)
mm.add(x)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 else:
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 aa.add(x)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # make sure any files deleted in the local dirstate
# are not in the add or change column of the patch
forget = []
for x in d + r:
if x in aa:
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 aa.remove(x)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 forget.append(x)
continue
Nicolas Dumazet
mq: use sets instead of lists for speed...
r12948 else:
mm.discard(x)
dd.add(x)
m = list(mm)
r = list(dd)
a = list(aa)
Durham Goode
mq: fix qrefresh case sensitivity (issue3271)...
r17888
Mads Kiilerich
spelling: fix some minor issues found by spell checker
r18644 # create 'match' that includes the files to be recommitted.
Martin von Zweigbergk
cleanup: rename "matchfn" to "match" where obviously a matcher...
r34085 # apply match1 via repo.status to ensure correct case handling.
cm, ca, cr, cd = repo.status(patchparent, match=match1)[:4]
Durham Goode
mq: fix qrefresh case sensitivity (issue3271)...
r17888 allmatches = set(cm + ca + cr + cd)
refreshchanges = [x.intersection(allmatches) for x in (mm, aa, dd)]
files = set(inclsubs)
for x in refreshchanges:
FUJIWARA Katsunori
localrepo: omit ".hgsubstate" also from "added" files...
r20827 files.update(x)
Durham Goode
mq: fix qrefresh case sensitivity (issue3271)...
r17888 match = scmutil.matchfiles(repo, files)
David Soria Parra
mq: update bookmarks during qrefresh...
r17730 bmlist = repo[top].bookmarks()
mason@suse.com
Add mq extension
r1808
FUJIWARA Katsunori
mq: use dirstateguard instead of dirstate.invalidate (qrefresh)...
r24997 dsguard = None
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 try:
Augie Fackler
mq: refer to dirstateguard by its new name
r30489 dsguard = dirstateguard.dirstateguard(repo, 'mq.refresh')
Patrick Mezard
Merge with crew-stable
r10368 if diffopts.git or diffopts.upgrade:
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 copies = {}
for dst in a:
src = repo.dirstate.copied(dst)
# during qfold, the source file for copies may
# be removed. Treat this as a simple add.
if src is not None and src in repo.dirstate:
copies.setdefault(src, []).append(dst)
repo.dirstate.add(dst)
# remember the copies between patchparent and qtip
for dst in aaa:
f = repo.file(dst)
src = f.renamed(man[dst])
if src:
Patrick Mezard
Merge with crew-stable
r10368 copies.setdefault(src[0], []).extend(
copies.get(dst, []))
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 if dst in a:
copies[src[0]].append(dst)
# we can't copy a file created by the patch itself
if dst in copies:
del copies[dst]
for src, dsts in copies.iteritems():
for dst in dsts:
repo.dirstate.copy(src, dst)
else:
for dst in a:
repo.dirstate.add(dst)
# Drop useless copy information
for f in list(repo.dirstate.copies()):
repo.dirstate.copy(None, f)
for f in r:
repo.dirstate.remove(f)
# if the patch excludes a modified file, mark that
# file with mtime=0 so status can see it.
mm = []
Mads Kiilerich
check-code: there must also be whitespace between ')' and operator...
r18054 for i in xrange(len(m) - 1, -1, -1):
Martin von Zweigbergk
cleanup: rename "matchfn" to "match" where obviously a matcher...
r34085 if not match1(m[i]):
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 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:
Matt Mackall
dirstate: rename forget to drop...
r14434 repo.dirstate.drop(f)
mason@suse.com
Add mq extension
r1808
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 user = ph.user or changes[1]
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673
Pierre-Yves David
qrefresh: keep changeset phase during refresh
r16026 oldphase = repo[top].phase()
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 # assumes strip can roll itself back if interrupted
Patrick Mezard
localrepo: add setparents() to adjust dirstate copies (issue3407)...
r16551 repo.setparents(*cparents)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 self.applied.pop()
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.applieddirty = True
Jordi Gutiérrez Hermoso
strip: remove -b/--backup codepaths...
r22057 strip(self.ui, repo, [top], update=False, backup=False)
FUJIWARA Katsunori
mq: use dirstateguard instead of dirstate.invalidate (qrefresh)...
r24997 dsguard.close()
finally:
release(dsguard)
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366
try:
# might be nice to attempt to roll back strip after this
Patrick Mezard
mq: ensure all mq commits are made with secretcommit()...
r16100
FUJIWARA Katsunori
qrefresh: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21236 defaultmsg = "[mq]: %s" % patchfn
FUJIWARA Katsunori
mq: pass 'editform' argument to 'cmdutil.getcommiteditor'...
r22003 editor = cmdutil.getcommiteditor(editform=editform)
FUJIWARA Katsunori
mq: fold the code paths to invoke editor into specific logic (qrefresh/qfold)...
r21422 if edit:
FUJIWARA Katsunori
mq: use the editor gotten by "getcommiteditor()" instead of "ui.edit()" (qrefresh/qfold)...
r21423 def finishdesc(desc):
FUJIWARA Katsunori
qrefresh: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21236 if desc.rstrip():
ph.setmessage(desc)
return desc
return defaultmsg
FUJIWARA Katsunori
mq: use the editor gotten by "getcommiteditor()" instead of "ui.edit()" (qrefresh/qfold)...
r21423 # i18n: this message is shown in editor with "HG: " prefix
extramsg = _('Leave message empty to use default message.')
editor = cmdutil.getcommiteditor(finishdesc=finishdesc,
FUJIWARA Katsunori
mq: pass 'editform' argument to 'cmdutil.getcommiteditor'...
r22003 extramsg=extramsg,
editform=editform)
FUJIWARA Katsunori
qrefresh: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21236 message = msg or "\n".join(ph.message)
elif not msg:
FUJIWARA Katsunori
qrefresh: relocate message/patch-header handling to delay message determination...
r21235 if not ph.message:
FUJIWARA Katsunori
qrefresh: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21236 message = defaultmsg
FUJIWARA Katsunori
qrefresh: relocate message/patch-header handling to delay message determination...
r21235 else:
message = "\n".join(ph.message)
else:
message = msg
ph.setmessage(msg)
Patrick Mezard
mq: ensure all mq commits are made with secretcommit()...
r16100 # Ensure we create a new changeset in the same phase than
# the old one.
Laurent Charignon
mq: use repo._bookmarks.recordchange instead of repo._bookmarks.write...
r27001 lock = tr = None
try:
lock = repo.lock()
tr = repo.transaction('mq')
Laurent Charignon
mq: indentation change to make the next patch more legible...
r27000 n = newcommit(repo, oldphase, message, user, ph.date,
FUJIWARA Katsunori
qrefresh: use "editor" argument of "commit()" instead of explicit "ui.edit()"...
r21236 match=match, force=True, editor=editor)
Laurent Charignon
mq: indentation change to make the next patch more legible...
r27000 # only write patch after a successful commit
c = [list(x) for x in refreshchanges]
if inclsubs:
self.putsubstate2changes(substatestate, c)
chunks = patchmod.diff(repo, patchparent,
changes=c, opts=diffopts)
Pulkit Goyal
py3: use bytes instead of str...
r35966 comments = bytes(ph)
Laurent Charignon
mq: indentation change to make the next patch more legible...
r27000 if comments:
patchf.write(comments)
for chunk in chunks:
patchf.write(chunk)
patchf.close()
marks = repo._bookmarks
Boris Feld
bookmark: use 'applychanges' in the mq extension
r33489 marks.applychanges(repo, tr, [(bm, n) for bm in bmlist])
Laurent Charignon
mq: use repo._bookmarks.recordchange instead of repo._bookmarks.write...
r27001 tr.close()
Laurent Charignon
mq: indentation change to make the next patch more legible...
r27000
self.applied.append(statusentry(n, patchfn))
Laurent Charignon
mq: use repo._bookmarks.recordchange instead of repo._bookmarks.write...
r27001 finally:
Pierre-Yves David
mq: release lock after transaction in qrefresh...
r30070 lockmod.release(tr, lock)
Brodie Rao
check-code: ignore naked excepts with a "re-raise" comment...
r16705 except: # re-raises
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 ctx = repo[cparents[0]]
repo.dirstate.rebuild(ctx.node(), ctx.manifest())
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 self.savedirty()
timeless@mozdev.org
mq: consistently use qrefresh
r26780 self.ui.warn(_('qrefresh interrupted while patch was popped! '
Dan Villiom Podlaski Christiansen
mq: remove qrefresh slow path (issue2025)...
r10366 '(revert --all, qpush to recover)\n'))
raise
Matt Mackall
Use try/finally pattern to cleanup locks and transactions
r4915 finally:
Ronny Pfannschmidt
switch lock releasing in the extensions from gc to explicit
r8112 wlock.release()
Brendan Cully
mq: recover more gracefully from interrupted qrefresh (issue1216)
r7401 self.removeundo(repo)
mason@suse.com
Add mq extension
r1808
def init(self, repo, create=False):
Alexis S. L. Carvalho
mq: qinit -c creates a repo even after a regular qinit
r4071 if not create and os.path.isdir(self.path):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.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)
Gregory Szorc
global: mass rewrite to use modern exception syntax...
r25660 except OSError as inst:
Alexis S. L. Carvalho
mq: qinit -c creates a repo even after a regular qinit
r4071 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:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("patch %s is not in series file") % patch)
mason@suse.com
Add mq extension
r1808 if not patch:
Adrian Buehlmann
mq: rename series_end to seriesend
r14586 start = self.seriesend()
mason@suse.com
Add mq extension
r1808 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]))
Adrian Buehlmann
mq: rename explain_pushable to explainpushable
r14579 self.explainpushable(i)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 return unapplied
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 def qseries(self, repo, missing=None, start=0, length=None, status=None,
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 summary=False):
Brodie Rao
qseries: make use of output labeling
r10824 def displayname(pfx, patchname, state):
Dan Villiom Podlaski Christiansen
mq: only highlight/label patch name for qseries....
r10932 if pfx:
self.ui.write(pfx)
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 if summary:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(self.join(patchname), self.plainmode)
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if ph.message:
msg = ph.message[0]
else:
msg = ''
Dan Villiom Podlaski Christiansen
mq: use ui.formatted() instead of ui.plain().
r11327 if self.ui.formatted():
Augie Fackler
termwidth: move to ui.ui from util
r12689 width = self.ui.termwidth() - len(pfx) - len(patchname) - 2
Dan Villiom Podlaski Christiansen
qseries: don't truncate the patch name (issue1912)...
r9874 if width > 0:
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 msg = stringutil.ellipsis(msg, width)
Dan Villiom Podlaski Christiansen
qseries: don't truncate the patch name (issue1912)...
r9874 else:
msg = ''
Dan Villiom Podlaski Christiansen
mq: only highlight/label patch name for qseries....
r10932 self.ui.write(patchname, label='qseries.' + state)
self.ui.write(': ')
self.ui.write(msg, label='qseries.message.' + state)
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 else:
Dan Villiom Podlaski Christiansen
mq: only highlight/label patch name for qseries....
r10932 self.ui.write(patchname, label='qseries.' + state)
self.ui.write('\n')
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183
Martin Geisler
replace set-like dictionaries with real sets...
r8152 applied = set([p.name for p in self.applied])
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 if length is None:
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 length = len(self.series) - start
mason@suse.com
Add mq extension
r1808 if not missing:
Dan Villiom Podlaski Christiansen
mq: align columns in verbose qseries output.
r9016 if self.ui.verbose:
Pulkit Goyal
py3: use b"%d" to covert integer to bytes instead of str...
r36686 idxwidth = len("%d" % (start + length - 1))
Matt Mackall
many, many trivial check-code fixups
r10282 for i in xrange(start, start + length):
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 patch = self.series[i]
if patch in applied:
Brodie Rao
qseries: make use of output labeling
r10824 char, state = 'A', 'applied'
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 elif self.pushable(i)[0]:
Brodie Rao
qseries: make use of output labeling
r10824 char, state = 'U', 'unapplied'
Thomas Arendsen Hein
Simplified qseries and hg qapplied to fix some bugs caused by optimization:...
r4239 else:
Brodie Rao
qseries: make use of output labeling
r10824 char, state = 'G', 'guarded'
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 pfx = ''
mason@suse.com
Add mq extension
r1808 if self.ui.verbose:
Brodie Rao
qseries: make use of output labeling
r10824 pfx = '%*d %s ' % (idxwidth, i, char)
elif status and status != char:
Thomas Arendsen Hein
Fix issue443: inconsistent output of "hg qunapplied -v"...
r4238 continue
Brodie Rao
qseries: make use of output labeling
r10824 displayname(pfx, patch, state)
mason@suse.com
Add mq extension
r1808 else:
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 msng_list = []
mason@suse.com
Add mq extension
r1808 for root, dirs, files in os.walk(self.path):
d = root[len(self.path) + 1:]
for f in files:
fl = os.path.join(d, f)
Thomas Arendsen Hein
Fix mq's usage of opener, which don't allow absolute paths now.
r1852 if (fl not in self.series and
Adrian Buehlmann
mq: rename status_path to statuspath
r14588 fl not in (self.statuspath, self.seriespath,
Adrian Buehlmann
mq: rename guards_path to guardspath
r14589 self.guardspath)
Thomas Arendsen Hein
Fix mq's usage of opener, which don't allow absolute paths now.
r1852 and not fl.startswith('.')):
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 msng_list.append(fl)
Matt Mackall
replace util.sort with sorted built-in...
r8209 for x in sorted(msng_list):
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 pfx = self.ui.verbose and ('D ') or ''
Brodie Rao
qseries: make use of output labeling
r10824 displayname(pfx, x, 'missing')
mason@suse.com
Add mq extension
r1808
def issaveline(self, l):
Brendan Cully
Update qsave to use StatusEntry; don't throw exception on bad status lines.
r2816 if l.name == '.hg.patches.save.line':
mason@suse.com
Add mq extension
r1808 return True
def qrepo(self, create=False):
Simon Heimberg
mq: do not inherit settings form base repo in mqrepo (Fixes issue2358)...
r19064 ui = self.baseui.copy()
Yuya Nishihara
mq: copy pager attributes back to qrepo.ui...
r34919 # copy back attributes set by ui.pager()
if self.ui.pageractive and not ui.pageractive:
ui.pageractive = self.ui.pageractive
# internal config: ui.formatted
ui.setconfig('ui', 'formatted',
self.ui.config('ui', 'formatted'), 'mqpager')
ui.setconfig('ui', 'interactive',
self.ui.config('ui', 'interactive'), 'mqpager')
Vadim Gelfer
mq: add join method
r2819 if create or os.path.isdir(self.join(".hg")):
Mads Kiilerich
mq: don't inherit default and default-push paths with --mq (issue2333)...
r11965 return hg.repository(ui, path=self.path, create=create)
mason@suse.com
Add mq extension
r1808
def restore(self, repo, rev, delete=None, qupdate=None):
Benoit Boissinot
mq: use context API
r10681 desc = repo[rev].description().strip()
mason@suse.com
Add mq extension
r1808 lines = desc.splitlines()
i = 0
datastart = None
series = []
applied = []
qpp = None
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 for i, line in enumerate(lines):
if line == 'Patch Data:':
mason@suse.com
Add mq extension
r1808 datastart = i + 1
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 elif line.startswith('Dirstate:'):
l = line.rstrip()
mason@suse.com
Add mq extension
r1808 l = l[10:].split(' ')
Matt Mackall
many, many trivial check-code fixups
r10282 qpp = [bin(x) for x in l]
Martin Geisler
code style: prefer 'is' and 'is not' tests with singletons
r13031 elif datastart is not None:
Martin Geisler
replace "i in range(len(xs))" with "i, x in enumerate(xs)"...
r8632 l = line.rstrip()
Benoit Boissinot
mq: qsave creates entries with the left part empty (':patchname')
r10683 n, name = l.split(':', 1)
if n:
applied.append(statusentry(bin(n), name))
Brendan Cully
mq: don't write applied patches into series twice in restore
r3185 else:
Benoit Boissinot
mq: simplify statusentry(), fix restore broken by ee48e5ef8753
r10682 series.append(l)
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if datastart is None:
Martin Geisler
mq: lowercase warning messages
r16929 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])
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 self.fullseries = series
mason@suse.com
Add mq extension
r1808 self.applied = applied
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 self.parseseries()
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.seriesdirty = True
self.applieddirty = True
mason@suse.com
Add mq extension
r1808 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
Jordi Gutiérrez Hermoso
strip: remove -b/--backup codepaths...
r22057 strip(self.ui, repo, [rev], update=update, backup=False)
mason@suse.com
Add mq extension
r1808 if qpp:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("saved queue repository parents: %s %s\n") %
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 (short(qpp[0]), short(qpp[1])))
mason@suse.com
Add mq extension
r1808 if qupdate:
timeless
qrestore: trying to improve the English
r12848 self.ui.status(_("updating queue directory\n"))
mason@suse.com
Add mq extension
r1808 r = self.qrepo()
if not r:
Martin Geisler
mq: lowercase warning messages
r16929 self.ui.warn(_("unable to load queue repository\n"))
mason@suse.com
Add mq extension
r1808 return 1
Matt Mackall
Introduce update helper functions: update, merge, clean, and revert
r2808 hg.clean(r, qpp[0])
mason@suse.com
Add mq extension
r1808
def save(self, repo, msg=None):
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if not self.applied:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("save: no patches applied, exiting\n"))
mason@suse.com
Add mq extension
r1808 return 1
if self.issaveline(self.applied[-1]):
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("status is already saved\n"))
mason@suse.com
Add mq extension
r1808 return 1
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808 if not msg:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 msg = _("hg patches saved state")
mason@suse.com
Add mq extension
r1808 else:
msg = "hg patches: " + msg.rstrip('\r\n')
r = self.qrepo()
if r:
pp = r.dirstate.parents()
Joel Rosdahl
Avoid importing mercurial.node/mercurial.repo stuff from mercurial.hg
r6217 msg += "\nDirstate: %s %s" % (hex(pp[0]), hex(pp[1]))
mason@suse.com
Add mq extension
r1808 msg += "\n\nPatch Data:\n"
Benoit Boissinot
mq: simplify commit message generation
r10679 msg += ''.join('%s\n' % x for x in self.applied)
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 msg += ''.join(':%s\n' % x for x in self.fullseries)
Benoit Boissinot
mq: simplify commit message generation
r10679 n = repo.commit(msg, force=True)
mason@suse.com
Add mq extension
r1808 if not n:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_("repo commit failed\n"))
mason@suse.com
Add mq extension
r1808 return 1
Benoit Boissinot
mq: fix coding style (missing space)
r10684 self.applied.append(statusentry(n, '.hg.patches.save.line'))
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 self.applieddirty = True
Matt Mackall
Merge with -stable, fix small test failure
r4209 self.removeundo(repo)
mason@suse.com
Add mq extension
r1808
Adrian Buehlmann
mq: rename full_series_end to fullseriesend
r14585 def fullseriesend(self):
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.applied:
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 p = self.applied[-1].name
Adrian Buehlmann
mq: rename find_series to findseries
r14574 end = self.findseries(p)
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if end is None:
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 return len(self.fullseries)
Chris Mason
mq: fix qnew and qimport to deal with series file comments...
r2698 return end + 1
return 0
Adrian Buehlmann
mq: rename series_end to seriesend
r14586 def seriesend(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
Augie Fackler
mq: rename next() to nextpatch() to avoid confusing a future check-code patch...
r19500 def nextpatch(start):
Benoit Boissinot
mq: use xrange/enumerate instead of += 1
r10687 if all_patches or start >= len(self.series):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 return start
Benoit Boissinot
mq: use xrange/enumerate instead of += 1
r10687 for i in xrange(start, len(self.series)):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 p, reason = self.pushable(i)
if p:
Patrick Mezard
mq: fix qnext when all remaining patches are guarded...
r16063 return i
Adrian Buehlmann
mq: rename explain_pushable to explainpushable
r14579 self.explainpushable(i)
Patrick Mezard
mq: fix qnext when all remaining patches are guarded...
r16063 return len(self.series)
Benoit Boissinot
mq: don't use len(list) unless necessary
r10686 if self.applied:
Brendan Cully
Use StatusEntry class instead of repeated status line parsing....
r2780 p = self.applied[-1].name
mason@suse.com
Add mq extension
r1808 try:
end = self.series.index(p)
except ValueError:
return 0
Augie Fackler
mq: rename next() to nextpatch() to avoid confusing a future check-code patch...
r19500 return nextpatch(end + 1)
return nextpatch(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:
Pulkit Goyal
py3: use b"%d" to covert integer to bytes instead of str...
r36686 p = ("%d" % 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:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('patch %s is already in the series file')
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 % patchname)
if rev:
if files:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('option "-r" not valid when importing '
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 'files'))
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 rev = scmutil.revrange(repo, rev)
Alejandro Santos
compat: use 'key' argument instead of 'cmp' when sorting a list
r9032 rev.sort(reverse=True)
Thomas Arendsen Hein
mq: abort if no files or revisions are specified for qimport
r16987 elif not files:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no files or revisions specified'))
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 if (len(files) > 1 or len(rev) > 1) and patchname:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('option "-n" not valid when importing multiple '
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 'patches'))
Patrick Mezard
mq: make qimport --push push all imported patches (issue3130)...
r16119 imported = []
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.
Pierre-Yves David
qimport: use `first` and `last` instead of direct indexing...
r22821 heads = repo.changelog.heads(repo.changelog.node(rev.first()))
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 if len(heads) > 1:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('revision %d is the root of more than one '
Pierre-Yves David
mq: use `last` instead of direct indexing...
r22819 'branch') % rev.last())
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 if self.applied:
Pierre-Yves David
qimport: use `first` and `last` instead of direct indexing...
r22821 base = repo.changelog.node(rev.first())
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 if base in [n.node for n in self.applied]:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('revision %d is already managed')
Pierre-Yves David
mq: do not call [0] on revset...
r23128 % rev.first())
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 if heads != [self.applied[-1].node]:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('revision %d is not the parent of '
Pierre-Yves David
qimport: use `first` and `last` instead of direct indexing...
r22821 'the queue') % rev.first())
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 base = repo.changelog.rev(self.applied[0].node)
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 lastparent = repo.changelog.parentrevs(base)[0]
else:
Pierre-Yves David
qimport: use `first` and `last` instead of direct indexing...
r22821 if heads != [repo.changelog.node(rev.first())]:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('revision %d has unmanaged children')
Pierre-Yves David
qimport: use `first` and `last` instead of direct indexing...
r22821 % rev.first())
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 lastparent = None
Patrick Mezard
mq: stop caching and sharing diff options...
r10184 diffopts = self.diffopts({'git': git})
Bryan O'Sullivan
with: use context manager for transaction in qimport
r27865 with repo.transaction('qimport') as tr:
Pierre-Yves David
mq: wrap qimport phase movement in a transaction...
r22049 for r in rev:
if not repo[r].mutable():
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('revision %d is not mutable') % r,
timeless
mq: use single quotes in use warning
r29968 hint=_("see 'hg help phases' "
Pierre-Yves David
mq: wrap qimport phase movement in a transaction...
r22049 'for details'))
p1, p2 = repo.changelog.parentrevs(r)
n = repo.changelog.node(r)
if p2 != nullrev:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot import merge revision %d')
Pierre-Yves David
mq: wrap qimport phase movement in a transaction...
r22049 % r)
if lastparent and lastparent != r:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('revision %d is not the parent of '
Pierre-Yves David
mq: wrap qimport phase movement in a transaction...
r22049 '%d')
% (r, lastparent))
lastparent = p1
if not patchname:
Mads Kiilerich
mq: refactor makepatchname into class method
r27918 patchname = self.makepatchname(
FUJIWARA Katsunori
mq: use fallback patch name if no alpha-numeric in summary line (issue5025)...
r27513 repo[r].description().split('\n', 1)[0],
'%d.diff' % r)
Pierre-Yves David
mq: wrap qimport phase movement in a transaction...
r22049 checkseries(patchname)
self.checkpatchname(patchname, force)
self.fullseries.insert(0, patchname)
Yuya Nishihara
export: extract function to write patch to file object (API)...
r37621 with self.opener(patchname, "w") as fp:
cmdutil.exportfile(repo, [n], fp, opts=diffopts)
Pierre-Yves David
mq: wrap qimport phase movement in a transaction...
r22049
se = statusentry(n, patchname)
self.applied.insert(0, se)
self.added.append(patchname)
imported.append(patchname)
patchname = None
Boris Feld
configitems: register the 'mq.secret' config
r34185 if rev and repo.ui.configbool('mq', 'secret'):
Pierre-Yves David
mq: wrap qimport phase movement in a transaction...
r22049 # if we added anything with --rev, move the secret root
Pierre-Yves David
phase: add a transaction argument to retractboundary...
r22070 phases.retractboundary(repo, tr, phases.secret, [n])
Pierre-Yves David
mq: wrap qimport phase movement in a transaction...
r22049 self.parseseries()
self.applieddirty = True
self.seriesdirty = True
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141
Benoit Boissinot
mq: use xrange/enumerate instead of += 1
r10687 for i, filename in enumerate(files):
mason@suse.com
Add mq extension
r1808 if existing:
Brendan Cully
mq: support qimport -
r3547 if filename == '-':
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('-e is incompatible with import from -')
)
Nicolas Dumazet
mq: support "qimport --existing --name renametothis thatexistingpatch"...
r11699 filename = normname(filename)
Adrian Buehlmann
mq: rename check_reserved_name to checkreservedname
r14584 self.checkreservedname(filename)
Matt Mackall
mq: fix qimport url check
r20402 if util.url(filename).islocal():
Matt Mackall
qimport: allow importing URLs
r20394 originpath = self.join(filename)
if not os.path.isfile(originpath):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Matt Mackall
mq: fix qimport url check
r20402 _("patch %s does not exist") % filename)
Nicolas Dumazet
mq: support "qimport --existing --name renametothis thatexistingpatch"...
r11699
if patchname:
Idan Kamara
mq: use checkpatchname...
r14423 self.checkpatchname(patchname, force)
Nicolas Dumazet
mq: support "qimport --existing --name renametothis thatexistingpatch"...
r11699
self.ui.write(_('renaming %s to %s\n')
% (filename, patchname))
Patrick Mezard
mq: fix qimport --name --existing --force on win32...
r11701 util.rename(originpath, self.join(patchname))
Nicolas Dumazet
mq: support "qimport --existing --name renametothis thatexistingpatch"...
r11699 else:
patchname = filename
mason@suse.com
Add mq extension
r1808 else:
Idan Kamara
mq: check patch name is valid before reading imported file
r14395 if filename == '-' and not patchname:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('need --name to import a patch from -'))
Idan Kamara
mq: check patch name is valid before reading imported file
r14395 elif not patchname:
Idan Kamara
mq: strip all leading slashes from url when importing...
r14396 patchname = normname(os.path.basename(filename.rstrip('/')))
Idan Kamara
mq: use checkpatchname...
r14423 self.checkpatchname(patchname, force)
mason@suse.com
Add mq extension
r1808 try:
Brendan Cully
mq: support qimport -
r3547 if filename == '-':
Idan Kamara
mq: use ui.fin when importing patch from '-'
r14636 text = self.ui.fin.read()
Brendan Cully
mq: support qimport -
r3547 else:
Siddharth Agarwal
url: use open and not url.open for local files (issue3624)
r17887 fp = hg.openpath(self.ui, filename)
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 text = fp.read()
fp.close()
Benoit Boissinot
Catch both IOError and OSError, fix regression introduced by 8046f0a070a6
r7421 except (OSError, IOError):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("unable to read file %s") % filename)
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 patchf = self.opener(patchname, "w")
mason@suse.com
Add mq extension
r1808 patchf.write(text)
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 patchf.close()
Brendan Cully
mq: make qimport -f work properly. Closes issue1255....
r7160 if not force:
checkseries(patchname)
if patchname not in self.series:
Adrian Buehlmann
mq: rename full_series_end to fullseriesend
r14585 index = self.fullseriesend() + i
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 self.fullseries[index:index] = [patchname]
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 self.parseseries()
Adrian Buehlmann
mq: rename series_dirty to seriesdirty
r14593 self.seriesdirty = True
Martin Geisler
mq, i18n: mark strings for translation
r7597 self.ui.warn(_("adding %s to series file\n") % patchname)
Vishakh H
mq: qimport cleanup on fail (issue2214)...
r11462 self.added.append(patchname)
Patrick Mezard
mq: make qimport --push push all imported patches (issue3130)...
r16119 imported.append(patchname)
Brendan Cully
qimport: rename patch to patchname to avoid shadowing module
r3133 patchname = None
mason@suse.com
Add mq extension
r1808
André Sintzoff
mq: remove undo after a qimport
r13409 self.removeundo(repo)
Patrick Mezard
mq: make qimport --push push all imported patches (issue3130)...
r16119 return imported
André Sintzoff
mq: remove undo after a qimport
r13409
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 def fixkeepchangesopts(ui, opts):
if (not ui.configbool('mq', 'keepchanges') or opts.get('force')
Patrick Mezard
mq: introduce mq.check setting...
r16656 or opts.get('exact')):
return opts
opts = dict(opts)
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 opts['keep_changes'] = True
Patrick Mezard
mq: introduce mq.check setting...
r16656 return opts
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qdelete|qremove|qrm",
[('k', 'keep', None, _('keep patch file')),
('r', 'rev', [],
_('stop managing a revision (DEPRECATED)'), _('REV'))],
_('hg qdelete [-k] [PATCH]...'))
Brendan Cully
mq: change qdel --forget to --rev; accept any revision symbol
r3373 def delete(ui, repo, *patches, **opts):
Brendan Cully
Allow qdel to delete multiple patches.
r2905 """remove patches from queue
Brendan Cully
Add -f option to qdelete, to remove patch file.
r2752
Olav Reinert
mq: Document that qdel requires exact patch identifiers
r15798 The patches must not be applied, and at least one patch is required. Exact
patch identifiers must be given. With -k/--keep, the patch files are
preserved in the patch directory.
Cédric Duval
mq: no longer mention the deprecated qdelete's --revision option...
r8904
To stop managing a patch and move it into permanent history,
Martin Geisler
mq: use hg reST role some more
r11307 use the :hg:`qfinish` command."""
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Pulkit Goyal
py3: use pycompat.byteskwargs() to convert opts keys to bytes...
r36295 q.delete(repo, patches, pycompat.byteskwargs(opts))
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qapplied",
Patrick Mezard
mq: fix qapplied --last and qprev documentation (issue3282)...
r16188 [('1', 'last', None, _('show only the preceding applied patch'))
Martin Geisler
mq: use cmdutil.command decorator
r14298 ] + seriesopts,
_('hg qapplied [-1] [-s] [PATCH]'))
mason@suse.com
Add mq extension
r1808 def applied(ui, repo, patch=None, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the patches already applied
Returns 0 on success."""
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 if patch:
if patch not in q.series:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("patch %s is not in series file") % patch)
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 end = q.series.index(patch) + 1
else:
Adrian Buehlmann
mq: rename series_end to seriesend
r14586 end = q.seriesend(True)
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
if opts.get('last') and not end:
ui.write(_("no patches applied\n"))
return 1
elif opts.get('last') and end == 1:
ui.write(_("only one patch applied\n"))
return 1
elif opts.get('last'):
start = end - 2
end = 1
else:
start = 0
Erik Zielke
mq: removed return from callers to patchheader.qseries...
r12539 q.qseries(repo, length=end, start=start, status='A',
summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qunapplied",
[('1', 'first', None, _('show only the first patch'))] + seriesopts,
_('hg qunapplied [-1] [-s] [PATCH]'))
mason@suse.com
Add mq extension
r1808 def unapplied(ui, repo, patch=None, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the patches not yet applied
Returns 0 on success."""
Dirkjan Ochtman
mq: add options to qapplied/qunapplied to act like qprev/qnext
r9364
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 if patch:
if patch not in q.series:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_("patch %s is not in series file") % patch)
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 start = q.series.index(patch) + 1
else:
Adrian Buehlmann
mq: rename series_end to seriesend
r14586 start = q.seriesend(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
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if opts.get('first'):
length = 1
else:
length = None
Erik Zielke
mq: removed return from callers to patchheader.qseries...
r12539 q.qseries(repo, start=start, length=length, status='U',
summary=opts.get('summary'))
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qimport",
[('e', 'existing', None, _('import file in patch directory')),
('n', 'name', '',
_('name of patch file'), _('NAME')),
('f', 'force', None, _('overwrite existing files')),
('r', 'rev', [],
_('place existing revisions under mq control'), _('REV')),
('g', 'git', None, _('use git extended diff format')),
('P', 'push', None, _('qpush after importing'))],
Thomas Arendsen Hein
qimport: use [FILE]... because if -r is used no file is needed
r16988 _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... [FILE]...'))
mason@suse.com
Add mq extension
r1808 def qimport(ui, repo, *filename, **opts):
Matt Mackall
mq: expand qimport summary
r16152 """import a patch or existing changeset
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141
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
Matt Mackall
mq: remove reference to tip
r19397 (e.g. qimport --rev . -n patch will place the current revision
under mq control). With -g/--git, patches imported with --rev will
use the git diff format. See the diffs help topic for information
on why this is important for preserving rename/copy information
and permission changes. Use :hg:`qfinish` to remove changesets
from mq control.
David Frey
Update qimport help explaining how to read a patch from stdin (Issue371)
r8075
To import a patch from standard input, pass - as the patch file.
When importing from standard input, a patch name must be specified
using the --name flag.
Nicolas Dumazet
mq: document possible combination of -e and -n for qimport
r11700
Nicolas Dumazet
mq: correct qimport documentation
r11706 To import an existing patch while renaming it::
Nicolas Dumazet
mq: document possible combination of -e and -n for qimport
r11700
hg qimport -e existing-patch -n new-name
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 if import succeeded.
Brendan Cully
mq: Add --rev argument to qimport, to adopt existing changesets.
r3141 """
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Bryan O'Sullivan
with: use context manager for lock in qimport
r27832 with repo.lock(): # cause this may move phase
Pierre-Yves David
qimport: when mq.secret=True set qimported revision as secret
r16027 q = repo.mq
try:
Patrick Mezard
mq: make qimport --push push all imported patches (issue3130)...
r16119 imported = q.qimport(
repo, filename, patchname=opts.get('name'),
existing=opts.get('existing'), force=opts.get('force'),
rev=opts.get('rev'), git=opts.get('git'))
Pierre-Yves David
qimport: when mq.secret=True set qimported revision as secret
r16027 finally:
q.savedirty()
Pierre-Yves David
mq: qimport need wlock for --push - do that after releasing lock...
r16681
if imported and opts.get('push') and not opts.get('rev'):
return q.push(repo, imported[-1])
mason@suse.com
Add mq extension
r1808 return 0
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 def qinit(ui, repo, create):
"""initialize a new queue repository
Brendan Cully
Add more verbose help text to mq commands.
r2754
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 This command also creates a series file for ordering patches, and
an mq-specific .hgignore file in the queue repository, to exclude
Erik Zielke
mq: added return 0 on success...
r12538 the status and guards files (these contain mostly transient state).
Returns 0 if initialization succeeded."""
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 r = q.init(repo, create)
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
mason@suse.com
Add mq extension
r1808 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')):
Angel Ezquerra
localrepo: remove all external users of localrepo.wopener...
r23879 fp = r.wvfs('.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')):
Angel Ezquerra
localrepo: remove all external users of localrepo.wopener...
r23879 r.wvfs('series', 'w').close()
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 r[None].add(['.hgignore', 'series'])
Alexis S. L. Carvalho
mq: qinit -c creates a repo even after a regular qinit
r4071 commands.add(ui, r)
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qinit",
[('c', 'create-repo', None, _('create queue repository'))],
_('hg qinit [-c]'))
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 def init(ui, repo, **opts):
"""init a new queue repository (DEPRECATED)
The queue repository is unversioned by default. If
-c/--create-repo is specified, qinit will create a separate nested
repository for patches (qinit -c may also be run later to convert
an unversioned patch repository into a versioned one). You can use
qcommit to commit changes to this queue repository.
This command is deprecated. Without -c, it's implied by other relevant
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 commands. With -c, use :hg:`init --mq` instead."""
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 return qinit(ui, repo, create=opts.get(r'create_repo'))
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qclone",
[('', 'pull', None, _('use pull protocol to copy metadata')),
Brodie Rao
cleanup: eradicate long lines
r16683 ('U', 'noupdate', None,
_('do not update the new working directories')),
Martin Geisler
mq: use cmdutil.command decorator
r14298 ('', 'uncompressed', None,
_('use uncompressed transfer (fast over LAN)')),
('p', 'patches', '',
_('location of source patch repository'), _('REPO')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ] + cmdutil.remoteopts,
Gregory Szorc
mq: define norepo in command decorator
r21771 _('hg qclone [OPTION]... SOURCE [DEST]'),
norepo=True)
Vadim Gelfer
mq: add qclone command
r2720 def clone(ui, source, dest=None, **opts):
'''clone main and patch repository at same time
Martin Geisler
Change double spaces to single spaces in help texts.
r7983 If source is local, destination will have no patches applied. If
Vadim Gelfer
mq: add qclone command
r2720 source is remote, this command can not check if patches are
applied in source, so cannot guarantee that patches are not
Martin Geisler
Change double spaces to single spaces in help texts.
r7983 applied in destination. If you clone remote repository, be sure
Vadim Gelfer
mq: add qclone command
r2720 before that it has no patches applied.
Source patch repository is looked for in <src>/.hg/patches by
Martin Geisler
Change double spaces to single spaces in help texts.
r7983 default. Use -p <url> to change.
Brendan Cully
mq: improve qclone error handling when patch directory is not a repository.
r4862
timeless
Spell Mercurial as a proper noun
r8760 The patch directory must be a nested Mercurial repository, as
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 would be created by :hg:`init --mq`.
Erik Zielke
mq: added return 0 on success...
r12538
Return 0 on success.
Vadim Gelfer
mq: add qclone command
r2720 '''
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Alexis S. L. Carvalho
avoid double slash problem mentioned in issue695
r5226 def patchdir(repo):
Pierre-Yves David
qclone: add a few comment and blank line...
r15921 """compute a patch repo url from a repo object"""
Alexis S. L. Carvalho
avoid double slash problem mentioned in issue695
r5226 url = repo.url()
if url.endswith('/'):
url = url[:-1]
return url + '/.hg/patches'
Pierre-Yves David
qclone: add a few comment and blank line...
r15921
# main repo (destination and sources)
Vadim Gelfer
mq: add qclone command
r2720 if dest is None:
dest = hg.defaultdest(source)
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 sr = hg.peer(ui, opts, ui.expandpath(source))
Pierre-Yves David
qclone: add a few comment and blank line...
r15921
# patches repo (source only)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('patches'):
patchespath = ui.expandpath(opts.get('patches'))
John Mulligan
mq: allow qclone's -p option to use path alias...
r7729 else:
patchespath = patchdir(sr)
Brendan Cully
mq: improve qclone error handling when patch directory is not a repository.
r4862 try:
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 hg.peer(ui, opts, patchespath)
Matt Mackall
error: move repo errors...
r7637 except error.RepoError:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('versioned patch repository not found'
Cédric Duval
mq: no longer refer to deprecated qinit -c command
r10690 ' (see init --mq)'))
Vadim Gelfer
mq: add qclone command
r2720 qbase, destrev = None, None
if sr.local():
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 repo = sr.local()
if repo.mq.applied and repo[qbase].phase() != phases.secret:
qbase = repo.mq.applied[0].node
Vadim Gelfer
mq: add qclone command
r2720 if not hg.islocal(dest):
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 heads = set(repo.heads())
destrev = list(heads.difference(repo.heads(qbase)))
destrev.append(repo.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
Pierre-Yves David
qclone: add a few comment and blank line...
r15921
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('cloning main repository\n'))
Peter Arrenbrecht
hg: add opts argument to clone for internal remoteui
r14553 sr, dr = hg.clone(ui, opts, sr.url(), dest,
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 pull=opts.get('pull'),
Martin von Zweigbergk
clone: rename "rev" to "revs" since there can be many...
r37279 revs=destrev,
Vadim Gelfer
mq: add qclone command
r2720 update=False,
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 stream=opts.get('uncompressed'))
Pierre-Yves David
qclone: add a few comment and blank line...
r15921
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('cloning patch repository\n'))
Peter Arrenbrecht
hg: add opts argument to clone for internal remoteui
r14553 hg.clone(ui, opts, opts.get('patches') or patchdir(sr), patchdir(dr),
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 pull=opts.get('pull'), update=not opts.get('noupdate'),
stream=opts.get('uncompressed'))
Pierre-Yves David
qclone: add a few comment and blank line...
r15921
Vadim Gelfer
mq: add qclone command
r2720 if dr.local():
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 repo = dr.local()
Vadim Gelfer
mq: add qclone command
r2720 if qbase:
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('stripping applied patches from destination '
'repository\n'))
Pierre-Yves David
mq: extract `mq.queue.strip`...
r19819 strip(ui, repo, [qbase], update=False, backup=None)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if not opts.get('noupdate'):
Martin Geisler
expand "repo" to "repository" in help texts
r8027 ui.note(_('updating destination repository\n'))
Sune Foldager
peer: introduce peer methods to prepare for peer classes...
r17191 hg.update(repo, repo.changelog.tip())
Vadim Gelfer
mq: add qclone command
r2720
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qcommit|qci",
commands.table["^commit|ci"][1],
Gregory Szorc
mq: define inferrepo in command decorator
r21786 _('hg qcommit [OPTION]... [FILE]...'),
inferrepo=True)
mason@suse.com
Add mq extension
r1808 def commit(ui, repo, *pats, **opts):
Dirkjan Ochtman
mq: deprecate qinit and qcommit
r10361 """commit changes in the queue repository (DEPRECATED)
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 This command is deprecated; use :hg:`commit --mq` instead."""
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
mason@suse.com
Add mq extension
r1808 r = q.qrepo()
Matt Mackall
many, many trivial check-code fixups
r10282 if not r:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort('no queue repository')
mason@suse.com
Add mq extension
r1808 commands.commit(r.ui, r, *pats, **opts)
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qseries",
[('m', 'missing', None, _('print patches not in series')),
] + seriesopts,
_('hg qseries [-ms]'))
mason@suse.com
Add mq extension
r1808 def series(ui, repo, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the entire series file
Returns 0 on success."""
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 repo.mq.qseries(repo, missing=opts.get(r'missing'),
summary=opts.get(r'summary'))
mason@suse.com
Add mq extension
r1808 return 0
Idan Kamara
mq: no need to make a copy of seriesopts...
r14468 @command("qtop", seriesopts, _('hg qtop [-s]'))
mason@suse.com
Add mq extension
r1808 def top(ui, repo, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 """print the name of the current patch
Returns 0 on success."""
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if q.applied:
t = q.seriesend(True)
else:
t = 0
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 if t:
Erik Zielke
mq: removed return from callers to patchheader.qseries...
r12539 q.qseries(repo, start=t - 1, length=1, status='A',
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 summary=opts.get(r'summary'))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 else:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_("no patches applied\n"))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 return 1
mason@suse.com
Add mq extension
r1808
Idan Kamara
mq: no need to make a copy of seriesopts...
r14468 @command("qnext", seriesopts, _('hg qnext [-s]'))
mason@suse.com
Add mq extension
r1808 def next(ui, repo, **opts):
Patrick Mezard
mq: fix qnext when all remaining patches are guarded...
r16063 """print the name of the next pushable patch
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success."""
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
Adrian Buehlmann
mq: rename series_end to seriesend
r14586 end = q.seriesend()
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 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
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 q.qseries(repo, start=end, length=1, summary=opts.get(r'summary'))
mason@suse.com
Add mq extension
r1808
Idan Kamara
mq: no need to make a copy of seriesopts...
r14468 @command("qprev", seriesopts, _('hg qprev [-s]'))
mason@suse.com
Add mq extension
r1808 def prev(ui, repo, **opts):
Patrick Mezard
mq: fix qapplied --last and qprev documentation (issue3282)...
r16188 """print the name of the preceding applied patch
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success."""
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 q = repo.mq
l = len(q.applied)
if l == 1:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_("only one patch applied\n"))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 return 1
if not l:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_("no patches applied\n"))
Brendan Cully
mq: add --summary to qapplied, qunapplied, qtop, qnext and qprev...
r3183 return 1
Patrick Mezard
mq: make qprev return the previous applied patch (issue3245)...
r16064 idx = q.series.index(q.applied[-2].name)
q.qseries(repo, start=idx, length=1, status='A',
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 summary=opts.get(r'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'):
Boris Feld
util: extract all date-related utils in utils/dateutil module...
r36625 opts['date'] = "%d %d" % dateutil.makedate()
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qnew",
FUJIWARA Katsunori
doc: unify help text for "--edit" option...
r21952 [('e', 'edit', None, _('invoke editor on commit messages')),
Martin Geisler
mq: use cmdutil.command decorator
r14298 ('f', 'force', None, _('import uncommitted changes (DEPRECATED)')),
('g', 'git', None, _('use git extended diff format')),
('U', 'currentuser', None, _('add "From: <current user>" to patch')),
('u', 'user', '',
_('add "From: <USER>" to patch'), _('USER')),
('D', 'currentdate', None, _('add "Date: <current date>" to patch')),
('d', 'date', '',
_('add "Date: <DATE>" to patch'), _('DATE'))
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ] + cmdutil.walkopts + cmdutil.commitopts,
Gregory Szorc
mq: define inferrepo in command decorator
r21786 _('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...'),
inferrepo=True)
Brendan Cully
mq: support qnew -I/-X and file name lists
r4713 def new(ui, repo, patch, *args, **opts):
Brendan Cully
Add more verbose help text to mq commands.
r2754 """create a new patch
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 qnew creates a new patch on top of the currently-applied patch (if
Wagner Bruna
mq: remove reference for deprecated -f option...
r10808 any). The patch will be initialized with any outstanding changes
in the working directory. You may also use -I/--include,
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 -X/--exclude, and/or a list of files after the patch name to add
only changes to matching files to the new patch, leaving the rest
as uncommitted modifications.
Brendan Cully
Add more verbose help text to mq commands.
r2754
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 -u/--user and -d/--date can be used to set the (given) user and
date, respectively. -U/--currentuser and -D/--currentdate set user
to current user and date to current date.
Dirkjan Ochtman
mq: reflow qnew help, add help for options
r7306
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 -e/--edit, -m/--message or -l/--logfile set the patch header as
well as the commit message. If none is specified, the header is
empty and the commit message is '[mq]: PATCH'.
Dirkjan Ochtman
help: commands supporting --git point to the gitdiffs topic (issue1352)
r7307
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 Use the -g/--git option to keep the patch in the git extended diff
Matt Mackall
update help on git diffs
r7387 format. Read the diffs help topic for more information on why this
is important for preserving permission changes and copy/rename
information.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on successful creation of a new patch.
Dirkjan Ochtman
mq: reflow qnew help, add help for options
r7306 """
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Idan Kamara
cmdutil, logmessage: use ui.fin when reading from '-'
r14635 msg = cmdutil.logmessage(ui, opts)
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
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673 setupheaderopts(ui, opts)
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 q.new(repo, patch, *args, **pycompat.strkwargs(opts))
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qrefresh",
FUJIWARA Katsunori
doc: unify help text for "--edit" option...
r21952 [('e', 'edit', None, _('invoke editor on commit messages')),
Martin Geisler
mq: use cmdutil.command decorator
r14298 ('g', 'git', None, _('use git extended diff format')),
('s', 'short', None,
_('refresh only files already in the patch and specified files')),
('U', 'currentuser', None,
_('add/update author field in patch with current user')),
('u', 'user', '',
_('add/update author field in patch with given user'), _('USER')),
('D', 'currentdate', None,
_('add/update date field in patch with current date')),
('d', 'date', '',
_('add/update date field in patch with given date'), _('DATE'))
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ] + cmdutil.walkopts + cmdutil.commitopts,
Gregory Szorc
mq: define inferrepo in command decorator
r21786 _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...'),
inferrepo=True)
Brendan Cully
allow qrefresh to take a list of files; closes #96.
r2938 def refresh(ui, repo, *pats, **opts):
Brendan Cully
mq help text updates and speling fixes
r2940 """update the current patch
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 If any file patterns are provided, the refreshed patch will
contain only the modifications that match those patterns; the
remaining modifications will remain in the working directory.
Thomas Arendsen Hein
mq: Mention usage of hg add/remove/copy/rename in qrefresh help text.
r4048
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 If -s/--short is specified, files currently included in the patch
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 will be refreshed just like matched files and remain in the patch.
Mads Kiilerich
mq: Allow qrefresh --silent to take parameters...
r7113
Renato Cunha
mq: save qrefresh message for easy recovery in case it fails (issue2062)...
r11947 If -e/--edit is specified, Mercurial will start your configured editor for
you to enter a message. In case qrefresh fails, you will find a backup of
your message in ``.hg/last-message.txt``.
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 hg add/remove/copy/rename work as usual, though you might want to
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 use git-style patches (-g/--git or [diff] git=1) to track copies
and renames. See the diffs help topic for more information on the
git diff format.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Brendan Cully
mq help text updates and speling fixes
r2940 """
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Idan Kamara
cmdutil, logmessage: use ui.fin when reading from '-'
r14635 message = cmdutil.logmessage(ui, opts)
peter.arrenbrecht@gmail.com
mq: add --currentuser and --user options to qnew and qrefresh...
r5673 setupheaderopts(ui, opts)
Bryan O'Sullivan
with: use context manager for wlock in qrefresh
r27830 with repo.wlock():
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 ret = q.refresh(repo, pats, msg=message, **pycompat.strkwargs(opts))
Yuya Nishihara
mq: make qrefresh/qfold keep wlock until saving patch status...
r14620 q.savedirty()
return ret
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qdiff",
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 cmdutil.diffopts + cmdutil.diffopts2 + cmdutil.walkopts,
Gregory Szorc
mq: define inferrepo in command decorator
r21786 _('hg qdiff [OPTION]... [FILE]...'),
inferrepo=True)
Brendan Cully
Fix test-mq-qdiff; add -I and -X options to qdiff
r2937 def diff(ui, repo, *pats, **opts):
Dirkjan Ochtman
mq: expand help text for qdiff...
r6606 """diff of the current patch and subsequent modifications
Dirkjan Ochtman
mq: lose the trailing whitespace
r6621
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 Shows a diff which includes the current patch as well as any
changes which have been made in the working directory since the
last refresh (thus showing what the current patch would become
after a qrefresh).
Dirkjan Ochtman
mq: lose the trailing whitespace
r6621
Martin Geisler
Use hg role in help strings
r10973 Use :hg:`diff` if you only want to see the changes made since the
last qrefresh, or :hg:`export qtip` if you want to see changes
made by the current patch without including changes made since the
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 qrefresh.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Dirkjan Ochtman
mq: expand help text for qdiff...
r6606 """
Augie Fackler
qdiff: migrate to modern pager API...
r31033 ui.pager('qdiff')
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 repo.mq.diff(repo, pats, pycompat.byteskwargs(opts))
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command('qfold',
FUJIWARA Katsunori
doc: unify help text for "--edit" option...
r21952 [('e', 'edit', None, _('invoke editor on commit messages')),
Martin Geisler
mq: use cmdutil.command decorator
r14298 ('k', 'keep', None, _('keep folded patch files')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ] + cmdutil.commitopts,
Martin Geisler
mq: use cmdutil.command decorator
r14298 _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...'))
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 def fold(ui, repo, *files, **opts):
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 """fold the named patches into the current patch
Brendan Cully
Add -m, -l, -e options to qfold.
r2753
Brendan Cully
Add -f option to qfold; improve qfold documentation.
r2771 Patches must not yet be applied. Each patch will be successively
applied to the current patch in the order given. If all the
patches apply successfully, the current patch will be refreshed
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 with the new cumulative patch, and the folded patches will be
deleted. With -k/--keep, the folded patch files will not be
removed afterwards.
Brendan Cully
Add -f option to qfold; improve qfold documentation.
r2771
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 The header for each folded patch will be concatenated with the
Erik Zielke
mq: switched to `` around * * *...
r12755 current patch header, separated by a line of ``* * *``.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success."""
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 q = repo.mq
if not files:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('qfold requires at least one patch name'))
Adrian Buehlmann
mq: rename check_toppatch to checktoppatch
r14581 if not q.checktoppatch(repo)[0]:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no patches applied'))
Adrian Buehlmann
mq: rename check_localchanges to checklocalchanges
r14583 q.checklocalchanges(repo)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Idan Kamara
cmdutil, logmessage: use ui.fin when reading from '-'
r14635 message = cmdutil.logmessage(ui, opts)
Brendan Cully
Add -m, -l, -e options to qfold.
r2753
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:
Martin Geisler
mq: lowercase warning messages
r16929 ui.warn(_('skipping already folded patch %s\n') % p)
Brendan Cully
Fix qfold after recent changes
r2936 if q.isapplied(p):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('qfold cannot fold already applied patch %s')
Brodie Rao
cleanup: eradicate long lines
r16683 % p)
Brendan Cully
Fix qfold after recent changes
r2936 patches.append(p)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Brendan Cully
Fix qfold after recent changes
r2936 for p in patches:
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 if not message:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(q.join(p), q.plainmode)
Brendan Cully
mq: filter out empty commit messages in qfold
r7454 if ph.message:
messages.append(ph.message)
Brendan Cully
Fix qfold after recent changes
r2936 pf = q.join(p)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748 (patchsuccess, files, fuzz) = q.patch(repo, pf)
if not patchsuccess:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('error folding patch %s') % p)
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 if not message:
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(q.join(parent), q.plainmode)
FUJIWARA Katsunori
mq: eliminate unused variable for test-check-pyflakes.t...
r21270 message = ph.message
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 for msg in messages:
Mads Kiilerich
mq: don't add '* * *' separators when there is no commit message
r20053 if msg:
if message:
message.append('* * *')
message.extend(msg)
Brendan Cully
Add -m, -l, -e options to qfold.
r2753 message = '\n'.join(message)
Patrick Mezard
mq: preserve --git flag when folding patches...
r10186 diffopts = q.patchopts(q.diffopts(), *patches)
Bryan O'Sullivan
with: use context manager for wlock in qfold
r27831 with repo.wlock():
FUJIWARA Katsunori
mq: pass 'editform' argument to 'cmdutil.getcommiteditor'...
r22003 q.refresh(repo, msg=message, git=diffopts.git, edit=opts.get('edit'),
editform='mq.qfold')
Yuya Nishihara
mq: make qrefresh/qfold keep wlock until saving patch status...
r14620 q.delete(repo, patches, opts)
q.savedirty()
Brendan Cully
New mq command qfold: Merge patches into the current patch....
r2748
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qgoto",
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 [('', 'keep-changes', None,
_('tolerate non-conflicting local changes')),
Patrick Mezard
mq: introduce qgoto --check
r16655 ('f', 'force', None, _('overwrite any local changes')),
Patrick Mezard
mq: add --no-backup for qpush/qpop/qgoto
r16635 ('', 'no-backup', None, _('do not save backup copies of files'))],
Martin Geisler
mq: use cmdutil.command decorator
r14298 _('hg qgoto [OPTION]... PATCH'))
Bryan O'Sullivan
mq: add qgoto command.
r4432 def goto(ui, repo, patch, **opts):
Erik Zielke
mq: added return 0 on success...
r12538 '''push or pop patches until named patch is at top of stack
Returns 0 on success.'''
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 opts = fixkeepchangesopts(ui, opts)
Bryan O'Sullivan
mq: add qgoto command.
r4432 q = repo.mq
patch = q.lookup(patch)
Patrick Mezard
mq: add --no-backup for qpush/qpop/qgoto
r16635 nobackup = opts.get('no_backup')
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 keepchanges = opts.get('keep_changes')
Bryan O'Sullivan
mq: add qgoto command.
r4432 if q.isapplied(patch):
Patrick Mezard
mq: introduce qgoto --check
r16655 ret = q.pop(repo, patch, force=opts.get('force'), nobackup=nobackup,
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 keepchanges=keepchanges)
Bryan O'Sullivan
mq: add qgoto command.
r4432 else:
Patrick Mezard
mq: introduce qgoto --check
r16655 ret = q.push(repo, patch, force=opts.get('force'), nobackup=nobackup,
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 keepchanges=keepchanges)
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
Bryan O'Sullivan
mq: add qgoto command.
r4432 return ret
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qguard",
[('l', 'list', None, _('list all patches and guards')),
('n', 'none', None, _('drop all guards'))],
_('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]'))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def guard(ui, repo, *args, **opts):
'''set or print guards for a patch
Brendan Cully
mq help text updates and speling fixes
r2940 Guards control whether a patch can be pushed. A patch with no
guards is always pushed. A patch with a positive guard ("+foo") is
Martin Geisler
mq: use hg reST role some more
r11307 pushed only if the :hg:`qselect` command has activated it. A patch with
a negative guard ("-foo") is never pushed if the :hg:`qselect` command
Brendan Cully
mq help text updates and speling fixes
r2940 has activated it.
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Brendan Cully
mq help text updates and speling fixes
r2940 With no arguments, print the currently active guards.
With arguments, set guards for the named patch.
Erik Zielke
Use note admonition
r12389
.. note::
Simon Heimberg
documentation: add an extra newline after note directive...
r19997
Erik Zielke
Use note admonition
r12389 Specifying negative guards now requires '--'.
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Martin Geisler
mq: fix literal blocks in docstrings
r9824 To set guards on another patch::
Martin Geisler
mq: more instructive use of "--" in qguard help (issue2040)
r10476 hg qguard other.patch -- +2.6.17 -stable
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 '''
def status(idx):
Adrian Buehlmann
mq: rename series_guards to seriesguards
r14573 guards = q.seriesguards[idx] or ['unguarded']
Dan Villiom Podlaski Christiansen
qguard: label patch names by status when listing guards
r11819 if q.series[idx] in applied:
state = 'applied'
elif q.pushable(idx)[0]:
state = 'unapplied'
else:
state = 'guarded'
label = 'qguard.patch qguard.%s qseries.%s' % (state, state)
ui.write('%s: ' % ui.label(q.series[idx], label))
Brodie Rao
qguard: make use of output labeling
r10822 for i, guard in enumerate(guards):
if guard.startswith('+'):
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(guard, label='qguard.positive')
Brodie Rao
qguard: make use of output labeling
r10822 elif guard.startswith('-'):
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(guard, label='qguard.negative')
Brodie Rao
qguard: make use of output labeling
r10822 else:
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(guard, label='qguard.unguarded')
Brodie Rao
qguard: make use of output labeling
r10822 if i != len(guards) - 1:
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(' ')
ui.write('\n')
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 q = repo.mq
Dan Villiom Podlaski Christiansen
qguard: label patch names by status when listing guards
r11819 applied = set(p.name for p in q.applied)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 patch = None
args = list(args)
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 if opts.get(r'list'):
Pulkit Goyal
py3: fix kwargs handling in qgurad in hgext/mq.py...
r38060 if args or opts.get(r'none'):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot mix -l/--list with options or '
Brodie Rao
cleanup: eradicate long lines
r16683 'arguments'))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 for i in xrange(len(q.series)):
status(i)
return
if not args or args[0][0:1] in '-+':
if not q.applied:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no patches applied'))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 patch = q.applied[-1].name
if patch is None and args[0][0:1] not in '-+':
patch = args.pop(0)
if patch is None:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no patch to work with'))
Pulkit Goyal
py3: fix kwargs handling in qgurad in hgext/mq.py...
r38060 if args or opts.get(r'none'):
Adrian Buehlmann
mq: rename find_series to findseries
r14574 idx = q.findseries(patch)
Christian Ebert
mq: abort cleanly when invalid patch name is given to qguard
r4133 if idx is None:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no patch named %s') % patch)
Adrian Buehlmann
mq: rename set_guards to setguards
r14577 q.setguards(idx, args)
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 else:
status(q.series.index(q.lookup(patch)))
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qheader", [], _('hg qheader [PATCH]'))
Brendan Cully
Add command qheader to display the header of a given patch.
r2747 def header(ui, repo, patch=None):
Erik Zielke
mq: added return 0 on success...
r12538 """print the header of the topmost or specified patch
Returns 0 on success."""
Brendan Cully
Add command qheader to display the header of a given patch.
r2747 q = repo.mq
if patch:
patch = q.lookup(patch)
else:
if not q.applied:
Benoit Boissinot
i18n: mark more strings for translation
r10510 ui.write(_('no patches applied\n'))
Bryan O'Sullivan
qheader: exit withh meaningful error code.
r3008 return 1
Brendan Cully
Add command qheader to display the header of a given patch.
r2747 patch = q.lookup('qtip')
Steve Losh
mq: add parent node IDs to MQ patches on qrefresh/qnew...
r10397 ph = patchheader(q.join(patch), q.plainmode)
Brendan Cully
Add command qheader to display the header of a given patch.
r2747
Brendan Cully
mq: create patch header class to abstract header manipulation
r7399 ui.write('\n'.join(ph.message) + '\n')
Brendan Cully
Add command qheader to display the header of a given patch.
r2747
mason@suse.com
Add mq extension
r1808 def lastsavename(path):
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 (directory, base) = os.path.split(path)
names = os.listdir(directory)
mason@suse.com
Add mq extension
r1808 namere = re.compile("%s.([0-9]+)" % base)
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 maxindex = None
mason@suse.com
Add mq extension
r1808 maxname = None
for f in names:
m = namere.match(f)
if m:
index = int(m.group(1))
Martin Geisler
use 'x is None' instead of 'x == None'...
r8527 if maxindex is None or index > maxindex:
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 maxindex = index
mason@suse.com
Add mq extension
r1808 maxname = f
if maxname:
Benoit Boissinot
mq: fix variables shadowing builtin
r2794 return (os.path.join(directory, maxname), maxindex)
mason@suse.com
Add mq extension
r1808 return (None, None)
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808 def savename(path):
(last, index) = lastsavename(path)
if last is None:
index = 0
newpath = path + ".%d" % (index + 1)
return newpath
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qpush",
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 [('', 'keep-changes', None,
_('tolerate non-conflicting local changes')),
Patrick Mezard
mq: introduce qpush --check...
r16654 ('f', 'force', None, _('apply on top of local changes')),
Brodie Rao
cleanup: eradicate long lines
r16683 ('e', 'exact', None,
_('apply the target patch to its recorded parent')),
Martin Geisler
mq: use cmdutil.command decorator
r14298 ('l', 'list', None, _('list patch name in commit text')),
('a', 'all', None, _('apply all patches')),
('m', 'merge', None, _('merge from another queue (DEPRECATED)')),
('n', 'name', '',
_('merge queue name (DEPRECATED)'), _('NAME')),
Patrick Mezard
mq: add --no-backup for qpush/qpop/qgoto
r16635 ('', 'move', None,
_('reorder patch series and apply only the patch')),
('', 'no-backup', None, _('do not save backup copies of files'))],
Martin Geisler
mq: use cmdutil.command decorator
r14298 _('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]'))
mason@suse.com
Add mq extension
r1808 def push(ui, repo, patch=None, **opts):
Dirkjan Ochtman
mq: add a little documentation on qpush -f
r6552 """push the next patch onto the stack
Dirkjan Ochtman
remove trailing spaces
r6553
Patrick Mezard
mq: introduce qpush --check...
r16654 By default, abort if the working directory contains uncommitted
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 changes. With --keep-changes, abort only if the uncommitted files
Patrick Mezard
mq: introduce qpush --check...
r16654 overlap with patched files. With -f/--force, backup and patch over
uncommitted changes.
Erik Zielke
mq: added return 0 on success...
r12538
Stefano Tortarolo
mq: fix typo in docstring
r13725 Return 0 on success.
Dirkjan Ochtman
mq: add a little documentation on qpush -f
r6552 """
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
mason@suse.com
Add mq extension
r1808 mergeq = None
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 opts = fixkeepchangesopts(ui, opts)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('merge'):
if opts.get('name'):
Pierre-Yves David
mq: directly use repo.vfs.join...
r31333 newpath = repo.vfs.join(opts.get('name'))
mason@suse.com
Add mq extension
r1808 else:
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810 newpath, i = lastsavename(q.path)
mason@suse.com
Add mq extension
r1808 if not newpath:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 ui.warn(_("no saved queues found, please use -n\n"))
mason@suse.com
Add mq extension
r1808 return 1
Simon Heimberg
mq: do not inherit settings form base repo in mqrepo (Fixes issue2358)...
r19064 mergeq = queue(ui, repo.baseui, repo.path, newpath)
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 ui.warn(_("merging with queue at: %s\n") % mergeq.path)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'),
Steve Losh
mq: add an '-e/--exact' option to qpush...
r13033 mergeq=mergeq, all=opts.get('all'), move=opts.get('move'),
Patrick Mezard
mq: introduce qpush --check...
r16654 exact=opts.get('exact'), nobackup=opts.get('no_backup'),
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 keepchanges=opts.get('keep_changes'))
mason@suse.com
Add mq extension
r1808 return ret
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("^qpop",
[('a', 'all', None, _('pop all patches')),
('n', 'name', '',
_('queue name to pop (DEPRECATED)'), _('NAME')),
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 ('', 'keep-changes', None,
_('tolerate non-conflicting local changes')),
Patrick Mezard
mq: add --no-backup for qpush/qpop/qgoto
r16635 ('f', 'force', None, _('forget any local changes to patched files')),
('', 'no-backup', None, _('do not save backup copies of files'))],
Martin Geisler
mq: use cmdutil.command decorator
r14298 _('hg qpop [-a] [-f] [PATCH | INDEX]'))
mason@suse.com
Add mq extension
r1808 def pop(ui, repo, patch=None, **opts):
Dirkjan Ochtman
mq: add correct documentation for qpop
r6611 """pop the current patch off the stack
Dirkjan Ochtman
mq: lose the trailing whitespace
r6621
Patrick Mezard
mq: introduce qpop --check...
r16653 Without argument, 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.
By default, abort if the working directory contains uncommitted
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 changes. With --keep-changes, abort only if the uncommitted files
Patrick Mezard
mq: introduce qpop --check...
r16653 overlap with patched files. With -f/--force, backup and discard
changes made to such files.
Erik Zielke
mq: added return 0 on success...
r12538
Return 0 on success.
Dirkjan Ochtman
mq: add correct documentation for qpop
r6611 """
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 opts = fixkeepchangesopts(ui, opts)
mason@suse.com
Add mq extension
r1808 localupdate = True
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('name'):
Pierre-Yves David
mq: directly use repo.vfs.join...
r31333 q = queue(ui, repo.baseui, repo.path, repo.vfs.join(opts.get('name')))
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 ui.warn(_('using patch queue: %s\n') % q.path)
mason@suse.com
Add mq extension
r1808 localupdate = False
else:
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate,
Patrick Mezard
mq: introduce qpop --check...
r16653 all=opts.get('all'), nobackup=opts.get('no_backup'),
Patrick Mezard
mq: rename --check into --keep-changes...
r16733 keepchanges=opts.get('keep_changes'))
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
Alexis S. L. Carvalho
mq: propagate the return error of pop
r4099 return ret
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qrename|qmv", [], _('hg qrename PATCH1 [PATCH2]'))
Brendan Cully
New self-explanatory command qrename.
r2750 def rename(ui, repo, patch, name=None, **opts):
"""rename a patch
With one argument, renames the current patch to PATCH1.
Erik Zielke
mq: added return 0 on success...
r12538 With two arguments, renames PATCH1 to PATCH2.
Returns 0 on success."""
Brendan Cully
New self-explanatory command qrename.
r2750 q = repo.mq
if not name:
name = patch
patch = None
if patch:
patch = q.lookup(patch)
else:
if not q.applied:
Martin Geisler
mq: lowercase output...
r7627 ui.write(_('no patches applied\n'))
Brendan Cully
New self-explanatory command qrename.
r2750 return
patch = q.lookup('qtip')
Brendan Cully
Make qrename handle directory targets; closes #333.
r3083 absdest = q.join(name)
if os.path.isdir(absdest):
Patrick Mezard
Enforce unixish style for all generated patch names....
r4037 name = normname(os.path.join(name, os.path.basename(patch)))
Brendan Cully
Make qrename handle directory targets; closes #333.
r3083 absdest = q.join(name)
Idan Kamara
mq: use checkpatchname...
r14423 q.checkpatchname(name)
Brendan Cully
New self-explanatory command qrename.
r2750
Benoit Boissinot
i18n: mark more strings for translation
r10510 ui.note(_('renaming %s to %s\n') % (patch, name))
Adrian Buehlmann
mq: rename find_series to findseries
r14574 i = q.findseries(patch)
Adrian Buehlmann
mq: rename full_series to fullseries
r14572 guards = q.guard_re.findall(q.fullseries[i])
q.fullseries[i] = name + ''.join([' #' + g for g in guards])
Adrian Buehlmann
mq: rename parse_series to parseseries
r14575 q.parseseries()
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 q.seriesdirty = True
Brendan Cully
New self-explanatory command qrename.
r2750
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)
Mads Kiilerich
mq: consistently use boolean values for dirty flags
r15879 q.applieddirty = True
Brendan Cully
New self-explanatory command qrename.
r2750
Yuya Nishihara
mq: fixed ENOENT when qrename to new/directory.patch...
r11513 destdir = os.path.dirname(absdest)
if not os.path.isdir(destdir):
os.makedirs(destdir)
Vadim Gelfer
mq: add join method
r2819 util.rename(q.join(patch), absdest)
Brendan Cully
New self-explanatory command qrename.
r2750 r = q.qrepo()
Patrick Mezard
mq: qrename should not touch the dirstate if src is untracked (issue2460)
r12875 if r and patch in r.dirstate:
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 wctx = r[None]
Bryan O'Sullivan
with: use context manager in qrename
r27848 with r.wlock():
Weijun Wang
mq: handle added patch renaming correctly
r6648 if r.dirstate[patch] == 'a':
Matt Mackall
dirstate: rename forget to drop...
r14434 r.dirstate.drop(patch)
Weijun Wang
mq: handle added patch renaming correctly
r6648 r.dirstate.add(name)
else:
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 wctx.copy(patch, name)
Matt Mackall
context: make forget work like commands.forget...
r14435 wctx.forget([patch])
Brendan Cully
New self-explanatory command qrename.
r2750
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
Brendan Cully
New self-explanatory command qrename.
r2750
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qrestore",
[('d', 'delete', None, _('delete save entry')),
('u', 'update', None, _('update queue working directory'))],
_('hg qrestore [-d] [-u] REV'))
mason@suse.com
Add mq extension
r1808 def restore(ui, repo, rev, **opts):
Dirkjan Ochtman
mq: deprecate qsave, qrestore and related options
r10360 """restore the queue state saved by a revision (DEPRECATED)
Dan Villiom Podlaski Christiansen
mq: fix the deprecation comment for qsave & qrestore....
r12352 This command is deprecated, use :hg:`rebase` instead."""
mason@suse.com
Add mq extension
r1808 rev = repo.lookup(rev)
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 q.restore(repo, rev, delete=opts.get(r'delete'),
qupdate=opts.get(r'update'))
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
mason@suse.com
Add mq extension
r1808 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qsave",
[('c', 'copy', None, _('copy patch directory')),
('n', 'name', '',
_('copy directory name'), _('NAME')),
('e', 'empty', None, _('clear queue status file')),
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 ('f', 'force', None, _('force copy'))] + cmdutil.commitopts,
Martin Geisler
mq: use cmdutil.command decorator
r14298 _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'))
mason@suse.com
Add mq extension
r1808 def save(ui, repo, **opts):
Dirkjan Ochtman
mq: deprecate qsave, qrestore and related options
r10360 """save current queue state (DEPRECATED)
Dan Villiom Podlaski Christiansen
mq: fix the deprecation comment for qsave & qrestore....
r12352 This command is deprecated, use :hg:`rebase` instead."""
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = repo.mq
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Idan Kamara
cmdutil, logmessage: use ui.fin when reading from '-'
r14635 message = cmdutil.logmessage(ui, 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
Mads Kiilerich
mq: make qsave implementation more explicit...
r15880 q.savedirty() # save to .hg/patches before copying
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('copy'):
mason@suse.com
Add mq extension
r1808 path = q.path
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('name'):
newpath = os.path.join(q.basepath, opts.get('name'))
mason@suse.com
Add mq extension
r1808 if os.path.exists(newpath):
if not os.path.isdir(newpath):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('destination %s exists and is not '
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 'a directory') % newpath)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if not opts.get('force'):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('destination %s exists, '
Vadim Gelfer
mq: move many error messages to util.Abort
r2712 'use -f to force') % newpath)
mason@suse.com
Add mq extension
r1808 else:
newpath = savename(path)
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 ui.warn(_("copy %s to %s\n") % (path, newpath))
mason@suse.com
Add mq extension
r1808 util.copyfiles(path, newpath)
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('empty'):
Mads Kiilerich
mq: make qsave implementation more explicit...
r15880 del q.applied[:]
q.applieddirty = True
q.savedirty()
mason@suse.com
Add mq extension
r1808 return 0
Thomas Arendsen Hein
Whitespace, tab and formatting cleanups, mainly in mq.py
r1810
mason@suse.com
Add mq extension
r1808
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qselect",
[('n', 'none', None, _('disable all guards')),
('s', 'series', None, _('list all guards in series file')),
('', 'pop', None, _('pop to before first guarded applied patch')),
('', 'reapply', None, _('pop, then reapply patches'))],
_('hg qselect [OPTION]... [GUARD]...'))
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 def select(ui, repo, *args, **opts):
'''set or print guarded patches to push
Martin Geisler
mq: use hg reST role some more
r11307 Use the :hg:`qguard` command to set or print guards on patch, then use
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 qselect to tell mq which guards to use. A patch will be pushed if
it has no guards or any positive guards match the currently
selected guard, but will not be pushed if any negative guards
Martin Geisler
mq: fix literal blocks in docstrings
r9824 match the current guard. For example::
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
timeless@gmail.com
mq: fix qselect help for qguard
r13791 qguard foo.patch -- -stable (negative guard)
qguard bar.patch +stable (positive guard)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 qselect stable
Brendan Cully
mq help text updates and speling fixes
r2940 This activates the "stable" guard. mq will skip foo.patch (because
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 it has a negative match) but push bar.patch (because it has a
positive match).
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Brendan Cully
mq help text updates and speling fixes
r2940 With no arguments, prints the currently active guards.
With one argument, sets the active guard.
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Brendan Cully
mq help text updates and speling fixes
r2940 Use -n/--none to deactivate guards (no other arguments needed).
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 When no guards are active, patches with positive guards are
skipped and patches with negative guards are pushed.
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Brendan Cully
mq help text updates and speling fixes
r2940 qselect can change the guards on applied patches. It does not pop
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 guarded patches by default. Use --pop to pop back to the last
applied patch that is not guarded. Use --reapply (which implies
--pop) to push back to the current patch afterwards, but skip
guarded patches.
Vadim Gelfer
qselect: add --pop, --reapply options
r2844
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 Use -s/--series to print a list of all guards in the series file
Erik Zielke
mq: added return 0 on success...
r12538 (no other arguments needed). Use -v for more information.
Returns 0 on success.'''
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
q = repo.mq
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 guards = q.active()
FUJIWARA Katsunori
mq: report correct numbers for changing "number of guarded, applied patches"...
r22453 pushable = lambda i: q.pushable(q.applied[i].name)[0]
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if args or opts.get('none'):
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 old_unapplied = q.unapplied(repo)
FUJIWARA Katsunori
mq: report correct numbers for changing "number of guarded, applied patches"...
r22453 old_guarded = [i for i in xrange(len(q.applied)) if not pushable(i)]
Adrian Buehlmann
mq: rename set_active to setactive
r14578 q.setactive(args)
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if not args:
ui.status(_('guards deactivated\n'))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if not opts.get('pop') and not opts.get('reapply'):
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 unapplied = q.unapplied(repo)
FUJIWARA Katsunori
mq: report correct numbers for changing "number of guarded, applied patches"...
r22453 guarded = [i for i in xrange(len(q.applied)) if not pushable(i)]
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 if len(unapplied) != len(old_unapplied):
ui.status(_('number of unguarded, unapplied patches has '
'changed from %d to %d\n') %
(len(old_unapplied), len(unapplied)))
if len(guarded) != len(old_guarded):
ui.status(_('number of guarded, applied patches has changed '
'from %d to %d\n') %
(len(old_guarded), len(guarded)))
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 elif opts.get('series'):
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 guards = {}
noguards = 0
Adrian Buehlmann
mq: rename series_guards to seriesguards
r14573 for gs in q.seriesguards:
Vadim Gelfer
mq: new commands qselect, qguard...
r2821 if not gs:
noguards += 1
for g in gs:
guards.setdefault(g, 0)
guards[g] += 1
if ui.verbose:
guards['NONE'] = noguards
Pulkit Goyal
py3: explicitly convert result of dict.items() into list...
r36296 guards = list(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'))
FUJIWARA Katsunori
mq: use "mq.applied[i].name" instead of "mq.appliedname(i)" for safety...
r22454 reapply = opts.get('reapply') and q.applied and q.applied[-1].name
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 popped = False
Christian Ebert
mq: consistently use opts.get() to prevent potential KeyError
r12281 if opts.get('pop') or opts.get('reapply'):
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 for i in xrange(len(q.applied)):
FUJIWARA Katsunori
mq: examine "pushable" of already applied patch correctly...
r22456 if not pushable(i):
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 ui.status(_('popping guarded patches\n'))
popped = True
if i == 0:
q.pop(repo, all=True)
else:
FUJIWARA Katsunori
mq: pop correct patches when changing pushable-ness of already applied ones...
r22455 q.pop(repo, q.applied[i - 1].name)
Vadim Gelfer
qselect: add --pop, --reapply options
r2844 break
if popped:
try:
if reapply:
ui.status(_('reapplying unguarded patches\n'))
q.push(repo, reapply)
finally:
Adrian Buehlmann
mq: rename save_dirty to savedirty
r14580 q.savedirty()
Vadim Gelfer
mq: new commands qselect, qguard...
r2821
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qfinish",
[('a', 'applied', None, _('finish all applied changesets'))],
_('hg qfinish [-a] [REV]...'))
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 def finish(ui, repo, *revrange, **opts):
"""move applied patches into repository history
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 Finishes the specified revisions (corresponding to applied
patches) by moving them out of mq control into regular repository
history.
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
Martin Geisler
help texts: write command line switches as -a/--abc
r8076 Accepts a revision range or the -a/--applied option. If --applied
is specified, all applied mq revisions are removed from mq
control. Otherwise, the given revisions must be at the base of the
stack of applied patches.
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
Martin Geisler
mq: word-wrap help texts at 70 characters
r7994 This can be especially useful if your changes have been applied to
an upstream repository, or if you are about to push your changes
to upstream.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 """
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 if not opts.get(r'applied') and not revrange:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no revisions specified'))
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 elif opts.get(r'applied'):
Matt Mackall
qfinish: fix range logic for --applied...
r11730 revrange = ('qbase::qtip',) + revrange
Dirkjan Ochtman
mq: introduce the qfinish command
r6645
q = repo.mq
if not q.applied:
ui.status(_('no patches applied\n'))
return 0
Matt Mackall
scmutil: move revsingle/pair/range from cmdutil...
r14319 revs = scmutil.revrange(repo, revrange)
Matt Mackall
mq: add a warning about uncommitted changes for qfinish
r15476 if repo['.'].rev() in revs and repo[None].files():
ui.warn(_('warning: uncommitted changes in the working directory\n'))
timeless@mozdev.org
spelling: responsibility
r17512 # queue.finish may changes phases but leave the responsibility to lock the
Pierre-Yves David
mq: turn changeset draft on qfinish (except if qparent is secret)...
r15920 # repo to the caller to avoid deadlock with wlock. This command code is
Mads Kiilerich
fix trivial spelling errors
r17424 # responsibility for this locking.
Bryan O'Sullivan
with: use context manager in qfinish
r27847 with repo.lock():
Pierre-Yves David
mq: turn changeset draft on qfinish (except if qparent is secret)...
r15920 q.finish(repo, revs)
q.savedirty()
Dirkjan Ochtman
mq: introduce the qfinish command
r6645 return 0
Martin Geisler
mq: use cmdutil.command decorator
r14298 @command("qqueue",
[('l', 'list', False, _('list all available queues')),
"Yann E. MORIN"
mq/qqueue: print current queue name...
r14987 ('', 'active', False, _('print name of active queue')),
Martin Geisler
mq: use cmdutil.command decorator
r14298 ('c', 'create', False, _('create new queue')),
('', 'rename', False, _('rename active queue')),
('', 'delete', False, _('delete reference to queue')),
('', 'purge', False, _('delete queue, and remove patch dir')),
],
_('[OPTION] [QUEUE]'))
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 def qqueue(ui, repo, name=None, **opts):
'''manage multiple patch queues
Supports switching between different patch queues, as well as creating
new patch queues and deleting existing ones.
Omitting a queue name or specifying -l/--list will show you the registered
queues - by default the "normal" patches queue is registered. The currently
"Yann E. MORIN"
mq/qqueue: print current queue name...
r14987 active queue will be marked with "(active)". Specifying --active will print
only the name of the active queue.
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229
To create a new queue, use -c/--create. The queue is automatically made
active, except in the case where there are applied patches from the
currently active queue in the repository. Then the queue will only be
created and switching will fail.
To delete an existing queue, use --delete. You cannot delete the currently
active queue.
Erik Zielke
mq: added return 0 on success...
r12538
Returns 0 on success.
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 '''
q = repo.mq
_defaultqueue = 'patches'
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 _allqueues = 'patches.queues'
_activequeue = 'patches.queue'
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229
def _getcurrent():
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 cur = os.path.basename(q.path)
if cur.startswith('patches-'):
cur = cur[8:]
return cur
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229
def _noqueues():
try:
Angel Ezquerra
localrepo: remove all external users of localrepo.opener...
r23877 fh = repo.vfs(_allqueues, 'r')
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 fh.close()
except IOError:
return True
return False
def _getqueues():
current = _getcurrent()
try:
Angel Ezquerra
localrepo: remove all external users of localrepo.opener...
r23877 fh = repo.vfs(_allqueues, 'r')
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 queues = [queue.strip() for queue in fh if queue.strip()]
Dan Villiom Podlaski Christiansen
explicitly close files...
r13400 fh.close()
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 if current not in queues:
queues.append(current)
except IOError:
queues = [_defaultqueue]
return sorted(queues)
def _setactive(name):
if q.applied:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('new queue created, but cannot make active '
Bryan O'Sullivan
mq: improve qqueue message with patches applied (issue3036)
r17708 'as patches are applied'))
"Yann E. MORIN"
mq/qqueue: split _setactive...
r11938 _setactivenocheck(name)
def _setactivenocheck(name):
Angel Ezquerra
localrepo: remove all external users of localrepo.opener...
r23877 fh = repo.vfs(_activequeue, 'w')
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 if name != 'patches':
fh.write(name)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 fh.close()
def _addqueue(name):
Angel Ezquerra
localrepo: remove all external users of localrepo.opener...
r23877 fh = repo.vfs(_allqueues, 'a')
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 fh.write('%s\n' % (name,))
fh.close()
"Yann E. MORIN"
mq/qqueue: enable renaming of active queue
r11939 def _queuedir(name):
if name == 'patches':
Pierre-Yves David
mq: directly use repo.vfs.join...
r31333 return repo.vfs.join('patches')
"Yann E. MORIN"
mq/qqueue: enable renaming of active queue
r11939 else:
Pierre-Yves David
mq: directly use repo.vfs.join...
r31333 return repo.vfs.join('patches-' + name)
"Yann E. MORIN"
mq/qqueue: enable renaming of active queue
r11939
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 def _validname(name):
for n in name:
if n in ':\\/.':
return False
return True
"Yann E. MORIN"
mq/qqueue: commonalise the queue deletion code
r11966 def _delete(name):
if name not in existing:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot delete queue that does not exist'))
"Yann E. MORIN"
mq/qqueue: commonalise the queue deletion code
r11966
current = _getcurrent()
if name == current:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('cannot delete currently active queue'))
"Yann E. MORIN"
mq/qqueue: commonalise the queue deletion code
r11966
Angel Ezquerra
localrepo: remove all external users of localrepo.opener...
r23877 fh = repo.vfs('patches.queues.new', 'w')
"Yann E. MORIN"
mq/qqueue: commonalise the queue deletion code
r11966 for queue in existing:
if queue == name:
continue
fh.write('%s\n' % (queue,))
fh.close()
Mads Kiilerich
vfs: use repo.vfs.rename
r31312 repo.vfs.rename('patches.queues.new', _allqueues)
"Yann E. MORIN"
mq/qqueue: commonalise the queue deletion code
r11966
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 opts = pycompat.byteskwargs(opts)
"Yann E. MORIN"
mq/qqueue: print current queue name...
r14987 if not name or opts.get('list') or opts.get('active'):
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 current = _getcurrent()
"Yann E. MORIN"
mq/qqueue: print current queue name...
r14987 if opts.get('active'):
ui.write('%s\n' % (current,))
return
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 for queue in _getqueues():
ui.write('%s' % (queue,))
"Yann E. MORIN"
mq/qqueue: --list does not print (active) with --quiet...
r11767 if queue == current and not ui.quiet:
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229 ui.write(_(' (active)\n'))
else:
ui.write('\n')
return
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 if not _validname(name):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(
Henrik Stuart
mq: fix naming issues for qqueue directories
r11270 _('invalid queue name, may not contain the characters ":\\/."'))
Pierre-Yves David
mq: take wlock when 'qqueue' is doing write operations...
r29752 with repo.wlock():
existing = _getqueues()
if opts.get('create'):
if name in existing:
raise error.Abort(_('queue "%s" already exists') % name)
if _noqueues():
_addqueue(_defaultqueue)
_addqueue(name)
_setactive(name)
elif opts.get('rename'):
current = _getcurrent()
if name == current:
raise error.Abort(_('can\'t rename "%s" to its current name')
% name)
if name in existing:
raise error.Abort(_('queue "%s" already exists') % name)
olddir = _queuedir(current)
newdir = _queuedir(name)
if os.path.exists(newdir):
raise error.Abort(_('non-queue directory "%s" already exists') %
newdir)
fh = repo.vfs('patches.queues.new', 'w')
for queue in existing:
if queue == current:
fh.write('%s\n' % (name,))
if os.path.exists(olddir):
util.rename(olddir, newdir)
else:
fh.write('%s\n' % (queue,))
fh.close()
Mads Kiilerich
vfs: use repo.vfs.rename
r31312 repo.vfs.rename('patches.queues.new', _allqueues)
Pierre-Yves David
mq: take wlock when 'qqueue' is doing write operations...
r29752 _setactivenocheck(name)
elif opts.get('delete'):
"Yann E. MORIN"
mq/qqueue: add --purge option to delete a queue and its patch dir...
r11967 _delete(name)
Pierre-Yves David
mq: take wlock when 'qqueue' is doing write operations...
r29752 elif opts.get('purge'):
if name in existing:
_delete(name)
qdir = _queuedir(name)
if os.path.exists(qdir):
shutil.rmtree(qdir)
else:
if name not in existing:
raise error.Abort(_('use --create to create a new queue'))
_setactive(name)
Henrik Stuart
mq: support multiple patch queues using qqueue
r11229
Pierre-Yves David
mq: ensure mq changesets are set to secret when no phase data are found
r15928 def mqphasedefaults(repo, roots):
"""callback used to set mq changeset as secret when no phase data exists"""
if repo.mq.applied:
Boris Feld
configitems: register the 'mq.secret' config
r34185 if repo.ui.configbool('mq', 'secret'):
Pierre-Yves David
mq: take mq.secret configuration into account when picking the default phase
r16028 mqphase = phases.secret
else:
mqphase = phases.draft
Augie Fackler
mq: pass qbase node instead of mq statusentry in phasedefaults...
r15972 qbase = repo[repo.mq.applied[0].node]
Pierre-Yves David
mq: take mq.secret configuration into account when picking the default phase
r16028 roots[mqphase].add(qbase.node())
Pierre-Yves David
mq: ensure mq changesets are set to secret when no phase data are found
r15928 return roots
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__):
Pierre-Yves David
mq: use an unfiltered property cache for the queue object...
r19395 @localrepo.unfilteredpropertycache
Simon Heimberg
mq: only read files when needed...
r8524 def mq(self):
Simon Heimberg
mq: do not inherit settings form base repo in mqrepo (Fixes issue2358)...
r19064 return queue(self.ui, self.baseui, self.path)
Simon Heimberg
mq: only read files when needed...
r8524
Yuya Nishihara
cmdserver: reload mq on each runcommand request to avoid corruption...
r20628 def invalidateall(self):
super(mqrepo, self).invalidateall()
if localrepo.hasunfilteredcache(self, 'mq'):
Yuya Nishihara
cmdserver: recreate mq object on runcommand in case queue path was changed...
r20629 # recreate mq in case queue path was changed
delattr(self.unfiltered(), 'mq')
Yuya Nishihara
cmdserver: reload mq on each runcommand request to avoid corruption...
r20628
Adrian Buehlmann
mq: rename abort_if_wdir_patched to abortifwdirpatched
r14596 def abortifwdirpatched(self, errmsg, force=False):
David Soria Parra
shelve: allow shelving of a change with an mq patch applied...
r19856 if self.mq.applied and self.mq.checkapplied and not force:
Martin Geisler
mq: forbid commit of merge involving mq patches
r13520 parents = self.dirstate.parents()
patches = [s.node for s in self.mq.applied]
if parents[0] in patches or parents[1] in patches:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.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,
Pierre-Yves David
mq: don't use mutable default argument value...
r31407 force=False, editor=False, extra=None):
if extra is None:
extra = {}
Adrian Buehlmann
mq: rename abort_if_wdir_patched to abortifwdirpatched
r14596 self.abortifwdirpatched(
Vadim Gelfer
mq: do not allow to push from repo with patches applied
r2848 _('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
Pierre-Yves David
push: pass a `pushoperation` object to localrepo.checkpush...
r20924 def checkpush(self, pushop):
if self.mq.applied and self.mq.checkapplied and not pushop.force:
Pierre-Yves David
mq-safety: don't apply safety on non-outgoing changeset...
r15952 outapplied = [e.node for e in self.mq.applied]
Pierre-Yves David
push: pass a `pushoperation` object to localrepo.checkpush...
r20924 if pushop.revs:
Pierre-Yves David
mq-safety: don't apply safety on non-outgoing changeset...
r15952 # Assume applied patches have no non-patch descendants and
# are not on remote already. Filtering any changeset not
# pushed.
Pierre-Yves David
push: pass a `pushoperation` object to localrepo.checkpush...
r20924 heads = set(pushop.revs)
Pierre-Yves David
mq-safety: don't apply safety on non-outgoing changeset...
r15952 for node in reversed(outapplied):
if node in heads:
break
else:
outapplied.pop()
# looking for pushed and shared changeset
for node in outapplied:
Bryan O'Sullivan
mq: don't refer to a random name-captured repo object...
r17954 if self[node].phase() < phases.secret:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('source has mq patches applied'))
Pierre-Yves David
mq-safety: don't apply safety on non-outgoing changeset...
r15952 # no non-secret patches pushed
Pierre-Yves David
push: pass a `pushoperation` object to localrepo.checkpush...
r20924 super(mqrepo, self).checkpush(pushop)
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 def _findtags(self):
'''augment tags from base class with patch tags'''
result = super(mqrepo, self)._findtags()
Brendan Cully
Add mq patch names to tagscache instead of overriding lookup....
r2682
Brendan Cully
mq: replace module-wide repo hash with a repo attribute
r2724 q = self.mq
Brendan Cully
mq: do not hold a reference to repo in tags override...
r2723 if not q.applied:
Greg Ward
localrepo: factor _findtags() out of tags() (issue548)....
r9145 return result
Brendan Cully
Mq: modify repo.lookup to resolve applied patches too.
r2663
Benoit Boissinot
mq: avoid many hex/bin conversions, keep the binary node when possible
r10678 mqtags = [(patch.node, patch.name) for patch in q.applied]
Alexis S. L. Carvalho
mqrepo: don't abort if the status file has an unknown node
r5979
Matt Mackall
mq: fix qpush recursion in _findtags when status file is wrong (issue2664)...
r13508 try:
Pierre-Yves David
clfilter: mq should not warn about filtered mq patches...
r18011 # for now ignore filtering business
self.unfiltered().changelog.rev(mqtags[-1][0])
Idan Kamara
mq: catch correct exception when calling changelog.rev()
r14600 except error.LookupError:
Martin Geisler
i18n: mark strings for translation in mq extension
r6960 self.ui.warn(_('mq status file refers to unknown node %s\n')
Matt Mackall
mq: remove import of revlog
r7639 % short(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
Pierre-Yves David
mq: comply with filtering when injecting fake tags (issue3812)...
r18662 # do not add fake tags for filtered revisions
included = self.changelog.hasnode
mqtags = [mqt for mqt in mqtags if included(mqt[0])]
if not mqtags:
return result
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
mq: lowercase warning messages
r16929 self.ui.warn(_('tag %s overrides mq patch of the same '
Brodie Rao
cleanup: eradicate long lines
r16683 '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
Vadim Gelfer
mq: only add mq attribute to local repo
r2851 if repo.local():
repo.__class__ = mqrepo
mason@suse.com
Add mq extension
r1808
Pierre-Yves David
mq: ensure mq changesets are set to secret when no phase data are found
r15928 repo._phasedefaults.append(mqphasedefaults)
Matt Mackall
extensions: use new wrapper functions
r7216 def mqimport(orig, ui, repo, *args, **kwargs):
Patrick Mezard
mq: replace hasattr() with util.safehasattr(), update check-code.py
r16416 if (util.safehasattr(repo, 'abortifwdirpatched')
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 and not kwargs.get(r'no_commit', False)):
Adrian Buehlmann
mq: rename abort_if_wdir_patched to abortifwdirpatched
r14596 repo.abortifwdirpatched(_('cannot import over an applied patch'),
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 kwargs.get(r'force'))
Matt Mackall
extensions: use new wrapper functions
r7216 return orig(ui, repo, *args, **kwargs)
Brendan Cully
mq: make init -Q do what qinit -c did
r10402 def mqinit(orig, ui, *args, **kwargs):
Pulkit Goyal
py3: fix keyword arguments handling in mq...
r34506 mq = kwargs.pop(r'mq', None)
Brendan Cully
mq: make init -Q do what qinit -c did
r10402
if not mq:
return orig(ui, *args, **kwargs)
Cédric Duval
mq: fix init with nonexistent or non-local repository
r10691 if args:
repopath = args[0]
if not hg.islocal(repopath):
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('only a local queue repository '
Cédric Duval
mq: fix init with nonexistent or non-local repository
r10691 'may be initialized'))
else:
Pulkit Goyal
py3: use pycompat.getcwd() instead of os.getcwd()...
r30519 repopath = cmdutil.findrepo(pycompat.getcwd())
Cédric Duval
mq: fix init with nonexistent or non-local repository
r10691 if not repopath:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('there is no Mercurial repository here '
Cédric Duval
mq: fix init with nonexistent or non-local repository
r10691 '(.hg not found)'))
Brendan Cully
mq: make init -Q do what qinit -c did
r10402 repo = hg.repository(ui, repopath)
Brendan Cully
mq: unify implementation of qinit and init -Q
r10480 return qinit(ui, repo, True)
Brendan Cully
mq: make init -Q do what qinit -c did
r10402
Brendan Cully
mq: add --mq option to some commands...
r10359 def mqcommand(orig, ui, repo, *args, **kwargs):
"""Add --mq option to operate on patch repository instead of main"""
# some commands do not like getting unknown options
Pulkit Goyal
py3: convert key to str to make kwargs.pop work in mq...
r32193 mq = kwargs.pop(r'mq', None)
Brendan Cully
mq: add --mq option to some commands...
r10359
if not mq:
return orig(ui, repo, *args, **kwargs)
q = repo.mq
r = q.qrepo()
if not r:
Pierre-Yves David
error: get Abort from 'error' instead of 'util'...
r26587 raise error.Abort(_('no queue repository'))
Brendan Cully
mq: incorporate mq repo config when using --mq...
r10407 return orig(r.ui, r, *args, **kwargs)
Brendan Cully
mq: add --mq option to some commands...
r10359
Bryan O'Sullivan
mq: switch to new summary hook mechanism
r19212 def summaryhook(ui, repo):
Matt Mackall
mq: add a line to hg summary
r11107 q = repo.mq
m = []
a, u = len(q.applied), len(q.unapplied(repo))
if a:
Eric Eisner
mq: make use of output labeling for summary
r11121 m.append(ui.label(_("%d applied"), 'qseries.applied') % a)
Matt Mackall
mq: add a line to hg summary
r11107 if u:
Eric Eisner
mq: make use of output labeling for summary
r11121 m.append(ui.label(_("%d unapplied"), 'qseries.unapplied') % u)
Matt Mackall
mq: add a line to hg summary
r11107 if m:
FUJIWARA Katsunori
i18n: make column positioning message of MQ summary output translatable...
r17893 # i18n: column positioning for "hg summary"
ui.write(_("mq: %s\n") % ', '.join(m))
Matt Mackall
mq: add a line to hg summary
r11107 else:
FUJIWARA Katsunori
i18n: add "i18n" comment to column positioning messages of "hg summary"...
r17892 # i18n: column positioning for "hg summary"
Martin Geisler
mq: mark string for translation
r11119 ui.note(_("mq: (empty queue)\n"))
Matt Mackall
mq: add a line to hg summary
r11107
FUJIWARA Katsunori
revset: replace extpredicate by revsetpredicate of registrar...
r28394 revsetpredicate = registrar.revsetpredicate()
FUJIWARA Katsunori
revset: use delayregistrar to register predicate in extension easily...
r27586
@revsetpredicate('mq()')
Idan Kamara
mq: add a 'mq()' revset predicate that returns applied mq csets
r14210 def revsetmq(repo, subset, x):
FUJIWARA Katsunori
revset: use delayregistrar to register predicate in extension easily...
r27586 """Changesets managed by MQ.
Idan Kamara
mq: add a 'mq()' revset predicate that returns applied mq csets
r14210 """
Yuya Nishihara
revset: split language services to revsetlang module (API)...
r31024 revsetlang.getargs(x, 0, 0, _("mq takes no arguments"))
Idan Kamara
mq: add a 'mq()' revset predicate that returns applied mq csets
r14210 applied = set([repo[r.node].rev() for r in repo.mq.applied])
Yuya Nishihara
revset: import set classes directly from smartset module...
r31023 return smartset.baseset([r for r in subset if r in applied])
Idan Kamara
mq: add a 'mq()' revset predicate that returns applied mq csets
r14210
# tell hggettext to extract docstrings from these functions:
i18nfunctions = [revsetmq]
Matt Harbison
mq: defer command wrapping to extsetup (API)...
r17101 def extsetup(ui):
# Ensure mq wrappers are called first, regardless of extension load order by
# NOT wrapping in uisetup() and instead deferring to init stage two here.
Matt Mackall
mq: drop -Q in favor of --mq only
r10591 mqopt = [('', 'mq', None, _("operate on patch repository"))]
Brendan Cully
mq: make init -Q do what qinit -c did
r10402
Matt Mackall
extensions: use new wrapper functions
r7216 extensions.wrapcommand(commands.table, 'import', mqimport)
Bryan O'Sullivan
mq: switch to new summary hook mechanism
r19212 cmdutil.summaryhooks.add('mq', summaryhook)
Brendan Cully
mq: make init -Q do what qinit -c did
r10402
entry = extensions.wrapcommand(commands.table, 'init', mqinit)
entry[1].extend(mqopt)
Dan Villiom Podlaski Christiansen
mq: extend support for the --mq argument to extension commands...
r12036 def dotable(cmdtable):
Yuya Nishihara
dispatch: store norepo/optionalrepo/inferrepo attributes in function (API)...
r28313 for cmd, entry in cmdtable.iteritems():
Dan Villiom Podlaski Christiansen
mq: extend support for the --mq argument to extension commands...
r12036 cmd = cmdutil.parsealiases(cmd)[0]
Yuya Nishihara
dispatch: store norepo/optionalrepo/inferrepo attributes in function (API)...
r28313 func = entry[0]
Augie Fackler
dispatch: stop supporting non-use of @command...
r30485 if func.norepo:
Dan Villiom Podlaski Christiansen
mq: extend support for the --mq argument to extension commands...
r12036 continue
entry = extensions.wrapcommand(cmdtable, cmd, mqcommand)
entry[1].extend(mqopt)
dotable(commands.table)
for extname, extmodule in extensions.extensions():
if extmodule.__file__ != __file__:
dotable(getattr(extmodule, 'cmdtable', {}))
Brendan Cully
Prevent import over an applied patch (closes issue795)
r7142
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 colortable = {'qguard.negative': 'red',
'qguard.positive': 'yellow',
'qguard.unguarded': 'green',
'qseries.applied': 'blue bold underline',
'qseries.guarded': 'black bold',
'qseries.missing': 'red bold',
'qseries.unapplied': 'black bold'}