##// END OF EJS Templates
pyoxidizer: produce working Python 3 Windows installers (issue6366)...
pyoxidizer: produce working Python 3 Windows installers (issue6366) While we've had code to produce Python 3 Windows installers with PyOxidizer, we haven't been advertising them on the web site due to a bug in making TLS connections and issues around resource handling. This commit upgrades our PyOxidizer install and configuration to use a recent Git commit of PyOxidizer. This new version of PyOxidizer contains a *ton* of changes, improvements, and bug fixes. Notably, Windows shared distributions now mostly "just work" and the TLS bug and random problems with Python extension modules in the standard library go away. And Python has been upgraded from 3.7 to 3.8.6. The price we pay for this upgrade is a ton of backwards incompatible changes to Starlark. I applied this commit (the overall series actually) on stable to produce Windows installers for Mercurial 5.5.2, which I published shortly before submitting this commit for review. In order to get the stable branch working, I decided to take a less aggressive approach to Python resource management. Previously, we were attempting to load all Python modules from memory and were performing some hacks to copy Mercurial's non-module resources into additional directories in Starlark. This commit implements a resource callback function in Starlark (a new feature since PyOxidizer 0.7) to dynamically assign standard library resources to in-memory loading and all other resources to filesystem loading. This means that Mercurial's files and all the other packages we ship in the Windows installers (e.g. certifi and pygments) are loaded from the filesystem instead of from memory. This avoids issues due to lack of __file__ and enables us to ship a working Python 3 installer on Windows. The end state of the install layout after this patch is not ideal for @: we still copy resource files like templates and help text to directories next to the hg.exe executable. There is code in @ to use importlib.resources to load these files and we could likely remove these copies once this lands on @. But for now, the install layout mimics what we've shipped for seemingly forever and is backwards compatible. It allows us to achieve the milestone of working Python 3 Windows installers and gets us a giant step closer to deleting Python 2. Differential Revision: https://phab.mercurial-scm.org/D9148

File last commit:

