[PATCH] convert: support glob patterns in filemap directives
Tessa Starkey
testarkey at gmail.com
Wed Mar 24 20:52:15 CDT 2010
# HG changeset patch
# User Tessa Starkey <testarkey at gmail.com>
# Date 1269481039 14400
# Node ID f428cd7661d07c6dd379760ccb99f51dcd359abb
# Parent d9aa5b368e36c10d2c29411772fef9fd339c2e9f
convert: support glob patterns in exclude and include filemap directives
This is implemented using the matcher from the mercurial core, in order to
make the it more consistant and avoid rewriting the matching code.
diff --git a/hgext/convert/__init__.py b/hgext/convert/__init__.py
--- a/hgext/convert/__init__.py
+++ b/hgext/convert/__init__.py
@@ -90,9 +90,10 @@
directory, to be included in the destination repository, and the
exclusion of all other files and directories not explicitly
included. The 'exclude' directive causes files or directories to
- be omitted. The 'rename' directive renames a file or directory. To
- rename from a subdirectory into the root of the repository, use
- '.' as the path to rename to.
+ be omitted. In the arguments to 'include' and 'exclude' directives,
+ glob patterns can be used, but not regular expressions. The 'rename'
+ directive renames a file or directory. To rename from a subdirectory
+ into the root of the repository, use '.' as the path to rename to.
The splicemap is a file that allows insertion of synthetic
history, letting you specify the parents of a revision. This is
diff --git a/hgext/convert/filemap.py b/hgext/convert/filemap.py
--- a/hgext/convert/filemap.py
+++ b/hgext/convert/filemap.py
@@ -1,3 +1,4 @@
+
# Copyright 2007 Bryan O'Sullivan <bos at serpentine.com>
# Copyright 2007 Alexis S. L. Carvalho <alexis at cecm.usp.br>
#
@@ -6,7 +7,7 @@
import shlex
from mercurial.i18n import _
-from mercurial import util
+from mercurial import util, match
from common import SKIPREV, converter_source
def rpairs(name):
@@ -21,17 +22,20 @@
A name can be mapped to itself, a new name, or None (omit from new
repository).'''
- def __init__(self, ui, path=None):
+ def __init__(self, ui, root, path=None):
self.ui = ui
- self.include = {}
- self.exclude = {}
+ self.root = root
self.rename = {}
+ self.includematch = None
+ self.excludematch = None
if path:
if self.parse(path):
raise util.Abort(_('errors in filemap'))
def parse(self, path):
errs = 0
+ include = []
+ exclude = []
def check(name, mapping, listname):
if name in mapping:
self.ui.warn(_('%s:%d: %r already in %s list\n') %
@@ -44,17 +48,17 @@
while cmd:
if cmd == 'include':
name = lex.get_token()
- errs += check(name, self.exclude, 'exclude')
- self.include[name] = name
+ errs += check(name, exclude, 'exclude')
+ include.append(name)
elif cmd == 'exclude':
name = lex.get_token()
- errs += check(name, self.include, 'include')
+ errs += check(name, include, 'include')
errs += check(name, self.rename, 'rename')
- self.exclude[name] = name
+ exclude.append(name)
elif cmd == 'rename':
src = lex.get_token()
dest = lex.get_token()
- errs += check(src, self.exclude, 'exclude')
+ errs += check(src, exclude, 'exclude')
self.rename[src] = dest
elif cmd == 'source':
errs += self.parse(lex.get_token())
@@ -63,6 +67,13 @@
(lex.infile, lex.lineno, cmd))
errs += 1
cmd = lex.get_token()
+ #deal with svn urls for files
+ if self.root.startswith("file://"):
+ self.root = self.root[7:]
+ if include:
+ self.includematch = match.match(self.root, '', include)
+ if exclude:
+ self.excludematch = match.match(self.root, '', exclude)
return errs
def lookup(self, name, mapping):
@@ -73,16 +84,22 @@
pass
return '', name, ''
+ def matchlookup(self, name, matcher):
+ for pre, suf in rpairs(name):
+ if matcher(pre):
+ return pre, pre, suf
+ return '', name, ''
+
def __call__(self, name):
- if self.include:
- inc = self.lookup(name, self.include)[0]
+ if self.includematch:
+ inc = self.matchlookup(name, self.includematch)[0]
else:
inc = name
- if self.exclude:
- exc = self.lookup(name, self.exclude)[0]
+ if self.excludematch:
+ exc = self.matchlookup(name, self.excludematch)[0]
else:
exc = ''
- if (not self.include and exc) or (len(inc) <= len(exc)):
+ if (not self.includematch and exc) or (len(inc) <= len(exc)):
return None
newpre, pre, suf = self.lookup(name, self.rename)
if newpre:
@@ -115,7 +132,7 @@
def __init__(self, ui, baseconverter, filemap):
super(filemap_source, self).__init__(ui)
self.base = baseconverter
- self.filemapper = filemapper(ui, filemap)
+ self.filemapper = filemapper(ui, self.base.path, filemap)
self.commits = {}
# if a revision rev has parent p in the original revision graph, then
# rev will have parent self.parentmap[p] in the restricted graph.
diff --git a/tests/test-convert-filemap b/tests/test-convert-filemap
--- a/tests/test-convert-filemap
+++ b/tests/test-convert-filemap
@@ -21,6 +21,8 @@
echo dir/file2 >> dir/file2
echo dir/subdir/file3 >> dir/subdir/file3
echo dir/subdir/file4 >> dir/subdir/file4
+echo dir/fi.bin >> dir/fi.bin
+echo dir/file5.bin >> dir/file5.bin
hg ci -d '0 0' -qAm '0: add foo baz dir/'
echo bar > bar
@@ -128,3 +130,17 @@
hg --cwd source cat copied
echo 'copied2:'
hg --cwd renames.repo cat copied2
+
+echo % convert with glob exclude patterns in filemap
+cat > globs.fmap <<EOF
+exclude dir/file2
+exclude b*
+rename dir dir2
+rename foo foo2
+exclude */f?.bin
+EOF
+hg -q convert --filemap globs.fmap --datesort source globs.repo
+hg up -q -R globs.repo
+glog -R globs.repo
+hg -R globs.repo manifest --debug
+
diff --git a/tests/test-convert-filemap.out b/tests/test-convert-filemap.out
--- a/tests/test-convert-filemap.out
+++ b/tests/test-convert-filemap.out
@@ -16,14 +16,16 @@
|/
o 1 "1: add bar quux; copy foo to copied" files: bar copied quux
|
-o 0 "0: add foo baz dir/" files: baz dir/file dir/file2 dir/subdir/file3 dir/subdir/file4 foo
+o 0 "0: add foo baz dir/" files: baz dir/fi.bin dir/file dir/file2 dir/file5.bin dir/subdir/file3 dir/subdir/file4 foo
% final file versions in this repo:
9463f52fe115e377cf2878d4fc548117211063f2 644 bar
94c1be4dfde2ee8d78db8bbfcf81210813307c3d 644 baz
6ca237634e1f6bee1b6db94292fb44f092a25842 644 copied
+6617e5e33028b1dd4bc5a15ddfe1657fc0f9bb34 644 dir/fi.bin
3e20847584beff41d7cd16136b7331ab3d754be0 644 dir/file
75e6d3f8328f5f6ace6bf10b98df793416a09dca 644 dir/file2
+18b2e207d8149c85a4f4e9baf4a9d8d8d8bbd22d 644 dir/file5.bin
5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir/subdir/file3
57a1c1511590f3de52874adfa04effe8a77d64af 644 dir/subdir/file4
9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo
@@ -146,10 +148,12 @@
|
o 1 "1: add bar quux; copy foo to copied" files: copied2
|
-o 0 "0: add foo baz dir/" files: dir2/file dir2/subdir/file3 foo2
+o 0 "0: add foo baz dir/" files: dir2/fi.bin dir2/file dir2/file5.bin dir2/subdir/file3 foo2
e5e3d520be9be45937d0b06b004fadcd6c221fa2 644 copied2
+6617e5e33028b1dd4bc5a15ddfe1657fc0f9bb34 644 dir2/fi.bin
3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file
+18b2e207d8149c85a4f4e9baf4a9d8d8d8bbd22d 644 dir2/file5.bin
5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3
9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2
copied2 renamed from foo2:2ed2a3912a0b24502043eae84ee4b279c18b90dd
@@ -157,3 +161,29 @@
foo
copied2:
foo
+% convert with glob exclude patterns in filemap
+@ 8 "8: change foo" files: foo2
+|
+o 7 "7: second merge; change bar" files:
+|\
+| o 6 "6: change foo baz" files: foo2
+| |
+o | 5 "5: change bar baz quux" files: quux
+|/
+o 4 "4: first merge; change bar baz" files:
+|\
+| o 3 "3: change bar quux" files: quux
+| |
+o | 2 "2: change foo" files: foo2
+|/
+o 1 "1: add bar quux; copy foo to copied" files: copied quux
+|
+o 0 "0: add foo baz dir/" files: dir2/file dir2/file5.bin dir2/subdir/file3 dir2/subdir/file4 foo2
+
+e5e3d520be9be45937d0b06b004fadcd6c221fa2 644 copied
+3e20847584beff41d7cd16136b7331ab3d754be0 644 dir2/file
+18b2e207d8149c85a4f4e9baf4a9d8d8d8bbd22d 644 dir2/file5.bin
+5fe139720576e18e34bcc9f79174db8897c8afe9 644 dir2/subdir/file3
+57a1c1511590f3de52874adfa04effe8a77d64af 644 dir2/subdir/file4
+9a7b52012991e4873687192c3e17e61ba3e837a3 644 foo2
+bc3eca3f47023a3e70ca0d8cc95a22a6827db19d 644 quux
diff --git a/tests/test-convert.out b/tests/test-convert.out
--- a/tests/test-convert.out
+++ b/tests/test-convert.out
@@ -69,9 +69,11 @@
The 'include' directive causes a file, or all files under a directory, to
be included in the destination repository, and the exclusion of all other
files and directories not explicitly included. The 'exclude' directive
- causes files or directories to be omitted. The 'rename' directive renames
- a file or directory. To rename from a subdirectory into the root of the
- repository, use '.' as the path to rename to.
+ causes files or directories to be omitted. In the arguments to 'include'
+ and 'exclude' directives, glob patterns can be used, but not regular
+ expressions. The 'rename' directive renames a file or directory. To rename
+ from a subdirectory into the root of the repository, use '.' as the path
+ to rename to.
The splicemap is a file that allows insertion of synthetic history,
letting you specify the parents of a revision. This is useful if you want
More information about the Mercurial-devel
mailing list