[PATCH] convert: support glob patterns in filemap directives

Benoit Boissinot benoit.boissinot at ens-lyon.org
Sun Apr 4 18:47:34 CDT 2010


On Sat, Apr 03, 2010 at 01:07:40PM -0400, Tessa Starkey wrote:
> This is a patch that I have submitted previously to the mailing list,
> then made some changes to it per the feedback I got. Any feedback on
> this version of the patch would be much appriciated.

I think Patrick knows more about this area (and he reviewed the first
version). I'm adding it to the CC list.  In general when you resend a
patch it's a good idea to CC any core dev who reviewed it, you'll have
better chances.

Cheers,

Benoit
> 
> On Wed, Mar 24, 2010 at 9:52 PM, Tessa Starkey <testarkey at gmail.com> wrote:
> > # 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
> >
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

-- 
:wq


More information about the Mercurial-devel mailing list