r46228:c7413ffe default
r46277:57b5452a default
Show More
logcmdutil.py
1210 lines | 40.4 KiB | text/x-python | PythonLexer
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 # logcmdutil.py - utility for log-like commands
#
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import itertools
import os
Martin von Zweigbergk
patch: replace "prefix" and "relroot" arguments by "pathfn" (API)...
r41795 import posixpath
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
from .i18n import _
from .node import (
nullid,
Yuya Nishihara
log: fill in pseudo rev and node as wdir() manifest identifiers...
r39832 wdirid,
wdirrev,
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 )
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 from .thirdparty import attr
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 from . import (
dagop,
error,
formatter,
graphmod,
match as matchmod,
mdiff,
patch,
pathutil,
pycompat,
revset,
revsetlang,
scmutil,
smartset,
templatekw,
templater,
util,
)
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 from .utils import (
dateutil,
stringutil,
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
typing: consolidate "if not globals():" trick...
r44212 if pycompat.TYPE_CHECKING:
Augie Fackler
logcmdutil: add a type annotation...
r44100 from typing import (
Any,
Yuya Nishihara
log: extract function that builds (revs, makefilematcher) from walkopts...
r46203 Callable,
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 Dict,
List,
Yuya Nishihara
typing: fix return type of logcmdutil.getrevs()...
r44213 Optional,
Augie Fackler
logcmdutil: add a type annotation...
r44100 Tuple,
)
Yuya Nishihara
log: extract function that builds (revs, makefilematcher) from walkopts...
r46203 for t in (Any, Callable, Dict, List, Optional, Tuple):
Augie Fackler
logcmdutil: add a type annotation...
r44100 assert t
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 def getlimit(opts):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """get the log limit according to option -l/--limit"""
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 limit = opts.get(b'limit')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if limit:
try:
limit = int(limit)
except ValueError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'limit must be a positive integer'))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if limit <= 0:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'limit must be positive'))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
limit = None
return limit
Augie Fackler
formatting: blacken the codebase...
r43346
def diffordiffstat(
ui,
repo,
diffopts,
Augie Fackler
cleanup: avoid extra node/ctx conversions in logcmdutil.diffordiffstat...
r45340 ctx1,
ctx2,
Augie Fackler
formatting: blacken the codebase...
r43346 match,
changes=None,
stat=False,
fp=None,
graphwidth=0,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 prefix=b'',
root=b'',
Augie Fackler
formatting: blacken the codebase...
r43346 listsubrepos=False,
hunksfilterfn=None,
):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 '''show diff or diffstat.'''
if root:
relroot = pathutil.canonpath(repo.root, repo.getcwd(), root)
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 relroot = b''
Martin von Zweigbergk
patch: accept second matcher that applies only to copy sources (API)...
r41769 copysourcematch = None
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
diff: make `hg diff --root=subrepo` work...
r41796 def compose(f, g):
return lambda x: f(g(x))
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
patch: replace "prefix" and "relroot" arguments by "pathfn" (API)...
r41795 def pathfn(f):
return posixpath.join(prefix, f)
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if relroot != b'':
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 # XXX relative roots currently don't work if the root is within a
# subrepo
Martin von Zweigbergk
diff: respect ui.relative-paths for warning about path outside --root...
r41804 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
uirelroot = uipathfn(pathfn(relroot))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 relroot += b'/'
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 for matchroot in match.files():
if not matchroot.startswith(relroot):
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'warning: %s not inside relative root %s\n')
Augie Fackler
formatting: blacken the codebase...
r43346 % (uipathfn(pathfn(matchroot)), uirelroot)
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 relrootmatch = scmutil.match(ctx2, pats=[relroot], default=b'path')
Martin von Zweigbergk
patch: let caller pass in root-filtering matcher (API)...
r41768 match = matchmod.intersectmatchers(match, relrootmatch)
Martin von Zweigbergk
patch: accept second matcher that applies only to copy sources (API)...
r41769 copysourcematch = relrootmatch
Martin von Zweigbergk
patch: let caller pass in root-filtering matcher (API)...
r41768
Augie Fackler
formatting: blacken the codebase...
r43346 checkroot = repo.ui.configbool(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'devel', b'all-warnings'
) or repo.ui.configbool(b'devel', b'check-relroot')
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
diff: make `hg diff --root=subrepo` work...
r41796 def relrootpathfn(f):
Martin von Zweigbergk
patch: replace "prefix" and "relroot" arguments by "pathfn" (API)...
r41795 if checkroot and not f.startswith(relroot):
raise AssertionError(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"file %s doesn't start with relroot %s" % (f, relroot)
Augie Fackler
formatting: blacken the codebase...
r43346 )
return f[len(relroot) :]
Martin von Zweigbergk
diff: make `hg diff --root=subrepo` work...
r41796 pathfn = compose(relrootpathfn, pathfn)
Martin von Zweigbergk
patch: replace "prefix" and "relroot" arguments by "pathfn" (API)...
r41795
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if stat:
diffopts = diffopts.copy(context=0, noprefix=False)
width = 80
if not ui.plain():
Navaneeth Suresh
log: fix line wrap on diffstat with -G/--graph (issue5800)...
r41129 width = ui.termwidth() - graphwidth
Martin von Zweigbergk
diff: make --stat respect ui.relative-paths...
r41819 # If an explicit --root was given, don't respect ui.relative-paths
if not relroot:
pathfn = compose(scmutil.getuipathfn(repo), pathfn)
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979
Augie Fackler
formatting: blacken the codebase...
r43346 chunks = ctx2.diff(
ctx1,
match,
changes,
opts=diffopts,
pathfn=pathfn,
copysourcematch=copysourcematch,
hunksfilterfn=hunksfilterfn,
)
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979
if fp is not None or ui.canwritewithoutlabels():
Yuya Nishihara
diff: remove fp.write() wrapper which drops label argument...
r36025 out = fp or ui
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979 if stat:
Gregory Szorc
py3: preserve chunks as an iterable of bytes...
r36132 chunks = [patch.diffstat(util.iterlines(chunks), width=width)]
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979 for chunk in util.filechunkiter(util.chunkbuffer(chunks)):
Yuya Nishihara
diff: remove fp.write() wrapper which drops label argument...
r36025 out.write(chunk)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979 if stat:
chunks = patch.diffstatui(util.iterlines(chunks), width=width)
else:
Augie Fackler
formatting: blacken the codebase...
r43346 chunks = patch.difflabel(
lambda chunks, **kwargs: chunks, chunks, opts=diffopts
)
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979 if ui.canbatchlabeledwrites():
Augie Fackler
formatting: blacken the codebase...
r43346
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979 def gen():
for chunk, label in chunks:
yield ui.label(chunk, label=label)
Augie Fackler
formatting: blacken the codebase...
r43346
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979 for chunk in util.filechunkiter(util.chunkbuffer(gen())):
Yuya Nishihara
diff: remove fp.write() wrapper which drops label argument...
r36025 ui.write(chunk)
Joerg Sonnenberger
diff: improve ui.write performance when not coloring on Windows...
r35979 else:
for chunk, label in chunks:
Yuya Nishihara
diff: remove fp.write() wrapper which drops label argument...
r36025 ui.write(chunk, label=label)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
cleanup: avoid extra node/ctx conversions in logcmdutil.diffordiffstat...
r45340 node2 = ctx2.node()
Matt Harbison
diff: support diffing explicit files in subrepos...
r42177 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
tempnode2 = node2
try:
if node2 is not None:
tempnode2 = ctx2.substate[subpath][1]
except KeyError:
# A subrepo that existed in node1 was deleted between node1 and
# node2 (inclusive). Thus, ctx2's substate won't contain that
# subpath. The best we can do is to ignore it.
tempnode2 = None
submatch = matchmod.subdirmatcher(subpath, match)
subprefix = repo.wvfs.reljoin(prefix, subpath)
if listsubrepos or match.exact(subpath) or any(submatch.files()):
Augie Fackler
formatting: blacken the codebase...
r43346 sub.diff(
ui,
diffopts,
tempnode2,
submatch,
changes=changes,
stat=stat,
fp=fp,
prefix=subprefix,
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 class changesetdiffer(object):
"""Generate diff of changeset with pre-configured filtering functions"""
def _makefilematcher(self, ctx):
return scmutil.matchall(ctx.repo())
def _makehunksfilter(self, ctx):
return None
Navaneeth Suresh
log: fix line wrap on diffstat with -G/--graph (issue5800)...
r41129 def showdiff(self, ui, ctx, diffopts, graphwidth=0, stat=False):
Augie Fackler
formatting: blacken the codebase...
r43346 diffordiffstat(
ui,
Augie Fackler
cleanup: avoid extra node/ctx conversions in logcmdutil.diffordiffstat...
r45340 ctx.repo(),
Augie Fackler
formatting: blacken the codebase...
r43346 diffopts,
Augie Fackler
cleanup: avoid extra node/ctx conversions in logcmdutil.diffordiffstat...
r45340 ctx.p1(),
ctx,
Augie Fackler
formatting: blacken the codebase...
r43346 match=self._makefilematcher(ctx),
stat=stat,
graphwidth=graphwidth,
hunksfilterfn=self._makehunksfilter(ctx),
)
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 def changesetlabels(ctx):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 labels = [b'log.changeset', b'changeset.%s' % ctx.phasestr()]
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if ctx.obsolete():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 labels.append(b'changeset.obsolete')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if ctx.isunstable():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 labels.append(b'changeset.unstable')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 for instability in ctx.instabilities():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 labels.append(b'instability.%s' % instability)
return b' '.join(labels)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 class changesetprinter(object):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 '''show changeset information when templating not requested.'''
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 self.ui = ui
self.repo = repo
self.buffered = buffered
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 self._differ = differ or changesetdiffer()
Yuya Nishihara
log: cache diffopts instance...
r37858 self._diffopts = patch.diffallopts(ui, diffopts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._includestat = diffopts and diffopts.get(b'stat')
self._includediff = diffopts and diffopts.get(b'patch')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 self.header = {}
self.hunk = {}
self.lastheader = None
self.footer = None
self._columns = templatekw.getlogcolumns()
def flush(self, ctx):
rev = ctx.rev()
if rev in self.header:
h = self.header[rev]
if h != self.lastheader:
self.lastheader = h
self.ui.write(h)
del self.header[rev]
if rev in self.hunk:
self.ui.write(self.hunk[rev])
del self.hunk[rev]
def close(self):
if self.footer:
self.ui.write(self.footer)
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 def show(self, ctx, copies=None, **props):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 props = pycompat.byteskwargs(props)
if self.buffered:
self.ui.pushbuffer(labeled=True)
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 self._show(ctx, copies, props)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 self.hunk[ctx.rev()] = self.ui.popbuffer()
else:
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 self._show(ctx, copies, props)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 def _show(self, ctx, copies, props):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 '''show a single changeset or file revision'''
changenode = ctx.node()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 graphwidth = props.get(b'graphwidth', 0)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
if self.ui.quiet:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b"%s\n" % scmutil.formatchangeid(ctx), label=b'log.node'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 return
columns = self._columns
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'changeset'] % scmutil.formatchangeid(ctx),
Augie Fackler
formatting: blacken the codebase...
r43346 label=changesetlabels(ctx),
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
# branches are shown first before any other names due to backwards
# compatibility
branch = ctx.branch()
# don't show the default branch name
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if branch != b'default':
self.ui.write(columns[b'branch'] % branch, label=b'log.branch')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Gregory Szorc
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 for nsname, ns in pycompat.iteritems(self.repo.names):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 # branches has special logic already handled above, so here we just
# skip it
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if nsname == b'branches':
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 continue
# we will use the templatename as the color name since those two
# should be the same
for name in ns.names(self.repo, changenode):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.write(ns.logfmt % name, label=b'log.%s' % ns.colorname)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if self.ui.debugflag:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.write(
columns[b'phase'] % ctx.phasestr(), label=b'log.phase'
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 for pctx in scmutil.meaningfulparents(self.repo, ctx):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 label = b'log.parent changeset.%s' % pctx.phasestr()
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'parent'] % scmutil.formatchangeid(pctx), label=label
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
log: fill in pseudo rev and node as wdir() manifest identifiers...
r39832 if self.ui.debugflag:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 mnode = ctx.manifestnode()
Yuya Nishihara
log: fill in pseudo rev and node as wdir() manifest identifiers...
r39832 if mnode is None:
mnode = wdirid
mrev = wdirrev
else:
mrev = self.repo.manifestlog.rev(mnode)
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'manifest']
Augie Fackler
formatting: blacken the codebase...
r43346 % scmutil.formatrevnode(self.ui, mrev, mnode),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 label=b'ui.debug log.manifest',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.write(columns[b'user'] % ctx.user(), label=b'log.user')
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'date'] % dateutil.datestr(ctx.date()), label=b'log.date'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
if ctx.isunstable():
instabilities = ctx.instabilities()
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'instability'] % b', '.join(instabilities),
label=b'log.instability',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
elif ctx.obsolete():
self._showobsfate(ctx)
self._exthook(ctx)
if self.ui.debugflag:
Augie Fackler
logcmdutil: use field names instead of field numbers on scmutil.status...
r44047 files = ctx.p1().status(ctx)
for key, value in zip(
[b'files', b'files+', b'files-'],
[files.modified, files.added, files.removed],
):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if value:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[key] % b" ".join(value),
label=b'ui.debug log.files',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 elif ctx.files() and self.ui.verbose:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'files'] % b" ".join(ctx.files()),
label=b'ui.note log.files',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if copies and self.ui.verbose:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 copies = [b'%s (%s)' % c for c in copies]
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'copies'] % b' '.join(copies),
label=b'ui.note log.copies',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
extra = ctx.extra()
if extra and self.ui.debugflag:
for key, value in sorted(extra.items()):
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'extra'] % (key, stringutil.escapestr(value)),
label=b'ui.debug log.extra',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
description = ctx.description().strip()
if description:
if self.ui.verbose:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"description:\n"), label=b'ui.note log.description'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.write(description, label=b'ui.note log.description')
self.ui.write(b"\n\n")
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 columns[b'summary'] % description.splitlines()[0],
label=b'log.summary',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.write(b"\n")
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Navaneeth Suresh
log: fix line wrap on diffstat with -G/--graph (issue5800)...
r41129 self._showpatch(ctx, graphwidth)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
def _showobsfate(self, ctx):
Yuya Nishihara
log: do not invoke templatekw.showobsfate() as a function...
r36534 # TODO: do not depend on templater
tres = formatter.templateresources(self.repo.ui, self.repo)
Augie Fackler
formatting: blacken the codebase...
r43346 t = formatter.maketemplater(
self.repo.ui,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'{join(obsfate, "\n")}',
Augie Fackler
formatting: blacken the codebase...
r43346 defaults=templatekw.keywords,
resources=tres,
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 obsfate = t.renderdefault({b'ctx': ctx}).splitlines()
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
if obsfate:
for obsfateline in obsfate:
Augie Fackler
formatting: blacken the codebase...
r43346 self.ui.write(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self._columns[b'obsolete'] % obsfateline,
label=b'log.obsfate',
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
def _exthook(self, ctx):
'''empty method used by extension as a hook point
'''
Navaneeth Suresh
log: fix line wrap on diffstat with -G/--graph (issue5800)...
r41129 def _showpatch(self, ctx, graphwidth=0):
Yuya Nishihara
log: consume --stat/patch options at constructor of changesetprinter...
r37859 if self._includestat:
Augie Fackler
formatting: blacken the codebase...
r43346 self._differ.showdiff(
self.ui, ctx, self._diffopts, graphwidth, stat=True
)
Yuya Nishihara
log: consume --stat/patch options at constructor of changesetprinter...
r37859 if self._includestat and self._includediff:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.write(b"\n")
Yuya Nishihara
log: consume --stat/patch options at constructor of changesetprinter...
r37859 if self._includediff:
Augie Fackler
formatting: blacken the codebase...
r43346 self._differ.showdiff(
self.ui, ctx, self._diffopts, graphwidth, stat=False
)
Yuya Nishihara
log: consume --stat/patch options at constructor of changesetprinter...
r37859 if self._includestat or self._includediff:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.ui.write(b"\n")
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: pass formatter to jsonchangeset as argument...
r37791 class changesetformatter(changesetprinter):
"""Format changeset information by generic formatter"""
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346 def __init__(
self, ui, repo, fm, differ=None, diffopts=None, buffered=False
):
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
Yuya Nishihara
log: cache diffopts instance...
r37858 self._diffopts = patch.difffeatureopts(ui, diffopts, git=True)
Yuya Nishihara
logcmdutil: pass formatter to jsonchangeset as argument...
r37791 self._fm = fm
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
def close(self):
Yuya Nishihara
logcmdutil: rewrite jsonchangeset printer to be backed by jsonformatter...
r37790 self._fm.end()
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 def _show(self, ctx, copies, props):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 '''show a single changeset or file revision'''
Yuya Nishihara
logcmdutil: rewrite jsonchangeset printer to be backed by jsonformatter...
r37790 fm = self._fm
fm.startitem()
Yuya Nishihara
log: make changesetformatter pass in changectx to formatter...
r39741 fm.context(ctx=ctx)
Augie Fackler
formatting: blacken the codebase...
r43346 fm.data(rev=scmutil.intrev(ctx), node=fm.hexfunc(scmutil.binnode(ctx)))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
log: populate keywords if specified in custom -Tjson(...) or -Tcbor(...)...
r43372 datahint = fm.datahint()
if self.ui.quiet and not datahint:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 return
Augie Fackler
formatting: blacken the codebase...
r43346 fm.data(
branch=ctx.branch(),
phase=ctx.phasestr(),
user=ctx.user(),
date=fm.formatdate(ctx.date()),
desc=ctx.description(),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'),
tags=fm.formatlist(ctx.tags(), name=b'tag'),
Augie Fackler
formatting: blacken the codebase...
r43346 parents=fm.formatlist(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 [fm.hexfunc(c.node()) for c in ctx.parents()], name=b'node'
Augie Fackler
formatting: blacken the codebase...
r43346 ),
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
log: populate keywords if specified in custom -Tjson(...) or -Tcbor(...)...
r43372 if self.ui.debugflag or b'manifest' in datahint:
fm.data(manifest=fm.hexfunc(ctx.manifestnode() or wdirid))
if self.ui.debugflag or b'extra' in datahint:
fm.data(extra=fm.formatdict(ctx.extra()))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
log: populate keywords if specified in custom -Tjson(...) or -Tcbor(...)...
r43372 if (
self.ui.debugflag
or b'modified' in datahint
or b'added' in datahint
or b'removed' in datahint
):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 files = ctx.p1().status(ctx)
Augie Fackler
formatting: blacken the codebase...
r43346 fm.data(
Augie Fackler
logcmdutil: use field names instead of field numbers on scmutil.status...
r44047 modified=fm.formatlist(files.modified, name=b'file'),
added=fm.formatlist(files.added, name=b'file'),
removed=fm.formatlist(files.removed, name=b'file'),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
log: populate keywords if specified in custom -Tjson(...) or -Tcbor(...)...
r43372 verbose = not self.ui.debugflag and self.ui.verbose
if verbose or b'files' in datahint:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm.data(files=fm.formatlist(ctx.files(), name=b'file'))
Yuya Nishihara
log: populate keywords if specified in custom -Tjson(...) or -Tcbor(...)...
r43372 if verbose and copies or b'copies' in datahint:
fm.data(
copies=fm.formatdict(copies or {}, key=b'name', value=b'source')
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
log: populate keywords if specified in custom -Tjson(...) or -Tcbor(...)...
r43372 if self._includestat or b'diffstat' in datahint:
Yuya Nishihara
logcmdutil: unindent diff generator of changesetprinter...
r36021 self.ui.pushbuffer()
Yuya Nishihara
log: cache diffopts instance...
r37858 self._differ.showdiff(self.ui, ctx, self._diffopts, stat=True)
Yuya Nishihara
logcmdutil: rewrite jsonchangeset printer to be backed by jsonformatter...
r37790 fm.data(diffstat=self.ui.popbuffer())
Yuya Nishihara
log: populate keywords if specified in custom -Tjson(...) or -Tcbor(...)...
r43372 if self._includediff or b'diff' in datahint:
Yuya Nishihara
logcmdutil: unindent diff generator of changesetprinter...
r36021 self.ui.pushbuffer()
Yuya Nishihara
log: cache diffopts instance...
r37858 self._differ.showdiff(self.ui, ctx, self._diffopts, stat=False)
Yuya Nishihara
logcmdutil: rewrite jsonchangeset printer to be backed by jsonformatter...
r37790 fm.data(diff=self.ui.popbuffer())
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 class changesettemplater(changesetprinter):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 '''format changeset information.
Note: there are a variety of convenience functions to build a
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 changesettemplater for common cases. See functions such as:
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 maketemplater, changesetdisplayer, buildcommittemplate, or other
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 functions that use changesest_templater.
'''
# Arguments before "buffered" used to be positional. Consider not
# adding/removing arguments before "buffered" to not break callers.
Augie Fackler
formatting: blacken the codebase...
r43346 def __init__(
self, ui, repo, tmplspec, differ=None, diffopts=None, buffered=False
):
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
Yuya Nishihara
log: do no expect templateresources() returning a dict...
r37090 # tres is shared with _graphnodeformatter()
self._tresources = tres = formatter.templateresources(ui, repo)
Augie Fackler
formatting: blacken the codebase...
r43346 self.t = formatter.loadtemplater(
ui,
tmplspec,
defaults=templatekw.keywords,
resources=tres,
cache=templatekw.defaulttempl,
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 self._counter = itertools.count()
self._tref = tmplspec.ref
Augie Fackler
formatting: blacken the codebase...
r43346 self._parts = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'header': b'',
b'footer': b'',
Augie Fackler
formatting: blacken the codebase...
r43346 tmplspec.ref: tmplspec.ref,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'docheader': b'',
b'docfooter': b'',
b'separator': b'',
Augie Fackler
formatting: blacken the codebase...
r43346 }
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if tmplspec.mapfile:
# find correct templates for current mode, for backward
# compatibility with 'log -v/-q/--debug' using a mapfile
tmplmodes = [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (True, b''),
(self.ui.verbose, b'_verbose'),
(self.ui.quiet, b'_quiet'),
(self.ui.debugflag, b'_debug'),
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 ]
for mode, postfix in tmplmodes:
for t in self._parts:
cur = t + postfix
if mode and cur in self.t:
self._parts[t] = cur
else:
partnames = [p for p in self._parts.keys() if p != tmplspec.ref]
m = formatter.templatepartsmap(tmplspec, self.t, partnames)
self._parts.update(m)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if self._parts[b'docheader']:
self.ui.write(self.t.render(self._parts[b'docheader'], {}))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
def close(self):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if self._parts[b'docfooter']:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not self.footer:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.footer = b""
self.footer += self.t.render(self._parts[b'docfooter'], {})
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 return super(changesettemplater, self).close()
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 def _show(self, ctx, copies, props):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 '''show a single changeset or file revision'''
props = props.copy()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 props[b'ctx'] = ctx
props[b'index'] = index = next(self._counter)
props[b'revcache'] = {b'copies': copies}
graphwidth = props.get(b'graphwidth', 0)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
# write separator, which wouldn't work well with the header part below
# since there's inherently a conflict between header (across items) and
# separator (per item)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if self._parts[b'separator'] and index > 0:
self.ui.write(self.t.render(self._parts[b'separator'], {}))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
# write header
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if self._parts[b'header']:
h = self.t.render(self._parts[b'header'], props)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if self.buffered:
self.header[ctx.rev()] = h
else:
if self.lastheader != h:
self.lastheader = h
self.ui.write(h)
# write changeset metadata, then patch if requested
key = self._parts[self._tref]
Yuya Nishihara
templater: factor out helper that renders named template as string...
r37004 self.ui.write(self.t.render(key, props))
Denis Laxalde
logcmdutil: call _exthook() in changesettemplater...
r44282 self._exthook(ctx)
Navaneeth Suresh
log: fix line wrap on diffstat with -G/--graph (issue5800)...
r41129 self._showpatch(ctx, graphwidth)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if self._parts[b'footer']:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not self.footer:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.footer = self.t.render(self._parts[b'footer'], props)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 def templatespec(tmpl, mapfile):
Martin von Zweigbergk
templatespec: logcmdutil.templatespec() gets either template or mapfile...
r45825 assert not (tmpl and mapfile)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if mapfile:
Martin von Zweigbergk
templatespec: logcmdutil.templatespec() gets either template or mapfile...
r45825 return formatter.mapfile_templatespec(b'changeset', mapfile)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
Martin von Zweigbergk
templatespec: logcmdutil.templatespec() gets either template or mapfile...
r45825 return formatter.literal_templatespec(tmpl)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 def _lookuptemplate(ui, tmpl, style):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """Find the template matching the given template spec or style
See formatter.lookuptemplate() for details.
"""
# ui settings
Augie Fackler
formatting: blacken the codebase...
r43346 if not tmpl and not style: # template are stronger than style
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tmpl = ui.config(b'ui', b'logtemplate')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if tmpl:
Martin von Zweigbergk
templatespec: use new factory functions in logcmdutil...
r45827 return formatter.literal_templatespec(templater.unquotestring(tmpl))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 style = util.expandpath(ui.config(b'ui', b'style'))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
if not tmpl and style:
mapfile = style
Martin von Zweigbergk
templater: pass opened file-like object to templatespec...
r45870 fp = None
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not os.path.split(mapfile)[0]:
Martin von Zweigbergk
templater: add exception-raising version of open_template()...
r45880 (mapname, fp) = templater.try_open_template(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'map-cmdline.' + mapfile
Martin von Zweigbergk
templater: add exception-raising version of open_template()...
r45880 ) or templater.try_open_template(mapfile)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if mapname:
mapfile = mapname
Martin von Zweigbergk
templater: pass opened file-like object to templatespec...
r45870 return formatter.mapfile_templatespec(b'changeset', mapfile, fp)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return formatter.lookuptemplate(ui, b'changeset', tmpl)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 def maketemplater(ui, repo, tmpl, buffered=False):
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 """Create a changesettemplater from a literal template 'tmpl'
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 byte-string."""
Martin von Zweigbergk
templatespec: use new factory functions in logcmdutil...
r45827 spec = formatter.literal_templatespec(tmpl)
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 return changesettemplater(ui, repo, spec, buffered=buffered)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 def changesetdisplayer(ui, repo, opts, differ=None, buffered=False):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """show one changeset using template or regular display.
Display format will be the first non-empty hit of:
1. option 'template'
2. option 'style'
3. [ui] setting 'logtemplate'
4. [ui] setting 'style'
If all of these values are either the unset or the empty string,
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 regular display via changesetprinter() is done.
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 postargs = (differ, opts, buffered)
Yuya Nishihara
formatter: parse name of built-in formatter templates in standard way...
r43370 spec = _lookuptemplate(ui, opts.get(b'template'), opts.get(b'style'))
# machine-readable formats have slightly different keyword set than
# plain templates, which are handled by changesetformatter.
# note that {b'pickle', b'debug'} can also be added to the list if needed.
if spec.ref in {b'cbor', b'json'}:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fm = ui.formatter(b'log', opts)
Yuya Nishihara
logcmdutil: pass formatter to jsonchangeset as argument...
r37791 return changesetformatter(ui, repo, fm, *postargs)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
if not spec.ref and not spec.tmpl and not spec.mapfile:
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 return changesetprinter(ui, repo, *postargs)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 return changesettemplater(ui, repo, spec, *postargs)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 @attr.s
class walkopts(object):
"""Options to configure a set of revisions and file matcher factory
to scan revision/file history
"""
# raw command-line parameters, which a matcher will be built from
pats = attr.ib() # type: List[bytes]
opts = attr.ib() # type: Dict[bytes, Any]
Yuya Nishihara
log: pass around --rev option by walkopts
r46142 # a list of revset expressions to be traversed; if follow, it specifies
# the start revisions
revspec = attr.ib() # type: List[bytes]
Yuya Nishihara
log: move miscellaneous filter/matcher options to walkopts...
r46201 # miscellaneous queries to filter revisions (see "hg help log" for details)
branches = attr.ib(default=attr.Factory(list)) # type: List[bytes]
date = attr.ib(default=None) # type: Optional[bytes]
keywords = attr.ib(default=attr.Factory(list)) # type: List[bytes]
no_merges = attr.ib(default=False) # type: bool
only_merges = attr.ib(default=False) # type: bool
prune_ancestors = attr.ib(default=attr.Factory(list)) # type: List[bytes]
users = attr.ib(default=attr.Factory(list)) # type: List[bytes]
# miscellaneous matcher arguments
include_pats = attr.ib(default=attr.Factory(list)) # type: List[bytes]
exclude_pats = attr.ib(default=attr.Factory(list)) # type: List[bytes]
Yuya Nishihara
log: pass around --follow/--follow-first options by walkopts
r46140 # 0: no follow, 1: follow first, 2: follow both parents
follow = attr.ib(default=0) # type: int
Yuya Nishihara
log: map --removed to walkopts.force_changelog_traversal...
r46200 # do not attempt filelog-based traversal, which may be fast but cannot
# include revisions where files were removed
force_changelog_traversal = attr.ib(default=False) # type: bool
Yuya Nishihara
grep: add option for logcmdutil.makewalker() to not filter revs by file pats...
r46224 # filter revisions by file patterns, which should be disabled only if
# you want to include revisions where files were unmodified
filter_revisions_by_pats = attr.ib(default=True) # type: bool
Yuya Nishihara
log: move --graph and topo sort options to walkopts...
r46202 # sort revisions prior to traversal: 'desc', 'topo', or None
sort_revisions = attr.ib(default=None) # type: Optional[bytes]
Yuya Nishihara
log: parse --limit option by logcmdutil.parseopts()
r46141 # limit number of changes displayed; None means unlimited
limit = attr.ib(default=None) # type: Optional[int]
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139
def parseopts(ui, pats, opts):
# type: (Any, List[bytes], Dict[bytes, Any]) -> walkopts
"""Parse log command options into walkopts
Yuya Nishihara
log: extract function that builds (revs, makefilematcher) from walkopts...
r46203 The returned walkopts will be passed in to getrevs() or makewalker().
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 """
Yuya Nishihara
log: pass around --follow/--follow-first options by walkopts
r46140 if opts.get(b'follow_first'):
follow = 1
elif opts.get(b'follow'):
follow = 2
else:
follow = 0
Yuya Nishihara
log: move --graph and topo sort options to walkopts...
r46202 if opts.get(b'graph'):
if ui.configbool(b'experimental', b'log.topo'):
sort_revisions = b'topo'
else:
sort_revisions = b'desc'
else:
sort_revisions = None
Yuya Nishihara
log: pass around --rev option by walkopts
r46142 return walkopts(
pats=pats,
opts=opts,
revspec=opts.get(b'rev', []),
Yuya Nishihara
log: move miscellaneous filter/matcher options to walkopts...
r46201 # branch and only_branch are really aliases and must be handled at
# the same time
branches=opts.get(b'branch', []) + opts.get(b'only_branch', []),
date=opts.get(b'date'),
keywords=opts.get(b'keyword', []),
no_merges=bool(opts.get(b'no_merges')),
only_merges=bool(opts.get(b'only_merges')),
prune_ancestors=opts.get(b'prune', []),
users=opts.get(b'user', []),
include_pats=opts.get(b'include', []),
exclude_pats=opts.get(b'exclude', []),
Yuya Nishihara
log: pass around --rev option by walkopts
r46142 follow=follow,
Yuya Nishihara
log: map --removed to walkopts.force_changelog_traversal...
r46200 force_changelog_traversal=bool(opts.get(b'removed')),
Yuya Nishihara
log: move --graph and topo sort options to walkopts...
r46202 sort_revisions=sort_revisions,
Yuya Nishihara
log: pass around --rev option by walkopts
r46142 limit=getlimit(opts),
)
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139
def _makematcher(repo, revs, wopts):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """Build matcher and expanded patterns from log options
If --follow, revs are the revisions to follow from.
Returns (match, pats, slowpath) where
- match: a matcher built from the given pats and -I/-X opts
- pats: patterns used (globs are expanded on Windows)
- slowpath: True if patterns aren't as simple as scanning filelogs
"""
# pats/include/exclude are passed to match.match() directly in
Yuya Nishihara
cmdutil: remove remainder of old walkchangerevs() implementation
r46228 # _matchfiles() revset, but a log-like command should build its matcher
# with scmutil.match(). The difference is input pats are globbed on
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 # platforms without shell expansion (windows).
wctx = repo[None]
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 match, pats = scmutil.matchandpats(wctx, wopts.pats, wopts.opts)
slowpath = match.anypats() or (
Yuya Nishihara
log: map --removed to walkopts.force_changelog_traversal...
r46200 not match.always() and wopts.force_changelog_traversal
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not slowpath:
Yuya Nishihara
log: pass around --rev option by walkopts
r46142 if wopts.follow and wopts.revspec:
Yuya Nishihara
log: make -frREV PATH detect missing files before falling back to slow path...
r46045 # There may be the case that a path doesn't exist in some (but
# not all) of the specified start revisions, but let's consider
# the path is valid. Missing files will be warned by the matcher.
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 startctxs = [repo[r] for r in revs]
Yuya Nishihara
log: reorganize if-else and for loop in logcmdutil._makematcher()...
r46043 for f in match.files():
Yuya Nishihara
log: make -frREV PATH detect missing files before falling back to slow path...
r46045 found = False
for c in startctxs:
if f in c:
found = True
elif c.hasdir(f):
# If a directory exists in any of the start revisions,
# take the slow path.
found = slowpath = True
if not found:
raise error.Abort(
_(
b'cannot follow file not in any of the specified '
b'revisions: "%s"'
)
% f
)
Yuya Nishihara
log: pass around --follow/--follow-first options by walkopts
r46140 elif wopts.follow:
Yuya Nishihara
log: reorganize if-else and for loop in logcmdutil._makematcher()...
r46043 for f in match.files():
if f not in wctx:
# If the file exists, it may be a directory, so let it
# take the slow path.
if os.path.exists(repo.wjoin(f)):
slowpath = True
continue
else:
raise error.Abort(
_(
b'cannot follow file not in parent '
b'revision: "%s"'
)
% f
)
filelog = repo.file(f)
if not filelog:
Yuya Nishihara
log: fix -fr'wdir()' PATH to follow newly added file...
r46044 # A file exists in wdir but not in history, which means
# the file isn't committed yet.
Yuya Nishihara
log: reorganize if-else and for loop in logcmdutil._makematcher()...
r46043 raise error.Abort(
_(b'cannot follow nonexistent file: "%s"') % f
)
else:
for f in match.files():
filelog = repo.file(f)
if not filelog:
# A zero count may be a directory or deleted file, so
# try to find matching entries on the slow path.
slowpath = True
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
# We decided to fall back to the slowpath because at least one
# of the paths was not a file. Check to see if at least one of them
# existed in history - in that case, we'll continue down the
# slowpath; otherwise, we can turn off the slowpath
if slowpath:
for path in match.files():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if path == b'.' or path in repo.store:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 break
else:
slowpath = False
return match, pats, slowpath
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 def _fileancestors(repo, revs, match, followfirst):
fctxs = []
for r in revs:
ctx = repo[r]
fctxs.extend(ctx[f].introfilectx() for f in ctx.walk(match))
# When displaying a revision with --patch --follow FILE, we have
# to know which file of the revision must be diffed. With
# --follow, we want the names of the ancestors of FILE in the
# revision, stored in "fcache". "fcache" is populated as a side effect
# of the graph traversal.
fcache = {}
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: pass ctx to makefilematcher() and makehunksfilter() functions...
r36019 def filematcher(ctx):
Yuya Nishihara
log: fix crash and bad filematcher lookup by -fr'wdir()' PATH...
r46019 return scmutil.matchfiles(repo, fcache.get(scmutil.intrev(ctx), []))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
def revgen():
for rev, cs in dagop.filectxancestors(fctxs, followfirst=followfirst):
fcache[rev] = [c.path() for c in cs]
yield rev
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 return smartset.generatorset(revgen(), iterasc=False), filematcher
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 def _makenofollowfilematcher(repo, pats, opts):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 '''hook for extensions to override the filematcher for non-follow cases'''
return None
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 _opt2logrevset = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'no_merges': (b'not merge()', None),
b'only_merges': (b'merge()', None),
b'_matchfiles': (None, b'_matchfiles(%ps)'),
b'date': (b'date(%s)', None),
b'branch': (b'branch(%s)', b'%lr'),
b'_patslog': (b'filelog(%s)', b'%lr'),
b'keyword': (b'keyword(%s)', b'%lr'),
b'prune': (b'ancestors(%s)', b'not %lr'),
b'user': (b'user(%s)', b'%lr'),
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 }
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 def _makerevset(repo, wopts, slowpath):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """Return a revset string built from log options and file patterns"""
Yuya Nishihara
log: move miscellaneous filter/matcher options to walkopts...
r46201 opts = {
b'branch': [repo.lookupbranch(b) for b in wopts.branches],
b'date': wopts.date,
b'keyword': wopts.keywords,
b'no_merges': wopts.no_merges,
b'only_merges': wopts.only_merges,
b'prune': wopts.prune_ancestors,
b'user': wopts.users,
}
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
grep: add option for logcmdutil.makewalker() to not filter revs by file pats...
r46224 if wopts.filter_revisions_by_pats and slowpath:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 # pats/include/exclude cannot be represented as separate
# revset expressions as their filtering logic applies at file
# level. For instance "-I a -X b" matches a revision touching
# "a" and "b" while "file(a) and not file(b)" does
# not. Besides, filesets are evaluated against the working
# directory.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 matchargs = [b'r:', b'd:relpath']
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 for p in wopts.pats:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 matchargs.append(b'p:' + p)
Yuya Nishihara
log: move miscellaneous filter/matcher options to walkopts...
r46201 for p in wopts.include_pats:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 matchargs.append(b'i:' + p)
Yuya Nishihara
log: move miscellaneous filter/matcher options to walkopts...
r46201 for p in wopts.exclude_pats:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 matchargs.append(b'x:' + p)
opts[b'_matchfiles'] = matchargs
Yuya Nishihara
grep: add option for logcmdutil.makewalker() to not filter revs by file pats...
r46224 elif wopts.filter_revisions_by_pats and not wopts.follow:
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 opts[b'_patslog'] = list(wopts.pats)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
expr = []
Gregory Szorc
py3: finish porting iteritems() to pycompat and remove source transformer...
r43376 for op, val in sorted(pycompat.iteritems(opts)):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not val:
continue
revop, listop = _opt2logrevset[op]
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if revop and b'%' not in revop:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 expr.append(revop)
elif not listop:
expr.append(revsetlang.formatspec(revop, val))
else:
if revop:
val = [revsetlang.formatspec(revop, v) for v in val]
expr.append(revsetlang.formatspec(listop, val))
if expr:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 expr = b'(' + b' and '.join(expr) + b')'
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
expr = None
return expr
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 def _initialrevs(repo, wopts):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """Return the initial set of revisions to be filtered or followed"""
Yuya Nishihara
log: pass around --rev option by walkopts
r46142 if wopts.revspec:
revs = scmutil.revrange(repo, wopts.revspec)
Yuya Nishihara
log: pass around --follow/--follow-first options by walkopts
r46140 elif wopts.follow and repo.dirstate.p1() == nullid:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 revs = smartset.baseset()
Yuya Nishihara
log: pass around --follow/--follow-first options by walkopts
r46140 elif wopts.follow:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 revs = repo.revs(b'.')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
revs = smartset.spanset(repo)
revs.reverse()
return revs
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: extract function that builds (revs, makefilematcher) from walkopts...
r46203 def makewalker(repo, wopts):
# type: (Any, walkopts) -> Tuple[smartset.abstractsmartset, Optional[Callable[[Any], matchmod.basematcher]]]
"""Build (revs, makefilematcher) to scan revision/file history
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
log: extract function that builds (revs, makefilematcher) from walkopts...
r46203 - revs is the smartset to be traversed.
- makefilematcher is a function to map ctx to a matcher for that revision
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 revs = _initialrevs(repo, wopts)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not revs:
return smartset.baseset(), None
Yuya Nishihara
log: map --removed to walkopts.force_changelog_traversal...
r46200 # TODO: might want to merge slowpath with wopts.force_changelog_traversal
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 match, pats, slowpath = _makematcher(repo, revs, wopts)
wopts = attr.evolve(wopts, pats=pats)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 filematcher = None
Yuya Nishihara
log: pass around --follow/--follow-first options by walkopts
r46140 if wopts.follow:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if slowpath or match.always():
Yuya Nishihara
log: pass around --follow/--follow-first options by walkopts
r46140 revs = dagop.revancestors(repo, revs, followfirst=wopts.follow == 1)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
Yuya Nishihara
log: map --removed to walkopts.force_changelog_traversal...
r46200 assert not wopts.force_changelog_traversal
Yuya Nishihara
log: pass around --follow/--follow-first options by walkopts
r46140 revs, filematcher = _fileancestors(
repo, revs, match, followfirst=wopts.follow == 1
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 revs.reverse()
if filematcher is None:
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 filematcher = _makenofollowfilematcher(repo, wopts.pats, wopts.opts)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if filematcher is None:
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: pass ctx to makefilematcher() and makehunksfilter() functions...
r36019 def filematcher(ctx):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 return match
Yuya Nishihara
log: introduce struct that carries log traversal options...
r46139 expr = _makerevset(repo, wopts, slowpath)
Yuya Nishihara
log: move --graph and topo sort options to walkopts...
r46202 if wopts.sort_revisions:
assert wopts.sort_revisions in {b'topo', b'desc'}
if wopts.sort_revisions == b'topo':
Martin von Zweigbergk
log: add config for making `hg log -G` always topo-sorted...
r42500 if not revs.istopo():
revs = dagop.toposort(revs, repo.changelog.parentrevs)
# TODO: try to iterate the set lazily
Yuya Nishihara
log: flag topo-sorted set as such...
r42510 revs = revset.baseset(list(revs), istopo=True)
Martin von Zweigbergk
log: add config for making `hg log -G` always topo-sorted...
r42500 elif not (revs.isdescending() or revs.istopo()):
Yuya Nishihara
log: remove stale comment about order of user revset...
r46137 # User-specified revs might be unsorted
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 revs.sort(reverse=True)
if expr:
matcher = revset.match(None, expr)
revs = matcher(repo, revs)
Yuya Nishihara
log: parse --limit option by logcmdutil.parseopts()
r46141 if wopts.limit is not None:
revs = revs.slice(0, wopts.limit)
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024
Yuya Nishihara
log: extract function that builds (revs, makefilematcher) from walkopts...
r46203 return revs, filematcher
def getrevs(repo, wopts):
# type: (Any, walkopts) -> Tuple[smartset.abstractsmartset, Optional[changesetdiffer]]
"""Return (revs, differ) where revs is a smartset
differ is a changesetdiffer with pre-configured file matcher.
"""
revs, filematcher = makewalker(repo, wopts)
if not revs:
return revs, None
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 differ = changesetdiffer()
differ._makefilematcher = filematcher
return revs, differ
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 def _parselinerangeopt(repo, opts):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """Parse --line-range log option and return a list of tuples (filename,
(fromline, toline)).
"""
linerangebyfname = []
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for pat in opts.get(b'line_range', []):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 pat, linerange = pat.rsplit(b',', 1)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 except ValueError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'malformatted line-range pattern %s') % pat)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fromline, toline = map(int, linerange.split(b':'))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 except ValueError:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b"invalid line range for %s") % pat)
msg = _(b"line range pattern '%s' must match exactly one file") % pat
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 fname = scmutil.parsefollowlinespattern(repo, None, pat, msg)
linerangebyfname.append(
Augie Fackler
formatting: blacken the codebase...
r43346 (fname, util.processlinerange(fromline, toline))
)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 return linerangebyfname
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 def getlinerangerevs(repo, userrevs, opts):
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 """Return (revs, differ).
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
"revs" are revisions obtained by processing "line-range" log options and
walking block ancestors of each specified file/line-range.
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 "differ" is a changesetdiffer with pre-configured file matcher and hunks
filter.
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 """
wctx = repo[None]
# Two-levels map of "rev -> file ctx -> [line range]".
linerangesbyrev = {}
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 for fname, (fromline, toline) in _parselinerangeopt(repo, opts):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if fname not in wctx:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 _(b'cannot follow file not in parent revision: "%s"') % fname
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 fctx = wctx.filectx(fname)
for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
rev = fctx.introrev()
Denis Laxalde
log: map None rev to wdirrev when filtering revisions with --line-range...
r44173 if rev is None:
rev = wdirrev
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if rev not in userrevs:
continue
Augie Fackler
formatting: blacken the codebase...
r43346 linerangesbyrev.setdefault(rev, {}).setdefault(
fctx.path(), []
).append(linerange)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 def nofilterhunksfn(fctx, hunks):
return hunks
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 def hunksfilter(ctx):
Denis Laxalde
log: map None rev to wdirrev when filtering revisions with --line-range...
r44173 fctxlineranges = linerangesbyrev.get(scmutil.intrev(ctx))
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 if fctxlineranges is None:
return nofilterhunksfn
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 def filterfn(fctx, hunks):
lineranges = fctxlineranges.get(fctx.path())
if lineranges is not None:
for hr, lines in hunks:
Augie Fackler
formatting: blacken the codebase...
r43346 if hr is None: # binary
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 yield hr, lines
continue
Augie Fackler
formatting: blacken the codebase...
r43346 if any(mdiff.hunkinrange(hr[2:], lr) for lr in lineranges):
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 yield hr, lines
else:
for hunk in hunks:
yield hunk
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 return filterfn
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 def filematcher(ctx):
Denis Laxalde
log: map None rev to wdirrev when filtering revisions with --line-range...
r44173 files = list(linerangesbyrev.get(scmutil.intrev(ctx), []))
Yuya Nishihara
logcmdutil: create hunksfilter and filematcher even if no diff option given...
r36022 return scmutil.matchfiles(repo, files)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
revs = sorted(linerangesbyrev, reverse=True)
Yuya Nishihara
log: pack filematcher and hunksfilter into changesetdiffer object...
r36024 differ = changesetdiffer()
differ._makefilematcher = filematcher
differ._makehunksfilter = hunksfilter
Denis Laxalde
logcmdutil: let getlinerangerevs() return "revs" as a smartset...
r44029 return smartset.baseset(revs), differ
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 def _graphnodeformatter(ui, displayer):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 spec = ui.config(b'ui', b'graphnodetemplate')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not spec:
Yuya Nishihara
templatekw: extract non-templatekw function as getgraphnode()...
r36530 return templatekw.getgraphnode # fast path for "{graphnode}"
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
spec = templater.unquotestring(spec)
Yuya Nishihara
logcmdutil: rename classes and functions to conform to our coding style (API)...
r35904 if isinstance(displayer, changesettemplater):
Yuya Nishihara
templater: convert resources to a table of callables for future extension...
r36997 # reuse cache of slow templates
Yuya Nishihara
log: do no expect templateresources() returning a dict...
r37090 tres = displayer._tresources
else:
tres = formatter.templateresources(ui)
Augie Fackler
formatting: blacken the codebase...
r43346 templ = formatter.maketemplater(
ui, spec, defaults=templatekw.keywords, resources=tres
)
Martin von Zweigbergk
graphlog: use '%' for other context in merge conflict...
r44819 def formatnode(repo, ctx, cache):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 props = {b'ctx': ctx, b'repo': repo}
Yuya Nishihara
templater: rename .render(mapping) to .renderdefault(mapping) (API)...
r37003 return templ.renderdefault(props)
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 return formatnode
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
log: pass getcopies() function instead of getrenamed() to displayer (API)...
r42704 def displaygraph(ui, repo, dag, displayer, edgefn, getcopies=None, props=None):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 props = props or {}
formatnode = _graphnodeformatter(ui, displayer)
state = graphmod.asciistate()
Yuya Nishihara
graphlog: change state dict to attr struct...
r44215 styles = state.styles
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
# only set graph styling if HGPLAIN is not set.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if ui.plain(b'graph'):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 # set all edge styles to |, the default pre-3.8 behaviour
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 styles.update(dict.fromkeys(styles, b'|'))
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 else:
edgetypes = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'parent': graphmod.PARENT,
b'grandparent': graphmod.GRANDPARENT,
b'missing': graphmod.MISSINGPARENT,
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 }
for name, key in edgetypes.items():
# experimental config: experimental.graphstyle.*
Augie Fackler
formatting: blacken the codebase...
r43346 styles[key] = ui.config(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'experimental', b'graphstyle.%s' % name, styles[key]
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not styles[key]:
styles[key] = None
# experimental config: experimental.graphshorten
Yuya Nishihara
graphlog: change state dict to attr struct...
r44215 state.graphshorten = ui.configbool(b'experimental', b'graphshorten')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Martin von Zweigbergk
graphlog: use '%' for other context in merge conflict...
r44819 formatnode_cache = {}
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 for rev, type, ctx, parents in dag:
Martin von Zweigbergk
graphlog: use '%' for other context in merge conflict...
r44819 char = formatnode(repo, ctx, formatnode_cache)
Martin von Zweigbergk
log: pass getcopies() function instead of getrenamed() to displayer (API)...
r42704 copies = getcopies(ctx) if getcopies else None
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 edges = edgefn(type, char, state, rev, parents)
firstedge = next(edges)
width = firstedge[2]
Augie Fackler
formatting: blacken the codebase...
r43346 displayer.show(
ctx, copies=copies, graphwidth=width, **pycompat.strkwargs(props)
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 lines = displayer.hunk.pop(rev).split(b'\n')
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if not lines[-1]:
del lines[-1]
displayer.flush(ctx)
for type, char, width, coldata in itertools.chain([firstedge], edges):
graphmod.ascii(ui, state, type, char, lines, coldata)
lines = []
displayer.close()
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
log: factor out function to feed revisions to displayer
r36216 def displaygraphrevs(ui, repo, revs, displayer, getrenamed):
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 revdag = graphmod.dagwalker(repo, revs)
Yuya Nishihara
logcmdutil: hold makefilematcher/makehunksfilter() by changesetpriner (API)...
r36020 displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
Augie Fackler
formatting: blacken the codebase...
r43346
Martin von Zweigbergk
log: pass getcopies() function instead of getrenamed() to displayer (API)...
r42704 def displayrevs(ui, repo, revs, displayer, getcopies):
Yuya Nishihara
log: factor out function to feed revisions to displayer
r36216 for rev in revs:
ctx = repo[rev]
Martin von Zweigbergk
log: pass getcopies() function instead of getrenamed() to displayer (API)...
r42704 copies = getcopies(ctx) if getcopies else None
Yuya Nishihara
log: factor out function to feed revisions to displayer
r36216 displayer.show(ctx, copies=copies)
displayer.flush(ctx)
displayer.close()
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 def checkunsupportedgraphflags(pats, opts):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for op in [b"newest_first"]:
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 if op in opts and opts[op]:
Augie Fackler
formatting: blacken the codebase...
r43346 raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"-G/--graph option is incompatible with --%s")
% op.replace(b"_", b"-")
Augie Fackler
formatting: blacken the codebase...
r43346 )
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903
def graphrevs(repo, nodes, opts):
Yuya Nishihara
logcmdutil: drop redundant "log" from function names (API)...
r35905 limit = getlimit(opts)
Yuya Nishihara
cmdutil: split functions of log-like commands to new module (API)...
r35903 nodes.reverse()
if limit is not None:
nodes = nodes[:limit]
return graphmod.nodes(repo, nodes)