Patchwork [v2] match: override 'visitdir' in subdirmatcher

login
register
mail settings
Submitter Martin von Zweigbergk
Date Feb. 14, 2016, 6:26 a.m.
Message ID <CAESOdVB19yQ_Hq_adRFUoFQ2y0Cj7GuObWS4q6zU-kHG+Ed9Wg@mail.gmail.com>
Download mbox | patch
Permalink /patch/13179/
State Accepted
Delegated to: Pierre-Yves David
Headers show

Comments

Martin von Zweigbergk - Feb. 14, 2016, 6:26 a.m.
# HG changeset patch
# User Martin von Zweigbergk <martinvonz@google.com>
# Date 1454736344 28800
#      Fri Feb 05 21:25:44 2016 -0800
# Node ID 8cb4bbe8ecb789bb8edcfdc69f5811418b188dd2
# Parent  420968ffb55af1f9182f86da25793920c934c208
match: override 'visitdir' in subdirmatcher

The manifest.manifest class has a _treeinmem member than one can
manually set to True to test that the treemanifest class works as a
drop-in replacement for manifestdict (which is mostly a requirement
for treemanifest repos to work). However, it doesn't quite work at the
moment. These tests fail:

test-largefiles-misc.t
test-rebase-newancestor.t
test-subrepo.t
test-subrepo-deep-nested-change.t
test-subrepo-recursion.t

All but test-rebase-newancestor.t fail because they trigger calls to
subdirmatcher.visitdir(), which tries to access a _excluderoots field
that does not exist on the subdirmatcher. Let's fix that by overriding
visitdir() in a similar way to how matchfn is overridden, i.e. by
prepending the directory before calling the superclass method.
Pierre-Yves David - Feb. 14, 2016, 4:50 p.m.
On 02/14/2016 06:26 AM, Martin von Zweigbergk wrote:
> # HG changeset patch
> # User Martin von Zweigbergk <martinvonz@google.com>
> # Date 1454736344 28800
> #      Fri Feb 05 21:25:44 2016 -0800
> # Node ID 8cb4bbe8ecb789bb8edcfdc69f5811418b188dd2
> # Parent  420968ffb55af1f9182f86da25793920c934c208
> match: override 'visitdir' in subdirmatcher

Thanks for adding the comment.

Pushed to the clowncopter.

Patch

diff -r 420968ffb55a -r 8cb4bbe8ecb7 mercurial/match.py
--- a/mercurial/match.py        Mon Feb 08 14:17:11 2016 -0800
+++ b/mercurial/match.py        Fri Feb 05 21:25:44 2016 -0800
@@ -381,7 +381,16 @@ 
             self._always = any(f == path for f in matcher._files)

         self._anypats = matcher._anypats
+        # Some information is lost in the superclass's constructor, so we
+        # can not accurately create the matching function for the subdirectory
+        # from the inputs. Instead, we override matchfn() and visitdir() to
+        # call the original matcher with the subdirectory path prepended.
         self.matchfn = lambda fn: matcher.matchfn(self._path + "/" + fn)
+        def visitdir(dir):
+            if dir == '.':
+                return matcher.visitdir(self._path)
+            return matcher.visitdir(self._path + "/" + dir)
+        self.visitdir = visitdir
         self._fileroots = set(self._files)

     def abs(self, f):