Mercurial > hg
diff hgext/mq.py @ 43076:2372284d9457
formatting: blacken the codebase
This is using my patch to black
(https://github.com/psf/black/pull/826) so we don't un-wrap collection
literals.
Done with:
hg files 'set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"' | xargs black -S
# skip-blame mass-reformatting only
# no-check-commit reformats foo_bar functions
Differential Revision: https://phab.mercurial-scm.org/D6971
author | Augie Fackler <augie@google.com> |
---|---|
date | Sun, 06 Oct 2019 09:45:02 -0400 |
parents | 51e52a495214 |
children | 687b865b95ad |
line wrap: on
line diff
--- a/hgext/mq.py Sat Oct 05 10:29:34 2019 -0400 +++ b/hgext/mq.py Sun Oct 06 09:45:02 2019 -0400 @@ -117,17 +117,17 @@ configtable = {} configitem = registrar.configitem(configtable) -configitem('mq', 'git', - default='auto', +configitem( + 'mq', 'git', default='auto', ) -configitem('mq', 'keepchanges', - default=False, +configitem( + 'mq', 'keepchanges', default=False, ) -configitem('mq', 'plain', - default=False, +configitem( + 'mq', 'plain', default=False, ) -configitem('mq', 'secret', - default=False, +configitem( + 'mq', 'secret', default=False, ) # force load strip extension formerly included in mq and import some utility @@ -139,12 +139,15 @@ class dummyui(object): def debug(self, msg): pass + def log(self, event, msgfmt, *msgargs, **opts): pass + stripext = extensions.load(dummyui(), 'strip', '') strip = stripext.strip + def checksubstate(repo, baserev=None): '''return list of subrepos at a different revision than substate. Abort if any subrepos have uncommitted changes.''' @@ -160,10 +163,12 @@ inclsubs.append(s) return inclsubs + # Patch names looks like unix-file names. # They must be joinable with queue directory and result in the patch path. normname = util.normpath + class statusentry(object): def __init__(self, node, name): self.node, self.name = node, name @@ -174,22 +179,24 @@ __str__ = encoding.strmethod(__bytes__) __repr__ = encoding.strmethod(__bytes__) + # The order of the headers in 'hg export' HG patches: HGHEADERS = [ -# '# HG changeset patch', + # '# HG changeset patch', '# User ', '# Date ', '# ', '# Branch ', '# Node ID ', - '# Parent ', # can occur twice for merges - but that is not relevant for mq - ] + '# Parent ', # can occur twice for merges - but that is not relevant for mq +] # The order of headers in plain 'mail style' patches: PLAINHEADERS = { 'from': 0, 'date': 1, 'subject': 2, - } +} + def inserthgheader(lines, header, value): """Assuming lines contains a HG patch header, add a header line with value. @@ -229,10 +236,11 @@ return lines if lineindex > newindex: bestpos = min(bestpos, i) - break # next line + break # next line lines.insert(bestpos, header + value) return lines + def insertplainheader(lines, header, value): """For lines containing a plain patch header, add a header line with value. >>> insertplainheader([], b'Date', b'z') @@ -270,17 +278,21 @@ lines.insert(bestpos, '%s: %s' % (header, value)) return lines + class patchheader(object): def __init__(self, pf, plainmode=False): def eatdiff(lines): while lines: l = lines[-1] - if (l.startswith("diff -") or - l.startswith("Index:") or - l.startswith("===========")): + if ( + l.startswith("diff -") + or l.startswith("Index:") + or l.startswith("===========") + ): del lines[-1] else: break + def eatempty(lines): while lines: if not lines[-1].strip(): @@ -301,11 +313,12 @@ for line in open(pf, 'rb'): line = line.rstrip() - if (line.startswith('diff --git') - or (diffstart and line.startswith('+++ '))): + if line.startswith('diff --git') or ( + diffstart and line.startswith('+++ ') + ): diffstart = 2 break - diffstart = 0 # reset + diffstart = 0 # reset if line.startswith("--- "): diffstart = 1 continue @@ -316,7 +329,7 @@ elif line.startswith("# Date "): date = line[7:] elif line.startswith("# Parent "): - parent = line[9:].lstrip() # handle double trailing space + parent = line[9:].lstrip() # handle double trailing space elif line.startswith("# Branch "): branch = line[9:] elif line.startswith("# Node ID "): @@ -327,16 +340,19 @@ elif line == '# HG changeset patch': message = [] format = "hgpatch" - elif (format != "tagdone" and (line.startswith("Subject: ") or - line.startswith("subject: "))): + 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: "))): + elif format != "tagdone" and ( + line.startswith("From: ") or line.startswith("from: ") + ): user = line[6:] format = "tag" - elif (format != "tagdone" and (line.startswith("Date: ") or - line.startswith("date: "))): + elif format != "tagdone" and ( + line.startswith("Date: ") or line.startswith("date: ") + ): date = line[6:] format = "tag" elif format == "tag" and line == "": @@ -368,11 +384,14 @@ self.nodeid = nodeid self.branch = branch self.haspatch = diffstart > 1 - self.plainmode = (plainmode or - '# HG changeset patch' not in self.comments and - any(c.startswith('Date: ') or - c.startswith('From: ') - for c in self.comments)) + self.plainmode = ( + plainmode + or '# HG changeset patch' not in self.comments + and any( + c.startswith('Date: ') or c.startswith('From: ') + for c in self.comments + ) + ) def setuser(self, user): try: @@ -439,6 +458,7 @@ ci += 1 del self.comments[ci] + def newcommit(repo, phase, *args, **kwargs): """helper dedicated to ensure a commit respect mq.secret setting @@ -456,9 +476,11 @@ repo.ui.setconfig('ui', 'allowemptycommit', True) return repo.commit(*args, **kwargs) + class AbortNoCleanup(error.Abort): pass + class queue(object): def __init__(self, ui, baseui, path, patchdir=None): self.basepath = path @@ -506,9 +528,12 @@ n, name = entry yield statusentry(bin(n), name) elif l.strip(): - self.ui.warn(_('malformated mq status line: %s\n') % - stringutil.pprint(entry)) + self.ui.warn( + _('malformated mq status line: %s\n') + % stringutil.pprint(entry) + ) # else we ignore empty lines + try: lines = self.opener.read(self.statuspath).splitlines() return list(parselines(lines)) @@ -548,8 +573,13 @@ 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) + diffopts = patchmod.difffeatureopts( + self.ui, + opts, + git=True, + whitespace=not plain, + formatchanging=not plain, + ) if self.gitmode == 'auto': diffopts.upgrade = True elif self.gitmode == 'keep': @@ -557,8 +587,10 @@ elif self.gitmode in ('yes', 'no'): diffopts.git = self.gitmode == 'yes' else: - raise error.Abort(_('mq.git option can be auto/keep/yes/no' - ' got %s') % self.gitmode) + raise error.Abort( + _('mq.git option can be auto/keep/yes/no' ' got %s') + % self.gitmode + ) if patchfn: diffopts = self.patchopts(diffopts, patchfn) return diffopts @@ -572,8 +604,9 @@ for patchfn in patches: patchf = self.opener(patchfn, 'r') # if the patch was a git patch, refresh it as a git patch - diffopts.git = any(line.startswith('diff --git') - for line in patchf) + diffopts.git = any( + line.startswith('diff --git') for line in patchf + ) patchf.close() return diffopts @@ -584,6 +617,7 @@ def matchpatch(l): l = l.split('#', 1)[0] return l.strip() == patch + for index, l in enumerate(self.fullseries): if matchpatch(l): return index @@ -607,8 +641,10 @@ patch = patch.strip() if patch: if patch in self.series: - raise error.Abort(_('%s appears more than once in %s') % - (patch, self.join(self.seriespath))) + raise error.Abort( + _('%s appears more than once in %s') + % (patch, self.join(self.seriespath)) + ) self.series.append(patch) self.seriesguards.append(self.guard_re.findall(comment)) @@ -618,8 +654,10 @@ bad_chars = '# \t\r\n\f' first = guard[0] if first in '-+': - return (_('guard %r starts with invalid character: %r') % - (guard, first)) + return _('guard %r starts with invalid character: %r') % ( + guard, + first, + ) for c in bad_chars: if c in guard: return _('invalid character in guard %r: %r') % (guard, c) @@ -646,8 +684,9 @@ for i, guard in enumerate(guards): bad = self.checkguard(guard) if bad: - self.ui.warn('%s:%d: %s\n' % - (self.join(self.guardspath), i + 1, bad)) + self.ui.warn( + '%s:%d: %s\n' % (self.join(self.guardspath), i + 1, bad) + ) else: self.activeguards.append(guard) return self.activeguards @@ -673,8 +712,9 @@ if not patchguards: return True, None guards = self.active() - exactneg = [g for g in patchguards - if g.startswith('-') and g[1:] in guards] + exactneg = [ + g for g in patchguards if g.startswith('-') and g[1:] in guards + ] if exactneg: return False, stringutil.pprint(exactneg[0]) pos = [g for g in patchguards if g.startswith('+')] @@ -697,22 +737,32 @@ 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]) + 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]) + write( + _('allowing %s - no matching negative guards\n') + % self.series[idx] + ) else: - write(_('allowing %s - guarded by %s\n') % - (self.series[idx], why)) + write( + _('allowing %s - guarded by %s\n') + % (self.series[idx], why) + ) if not pushable: if why: - write(_('skipping %s - guarded by %s\n') % - (self.series[idx], why)) + write( + _('skipping %s - guarded by %s\n') + % (self.series[idx], why) + ) else: - write(_('skipping %s - no matching guards\n') % - self.series[idx]) + write( + _('skipping %s - no matching guards\n') + % self.series[idx] + ) def savedirty(self): def writelist(items, path): @@ -720,6 +770,7 @@ for i in items: fp.write("%s\n" % i) fp.close() + if self.applieddirty: writelist(map(bytes, self.applied), self.statuspath) self.applieddirty = False @@ -742,8 +793,9 @@ try: os.unlink(undo) except OSError as inst: - self.ui.warn(_('error removing undo: %s\n') % - stringutil.forcebytestr(inst)) + self.ui.warn( + _('error removing undo: %s\n') % stringutil.forcebytestr(inst) + ) def backup(self, repo, files, copy=False): # backup local changes in --force case @@ -751,27 +803,40 @@ absf = repo.wjoin(f) if os.path.lexists(absf): absorig = scmutil.backuppath(self.ui, repo, f) - self.ui.note(_('saving current version of %s as %s\n') % - (f, os.path.relpath(absorig))) + self.ui.note( + _('saving current version of %s as %s\n') + % (f, os.path.relpath(absorig)) + ) if copy: util.copyfile(absf, absorig) else: util.rename(absf, absorig) - def printdiff(self, repo, diffopts, node1, node2=None, files=None, - fp=None, changes=None, opts=None): + def printdiff( + self, + repo, + diffopts, + node1, + node2=None, + files=None, + fp=None, + changes=None, + opts=None, + ): if opts is None: opts = {} stat = opts.get('stat') m = scmutil.match(repo[node1], files, opts) - logcmdutil.diffordiffstat(self.ui, repo, diffopts, node1, node2, m, - changes, stat, fp) + logcmdutil.diffordiffstat( + self.ui, repo, diffopts, node1, node2, m, changes, stat, fp + ) def mergeone(self, repo, mergeq, head, patch, rev, diffopts): # first try just applying the patch - (err, n) = self.apply(repo, [patch], update_status=False, - strict=True, merge=rev) + (err, n) = self.apply( + repo, [patch], update_status=False, strict=True, merge=rev + ) if err == 0: return (err, n) @@ -872,8 +937,9 @@ patchfile: name of patch file''' files = set() try: - fuzz = patchmod.patch(self.ui, repo, patchfile, strip=1, - files=files, eolmode=None) + fuzz = patchmod.patch( + self.ui, repo, patchfile, strip=1, files=files, eolmode=None + ) return (True, list(files), fuzz) except Exception as inst: self.ui.note(stringutil.forcebytestr(inst) + '\n') @@ -882,18 +948,37 @@ self.ui.traceback() return (False, list(files), False) - def apply(self, repo, series, list=False, update_status=True, - strict=False, patchdir=None, merge=None, all_files=None, - tobackup=None, keepchanges=False): + def apply( + self, + repo, + series, + list=False, + update_status=True, + strict=False, + patchdir=None, + merge=None, + all_files=None, + tobackup=None, + keepchanges=False, + ): wlock = lock = tr = None try: wlock = repo.wlock() lock = repo.lock() tr = repo.transaction("qpush") try: - ret = self._apply(repo, series, list, update_status, - strict, patchdir, merge, all_files=all_files, - tobackup=tobackup, keepchanges=keepchanges) + ret = self._apply( + repo, + series, + list, + update_status, + strict, + patchdir, + merge, + all_files=all_files, + tobackup=tobackup, + keepchanges=keepchanges, + ) tr.close() self.savedirty() return ret @@ -901,7 +986,7 @@ tr.close() self.savedirty() raise - except: # re-raises + except: # re-raises try: tr.abort() finally: @@ -911,9 +996,19 @@ release(tr, lock, wlock) self.removeundo(repo) - def _apply(self, repo, series, list=False, update_status=True, - strict=False, patchdir=None, merge=None, all_files=None, - tobackup=None, keepchanges=False): + def _apply( + self, + repo, + series, + list=False, + update_status=True, + strict=False, + patchdir=None, + merge=None, + all_files=None, + tobackup=None, + keepchanges=False, + ): """returns (error, hash) error = 1 for unable to read, 2 for patch failed, 3 for patch @@ -957,7 +1052,8 @@ if touched and keepchanges: raise AbortNoCleanup( _("conflicting local changes found"), - hint=_("did you forget to qrefresh?")) + hint=_("did you forget to qrefresh?"), + ) self.backup(repo, touched, copy=True) tobackup = tobackup - touched (patcherr, files, fuzz) = self.patch(repo, pf) @@ -989,14 +1085,16 @@ wctx = repo[None] pctx = repo['.'] overwrite = False - mergedsubstate = subrepoutil.submerge(repo, pctx, wctx, wctx, - overwrite) + mergedsubstate = subrepoutil.submerge( + repo, pctx, wctx, wctx, overwrite + ) files += mergedsubstate.keys() match = scmutil.matchfiles(repo, files or []) oldtip = repo.changelog.tip() - n = newcommit(repo, None, message, ph.user, ph.date, match=match, - force=True) + n = newcommit( + repo, None, message, ph.user, ph.date, match=match, force=True + ) if repo.changelog.tip() == oldtip: raise error.Abort(_("qpush exactly duplicates child changeset")) if n is None: @@ -1006,8 +1104,9 @@ self.applied.append(statusentry(n, patchname)) if patcherr: - self.ui.warn(_("patch failed, rejects left in working " - "directory\n")) + self.ui.warn( + _("patch failed, rejects left in working " "directory\n") + ) err = 2 break @@ -1054,7 +1153,7 @@ if unknown: if numrevs: - rev = dict((entry.name, entry.node) for entry in qfinished) + 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)) @@ -1106,8 +1205,9 @@ def delete(self, repo, patches, opts): if not patches and not opts.get('rev'): - raise error.Abort(_('qdelete requires at least one revision or ' - 'patch name')) + raise error.Abort( + _('qdelete requires at least one revision or ' 'patch name') + ) realpatches = [] for patch in patches: @@ -1145,13 +1245,13 @@ def putsubstate2changes(self, substatestate, changes): for files in changes[:3]: if '.hgsubstate' in files: - return # already listed up + 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 + else: # modified changes[0].append('.hgsubstate') def checklocalchanges(self, repo, force=False, refresh=True): @@ -1166,39 +1266,46 @@ if not force: cmdutil.checkunfinished(repo) if s.modified or s.added or s.removed or s.deleted: - _("local changes found") # i18n tool detection + _("local changes found") # i18n tool detection raise error.Abort(_("local changes found" + excsuffix)) if checksubstate(repo): - _("local changed subrepos found") # i18n tool detection + _("local changed subrepos found") # i18n tool detection raise error.Abort(_("local changed subrepos found" + excsuffix)) else: cmdutil.checkunfinished(repo, skipmerge=True) return s _reserved = ('series', 'status', 'guards', '.', '..') + def checkreservedname(self, name): if name in self._reserved: - raise error.Abort(_('"%s" cannot be used as the name of a patch') - % name) + raise error.Abort( + _('"%s" cannot be used as the name of a patch') % name + ) if name != name.strip(): # whitespace is stripped by parseseries() - raise error.Abort(_('patch name cannot begin or end with ' - 'whitespace')) + raise error.Abort( + _('patch name cannot begin or end with ' 'whitespace') + ) for prefix in ('.hg', '.mq'): if name.startswith(prefix): - raise error.Abort(_('patch name cannot begin with "%s"') - % prefix) + raise error.Abort( + _('patch name cannot begin with "%s"') % prefix + ) for c in ('#', ':', '\r', '\n'): if c in name: - raise error.Abort(_('%r cannot be used in the name of a patch') - % pycompat.bytestr(c)) + raise error.Abort( + _('%r cannot be used in the name of a patch') + % pycompat.bytestr(c) + ) def checkpatchname(self, name, force=False): self.checkreservedname(name) if not force and os.path.exists(self.join(name)): if os.path.isdir(self.join(name)): - raise error.Abort(_('"%s" already exists as a directory') - % name) + raise error.Abort( + _('"%s" already exists as a directory') % name + ) else: raise error.Abort(_('patch "%s" already exists') % name) @@ -1206,7 +1313,7 @@ """Return a suitable filename for title, adding a suffix to make it unique in the existing list""" namebase = re.sub(br'[\s\W_]+', b'_', title.lower()).strip(b'_') - namebase = namebase[:75] # avoid too long name (issue5117) + namebase = namebase[:75] # avoid too long name (issue5117) if namebase: try: self.checkreservedname(namebase) @@ -1252,8 +1359,9 @@ if opts.get('include') or opts.get('exclude') or pats: # detect missing files in pats def badfn(f, msg): - if f != '.hgsubstate': # .hgsubstate is auto-created + if f != '.hgsubstate': # .hgsubstate is auto-created raise error.Abort('%s: %s' % (f, msg)) + match = scmutil.match(repo[None], pats, opts, badfn=badfn) changes = repo.status(match=match) else: @@ -1271,28 +1379,42 @@ # if patch file write fails, abort early p = self.opener(patchfn, "w") except IOError as e: - raise error.Abort(_('cannot write patch "%s": %s') - % (patchfn, encoding.strtolocal(e.strerror))) + raise error.Abort( + _('cannot write patch "%s": %s') + % (patchfn, encoding.strtolocal(e.strerror)) + ) try: defaultmsg = "[mq]: %s" % patchfn editor = cmdutil.getcommiteditor(editform=editform) if edit: + def finishdesc(desc): if desc.rstrip(): return desc else: return defaultmsg + # i18n: this message is shown in editor with "HG: " prefix extramsg = _('Leave message empty to use default message.') - editor = cmdutil.getcommiteditor(finishdesc=finishdesc, - extramsg=extramsg, - editform=editform) + editor = cmdutil.getcommiteditor( + finishdesc=finishdesc, + extramsg=extramsg, + editform=editform, + ) commitmsg = msg else: commitmsg = msg or defaultmsg - n = newcommit(repo, None, commitmsg, user, date, match=match, - force=True, editor=editor) + n = newcommit( + repo, + None, + commitmsg, + user, + date, + match=match, + force=True, + editor=editor, + ) if n is None: raise error.Abort(_("repo commit failed")) try: @@ -1317,15 +1439,20 @@ parent = self.qparents(repo, n) if inclsubs: self.putsubstate2changes(substatestate, changes) - chunks = patchmod.diff(repo, node1=parent, node2=n, - changes=changes, opts=diffopts) + chunks = patchmod.diff( + repo, + node1=parent, + node2=n, + changes=changes, + opts=diffopts, + ) for chunk in chunks: p.write(chunk) p.close() r = self.qrepo() if r: r[None].add([patchfn]) - except: # re-raises + except: # re-raises repo.rollback() raise except Exception: @@ -1391,7 +1518,7 @@ if res: i = self.series.index(res) try: - off = int(patch[minus + 1:] or 1) + off = int(patch[minus + 1 :] or 1) except (ValueError, OverflowError): pass else: @@ -1403,7 +1530,7 @@ if res: i = self.series.index(res) try: - off = int(patch[plus + 1:] or 1) + off = int(patch[plus + 1 :] or 1) except (ValueError, OverflowError): pass else: @@ -1411,9 +1538,19 @@ return self.series[i + off] raise error.Abort(_("patch %s not in series") % patch) - def push(self, repo, patch=None, force=False, list=False, mergeq=None, - all=False, move=False, exact=False, nobackup=False, - keepchanges=False): + def push( + self, + repo, + patch=None, + force=False, + list=False, + mergeq=None, + all=False, + move=False, + exact=False, + nobackup=False, + keepchanges=False, + ): self.checkkeepchanges(keepchanges, force) diffopts = self.diffopts() with repo.wlock(): @@ -1437,15 +1574,15 @@ patch = self.lookup(patch) info = self.isapplied(patch) if info and info[0] >= len(self.applied) - 1: - self.ui.warn( - _('qpush: %s is already at the top\n') % patch) + self.ui.warn(_('qpush: %s is already at the top\n') % patch) return 0 pushable, reason = self.pushable(patch) if pushable: if self.series.index(patch) < self.seriesend(): raise error.Abort( - _("cannot push to a previous patch: %s") % patch) + _("cannot push to a previous patch: %s") % patch + ) else: if reason: reason = _('guarded by %s') % reason @@ -1474,18 +1611,22 @@ if exact: if keepchanges: raise error.Abort( - _("cannot use --exact and --keep-changes together")) + _("cannot use --exact and --keep-changes together") + ) if move: - raise error.Abort(_('cannot use --exact and --move ' - 'together')) + raise error.Abort( + _('cannot use --exact and --move ' 'together') + ) if self.applied: - raise error.Abort(_('cannot push --exact with applied ' - 'patches')) + raise error.Abort( + _('cannot push --exact with applied ' 'patches') + ) root = self.series[start] target = patchheader(self.join(root), self.plainmode).parent if not target: raise error.Abort( - _("%s does not have a parent recorded") % root) + _("%s does not have a parent recorded") % root + ) if not repo[target] == repo['.']: hg.update(repo, target) @@ -1521,8 +1662,12 @@ if (not nobackup and force) or keepchanges: status = self.checklocalchanges(repo, force=True) if keepchanges: - tobackup.update(status.modified + status.added + - status.removed + status.deleted) + tobackup.update( + status.modified + + status.added + + status.removed + + status.deleted + ) else: tobackup.update(status.modified + status.added) @@ -1532,14 +1677,25 @@ if mergeq: ret = self.mergepatch(repo, mergeq, s, diffopts) else: - ret = self.apply(repo, s, list, all_files=all_files, - tobackup=tobackup, keepchanges=keepchanges) + ret = self.apply( + repo, + s, + list, + all_files=all_files, + tobackup=tobackup, + keepchanges=keepchanges, + ) except AbortNoCleanup: raise - except: # re-raises + except: # re-raises self.ui.warn(_('cleaning up working directory...\n')) - cmdutil.revert(self.ui, repo, repo['.'], - repo.dirstate.parents(), no_backup=True) + cmdutil.revert( + self.ui, + repo, + repo['.'], + repo.dirstate.parents(), + no_backup=True, + ) # only remove unknown files that we know we touched or # created while patching for f in all_files: @@ -1558,8 +1714,16 @@ self.ui.write(_("now at: %s\n") % top) return ret[0] - def pop(self, repo, patch=None, force=False, update=True, all=False, - nobackup=False, keepchanges=False): + def pop( + self, + repo, + patch=None, + force=False, + update=True, + all=False, + nobackup=False, + keepchanges=False, + ): self.checkkeepchanges(keepchanges, force) with repo.wlock(): if patch: @@ -1597,8 +1761,9 @@ update = True else: parents = [p.node() for p in repo[None].parents()] - update = any(entry.node in parents - for entry in self.applied[start:]) + update = any( + entry.node in parents for entry in self.applied[start:] + ) tobackup = set() if update: @@ -1607,8 +1772,9 @@ if not nobackup: tobackup.update(s.modified + s.added) elif keepchanges: - tobackup.update(s.modified + s.added + - s.removed + s.deleted) + tobackup.update( + s.modified + s.added + s.removed + s.deleted + ) self.applieddirty = True end = len(self.applied) @@ -1621,12 +1787,17 @@ raise error.Abort(_('trying to pop unknown node %s') % node) if heads != [self.applied[-1].node]: - raise error.Abort(_("popping would remove a revision not " - "managed by this patch queue")) + raise error.Abort( + _( + "popping would remove a revision not " + "managed by this patch queue" + ) + ) if not repo[self.applied[-1].node].mutable(): raise error.Abort( _("popping would remove a public revision"), - hint=_("see 'hg help phases' for details")) + hint=_("see 'hg help phases' for details"), + ) # we know there are no local changes, so we can make a simplified # form of hg.update. @@ -1694,8 +1865,10 @@ if repo.changelog.heads(top) != [top]: raise error.Abort(_("cannot qrefresh a revision with children")) if not repo[top].mutable(): - raise error.Abort(_("cannot qrefresh public revision"), - hint=_("see 'hg help phases' for details")) + raise error.Abort( + _("cannot qrefresh public revision"), + hint=_("see 'hg help phases' for details"), + ) cparents = repo.changelog.parents(top) patchparent = self.qparents(repo, top) @@ -1705,8 +1878,9 @@ substatestate = repo.dirstate['.hgsubstate'] ph = patchheader(self.join(patchfn), self.plainmode) - diffopts = self.diffopts({'git': opts.get('git')}, patchfn, - plain=True) + diffopts = self.diffopts( + {'git': opts.get('git')}, patchfn, plain=True + ) if newuser: ph.setuser(newuser) if newdate: @@ -1804,7 +1978,8 @@ src = ctx[dst].copysource() if src: copies.setdefault(src, []).extend( - copies.get(dst, [])) + copies.get(dst, []) + ) if dst in a: copies[src].append(dst) # we can't copy a file created by the patch itself @@ -1854,16 +2029,20 @@ defaultmsg = "[mq]: %s" % patchfn editor = cmdutil.getcommiteditor(editform=editform) if edit: + def finishdesc(desc): if desc.rstrip(): ph.setmessage(desc) return desc return defaultmsg + # i18n: this message is shown in editor with "HG: " prefix extramsg = _('Leave message empty to use default message.') - editor = cmdutil.getcommiteditor(finishdesc=finishdesc, - extramsg=extramsg, - editform=editform) + editor = cmdutil.getcommiteditor( + finishdesc=finishdesc, + extramsg=extramsg, + editform=editform, + ) message = msg or "\n".join(ph.message) elif not msg: if not ph.message: @@ -1880,14 +2059,23 @@ try: lock = repo.lock() tr = repo.transaction('mq') - n = newcommit(repo, oldphase, message, user, ph.date, - match=match, force=True, editor=editor) + n = newcommit( + repo, + oldphase, + message, + user, + ph.date, + match=match, + force=True, + editor=editor, + ) # 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) + chunks = patchmod.diff( + repo, patchparent, changes=c, opts=diffopts + ) comments = bytes(ph) if comments: patchf.write(comments) @@ -1902,12 +2090,16 @@ self.applied.append(statusentry(n, patchfn)) finally: lockmod.release(tr, lock) - except: # re-raises + except: # re-raises ctx = repo[cparents[0]] repo.dirstate.rebuild(ctx.node(), ctx.manifest()) self.savedirty() - self.ui.warn(_('qrefresh interrupted while patch was popped! ' - '(revert --all, qpush to recover)\n')) + self.ui.warn( + _( + 'qrefresh interrupted while patch was popped! ' + '(revert --all, qpush to recover)\n' + ) + ) raise finally: wlock.release() @@ -1939,8 +2131,15 @@ self.explainpushable(i) return unapplied - def qseries(self, repo, missing=None, start=0, length=None, status=None, - summary=False): + def qseries( + self, + repo, + missing=None, + start=0, + length=None, + status=None, + summary=False, + ): def displayname(pfx, patchname, state): if pfx: self.ui.write(pfx) @@ -1987,16 +2186,22 @@ else: msng_list = [] for root, dirs, files in os.walk(self.path): - d = root[len(self.path) + 1:] + d = root[len(self.path) + 1 :] for f in files: fl = os.path.join(d, f) - if (fl not in self.series and - fl not in (self.statuspath, self.seriespath, - self.guardspath) - and not fl.startswith('.')): + if ( + fl not in self.series + and fl + not in ( + self.statuspath, + self.seriespath, + self.guardspath, + ) + and not fl.startswith('.') + ): msng_list.append(fl) for x in sorted(msng_list): - pfx = self.ui.verbose and ('D ') or '' + pfx = self.ui.verbose and 'D ' or '' displayname(pfx, x, 'missing') def issaveline(self, l): @@ -2009,10 +2214,15 @@ 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') + ui.setconfig( + 'ui', 'formatted', self.ui.config('ui', 'formatted'), 'mqpager' + ) + ui.setconfig( + 'ui', + 'interactive', + self.ui.config('ui', 'interactive'), + 'mqpager', + ) if create or os.path.isdir(self.join(".hg")): return hg.repository(ui, path=self.path, create=create) @@ -2060,8 +2270,10 @@ update = False strip(self.ui, repo, [rev], update=update, backup=False) if qpp: - self.ui.warn(_("saved queue repository parents: %s %s\n") % - (short(qpp[0]), short(qpp[1]))) + self.ui.warn( + _("saved queue repository parents: %s %s\n") + % (short(qpp[0]), short(qpp[1])) + ) if qupdate: self.ui.status(_("updating queue directory\n")) r = self.qrepo() @@ -2112,6 +2324,7 @@ index of the first patch past the last applied one. """ end = 0 + def nextpatch(start): if all_patches or start >= len(self.series): return start @@ -2121,6 +2334,7 @@ return i self.explainpushable(i) return len(self.series) + if self.applied: p = self.applied[-1].name try: @@ -2138,24 +2352,35 @@ p = ("%d" % self.series.index(pname)) + " " + pname return p - def qimport(self, repo, files, patchname=None, rev=None, existing=None, - force=None, git=False): + def qimport( + self, + repo, + files, + patchname=None, + rev=None, + existing=None, + force=None, + git=False, + ): def checkseries(patchname): if patchname in self.series: - raise error.Abort(_('patch %s is already in the series file') - % patchname) + raise error.Abort( + _('patch %s is already in the series file') % patchname + ) if rev: if files: - raise error.Abort(_('option "-r" not valid when importing ' - 'files')) + raise error.Abort( + _('option "-r" not valid when importing ' 'files') + ) rev = scmutil.revrange(repo, rev) rev.sort(reverse=True) elif not files: raise error.Abort(_('no files or revisions specified')) if (len(files) > 1 or len(rev) > 1) and patchname: - raise error.Abort(_('option "-n" not valid when importing multiple ' - 'patches')) + raise error.Abort( + _('option "-n" not valid when importing multiple ' 'patches') + ) imported = [] if rev: # If mq patches are applied, we can only import revisions @@ -2163,46 +2388,56 @@ # Otherwise, they should form a linear path to a head. heads = repo.changelog.heads(repo.changelog.node(rev.first())) if len(heads) > 1: - raise error.Abort(_('revision %d is the root of more than one ' - 'branch') % rev.last()) + raise error.Abort( + _('revision %d is the root of more than one ' 'branch') + % rev.last() + ) if self.applied: base = repo.changelog.node(rev.first()) if base in [n.node for n in self.applied]: - raise error.Abort(_('revision %d is already managed') - % rev.first()) + raise error.Abort( + _('revision %d is already managed') % rev.first() + ) if heads != [self.applied[-1].node]: - raise error.Abort(_('revision %d is not the parent of ' - 'the queue') % rev.first()) + raise error.Abort( + _('revision %d is not the parent of ' 'the queue') + % rev.first() + ) base = repo.changelog.rev(self.applied[0].node) lastparent = repo.changelog.parentrevs(base)[0] else: if heads != [repo.changelog.node(rev.first())]: - raise error.Abort(_('revision %d has unmanaged children') - % rev.first()) + raise error.Abort( + _('revision %d has unmanaged children') % rev.first() + ) lastparent = None diffopts = self.diffopts({'git': git}) with repo.transaction('qimport') as tr: for r in rev: if not repo[r].mutable(): - raise error.Abort(_('revision %d is not mutable') % r, - hint=_("see 'hg help phases' " - 'for details')) + raise error.Abort( + _('revision %d is not mutable') % r, + hint=_("see 'hg help phases' " 'for details'), + ) p1, p2 = repo.changelog.parentrevs(r) n = repo.changelog.node(r) if p2 != nullrev: - raise error.Abort(_('cannot import merge revision %d') - % r) + raise error.Abort( + _('cannot import merge revision %d') % r + ) if lastparent and lastparent != r: - raise error.Abort(_('revision %d is not the parent of ' - '%d') - % (r, lastparent)) + raise error.Abort( + _('revision %d is not the parent of ' '%d') + % (r, lastparent) + ) lastparent = p1 if not patchname: patchname = self.makepatchname( repo[r].description().split('\n', 1)[0], - '%d.diff' % r) + '%d.diff' % r, + ) checkseries(patchname) self.checkpatchname(patchname, force) self.fullseries.insert(0, patchname) @@ -2226,21 +2461,24 @@ for i, filename in enumerate(files): if existing: if filename == '-': - raise error.Abort(_('-e is incompatible with import from -') - ) + raise error.Abort( + _('-e is incompatible with import from -') + ) filename = normname(filename) self.checkreservedname(filename) if util.url(filename).islocal(): originpath = self.join(filename) if not os.path.isfile(originpath): raise error.Abort( - _("patch %s does not exist") % filename) + _("patch %s does not exist") % filename + ) if patchname: self.checkpatchname(patchname, force) - self.ui.write(_('renaming %s to %s\n') - % (filename, patchname)) + self.ui.write( + _('renaming %s to %s\n') % (filename, patchname) + ) util.rename(originpath, self.join(patchname)) else: patchname = filename @@ -2278,20 +2516,28 @@ self.removeundo(repo) return imported + def fixkeepchangesopts(ui, opts): - if (not ui.configbool('mq', 'keepchanges') or opts.get('force') - or opts.get('exact')): + if ( + not ui.configbool('mq', 'keepchanges') + or opts.get('force') + or opts.get('exact') + ): return opts opts = dict(opts) opts['keep_changes'] = True return opts -@command("qdelete|qremove|qrm", - [('k', 'keep', None, _('keep patch file')), - ('r', 'rev', [], - _('stop managing a revision (DEPRECATED)'), _('REV'))], - _('hg qdelete [-k] [PATCH]...'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qdelete|qremove|qrm", + [ + ('k', 'keep', None, _('keep patch file')), + ('r', 'rev', [], _('stop managing a revision (DEPRECATED)'), _('REV')), + ], + _('hg qdelete [-k] [PATCH]...'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def delete(ui, repo, *patches, **opts): """remove patches from queue @@ -2306,11 +2552,14 @@ q.savedirty() return 0 -@command("qapplied", - [('1', 'last', None, _('show only the preceding applied patch')) - ] + seriesopts, - _('hg qapplied [-1] [-s] [PATCH]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qapplied", + [('1', 'last', None, _('show only the preceding applied patch'))] + + seriesopts, + _('hg qapplied [-1] [-s] [PATCH]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def applied(ui, repo, patch=None, **opts): """print the patches already applied @@ -2338,14 +2587,17 @@ else: start = 0 - q.qseries(repo, length=end, start=start, status='A', - summary=opts.get('summary')) - - -@command("qunapplied", - [('1', 'first', None, _('show only the first patch'))] + seriesopts, - _('hg qunapplied [-1] [-s] [PATCH]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + q.qseries( + repo, length=end, start=start, status='A', summary=opts.get('summary') + ) + + +@command( + "qunapplied", + [('1', 'first', None, _('show only the first patch'))] + seriesopts, + _('hg qunapplied [-1] [-s] [PATCH]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def unapplied(ui, repo, patch=None, **opts): """print the patches not yet applied @@ -2368,20 +2620,34 @@ length = 1 else: length = None - q.qseries(repo, start=start, length=length, status='U', - summary=opts.get('summary')) - -@command("qimport", - [('e', 'existing', None, _('import file in patch directory')), - ('n', 'name', '', - _('name of patch file'), _('NAME')), - ('f', 'force', None, _('overwrite existing files')), - ('r', 'rev', [], - _('place existing revisions under mq control'), _('REV')), - ('g', 'git', None, _('use git extended diff format')), - ('P', 'push', None, _('qpush after importing'))], - _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... [FILE]...'), - helpcategory=command.CATEGORY_IMPORT_EXPORT) + q.qseries( + repo, + start=start, + length=length, + status='U', + summary=opts.get('summary'), + ) + + +@command( + "qimport", + [ + ('e', 'existing', None, _('import file in patch directory')), + ('n', 'name', '', _('name of patch file'), _('NAME')), + ('f', 'force', None, _('overwrite existing files')), + ( + 'r', + 'rev', + [], + _('place existing revisions under mq control'), + _('REV'), + ), + ('g', 'git', None, _('use git extended diff format')), + ('P', 'push', None, _('qpush after importing')), + ], + _('hg qimport [-e] [-n NAME] [-f] [-g] [-P] [-r REV]... [FILE]...'), + helpcategory=command.CATEGORY_IMPORT_EXPORT, +) def qimport(ui, repo, *filename, **opts): """import a patch or existing changeset @@ -2417,13 +2683,18 @@ Returns 0 if import succeeded. """ opts = pycompat.byteskwargs(opts) - with repo.lock(): # cause this may move phase + with repo.lock(): # cause this may move phase q = repo.mq try: 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')) + repo, + filename, + patchname=opts.get('name'), + existing=opts.get('existing'), + force=opts.get('force'), + rev=opts.get('rev'), + git=opts.get('git'), + ) finally: q.savedirty() @@ -2431,6 +2702,7 @@ return q.push(repo, imported[-1]) return 0 + def qinit(ui, repo, create): """initialize a new queue repository @@ -2457,11 +2729,14 @@ commands.add(ui, r) return 0 -@command("qinit", - [('c', 'create-repo', None, _('create queue repository'))], - _('hg qinit [-c]'), - helpcategory=command.CATEGORY_REPO_CREATION, - helpbasic=True) + +@command( + "qinit", + [('c', 'create-repo', None, _('create queue repository'))], + _('hg qinit [-c]'), + helpcategory=command.CATEGORY_REPO_CREATION, + helpbasic=True, +) def init(ui, repo, **opts): """init a new queue repository (DEPRECATED) @@ -2475,18 +2750,31 @@ commands. With -c, use :hg:`init --mq` instead.""" return qinit(ui, repo, create=opts.get(r'create_repo')) -@command("qclone", - [('', 'pull', None, _('use pull protocol to copy metadata')), - ('U', 'noupdate', None, - _('do not update the new working directories')), - ('', 'uncompressed', None, - _('use uncompressed transfer (fast over LAN)')), - ('p', 'patches', '', - _('location of source patch repository'), _('REPO')), - ] + cmdutil.remoteopts, - _('hg qclone [OPTION]... SOURCE [DEST]'), - helpcategory=command.CATEGORY_REPO_CREATION, - norepo=True) + +@command( + "qclone", + [ + ('', 'pull', None, _('use pull protocol to copy metadata')), + ('U', 'noupdate', None, _('do not update the new working directories')), + ( + '', + 'uncompressed', + None, + _('use uncompressed transfer (fast over LAN)'), + ), + ( + 'p', + 'patches', + '', + _('location of source patch repository'), + _('REPO'), + ), + ] + + cmdutil.remoteopts, + _('hg qclone [OPTION]... SOURCE [DEST]'), + helpcategory=command.CATEGORY_REPO_CREATION, + norepo=True, +) def clone(ui, source, dest=None, **opts): '''clone main and patch repository at same time @@ -2505,6 +2793,7 @@ Return 0 on success. ''' opts = pycompat.byteskwargs(opts) + def patchdir(repo): """compute a patch repo url from a repo object""" url = repo.url() @@ -2525,8 +2814,9 @@ try: hg.peer(ui, opts, patchespath) except error.RepoError: - raise error.Abort(_('versioned patch repository not found' - ' (see init --mq)')) + raise error.Abort( + _('versioned patch repository not found' ' (see init --mq)') + ) qbase, destrev = None, None if sr.local(): repo = sr.local() @@ -2543,32 +2833,47 @@ pass ui.note(_('cloning main repository\n')) - sr, dr = hg.clone(ui, opts, sr.url(), dest, - pull=opts.get('pull'), - revs=destrev, - update=False, - stream=opts.get('uncompressed')) + sr, dr = hg.clone( + ui, + opts, + sr.url(), + dest, + pull=opts.get('pull'), + revs=destrev, + update=False, + stream=opts.get('uncompressed'), + ) ui.note(_('cloning patch repository\n')) - hg.clone(ui, opts, opts.get('patches') or patchdir(sr), patchdir(dr), - pull=opts.get('pull'), update=not opts.get('noupdate'), - stream=opts.get('uncompressed')) + hg.clone( + ui, + opts, + opts.get('patches') or patchdir(sr), + patchdir(dr), + pull=opts.get('pull'), + update=not opts.get('noupdate'), + stream=opts.get('uncompressed'), + ) if dr.local(): repo = dr.local() if qbase: - ui.note(_('stripping applied patches from destination ' - 'repository\n')) + ui.note( + _('stripping applied patches from destination ' 'repository\n') + ) strip(ui, repo, [qbase], update=False, backup=None) if not opts.get('noupdate'): ui.note(_('updating destination repository\n')) hg.update(repo, repo.changelog.tip()) -@command("qcommit|qci", - commands.table["commit|ci"][1], - _('hg qcommit [OPTION]... [FILE]...'), - helpcategory=command.CATEGORY_COMMITTING, - inferrepo=True) + +@command( + "qcommit|qci", + commands.table["commit|ci"][1], + _('hg qcommit [OPTION]... [FILE]...'), + helpcategory=command.CATEGORY_COMMITTING, + inferrepo=True, +) def commit(ui, repo, *pats, **opts): """commit changes in the queue repository (DEPRECATED) @@ -2579,21 +2884,29 @@ raise error.Abort('no queue repository') commands.commit(r.ui, r, *pats, **opts) -@command("qseries", - [('m', 'missing', None, _('print patches not in series')), - ] + seriesopts, - _('hg qseries [-ms]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qseries", + [('m', 'missing', None, _('print patches not in series')),] + seriesopts, + _('hg qseries [-ms]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def series(ui, repo, **opts): """print the entire series file Returns 0 on success.""" - repo.mq.qseries(repo, missing=opts.get(r'missing'), - summary=opts.get(r'summary')) + repo.mq.qseries( + repo, missing=opts.get(r'missing'), summary=opts.get(r'summary') + ) return 0 -@command("qtop", seriesopts, _('hg qtop [-s]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qtop", + seriesopts, + _('hg qtop [-s]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def top(ui, repo, **opts): """print the name of the current patch @@ -2605,14 +2918,24 @@ t = 0 if t: - q.qseries(repo, start=t - 1, length=1, status='A', - summary=opts.get(r'summary')) + q.qseries( + repo, + start=t - 1, + length=1, + status='A', + summary=opts.get(r'summary'), + ) else: ui.write(_("no patches applied\n")) return 1 -@command("qnext", seriesopts, _('hg qnext [-s]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qnext", + seriesopts, + _('hg qnext [-s]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def next(ui, repo, **opts): """print the name of the next pushable patch @@ -2624,8 +2947,13 @@ return 1 q.qseries(repo, start=end, length=1, summary=opts.get(r'summary')) -@command("qprev", seriesopts, _('hg qprev [-s]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qprev", + seriesopts, + _('hg qprev [-s]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def prev(ui, repo, **opts): """print the name of the preceding applied patch @@ -2639,8 +2967,10 @@ ui.write(_("no patches applied\n")) return 1 idx = q.series.index(q.applied[-2].name) - q.qseries(repo, start=idx, length=1, status='A', - summary=opts.get(r'summary')) + q.qseries( + repo, start=idx, length=1, status='A', summary=opts.get(r'summary') + ) + def setupheaderopts(ui, opts): if not opts.get('user') and opts.get('currentuser'): @@ -2648,20 +2978,25 @@ if not opts.get('date') and opts.get('currentdate'): opts['date'] = "%d %d" % dateutil.makedate() -@command("qnew", - [('e', 'edit', None, _('invoke editor on commit messages')), - ('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')) - ] + cmdutil.walkopts + cmdutil.commitopts, - _('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...'), - helpcategory=command.CATEGORY_COMMITTING, helpbasic=True, - inferrepo=True) + +@command( + "qnew", + [ + ('e', 'edit', None, _('invoke editor on commit messages')), + ('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')), + ] + + cmdutil.walkopts + + cmdutil.commitopts, + _('hg qnew [-e] [-m TEXT] [-l FILE] PATCH [FILE]...'), + helpcategory=command.CATEGORY_COMMITTING, + helpbasic=True, + inferrepo=True, +) def new(ui, repo, patch, *args, **opts): """create a new patch @@ -2696,23 +3031,52 @@ q.savedirty() return 0 -@command("qrefresh", - [('e', 'edit', None, _('invoke editor on commit messages')), - ('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')) - ] + cmdutil.walkopts + cmdutil.commitopts, - _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...'), - helpcategory=command.CATEGORY_COMMITTING, helpbasic=True, - inferrepo=True) + +@command( + "qrefresh", + [ + ('e', 'edit', None, _('invoke editor on commit messages')), + ('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'), + ), + ] + + cmdutil.walkopts + + cmdutil.commitopts, + _('hg qrefresh [-I] [-X] [-e] [-m TEXT] [-l FILE] [-s] [FILE]...'), + helpcategory=command.CATEGORY_COMMITTING, + helpbasic=True, + inferrepo=True, +) def refresh(ui, repo, *pats, **opts): """update the current patch @@ -2743,11 +3107,15 @@ q.savedirty() return ret -@command("qdiff", - cmdutil.diffopts + cmdutil.diffopts2 + cmdutil.walkopts, - _('hg qdiff [OPTION]... [FILE]...'), - helpcategory=command.CATEGORY_FILE_CONTENTS, helpbasic=True, - inferrepo=True) + +@command( + "qdiff", + cmdutil.diffopts + cmdutil.diffopts2 + cmdutil.walkopts, + _('hg qdiff [OPTION]... [FILE]...'), + helpcategory=command.CATEGORY_FILE_CONTENTS, + helpbasic=True, + inferrepo=True, +) def diff(ui, repo, *pats, **opts): """diff of the current patch and subsequent modifications @@ -2767,12 +3135,17 @@ repo.mq.diff(repo, pats, pycompat.byteskwargs(opts)) return 0 -@command('qfold', - [('e', 'edit', None, _('invoke editor on commit messages')), - ('k', 'keep', None, _('keep folded patch files')), - ] + cmdutil.commitopts, - _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...'), - helpcategory=command.CATEGORY_CHANGE_MANAGEMENT) + +@command( + 'qfold', + [ + ('e', 'edit', None, _('invoke editor on commit messages')), + ('k', 'keep', None, _('keep folded patch files')), + ] + + cmdutil.commitopts, + _('hg qfold [-e] [-k] [-m TEXT] [-l FILE] PATCH...'), + helpcategory=command.CATEGORY_CHANGE_MANAGEMENT, +) def fold(ui, repo, *files, **opts): """fold the named patches into the current patch @@ -2805,8 +3178,9 @@ if p in patches or p == parent: ui.warn(_('skipping already folded patch %s\n') % p) if q.isapplied(p): - raise error.Abort(_('qfold cannot fold already applied patch %s') - % p) + raise error.Abort( + _('qfold cannot fold already applied patch %s') % p + ) patches.append(p) for p in patches: @@ -2831,18 +3205,27 @@ diffopts = q.patchopts(q.diffopts(), *patches) with repo.wlock(): - q.refresh(repo, msg=message, git=diffopts.git, edit=opts.get('edit'), - editform='mq.qfold') + q.refresh( + repo, + msg=message, + git=diffopts.git, + edit=opts.get('edit'), + editform='mq.qfold', + ) q.delete(repo, patches, opts) q.savedirty() -@command("qgoto", - [('', 'keep-changes', None, - _('tolerate non-conflicting local changes')), - ('f', 'force', None, _('overwrite any local changes')), - ('', 'no-backup', None, _('do not save backup copies of files'))], - _('hg qgoto [OPTION]... PATCH'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qgoto", + [ + ('', 'keep-changes', None, _('tolerate non-conflicting local changes')), + ('f', 'force', None, _('overwrite any local changes')), + ('', 'no-backup', None, _('do not save backup copies of files')), + ], + _('hg qgoto [OPTION]... PATCH'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def goto(ui, repo, patch, **opts): '''push or pop patches until named patch is at top of stack @@ -2854,19 +3237,34 @@ nobackup = opts.get('no_backup') keepchanges = opts.get('keep_changes') if q.isapplied(patch): - ret = q.pop(repo, patch, force=opts.get('force'), nobackup=nobackup, - keepchanges=keepchanges) + ret = q.pop( + repo, + patch, + force=opts.get('force'), + nobackup=nobackup, + keepchanges=keepchanges, + ) else: - ret = q.push(repo, patch, force=opts.get('force'), nobackup=nobackup, - keepchanges=keepchanges) + ret = q.push( + repo, + patch, + force=opts.get('force'), + nobackup=nobackup, + keepchanges=keepchanges, + ) q.savedirty() return ret -@command("qguard", - [('l', 'list', None, _('list all patches and guards')), - ('n', 'none', None, _('drop all guards'))], - _('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qguard", + [ + ('l', 'list', None, _('list all patches and guards')), + ('n', 'none', None, _('drop all guards')), + ], + _('hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def guard(ui, repo, *args, **opts): '''set or print guards for a patch @@ -2889,6 +3287,7 @@ Returns 0 on success. ''' + def status(idx): guards = q.seriesguards[idx] or ['unguarded'] if q.series[idx] in applied: @@ -2910,14 +3309,16 @@ if i != len(guards) - 1: ui.write(' ') ui.write('\n') + q = repo.mq applied = set(p.name for p in q.applied) patch = None args = list(args) if opts.get(r'list'): if args or opts.get(r'none'): - raise error.Abort(_('cannot mix -l/--list with options or ' - 'arguments')) + raise error.Abort( + _('cannot mix -l/--list with options or ' 'arguments') + ) for i in pycompat.xrange(len(q.series)): status(i) return @@ -2938,8 +3339,13 @@ else: status(q.series.index(q.lookup(patch))) -@command("qheader", [], _('hg qheader [PATCH]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qheader", + [], + _('hg qheader [PATCH]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def header(ui, repo, patch=None): """print the header of the topmost or specified patch @@ -2957,6 +3363,7 @@ ui.write('\n'.join(ph.message) + '\n') + def lastsavename(path): (directory, base) = os.path.split(path) names = os.listdir(directory) @@ -2974,6 +3381,7 @@ return (os.path.join(directory, maxname), maxindex) return (None, None) + def savename(path): (last, index) = lastsavename(path) if last is None: @@ -2981,23 +3389,29 @@ newpath = path + ".%d" % (index + 1) return newpath -@command("qpush", - [('', 'keep-changes', None, - _('tolerate non-conflicting local changes')), - ('f', 'force', None, _('apply on top of local changes')), - ('e', 'exact', None, - _('apply the target patch to its recorded parent')), - ('l', 'list', None, _('list patch name in commit text')), - ('a', 'all', None, _('apply all patches')), - ('m', 'merge', None, _('merge from another queue (DEPRECATED)')), - ('n', 'name', '', - _('merge queue name (DEPRECATED)'), _('NAME')), - ('', 'move', None, - _('reorder patch series and apply only the patch')), - ('', 'no-backup', None, _('do not save backup copies of files'))], - _('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, - helpbasic=True) + +@command( + "qpush", + [ + ('', 'keep-changes', None, _('tolerate non-conflicting local changes')), + ('f', 'force', None, _('apply on top of local changes')), + ( + 'e', + 'exact', + None, + _('apply the target patch to its recorded parent'), + ), + ('l', 'list', None, _('list patch name in commit text')), + ('a', 'all', None, _('apply all patches')), + ('m', 'merge', None, _('merge from another queue (DEPRECATED)')), + ('n', 'name', '', _('merge queue name (DEPRECATED)'), _('NAME')), + ('', 'move', None, _('reorder patch series and apply only the patch')), + ('', 'no-backup', None, _('do not save backup copies of files')), + ], + _('hg qpush [-f] [-l] [-a] [--move] [PATCH | INDEX]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, + helpbasic=True, +) def push(ui, repo, patch=None, **opts): """push the next patch onto the stack @@ -3023,23 +3437,34 @@ return 1 mergeq = queue(ui, repo.baseui, repo.path, newpath) ui.warn(_("merging with queue at: %s\n") % mergeq.path) - ret = q.push(repo, patch, force=opts.get('force'), list=opts.get('list'), - mergeq=mergeq, all=opts.get('all'), move=opts.get('move'), - exact=opts.get('exact'), nobackup=opts.get('no_backup'), - keepchanges=opts.get('keep_changes')) + ret = q.push( + repo, + patch, + force=opts.get('force'), + list=opts.get('list'), + mergeq=mergeq, + all=opts.get('all'), + move=opts.get('move'), + exact=opts.get('exact'), + nobackup=opts.get('no_backup'), + keepchanges=opts.get('keep_changes'), + ) return ret -@command("qpop", - [('a', 'all', None, _('pop all patches')), - ('n', 'name', '', - _('queue name to pop (DEPRECATED)'), _('NAME')), - ('', 'keep-changes', None, - _('tolerate non-conflicting local changes')), - ('f', 'force', None, _('forget any local changes to patched files')), - ('', 'no-backup', None, _('do not save backup copies of files'))], - _('hg qpop [-a] [-f] [PATCH | INDEX]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, - helpbasic=True) + +@command( + "qpop", + [ + ('a', 'all', None, _('pop all patches')), + ('n', 'name', '', _('queue name to pop (DEPRECATED)'), _('NAME')), + ('', 'keep-changes', None, _('tolerate non-conflicting local changes')), + ('f', 'force', None, _('forget any local changes to patched files')), + ('', 'no-backup', None, _('do not save backup copies of files')), + ], + _('hg qpop [-a] [-f] [PATCH | INDEX]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, + helpbasic=True, +) def pop(ui, repo, patch=None, **opts): """pop the current patch off the stack @@ -3063,14 +3488,25 @@ localupdate = False else: q = repo.mq - ret = q.pop(repo, patch, force=opts.get('force'), update=localupdate, - all=opts.get('all'), nobackup=opts.get('no_backup'), - keepchanges=opts.get('keep_changes')) + ret = q.pop( + repo, + patch, + force=opts.get('force'), + update=localupdate, + all=opts.get('all'), + nobackup=opts.get('no_backup'), + keepchanges=opts.get('keep_changes'), + ) q.savedirty() return ret -@command("qrename|qmv", [], _('hg qrename PATCH1 [PATCH2]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qrename|qmv", + [], + _('hg qrename PATCH1 [PATCH2]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def rename(ui, repo, patch, name=None, **opts): """rename a patch @@ -3125,30 +3561,41 @@ q.savedirty() -@command("qrestore", - [('d', 'delete', None, _('delete save entry')), - ('u', 'update', None, _('update queue working directory'))], - _('hg qrestore [-d] [-u] REV'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qrestore", + [ + ('d', 'delete', None, _('delete save entry')), + ('u', 'update', None, _('update queue working directory')), + ], + _('hg qrestore [-d] [-u] REV'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def restore(ui, repo, rev, **opts): """restore the queue state saved by a revision (DEPRECATED) This command is deprecated, use :hg:`rebase` instead.""" rev = repo.lookup(rev) q = repo.mq - q.restore(repo, rev, delete=opts.get(r'delete'), - qupdate=opts.get(r'update')) + q.restore( + repo, rev, delete=opts.get(r'delete'), qupdate=opts.get(r'update') + ) q.savedirty() return 0 -@command("qsave", - [('c', 'copy', None, _('copy patch directory')), - ('n', 'name', '', - _('copy directory name'), _('NAME')), - ('e', 'empty', None, _('clear queue status file')), - ('f', 'force', None, _('force copy'))] + cmdutil.commitopts, - _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qsave", + [ + ('c', 'copy', None, _('copy patch directory')), + ('n', 'name', '', _('copy directory name'), _('NAME')), + ('e', 'empty', None, _('clear queue status file')), + ('f', 'force', None, _('force copy')), + ] + + cmdutil.commitopts, + _('hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def save(ui, repo, **opts): """save current queue state (DEPRECATED) @@ -3159,18 +3606,21 @@ ret = q.save(repo, msg=message) if ret: return ret - q.savedirty() # save to .hg/patches before copying + q.savedirty() # save to .hg/patches before copying if opts.get('copy'): path = q.path if opts.get('name'): newpath = os.path.join(q.basepath, opts.get('name')) if os.path.exists(newpath): if not os.path.isdir(newpath): - raise error.Abort(_('destination %s exists and is not ' - 'a directory') % newpath) + raise error.Abort( + _('destination %s exists and is not ' 'a directory') + % newpath + ) if not opts.get('force'): - raise error.Abort(_('destination %s exists, ' - 'use -f to force') % newpath) + raise error.Abort( + _('destination %s exists, ' 'use -f to force') % newpath + ) else: newpath = savename(path) ui.warn(_("copy %s to %s\n") % (path, newpath)) @@ -3182,13 +3632,17 @@ return 0 -@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]...'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) +@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]...'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def select(ui, repo, *args, **opts): '''set or print guarded patches to push @@ -3230,24 +3684,34 @@ pushable = lambda i: q.pushable(q.applied[i].name)[0] if args or opts.get('none'): old_unapplied = q.unapplied(repo) - old_guarded = [i for i in pycompat.xrange(len(q.applied)) - if not pushable(i)] + old_guarded = [ + i for i in pycompat.xrange(len(q.applied)) if not pushable(i) + ] q.setactive(args) q.savedirty() if not args: ui.status(_('guards deactivated\n')) if not opts.get('pop') and not opts.get('reapply'): unapplied = q.unapplied(repo) - guarded = [i for i in pycompat.xrange(len(q.applied)) - if not pushable(i)] + guarded = [ + i for i in pycompat.xrange(len(q.applied)) if not pushable(i) + ] 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))) + 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))) + ui.status( + _( + 'number of guarded, applied patches has changed ' + 'from %d to %d\n' + ) + % (len(old_guarded), len(guarded)) + ) elif opts.get('series'): guards = {} noguards = 0 @@ -3295,10 +3759,13 @@ finally: q.savedirty() -@command("qfinish", - [('a', 'applied', None, _('finish all applied changesets'))], - _('hg qfinish [-a] [REV]...'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qfinish", + [('a', 'applied', None, _('finish all applied changesets'))], + _('hg qfinish [-a] [REV]...'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def finish(ui, repo, *revrange, **opts): """move applied patches into repository history @@ -3338,16 +3805,20 @@ q.savedirty() return 0 -@command("qqueue", - [('l', 'list', False, _('list all available queues')), - ('', 'active', False, _('print name of active queue')), - ('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]'), - helpcategory=command.CATEGORY_CHANGE_ORGANIZATION) + +@command( + "qqueue", + [ + ('l', 'list', False, _('list all available queues')), + ('', 'active', False, _('print name of active queue')), + ('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]'), + helpcategory=command.CATEGORY_CHANGE_ORGANIZATION, +) def qqueue(ui, repo, name=None, **opts): '''manage multiple patch queues @@ -3405,8 +3876,12 @@ def _setactive(name): if q.applied: - raise error.Abort(_('new queue created, but cannot make active ' - 'as patches are applied')) + raise error.Abort( + _( + 'new queue created, but cannot make active ' + 'as patches are applied' + ) + ) _setactivenocheck(name) def _setactivenocheck(name): @@ -3465,7 +3940,8 @@ if not _validname(name): raise error.Abort( - _('invalid queue name, may not contain the characters ":\\/."')) + _('invalid queue name, may not contain the characters ":\\/."') + ) with repo.wlock(): existing = _getqueues() @@ -3480,8 +3956,9 @@ elif opts.get('rename'): current = _getcurrent() if name == current: - raise error.Abort(_('can\'t rename "%s" to its current name') - % name) + raise error.Abort( + _('can\'t rename "%s" to its current name') % name + ) if name in existing: raise error.Abort(_('queue "%s" already exists') % name) @@ -3489,8 +3966,9 @@ newdir = _queuedir(name) if os.path.exists(newdir): - raise error.Abort(_('non-queue directory "%s" already exists') % - newdir) + raise error.Abort( + _('non-queue directory "%s" already exists') % newdir + ) fh = repo.vfs('patches.queues.new', 'w') for queue in existing: @@ -3516,6 +3994,7 @@ raise error.Abort(_('use --create to create a new queue')) _setactive(name) + def mqphasedefaults(repo, roots): """callback used to set mq changeset as secret when no phase data exists""" if repo.mq.applied: @@ -3527,6 +4006,7 @@ roots[mqphase].add(qbase.node()) return roots + def reposetup(ui, repo): class mqrepo(repo.__class__): @localrepo.unfilteredpropertycache @@ -3546,16 +4026,25 @@ if any(p in patches for p in parents): raise error.Abort(errmsg) - def commit(self, text="", user=None, date=None, match=None, - force=False, editor=False, extra=None): + def commit( + self, + text="", + user=None, + date=None, + match=None, + force=False, + editor=False, + extra=None, + ): if extra is None: extra = {} self.abortifwdirpatched( - _('cannot commit over an applied mq patch'), - force) - - return super(mqrepo, self).commit(text, user, date, match, force, - editor, extra) + _('cannot commit over an applied mq patch'), force + ) + + return super(mqrepo, self).commit( + text, user, date, match, force, editor, extra + ) def checkpush(self, pushop): if self.mq.applied and self.mq.checkapplied and not pushop.force: @@ -3591,8 +4080,10 @@ # for now ignore filtering business self.unfiltered().changelog.rev(mqtags[-1][0]) except error.LookupError: - self.ui.warn(_('mq status file refers to unknown node %s\n') - % short(mqtags[-1][0])) + self.ui.warn( + _('mq status file refers to unknown node %s\n') + % short(mqtags[-1][0]) + ) return result # do not add fake tags for filtered revisions @@ -3607,8 +4098,10 @@ tags = result[0] for patch in mqtags: if patch[1] in tags: - self.ui.warn(_('tag %s overrides mq patch of the same ' - 'name\n') % patch[1]) + self.ui.warn( + _('tag %s overrides mq patch of the same ' 'name\n') + % patch[1] + ) else: tags[patch[1]] = patch[0] @@ -3619,13 +4112,17 @@ repo._phasedefaults.append(mqphasedefaults) + def mqimport(orig, ui, repo, *args, **kwargs): - if (util.safehasattr(repo, 'abortifwdirpatched') - and not kwargs.get(r'no_commit', False)): - repo.abortifwdirpatched(_('cannot import over an applied patch'), - kwargs.get(r'force')) + if util.safehasattr(repo, 'abortifwdirpatched') and not kwargs.get( + r'no_commit', False + ): + repo.abortifwdirpatched( + _('cannot import over an applied patch'), kwargs.get(r'force') + ) return orig(ui, repo, *args, **kwargs) + def mqinit(orig, ui, *args, **kwargs): mq = kwargs.pop(r'mq', None) @@ -3635,16 +4132,19 @@ if args: repopath = args[0] if not hg.islocal(repopath): - raise error.Abort(_('only a local queue repository ' - 'may be initialized')) + raise error.Abort( + _('only a local queue repository ' 'may be initialized') + ) else: repopath = cmdutil.findrepo(encoding.getcwd()) if not repopath: - raise error.Abort(_('there is no Mercurial repository here ' - '(.hg not found)')) + raise error.Abort( + _('there is no Mercurial repository here ' '(.hg not found)') + ) repo = hg.repository(ui, repopath) return qinit(ui, repo, True) + def mqcommand(orig, ui, repo, *args, **kwargs): """Add --mq option to operate on patch repository instead of main""" @@ -3660,6 +4160,7 @@ raise error.Abort(_('no queue repository')) return orig(r.ui, r, *args, **kwargs) + def summaryhook(ui, repo): q = repo.mq m = [] @@ -3675,8 +4176,10 @@ # i18n: column positioning for "hg summary" ui.note(_("mq: (empty queue)\n")) + revsetpredicate = registrar.revsetpredicate() + @revsetpredicate('mq()') def revsetmq(repo, subset, x): """Changesets managed by MQ. @@ -3685,9 +4188,11 @@ applied = {repo[r.node].rev() for r in repo.mq.applied} return smartset.baseset([r for r in subset if r in applied]) + # tell hggettext to extract docstrings from these functions: i18nfunctions = [revsetmq] + 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. @@ -3714,10 +4219,13 @@ if extmodule.__file__ != __file__: dotable(getattr(extmodule, 'cmdtable', {})) -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'} + +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', +}