##// END OF EJS Templates
templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733)...
templater: parse \"...\" as string for 2.9.2-3.4 compatibility (issue4733) As of Mercurial 3.4, there were several syntax rules to process nested template strings. Unfortunately, they were inconsistent and conflicted each other. a. buildmap() rule - template string is _parsed_ as string, and parsed as template - <\"> is not allowed in nested template: {xs % "{f(\"{x}\")}"} -> parse error - template escaping <\{> is handled consistently: {xs % "\{x}"} -> escaped b. _evalifliteral() rule - template string is _interpreted_ as string, and parsed as template in crafted environment to avoid double processing of escape sequences - <\"> is allowed in nested template: {if(x, "{f(\"{x}\")}")} - <\{> and escape sequences in string literal in nested template are not handled well c. pad() rule - template string is first interpreted as string, and parsed as template, which means escape sequences are processed twice - <\"> is allowed in nested template: {pad("{xs % \"{x}\"}', 10)} Because of the issue of template escaping, issue4714, 7298da81f5a9 (in stable) unified the rule (b) to (a). Then, 576d6c74784b (in default) unified the rule (c) to (b) = (a). But they disabled the following syntax that was somewhat considered valid. {if(rev, "{if(rev, \"{rev}\")}")} {pad("{files % \"{file}\"}", 10)} So, this patch introduces \"...\" literal to work around the escaped-quoted nested template strings. Because this parsing rule exists only for the backward compatibility, it is designed to copy the behavior of old _evalifliteral() as possible. Future patches will introduce a better parsing rule similar to a command substitution of POSIX shells or a string interpolation of Ruby, where extra escapes won't be necessary at all. {pad("{files % "{file}"}", 10)} ~~~~~~~~~~~~~~~~~~ parsed as a template, not as a string Because <\> character wasn't allowed in a template fragment, this patch won't introduce more breakages. But the syntax of nested templates are interpreted differently by people, there might be unknown issues. So if we want, we could instead remove db7463aa080f, 890845af1ac2 and 7298da81f5a9 from the stable branch as the bug fixed by these patches existed for longer periods. 554d6fcc3c8, "strip single backslash before quotation mark in quoted template", should be superseded by this patch. I'll remove it later.

File last commit:

r25186:80c5b266 default
r25676:ec9c258e stable
Show More
purge.py
115 lines | 4.2 KiB | text/x-python | PythonLexer
Emanuele Aina
Move back the purge extension in hgext
r4311 # Copyright (C) 2006 - Marco Barisione <marco@barisione.org>
#
Dirkjan Ochtman
change wiki/bts URLs to point to new hostname
r8936 # This is a small extension for Mercurial (http://mercurial.selenic.com/)
Emanuele Aina
Move back the purge extension in hgext
r4311 # that removes files not known to mercurial
#
Martin Geisler
purge: wrap docstrings at 70 characters
r9270 # This program was inspired by the "cvspurge" script contained in CVS
# utilities (http://www.red-bean.com/cvsutils/).
Emanuele Aina
Move back the purge extension in hgext
r4311 #
# For help on the usage of "hg purge" use:
# hg help purge
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
Martin Geisler
Remove FSF mailing address from GPL headers...
r15782 # along with this program; if not, see <http://www.gnu.org/licenses/>.
Emanuele Aina
Move back the purge extension in hgext
r4311
Dirkjan Ochtman
extensions: change descriptions for extensions providing a few commands
r8934 '''command to delete untracked files from the working directory'''
Dirkjan Ochtman
help: add/fix docstrings for a bunch of extensions
r8873
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 from mercurial import util, commands, cmdutil, scmutil
Emanuele Aina
Move back the purge extension in hgext
r4311 from mercurial.i18n import _
Matt Mackall
purge: drop stat import
r21994 import os
Emanuele Aina
Move back the purge extension in hgext
r4311
Adrian Buehlmann
purge: use cmdutil.command decorator
r14310 cmdtable = {}
command = cmdutil.command(cmdtable)
Augie Fackler
hgext: mark all first-party extensions as such
r16743 testedwith = 'internal'
Adrian Buehlmann
purge: use cmdutil.command decorator
r14310
@command('purge|clean',
[('a', 'abort-on-err', None, _('abort if an error occurs')),
('', 'all', None, _('purge ignored files too')),
Ben Kehoe
purge: add options for deleting only files or only directories
r21853 ('', 'dirs', None, _('purge empty directories')),
('', 'files', None, _('purge files')),
Adrian Buehlmann
purge: use cmdutil.command decorator
r14310 ('p', 'print', None, _('print filenames instead of deleting them')),
('0', 'print0', None, _('end filenames with NUL, for use with xargs'
' (implies -p/--print)')),
] + commands.walkopts,
_('hg purge [OPTION]... [DIR]...'))
Matt Mackall
purge: eliminate dopurge
r6573 def purge(ui, repo, *dirs, **opts):
Benjamin Pollack
1 file changed, 7 insertions(+), 9 deletions(-)...
r7605 '''removes files not tracked by Mercurial
Matt Mackall
purge: eliminate dopurge
r6573
Martin Geisler
purge: wrap docstrings at 70 characters
r9270 Delete files not known to Mercurial. This is useful to test local
and uncommitted changes in an otherwise-clean source tree.
Matt Mackall
purge: eliminate dopurge
r6573
Ben Kehoe
purge: add options for deleting only files or only directories
r21853 This means that purge will delete the following by default:
Martin Geisler
purge: fix formatting of lists with proper reST markup
r9215
Martin Geisler
Use hg role in help strings
r10973 - Unknown files: files marked with "?" by :hg:`status`
Martin Geisler
purge: wrap docstrings at 70 characters
r9270 - Empty directories: in fact Mercurial ignores directories unless
they contain files under source control management
Martin Geisler
purge: fix formatting of lists with proper reST markup
r9215
Matt Mackall
purge: eliminate dopurge
r6573 But it will leave untouched:
Martin Geisler
purge: fix formatting of lists with proper reST markup
r9215
- Modified and unmodified tracked files
- Ignored files (unless --all is specified)
Martin Geisler
Use hg role in help strings
r10973 - New files added to the repository (with :hg:`add`)
Matt Mackall
purge: eliminate dopurge
r6573
Ben Kehoe
purge: add options for deleting only files or only directories
r21853 The --files and --dirs options can be used to direct purge to delete
only files, only directories, or both. If neither option is given,
both will be deleted.
Matt Mackall
purge: eliminate dopurge
r6573 If directories are given on the command line, only files in these
directories are considered.
Martin Geisler
purge: wrap docstrings at 70 characters
r9270 Be careful with purge, as you could irreversibly delete some files
you forgot to add to the repository. If you only want to print the
list of files that this program would delete, use the --print
option.
Matt Mackall
purge: eliminate dopurge
r6573 '''
act = not opts['print']
Matt Mackall
purge: cleanup...
r6757 eol = '\n'
if opts['print0']:
eol = '\0'
act = False # --print0 implies --print
Ben Kehoe
purge: add options for deleting only files or only directories
r21853 removefiles = opts['files']
removedirs = opts['dirs']
if not removefiles and not removedirs:
removefiles = True
removedirs = True
Emanuele Aina
Move back the purge extension in hgext
r4311
def remove(remove_func, name):
if act:
try:
Martin Geisler
use repo.wjoin(f) instead of os.path.join(repo.root, f)
r7570 remove_func(repo.wjoin(name))
Benoit Boissinot
remove unused variables
r7280 except OSError:
Matt Mackall
purge: cleanup...
r6757 m = _('%s cannot be removed') % name
if opts['abort_on_err']:
raise util.Abort(m)
ui.warn(_('warning: %s\n') % m)
Emanuele Aina
Move back the purge extension in hgext
r4311 else:
ui.write('%s%s' % (name, eol))
Matt Mackall
scmutil: switch match users to supplying contexts...
r14671 match = scmutil.match(repo[None], dirs, opts)
Siddharth Agarwal
purge: avoid full walks when directories aren't purged...
r22265 if removedirs:
directories = []
match.explicitdir = match.traversedir = directories.append
Matt Mackall
purge: use status
r6754 status = repo.status(match=match, ignored=opts['all'], unknown=True)
Emanuele Aina
Move back the purge extension in hgext
r4311
Ben Kehoe
purge: add options for deleting only files or only directories
r21853 if removefiles:
Martin von Zweigbergk
purge: access status fields by name rather than index
r22920 for f in sorted(status.unknown + status.ignored):
Ben Kehoe
purge: add options for deleting only files or only directories
r21853 if act:
ui.note(_('removing file %s\n') % f)
Christian Ebert
purge: prefer util.unlink instead over own removefile
r21983 remove(util.unlink, f)
Emanuele Aina
Move back the purge extension in hgext
r4311
Ben Kehoe
purge: add options for deleting only files or only directories
r21853 if removedirs:
for f in sorted(directories, reverse=True):
if match(f) and not os.listdir(repo.wjoin(f)):
if act:
ui.note(_('removing directory %s\n') % f)
remove(os.rmdir, f)