##// END OF EJS Templates
widening: remove unused "heads" argument...
widening: remove unused "heads" argument Differential Revision: https://phab.mercurial-scm.org/D7096

File last commit:

r43375:649d3ac3 default
r43521:f0764074 default
Show More
keyword.py
887 lines | 29.5 KiB | text/x-python | PythonLexer
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 # keyword.py - $Keyword$ expansion for Mercurial
#
Christian Ebert
keyword: update copyright year
r23723 # Copyright 2007-2015 Christian Ebert <blacktrash@gmx.net>
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
# $Id$
#
Mads Kiilerich
fix trivial spelling errors
r17424 # Keyword expansion hack against the grain of a Distributed SCM
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
# There are many good reasons why this is not needed in a distributed
# SCM, still it may be useful in very small projects based on single
Martin Geisler
keyword: word-wrap help texts at 70 characters
r7993 # files (like LaTeX packages), that are mostly addressed to an
# audience not running a version control system.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
# For in-depth discussion refer to
Matt Mackall
urls: bulk-change primary website URLs
r26421 # <https://mercurial-scm.org/wiki/KeywordPlan>.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 #
# Keyword expansion is based on Mercurial's changeset template mappings.
#
# Binary files are not touched.
#
# Files to act upon/ignore are specified in the [keyword] section.
# Customized keyword template mappings in the [keywordmaps] section.
#
timeless
keyword: use single quotes in use warning
r29969 # Run 'hg help keyword' and 'hg kwdemo' to get info on configuration.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Cédric Duval
extensions: improve the consistency of synopses...
r8894 '''expand keywords in tracked files
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 This extension expands RCS/CVS-like or self-customized $Keywords$ in
tracked text files selected by your configuration.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 Keywords are only expanded in local repositories and not stored in the
change history. The mechanism can be regarded as a convenience for the
current user or for archive distribution.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: explain file-wise expansion in help
r12203 Keywords expand to the changeset data pertaining to the latest change
relative to the working directory parent of each file.
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 Configuration is done in the [keyword], [keywordset] and [keywordmaps]
sections of hgrc files.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
commands: use minirst parser when displaying help
r9157 Example::
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
[keyword]
# expand keywords in every python file except those matching "x*"
**.py =
x* = ignore
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 [keywordset]
# prefer svn- over cvs-like default keywordmaps
svn = True
Christian Ebert
Use more note admonitions in help texts
r12390 .. note::
Simon Heimberg
documentation: add an extra newline after note directive...
r19997
Christian Ebert
Use more note admonitions in help texts
r12390 The more specific you are in your filename patterns the less you
lose speed in huge repositories.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 For [keywordmaps] template mapping and expansion demonstration and
Martin Geisler
Use hg role in help strings
r10973 control run :hg:`kwdemo`. See :hg:`help templates` for a list of
Christian Ebert
keyword: reference templating help, add utcdate filter example
r9307 available templates and filters.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: convert a verbatim block to a field list
r13885 Three additional date template filters are provided:
Christian Ebert
keyword: add 2 svn-like date filters...
r11213
Martin Geisler
keyword: convert a verbatim block to a field list
r13885 :``utcdate``: "2006/09/18 15:13:13"
:``svnutcdate``: "2006-09-18 15:13:13Z"
:``svnisodate``: "2006-09-18 08:13:13 -700 (Mon, 18 Sep 2006)"
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
Use hg role in help strings
r10973 The default template mappings (view with :hg:`kwdemo -d`) can be
replaced with customized keywords and templates. Again, run
Christian Ebert
keyword: s/config/configuration/ in help
r13025 :hg:`kwdemo` to control the results of your configuration changes.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: update documentation for kwshrink...
r13270 Before changing/disabling active keywords, you must run :hg:`kwshrink`
to avoid storing expanded keywords in the change history.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 To force expansion after enabling it, or a configuration change, run
Martin Geisler
Use hg role in help strings
r10973 :hg:`kwexpand`.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 Expansions spanning more than one line and incremental expansions,
like CVS' $Log$, are not supported. A keyword template map "Log =
{desc}" expands to the first line of the changeset description.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''
Christian Ebert
keyword: use absolute_import
r28321
from __future__ import absolute_import
import os
import re
FUJIWARA Katsunori
keyword: make wrapped repository and kwtemplater refer to each other...
r33067 import weakref
Christian Ebert
keyword: use absolute_import
r28321
Yuya Nishihara
py3: move up symbol imports to enforce import-checker rules...
r29205 from mercurial.i18n import _
Gregory Szorc
py3: manually import getattr where it is needed...
r43359 from mercurial.pycompat import getattr
Christian Ebert
keyword: no expansion in web diffs...
r6072 from mercurial.hgweb import webcommands
Christian Ebert
keyword: use absolute_import
r28321
from mercurial import (
cmdutil,
context,
dispatch,
error,
extensions,
filelog,
localrepo,
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 logcmdutil,
Christian Ebert
keyword: use absolute_import
r28321 match,
patch,
pathutil,
Pulkit Goyal
py3: handle keyword arguments in hgext/keyword.py...
r35002 pycompat,
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 registrar,
Christian Ebert
keyword: use absolute_import
r28321 scmutil,
templatefilters,
Yuya Nishihara
keyword: declare input type of date filters as date...
r37245 templateutil,
Christian Ebert
keyword: use absolute_import
r28321 util,
)
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 from mercurial.utils import (
dateutil,
stringutil,
)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: use cmdutil.command decorator
r14300 cmdtable = {}
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 command = registrar.command(cmdtable)
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
Augie Fackler
extensions: document that `testedwith = 'internal'` is special...
r25186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 testedwith = b'ships-with-hg-core'
Martin Geisler
keyword: use cmdutil.command decorator
r14300
Christian Ebert
keyword: nokwcommands, restricted string variables at top level...
r6024 # hg commands that do not act on keywords
Augie Fackler
formatting: blacken the codebase...
r43346 nokwcommands = (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'add addremove annotate bundle export grep incoming init log'
b' outgoing push tip verify convert email glog'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Christian Ebert
keyword: nokwcommands, restricted string variables at top level...
r6024
FUJIWARA Katsunori
keyword: make comparison webcommand suppress keyword expansion...
r33065 # webcommands that do not act on keywords
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 nokwwebcommands = b'annotate changeset rev filediff diff comparison'
FUJIWARA Katsunori
keyword: make comparison webcommand suppress keyword expansion...
r33065
Christian Ebert
keyword: detect restricted commands thru variable
r5961 # hg commands that trigger expansion only when writing to working dir,
# not when reading filelog, and unexpand when reading from working dir
Augie Fackler
formatting: blacken the codebase...
r43346 restricted = (
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'merge kwexpand kwshrink record qrecord resolve transplant'
b' unshelve rebase graft backout histedit fetch'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Christian Ebert
keyword: detect restricted commands thru variable
r5961
Christian Ebert
keyword: support extensions using dorecord, e.g. crecord...
r11168 # names of extensions using dorecord
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 recordextensions = b'record'
Christian Ebert
keyword: support (q)record...
r11045
Christian Ebert
keyword: colorize hg kwfiles output
r13078 colortable = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'kwfiles.enabled': b'green bold',
b'kwfiles.deleted': b'cyan bold underline',
b'kwfiles.enabledunknown': b'green',
b'kwfiles.ignored': b'bold',
b'kwfiles.ignoredunknown': b'none',
Christian Ebert
keyword: colorize hg kwfiles output
r13078 }
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 templatefilter = registrar.templatefilter()
Boris Feld
configitems: register the 'keywordset.svn' config
r34501 configtable = {}
configitem = registrar.configitem(configtable)
Augie Fackler
formatting: blacken the codebase...
r43346 configitem(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'keywordset', b'svn', default=False,
Boris Feld
configitems: register the 'keywordset.svn' config
r34501 )
Christian Ebert
keyword: add 2 svn-like date filters...
r11213 # date like in cvs' $Date
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 @templatefilter(b'utcdate', intype=templateutil.date)
Yuya Nishihara
keyword: declare input type of date filters as date...
r37245 def utcdate(date):
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 '''Date. Returns a UTC-date in this format: "2009/08/18 11:00:13".
Christian Ebert
keyword: docstrings for additional date filters
r13633 '''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 dateformat = b'%Y/%m/%d %H:%M:%S'
Yuya Nishihara
keyword: declare input type of date filters as date...
r37245 return dateutil.datestr((date[0], 0), dateformat)
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: add 2 svn-like date filters...
r11213 # date like in svn's $Date
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 @templatefilter(b'svnisodate', intype=templateutil.date)
Yuya Nishihara
keyword: declare input type of date filters as date...
r37245 def svnisodate(date):
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 '''Date. Returns a date in this format: "2009-08-18 13:00:13
Christian Ebert
keyword: docstrings for additional date filters
r13633 +0200 (Tue, 18 Aug 2009)".
'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return dateutil.datestr(date, b'%Y-%m-%d %H:%M:%S %1%2 (%a, %d %b %Y)')
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: add 2 svn-like date filters...
r11213 # date like in svn's $Id
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 @templatefilter(b'svnutcdate', intype=templateutil.date)
Yuya Nishihara
keyword: declare input type of date filters as date...
r37245 def svnutcdate(date):
FUJIWARA Katsunori
keyword: use templatefilter to mark a function as template filter...
r28694 '''Date. Returns a UTC-date in this format: "2009-08-18
Christian Ebert
keyword: docstrings for additional date filters
r13633 11:00:13Z".
'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 dateformat = b'%Y-%m-%d %H:%M:%SZ'
Yuya Nishihara
keyword: declare input type of date filters as date...
r37245 return dateutil.datestr((date[0], 0), dateformat)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: make main class and hg command accessible...
r6115 # make keyword tools accessible
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 kwtools = {b'hgcmd': b''}
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 def _defaultkwmaps(ui):
'''Returns default keywordmaps according to keywordset configuration.'''
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 templates = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Revision': b'{node|short}',
b'Author': b'{author|user}',
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 }
Augie Fackler
formatting: blacken the codebase...
r43346 kwsets = (
{
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Date': b'{date|utcdate}',
b'RCSfile': b'{file|basename},v',
b'RCSFile': b'{file|basename},v', # kept for backwards compatibility
Augie Fackler
formatting: blacken the codebase...
r43346 # with hg-keyword
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Source': b'{root}/{file},v',
b'Id': b'{file|basename},v {node|short} {date|utcdate} {author|user}',
b'Header': b'{root}/{file},v {node|short} {date|utcdate} {author|user}',
Augie Fackler
formatting: blacken the codebase...
r43346 },
{
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'Date': b'{date|svnisodate}',
b'Id': b'{file|basename},v {node|short} {date|svnutcdate} {author|user}',
b'LastChangedRevision': b'{node|short}',
b'LastChangedBy': b'{author|user}',
b'LastChangedDate': b'{date|svnisodate}',
Augie Fackler
formatting: blacken the codebase...
r43346 },
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 templates.update(kwsets[ui.configbool(b'keywordset', b'svn')])
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 return templates
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 def _shrinktext(text, subfunc):
'''Helper for keyword expansion removal in text.
Depending on subfunc also returns number of substitutions.'''
Pulkit Goyal
py3: make regexes in hgext/keyword.py bytes...
r39462 return subfunc(br'$\1$', text)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: code cleanup...
r12723 def _preselect(wstatus, changed):
Mads Kiilerich
fix trivial spelling errors
r17424 '''Retrieves modified and added files from a working directory state
Christian Ebert
keyword: code cleanup...
r12723 and returns the subset of each contained in given changed files
retrieved from a change context.'''
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 modified = [f for f in wstatus.modified if f in changed]
added = [f for f in wstatus.added if f in changed]
Christian Ebert
keyword: code cleanup...
r12723 return modified, added
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 class kwtemplater(object):
'''
Sets up keyword templates, corresponding keyword regex, and
provides keyword substitution functions.
'''
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 def __init__(self, ui, repo, inc, exc):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 self.ui = ui
FUJIWARA Katsunori
keyword: make wrapped repository and kwtemplater refer to each other...
r33067 self._repo = weakref.ref(repo)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 self.match = match.match(repo.root, b'', [], inc, exc)
self.restrict = kwtools[b'hgcmd'] in restricted.split()
Christian Ebert
keyword: rename kwt.record attribute to kwt.postcommit...
r16809 self.postcommit = False
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 kwmaps = self.ui.configitems(b'keywordmaps')
Augie Fackler
formatting: blacken the codebase...
r43346 if kwmaps: # override default templates
Yuya Nishihara
templater: remove noop calls of parsestring(s, quoted=False) (API)...
r24987 self.templates = dict(kwmaps)
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 else:
self.templates = _defaultkwmaps(self.ui)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
FUJIWARA Katsunori
keyword: make wrapped repository and kwtemplater refer to each other...
r33067 @property
def repo(self):
return self._repo()
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 @util.propertycache
def escape(self):
'''Returns bar-separated and escaped keywords.'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'|'.join(map(stringutil.reescape, self.templates.keys()))
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926
@util.propertycache
def rekw(self):
'''Returns regex for unexpanded keywords.'''
Pulkit Goyal
py3: make regexes in hgext/keyword.py bytes...
r39462 return re.compile(br'\$(%s)\$' % self.escape)
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926
@util.propertycache
def rekwexp(self):
'''Returns regex for expanded keywords.'''
Pulkit Goyal
py3: make regexes in hgext/keyword.py bytes...
r39462 return re.compile(br'\$(%s): [^$\n\r]*? \$' % self.escape)
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926
Dirkjan Ochtman
keyword: be more efficient about ctx usage
r7375 def substitute(self, data, path, ctx, subfunc):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 '''Replaces keywords in data with expanded template.'''
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def kwsub(mobj):
kw = mobj.group(1)
Augie Fackler
formatting: blacken the codebase...
r43346 ct = logcmdutil.maketemplater(
self.ui, self.repo, self.templates[kw]
)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 self.ui.pushbuffer()
Christian Ebert
keyword: make the templater a local variable...
r10894 ct.show(ctx, root=self.repo.root, file=path)
Christian Ebert
keyword: split line continuation in 2 steps (style)
r6023 ekw = templatefilters.firstline(self.ui.popbuffer())
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b'$%s: %s $' % (kw, ekw)
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 return subfunc(kwsub, data)
Christian Ebert
keyword: function to look up changectx for expansion...
r12920 def linkctx(self, path, fileid):
'''Similar to filelog.linkrev, but returns a changectx.'''
return self.repo.filectx(path, fileid=fileid).changectx()
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 def expand(self, path, node, data):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''Returns data with keywords expanded.'''
Augie Fackler
formatting: blacken the codebase...
r43346 if (
not self.restrict
and self.match(path)
and not stringutil.binary(data)
):
Christian Ebert
keyword: function to look up changectx for expansion...
r12920 ctx = self.linkctx(path, node)
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 return self.substitute(data, path, ctx, self.rekw.sub)
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 return data
Christian Ebert
keyword: make iskwfile() a weeding method in lieu of a boolean...
r12627 def iskwfile(self, cand, ctx):
'''Returns subset of candidates which are configured for keyword
Christian Ebert
keyword: correct grammar in iskwfile docstring
r15324 expansion but are not symbolic links.'''
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return [f for f in cand if self.match(f) and b'l' not in ctx.flags(f)]
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: enforce subn method via boolean switch...
r12685 def overwrite(self, ctx, candidates, lookup, expand, rekw=False):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 '''Overwrites selected files expanding/shrinking keywords.'''
Augie Fackler
formatting: blacken the codebase...
r43346 if self.restrict or lookup or self.postcommit: # exclude kw_copy
Christian Ebert
keyword: make iskwfile() a weeding method in lieu of a boolean...
r12627 candidates = self.iskwfile(candidates, ctx)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 if not candidates:
return
Augie Fackler
formatting: blacken the codebase...
r43346 kwcmd = self.restrict and lookup # kwexpand/kwshrink
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 if self.restrict or expand and lookup:
Christian Ebert
keyword: postpone manifest calculation in kwtemplater.overwrite...
r11350 mf = ctx.manifest()
Christian Ebert
keyword: avoid x = a and b or c
r15030 if self.restrict or rekw:
re_kw = self.rekw
else:
re_kw = self.rekwexp
if expand:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'overwriting %s expanding keywords\n')
Christian Ebert
keyword: avoid x = a and b or c
r15030 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 msg = _(b'overwriting %s shrinking keywords\n')
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 for f in candidates:
if self.restrict:
data = self.repo.file(f).read(mf[f])
else:
data = self.repo.wread(f)
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 if stringutil.binary(data):
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 continue
if expand:
Christian Ebert
keyword: handle resolve to either parent...
r23622 parents = ctx.parents()
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 if lookup:
Christian Ebert
keyword: use wopener(..., atomictemp=True) to overwrite
r15083 ctx = self.linkctx(f, mf[f])
Christian Ebert
keyword: handle resolve to either parent...
r23622 elif self.restrict and len(parents) > 1:
# merge commit
# in case of conflict f is in modified state during
# merge, even if f does not differ from f in parent
for p in parents:
if f in p and not p[f].cmp(ctx[f]):
ctx = p[f].changectx()
break
Christian Ebert
keyword: use wopener(..., atomictemp=True) to overwrite
r15083 data, found = self.substitute(data, f, ctx, re_kw.subn)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 elif self.restrict:
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 found = re_kw.search(data)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 else:
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 data, found = _shrinktext(data, re_kw.subn)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 if found:
self.ui.note(msg % f)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fp = self.repo.wvfs(f, b"wb", atomictemp=True)
Christian Ebert
keyword: use wopener(..., atomictemp=True) to overwrite
r15083 fp.write(data)
fp.close()
Christian Ebert
keyword: fix regressions introduced in d87f3ff904ba...
r12844 if kwcmd:
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 self.repo.dirstate.normal(f)
Christian Ebert
keyword: rename kwt.record attribute to kwt.postcommit...
r16809 elif self.postcommit:
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 self.repo.dirstate.normallookup(f)
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114
def shrink(self, fname, text):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''Returns text with all keyword substitutions removed.'''
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 if self.match(fname) and not stringutil.binary(text):
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 return _shrinktext(text, self.rekwexp.sub)
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 return text
def shrinklines(self, fname, lines):
'''Returns lines with keyword substitutions removed.'''
Christian Ebert
keyword: rename matcher() to match() mimicking changes in main
r8638 if self.match(fname):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 text = b''.join(lines)
Yuya Nishihara
stringutil: bulk-replace call sites to point to new module...
r37102 if not stringutil.binary(text):
Christian Ebert
keyword: turn regexes and escaped keywords into a propertycache
r12926 return _shrinktext(text, self.rekwexp.sub).splitlines(True)
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 return lines
def wread(self, fname, data):
'''If in restricted mode returns data read from wdir with
keyword substitutions removed.'''
Christian Ebert
keyword: avoid x = a and b or c
r15030 if self.restrict:
return self.shrink(fname, data)
return data
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 class kwfilelog(filelog.filelog):
'''
Subclass of filelog to hook into its read, add, cmp methods.
Keywords are "stored" unexpanded, and processed on reading.
'''
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503 def __init__(self, opener, kwt, path):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 super(kwfilelog, self).__init__(opener, path)
Christian Ebert
keyword: privatize remaining monkeypatches by moving them into reposetup...
r6503 self.kwt = kwt
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 self.path = path
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
def read(self, node):
'''Expands keywords when reading filelog.'''
data = super(kwfilelog, self).read(node)
Christian Ebert
keyword: disable expansion in kwfilelog.read() if file renamed in node...
r12628 if self.renamed(node):
return data
Christian Ebert
keyword: make main class and hg command accessible...
r6115 return self.kwt.expand(self.path, node, data)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
def add(self, text, meta, tr, link, p1=None, p2=None):
'''Removes keyword substitutions when adding to filelog.'''
Christian Ebert
keyword: make main class and hg command accessible...
r6115 text = self.kwt.shrink(self.path, text)
Christian Ebert
keyword: compact setting of optional arguments
r6504 return super(kwfilelog, self).add(text, meta, tr, link, p1, p2)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
def cmp(self, node, text):
'''Removes keyword substitutions for comparison.'''
Christian Ebert
keyword: make main class and hg command accessible...
r6115 text = self.kwt.shrink(self.path, text)
Christian Ebert
keyword: disable expansion in kwfilelog.read() if file renamed in node...
r12628 return super(kwfilelog, self).cmp(node, text)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: reuse already present working contexts for match...
r14835 def _status(ui, repo, wctx, kwt, *pats, **opts):
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''Bails out if [keyword] configuration is not active.
Returns status of working directory.'''
Christian Ebert
keyword: make main class and hg command accessible...
r6115 if kwt:
Pulkit Goyal
py3: handle keyword arguments in hgext/keyword.py...
r35002 opts = pycompat.byteskwargs(opts)
Augie Fackler
formatting: blacken the codebase...
r43346 return repo.status(
match=scmutil.match(wctx, pats, opts),
clean=True,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 unknown=opts.get(b'unknown') or opts.get(b'all'),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if ui.configitems(b'keyword'):
raise error.Abort(_(b'[keyword] patterns cannot match'))
raise error.Abort(_(b'no [keyword] patterns configured'))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def _kwfwrite(ui, repo, expand, *pats, **opts):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 '''Selects files and passes them to kwtemplater.overwrite.'''
Christian Ebert
keyword: pass context to kwtemplater.overwrite...
r11320 wctx = repo[None]
if len(wctx.parents()) > 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'outstanding uncommitted merge'))
FUJIWARA Katsunori
keyword: use _keywordkwt of repository instead of kwtools['templater']...
r33070 kwt = getattr(repo, '_keywordkwt', None)
Bryan O'Sullivan
with: use context manager for wlock in _kwfwrite
r27815 with repo.wlock():
Christian Ebert
keyword: reuse already present working contexts for match...
r14835 status = _status(ui, repo, wctx, kwt, *pats, **opts)
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 if status.modified or status.added or status.removed or status.deleted:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 raise error.Abort(_(b'outstanding uncommitted changes'))
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 kwt.overwrite(wctx, status.clean, True, expand)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: blacken the codebase...
r43346
@command(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'kwdemo',
Augie Fackler
formatting: blacken the codebase...
r43346 [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'd', b'default', None, _(b'show default keyword template maps')),
(b'f', b'rcfile', b'', _(b'read maps from rcfile'), _(b'FILE')),
Augie Fackler
formatting: blacken the codebase...
r43346 ],
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'hg kwdemo [-d] [-f RCFILE] [TEMPLATEMAP]...'),
Augie Fackler
formatting: blacken the codebase...
r43346 optionalrepo=True,
)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def demo(ui, repo, *args, **opts):
'''print [keywordmaps] configuration and an expansion example
Martin Geisler
keyword: word-wrap help texts at 70 characters
r7993 Show current, custom, or default keyword template maps and their
timeless
keyword: improve English
r8763 expansions.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 Extend the current configuration by specifying maps as arguments
and using -f/--rcfile to source an external hgrc file.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 Use -d/--default to disable current configuration.
Christian Ebert
keyword: reference templating help, add utcdate filter example
r9307
Martin Geisler
Use our custom hg reStructuredText role some more...
r11193 See :hg:`help templates` for information on templates and filters.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def demoitems(section, items):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(b'[%s]\n' % section)
Martin Geisler
keyword: sort demo output to ensure deterministic output
r9942 for k, v in sorted(items):
Pulkit Goyal
py3: use stringutil.pprint() if we are printing bool values...
r40256 if isinstance(v, bool):
v = stringutil.pprint(v)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(b'%s = %s\n' % (k, v))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 fn = b'demo.txt'
tmpdir = pycompat.mkdtemp(b'', b'kwdemo.')
ui.note(_(b'creating temporary repository at %s\n') % tmpdir)
Christian Ebert
keyword: avoid traceback when kwdemo is run outside a repo...
r29634 if repo is None:
baseui = ui
else:
baseui = repo.baseui
Gregory Szorc
localrepo: move repo creation logic out of localrepository.__init__ (API)...
r39584 repo = localrepo.instance(baseui, tmpdir, create=True)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.setconfig(b'keyword', fn, b'', b'keyword')
svn = ui.configbool(b'keywordset', b'svn')
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 # explicitly set keywordset for demo output
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.setconfig(b'keywordset', b'svn', svn, b'keyword')
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 uikwmaps = ui.configitems(b'keywordmaps')
Pulkit Goyal
py3: handle keyword arguments in hgext/keyword.py...
r35002 if args or opts.get(r'rcfile'):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\n\tconfiguration using custom keyword template maps\n'))
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 if uikwmaps:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\textending current template maps\n'))
Pulkit Goyal
py3: handle keyword arguments in hgext/keyword.py...
r35002 if opts.get(r'default') or not uikwmaps:
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 if svn:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\toverriding default svn keywordset\n'))
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\toverriding default cvs keywordset\n'))
Pulkit Goyal
py3: handle keyword arguments in hgext/keyword.py...
r35002 if opts.get(r'rcfile'):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.readconfig(opts.get(b'rcfile'))
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 if args:
# simulate hgrc parsing
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 rcmaps = b'[keywordmaps]\n%s\n' % b'\n'.join(args)
repo.vfs.write(b'hgrc', rcmaps)
ui.readconfig(repo.vfs.join(b'hgrc'))
kwmaps = dict(ui.configitems(b'keywordmaps'))
Pulkit Goyal
py3: handle keyword arguments in hgext/keyword.py...
r35002 elif opts.get(r'default'):
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 if svn:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\n\tconfiguration using default svn keywordset\n'))
Christian Ebert
keyword: inform user about current keywordset in kwdemo...
r13298 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\n\tconfiguration using default cvs keywordset\n'))
Christian Ebert
keyword: offer svn-like default keywordmaps...
r11214 kwmaps = _defaultkwmaps(ui)
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 if uikwmaps:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\tdisabling current template maps\n'))
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 for k, v in pycompat.iteritems(kwmaps):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.setconfig(b'keywordmaps', k, v, b'keyword')
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\n\tconfiguration using current keyword template maps\n'))
Christian Ebert
keyword: avoid x = a and b or c
r15030 if uikwmaps:
kwmaps = dict(uikwmaps)
else:
kwmaps = _defaultkwmaps(ui)
Christian Ebert
keyword: refactor kwdemo and make output translatable...
r9281
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502 uisetup(ui)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 reposetup(ui, repo)
Augie Fackler
cleanup: mark some ui.(status|note|warn|write) calls as not needing i18n...
r43350 ui.writenoi18n(b'[extensions]\nkeyword =\n')
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 demoitems(b'keyword', ui.configitems(b'keyword'))
demoitems(b'keywordset', ui.configitems(b'keywordset'))
Gregory Szorc
py3: define and use pycompat.iteritems() for hgext/...
r43375 demoitems(b'keywordmaps', pycompat.iteritems(kwmaps))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 keywords = b'$' + b'$\n$'.join(sorted(kwmaps.keys())) + b'$\n'
Angel Ezquerra
localrepo: remove all external users of localrepo.wopener...
r23879 repo.wvfs.write(fn, keywords)
Dirkjan Ochtman
move working dir/dirstate methods from localrepo to workingctx
r11303 repo[None].add([fn])
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.note(_(b'\nkeywords written to %s:\n') % fn)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 ui.note(keywords)
Bryan O'Sullivan
with: use context manager for wlock in keyword demo
r27816 with repo.wlock():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 repo.dirstate.setbranch(b'demobranch')
for name, cmd in ui.configitems(b'hooks'):
if name.split(b'.', 1)[0].find(b'commit') > -1:
repo.ui.setconfig(b'hooks', name, b'', b'keyword')
msg = _(b'hg keyword configuration and expansion example')
ui.note((b"hg ci -m '%s'\n" % msg))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 repo.commit(text=msg)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.status(_(b'\n\tkeywords expanded\n'))
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 ui.write(repo.wread(fn))
Christian Ebert
keyword: use wvfs.rmtree to remove kwdemo directory...
r24905 repo.wvfs.rmtree(repo.root)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: blacken the codebase...
r43346
@command(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'kwexpand',
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 cmdutil.walkopts,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'hg kwexpand [OPTION]... [FILE]...'),
Augie Fackler
formatting: blacken the codebase...
r43346 inferrepo=True,
)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def expand(ui, repo, *pats, **opts):
timeless
keyword: improve English
r8763 '''expand keywords in the working directory
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Run after (re)enabling keyword expansion.
kwexpand refuses to run if given files contain local changes.
'''
# 3rd argument sets expansion to True
_kwfwrite(ui, repo, True, *pats, **opts)
Augie Fackler
formatting: blacken the codebase...
r43346
@command(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'kwfiles',
Augie Fackler
formatting: blacken the codebase...
r43346 [
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'A', b'all', None, _(b'show keyword status flags of all files')),
(b'i', b'ignore', None, _(b'show files excluded from expansion')),
(b'u', b'unknown', None, _(b'only show unknown (not tracked) files')),
Augie Fackler
formatting: blacken the codebase...
r43346 ]
+ cmdutil.walkopts,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'hg kwfiles [OPTION]... [FILE]...'),
Augie Fackler
formatting: blacken the codebase...
r43346 inferrepo=True,
)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def files(ui, repo, *pats, **opts):
Christian Ebert
keyword: improve help for kwfiles...
r8957 '''show files configured for keyword expansion
Christian Ebert
keyword: improve help for kwfiles
r8950
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 List which files in the working directory are matched by the
[keyword] configuration patterns.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 Useful to prevent inadvertent keyword expansion and to speed up
execution by including only files that are actual candidates for
expansion.
Christian Ebert
keyword: improve help for kwfiles
r8950
Martin Geisler
Use hg role in help strings
r10973 See :hg:`help keyword` on how to construct patterns both for
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 inclusion and exclusion of files.
Christian Ebert
keyword: improve help for kwfiles...
r8957
Christian Ebert
keyword: uppercase short option for kwfiles --all, like hg status -A...
r9494 With -A/--all and -v/--verbose the codes used to show the status
Martin Geisler
keyword: wrap docstrings at 70 characters
r9264 of files are::
Christian Ebert
keyword: reformat kwfiles help for minirst parser
r9195
K = keyword expansion candidate
Christian Ebert
keyword: kwfiles --unknown instead of --untracked...
r9491 k = keyword expansion candidate (not tracked)
Christian Ebert
keyword: reformat kwfiles help for minirst parser
r9195 I = ignored
Christian Ebert
keyword: kwfiles --unknown instead of --untracked...
r9491 i = ignored (not tracked)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 '''
FUJIWARA Katsunori
keyword: use _keywordkwt of repository instead of kwtools['templater']...
r33070 kwt = getattr(repo, '_keywordkwt', None)
Christian Ebert
keyword: reuse already present working contexts for match...
r14835 wctx = repo[None]
status = _status(ui, repo, wctx, kwt, *pats, **opts)
Jordi Gutiérrez Hermoso
style: kill ersatz if-else ternary operators...
r24306 if pats:
cwd = repo.getcwd()
else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 cwd = b''
Christian Ebert
keyword: make kwfiles -u show untracked files only (like status)...
r9493 files = []
Pulkit Goyal
py3: handle keyword arguments in hgext/keyword.py...
r35002 opts = pycompat.byteskwargs(opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'unknown') or opts.get(b'all'):
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 files = sorted(status.modified + status.added + status.clean)
Christian Ebert
keyword: make iskwfile() a weeding method in lieu of a boolean...
r12627 kwfiles = kwt.iskwfile(files, wctx)
Martin von Zweigbergk
keyword: access status fields by name rather than index
r22918 kwdeleted = kwt.iskwfile(status.deleted, wctx)
kwunknown = kwt.iskwfile(status.unknown, wctx)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not opts.get(b'ignore') or opts.get(b'all'):
Christian Ebert
keyword: make kwfiles show deleted files configured for expansion
r13079 showfiles = kwfiles, kwdeleted, kwunknown
Christian Ebert
keyword: make kwfiles -u show untracked files only (like status)...
r9493 else:
Christian Ebert
keyword: make kwfiles show deleted files configured for expansion
r13079 showfiles = [], [], []
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'all') or opts.get(b'ignore'):
Augie Fackler
formatting: blacken the codebase...
r43346 showfiles += (
[f for f in files if f not in kwfiles],
[f for f in status.unknown if f not in kwunknown],
)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 kwlabels = b'enabled deleted enabledunknown ignored ignoredunknown'.split()
kwstates = zip(kwlabels, pycompat.bytestr(b'K!kIi'), showfiles)
fm = ui.formatter(b'kwfiles', opts)
fmt = b'%.0s%s\n'
if opts.get(b'all') or ui.verbose:
fmt = b'%s %s\n'
Christian Ebert
keyword: use ui.formatter for kwfiles output
r17057 for kwstate, char, filenames in kwstates:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 label = b'kwfiles.' + kwstate
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 for f in filenames:
Christian Ebert
keyword: use ui.formatter for kwfiles output
r17057 fm.startitem()
Yuya Nishihara
formatter: rename {abspath}/{file} to {path}, and drop relative {path} (BC)...
r39405 fm.data(kwstatus=char, path=f)
fm.plain(fmt % (char, repo.pathto(f, cwd)), label=label)
Christian Ebert
keyword: use ui.formatter for kwfiles output
r17057 fm.end()
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: blacken the codebase...
r43346
@command(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'kwshrink',
Yuya Nishihara
commands: move templates of common command options to cmdutil (API)...
r32375 cmdutil.walkopts,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'hg kwshrink [OPTION]... [FILE]...'),
Augie Fackler
formatting: blacken the codebase...
r43346 inferrepo=True,
)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def shrink(ui, repo, *pats, **opts):
timeless
keyword: improve English
r8763 '''revert expanded keywords in the working directory
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: update documentation for kwshrink...
r13270 Must be run before changing/disabling active keywords.
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
kwshrink refuses to run if given files contain local changes.
'''
# 3rd argument sets expansion to False
_kwfwrite(ui, repo, False, *pats, **opts)
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 # monkeypatches
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 def kwpatchfile_init(orig, self, ui, gp, backend, store, eolmode=None):
'''Monkeypatch/wrap patch.patchfile.__init__ to avoid
rejects or conflicts due to expanded keywords in working dir.'''
orig(self, ui, gp, backend, store, eolmode)
kwt = getattr(getattr(backend, 'repo', None), '_keywordkwt', None)
if kwt:
# shrink keywords read from working dir
self.lines = kwt.shrinklines(self.fname, self.lines)
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 def kwdiff(orig, repo, *args, **kwargs):
'''Monkeypatch patch.diff to avoid expansion.'''
kwt = getattr(repo, '_keywordkwt', None)
if kwt:
restrict = kwt.restrict
kwt.restrict = True
try:
for chunk in orig(repo, *args, **kwargs):
yield chunk
finally:
if kwt:
kwt.restrict = restrict
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
hgweb: stop passing req and tmpl into @webcommand functions (API)...
r36903 def kwweb_skip(orig, web):
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 '''Wraps webcommands.x turning off keyword expansion.'''
kwt = getattr(web.repo, '_keywordkwt', None)
if kwt:
origmatch = kwt.match
kwt.match = util.never
try:
Gregory Szorc
hgweb: stop passing req and tmpl into @webcommand functions (API)...
r36903 for chunk in orig(web):
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 yield chunk
finally:
if kwt:
kwt.match = origmatch
Augie Fackler
formatting: blacken the codebase...
r43346
Saurabh Singh
cmdutil: remove redundant commitfunc parameter in amend (API)...
r34088 def kw_amend(orig, ui, repo, old, extra, pats, opts):
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 '''Wraps cmdutil.amend expanding keywords after amend.'''
kwt = getattr(repo, '_keywordkwt', None)
if kwt is None:
Saurabh Singh
cmdutil: remove redundant commitfunc parameter in amend (API)...
r34088 return orig(ui, repo, old, extra, pats, opts)
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 with repo.wlock():
kwt.postcommit = True
Saurabh Singh
cmdutil: remove redundant commitfunc parameter in amend (API)...
r34088 newid = orig(ui, repo, old, extra, pats, opts)
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 if newid != old.node():
ctx = repo[newid]
kwt.restrict = True
kwt.overwrite(ctx, ctx.files(), False, True)
kwt.restrict = False
return newid
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 def kw_copy(orig, ui, repo, pats, opts, rename=False):
'''Wraps cmdutil.copy so that copy/rename destinations do not
contain expanded keywords.
Note that the source of a regular file destination may also be a
symlink:
hg cp sym x -> x is symlink
cp sym x; hg cp -A sym x -> x is file (maybe expanded keywords)
For the latter we have to follow the symlink to find out whether its
target is configured for expansion and we therefore must unexpand the
keywords in the destination.'''
kwt = getattr(repo, '_keywordkwt', None)
if kwt is None:
return orig(ui, repo, pats, opts, rename)
with repo.wlock():
orig(ui, repo, pats, opts, rename)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'dry_run'):
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 return
wctx = repo[None]
cwd = repo.getcwd()
def haskwsource(dest):
'''Returns true if dest is a regular file and configured for
expansion or a symlink which points to a file configured for
expansion. '''
source = repo.dirstate.copied(dest)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'l' in wctx.flags(source):
Augie Fackler
formatting: blacken the codebase...
r43346 source = pathutil.canonpath(
repo.root, cwd, os.path.realpath(source)
)
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 return kwt.match(source)
Augie Fackler
formatting: blacken the codebase...
r43346 candidates = [
f
for f in repo.dirstate.copies()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if b'l' not in wctx.flags(f) and haskwsource(f)
Augie Fackler
formatting: blacken the codebase...
r43346 ]
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 kwt.overwrite(wctx, candidates, False, False)
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 def kw_dorecord(orig, ui, repo, commitfunc, *pats, **opts):
'''Wraps record.dorecord expanding keywords after recording.'''
kwt = getattr(repo, '_keywordkwt', None)
if kwt is None:
return orig(ui, repo, commitfunc, *pats, **opts)
with repo.wlock():
# record returns 0 even when nothing has changed
# therefore compare nodes before and after
kwt.postcommit = True
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ctx = repo[b'.']
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 wstatus = ctx.status()
ret = orig(ui, repo, commitfunc, *pats, **opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 recctx = repo[b'.']
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 if ctx != recctx:
modified, added = _preselect(wstatus, recctx.files())
kwt.restrict = False
kwt.overwrite(recctx, modified, False, True)
kwt.overwrite(recctx, added, False, True, True)
kwt.restrict = True
return ret
Augie Fackler
formatting: blacken the codebase...
r43346
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 def kwfilectx_cmp(orig, self, fctx):
if fctx._customcmp:
return fctx.cmp(self)
kwt = getattr(self._repo, '_keywordkwt', None)
if kwt is None:
return orig(self, fctx)
# keyword affects data size, comparing wdir and filelog size does
# not make sense
Augie Fackler
formatting: blacken the codebase...
r43346 if (
fctx._filenode is None
and (
self._repo._encodefilterpats
or kwt.match(fctx.path())
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 and b'l' not in fctx.flags()
Augie Fackler
formatting: blacken the codebase...
r43346 or self.size() - 4 == fctx.size()
)
or self.size() == fctx.size()
):
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 return self._filelog.cmp(self._filenode, fctx.data())
return True
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502 def uisetup(ui):
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 ''' Monkeypatches dispatch._parse to retrieve user command.
Overrides file method to return kwfilelog instead of filelog
if file matches user configuration.
Wraps commit to overwrite configured files with updated
keyword substitutions.
Monkeypatches patch and webcommands.'''
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 def kwdispatch_parse(orig, ui, args):
'''Monkeypatch dispatch._parse to obtain running hg command.'''
cmd, func, args, options, cmdoptions = orig(ui, args)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 kwtools[b'hgcmd'] = cmd
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 return cmd, func, args, options, cmdoptions
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extensions.wrapfunction(dispatch, b'_parse', kwdispatch_parse)
Christian Ebert
keyword: collect filename patterns, wrap dispatch._parse in uisetup...
r6502
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 extensions.wrapfunction(context.filectx, b'cmp', kwfilectx_cmp)
extensions.wrapfunction(patch.patchfile, b'__init__', kwpatchfile_init)
extensions.wrapfunction(patch, b'diff', kwdiff)
extensions.wrapfunction(cmdutil, b'amend', kw_amend)
extensions.wrapfunction(cmdutil, b'copy', kw_copy)
extensions.wrapfunction(cmdutil, b'dorecord', kw_dorecord)
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 for c in nokwwebcommands.split():
extensions.wrapfunction(webcommands, c, kwweb_skip)
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 def reposetup(ui, repo):
FUJIWARA Katsunori
keyword: wrap functions only once at loading keyword extension...
r33071 '''Sets up repo as kwrepo for keyword substitution.'''
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Matt Mackall
bundlerepo: reintroduce dirstate
r7853 try:
Augie Fackler
formatting: blacken the codebase...
r43346 if (
not repo.local()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 or kwtools[b'hgcmd'] in nokwcommands.split()
or b'.hg' in util.splitpath(repo.root)
or repo._url.startswith(b'bundle:')
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Matt Mackall
bundlerepo: reintroduce dirstate
r7853 return
except AttributeError:
pass
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 inc, exc = [], [b'.hg*']
for pat, opt in ui.configitems(b'keyword'):
if opt != b'ignore':
Christian Ebert
keyword: move collecting of [keyword] patterns to reposetup (issue2303)...
r11678 inc.append(pat)
else:
exc.append(pat)
if not inc:
return
FUJIWARA Katsunori
keyword: use _keywordkwt of repository instead of kwtools['templater']...
r33070 kwt = kwtemplater(ui, repo, inc, exc)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
class kwrepo(repo.__class__):
Christian Ebert
keyword: move expand/shrink decisions into kwtemplater...
r6114 def file(self, f):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if f[0] == b'/':
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815 f = f[1:]
Angel Ezquerra
localrepo: remove all external users of localrepo.sopener...
r23878 return kwfilelog(self.svfs, kwt, f)
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Christian Ebert
keyword: support mq; handle (q)record more gracefully...
r5884 def wread(self, filename):
data = super(kwrepo, self).wread(filename)
Christian Ebert
keyword: make main class and hg command accessible...
r6115 return kwt.wread(filename, data)
Christian Ebert
keyword: support mq; handle (q)record more gracefully...
r5884
Christian Ebert
keyword: eliminate potential reference cycles from kwrepo...
r9096 def commit(self, *args, **opts):
Christian Ebert
keyword: make repo.commit use a custom commitctx wrapper...
r8996 # use custom commitctx for user commands
# other extensions can still wrap repo.commitctx directly
Christian Ebert
keyword: eliminate potential reference cycles from kwrepo...
r9096 self.commitctx = self.kwcommitctx
try:
Christian Ebert
keyword: do not postpone commit hooks...
r10495 return super(kwrepo, self).commit(*args, **opts)
Christian Ebert
keyword: eliminate potential reference cycles from kwrepo...
r9096 finally:
del self.commitctx
Christian Ebert
keyword: make repo.commit use a custom commitctx wrapper...
r8996
Valentin Gatien-Baron
convert: add a config option to help doing identity hg->hg conversion...
r42839 def kwcommitctx(self, ctx, error=False, origctx=None):
n = super(kwrepo, self).commitctx(ctx, error, origctx)
Christian Ebert
keyword: remove spurious locks, improve handling of wlock...
r10604 # no lock needed, only called from repo.commit() which already locks
Christian Ebert
keyword: rename kwt.record attribute to kwt.postcommit...
r16809 if not kwt.postcommit:
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 restrict = kwt.restrict
kwt.restrict = True
Augie Fackler
formatting: blacken the codebase...
r43346 kwt.overwrite(
self[n], sorted(ctx.added() + ctx.modified()), False, True
)
Christian Ebert
keyword: refactor kwtemplater.overwrite()...
r12625 kwt.restrict = restrict
Christian Ebert
keyword: remove spurious locks, improve handling of wlock...
r10604 return n
Christian Ebert
Add extension for filewise RCS-keyword expansion in working dir...
r5815
Greg Ward
rollback: avoid unsafe rollback when not at tip (issue2998)...
r15183 def rollback(self, dryrun=False, force=False):
Christian Ebert
keyword: use context manager for rollback locking
r32935 with self.wlock():
origrestrict = kwt.restrict
try:
if not dryrun:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 changed = self[b'.'].files()
Christian Ebert
keyword: use context manager for rollback locking
r32935 ret = super(kwrepo, self).rollback(dryrun, force)
if not dryrun:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ctx = self[b'.']
Christian Ebert
keyword: use context manager for rollback locking
r32935 modified, added = _preselect(ctx.status(), changed)
kwt.restrict = False
kwt.overwrite(ctx, modified, True, True)
kwt.overwrite(ctx, added, True, False)
return ret
finally:
kwt.restrict = origrestrict
Christian Ebert
keyword: support rollback by restoring expansion to previous values...
r12498
FUJIWARA Katsunori
keyword: make wrapped repository and kwtemplater refer to each other...
r33067 repo.__class__ = kwrepo
repo._keywordkwt = kwt