Patchwork D2490: narrow: consider both local and remote matchers in narrowchangegroup

login
register
mail settings
Submitter phabricator
Date Feb. 28, 2018, 8:57 p.m.
Message ID <differential-rev-PHID-DREV-coqirxa5ompi5eoe4mkf-req@phab.mercurial-scm.org>
Download mbox | patch
Permalink /patch/28491/
State Superseded
Headers show

Comments

phabricator - Feb. 28, 2018, 8:57 p.m.
martinvonz created this revision.
Herald added a reviewer: durin42.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  The existing code that picked one or the other seemed very
  suspicious. This patch makes us intersect the local matcher with the
  matcher from the remote, which seems better. It fixes one test case
  and makes another one that used to crash no longer crash, but instead
  silently succeed with a push that's lossy, so that remains to be
  fixed.
  
  The real reason for doing this now is that I'm going to move
  narrowrepo.narrowmatch() onto localrepo and then it will always be
  defined, which would otherwise break this code.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D2490

AFFECTED FILES
  hgext/narrow/narrowchangegroup.py
  tests/test-narrow-exchange.t

CHANGE DETAILS




To: martinvonz, durin42, #hg-reviewers
Cc: mercurial-devel

Patch

diff --git a/tests/test-narrow-exchange.t b/tests/test-narrow-exchange.t
--- a/tests/test-narrow-exchange.t
+++ b/tests/test-narrow-exchange.t
@@ -137,13 +137,12 @@ 
   $ hg pull ssh://user@dummy/narrow2
   pulling from ssh://user@dummy/narrow2
   searching for changes
-  remote: abort: unable to resolve parent while packing 'data/inside2/f.i' 3 for changeset 5 (?)
   adding changesets
-  remote: abort: unexpected error: unable to resolve parent while packing 'data/inside2/f.i' 3 for changeset 5
-  transaction abort!
-  rollback completed
-  abort: pull failed on remote
-  [255]
+  adding manifests
+  adding file changes
+  added 1 changesets with 0 changes to 0 files
+  new changesets d78a96df731d
+  (run 'hg update' to get a working copy)
 
 Check that the resulting history is valid in the full repo
 
@@ -204,7 +203,7 @@ 
   $ hg push ssh://user@dummy/narrow2
   pushing to ssh://user@dummy/narrow2
   searching for changes
-  remote has heads on branch 'default' that are not known locally: d78a96df731d
-  abort: push creates new remote head 5970befb64ba!
-  (pull and merge or see 'hg help push' for details about pushing new heads)
-  [255]
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 0 changes to 0 files
diff --git a/hgext/narrow/narrowchangegroup.py b/hgext/narrow/narrowchangegroup.py
--- a/hgext/narrow/narrowchangegroup.py
+++ b/hgext/narrow/narrowchangegroup.py
@@ -13,32 +13,38 @@ 
     error,
     extensions,
     manifest,
+    match as matchmod,
     mdiff,
     node,
     revlog,
     util,
 )
 
 def setup():
 
+    def _cgmatcher(cgpacker):
+        localmatcher = getattr(cgpacker._repo, 'narrowmatch', lambda: None)()
+        remotematcher = getattr(cgpacker, '_narrow_matcher', lambda: None)()
+        if localmatcher and remotematcher:
+            return matchmod.intersectmatchers(localmatcher, remotematcher)
+        else:
+            return localmatcher or remotematcher
+
     def prune(orig, self, revlog, missing, commonrevs):
         if isinstance(revlog, manifest.manifestrevlog):
-            matcher = getattr(self._repo, 'narrowmatch',
-                              getattr(self, '_narrow_matcher', None))
-            if (matcher is not None and
-                not matcher().visitdir(revlog._dir[:-1] or '.')):
+            matcher = _cgmatcher(self)
+            if (matcher and
+                not matcher.visitdir(revlog._dir[:-1] or '.')):
                 return []
         return orig(self, revlog, missing, commonrevs)
 
     extensions.wrapfunction(changegroup.cg1packer, 'prune', prune)
 
     def generatefiles(orig, self, changedfiles, linknodes, commonrevs,
                       source):
-        matcher = getattr(self._repo, 'narrowmatch',
-                          getattr(self, '_narrow_matcher', None))
-        if matcher is not None:
-            narrowmatch = matcher()
-            changedfiles = [f for f in changedfiles if narrowmatch(f)]
+        matcher = _cgmatcher(self)
+        if matcher:
+            changedfiles = filter(matcher, changedfiles)
         if getattr(self, 'is_shallow', False):
             # See comment in generate() for why this sadness is a thing.
             mfdicts = self._mfdicts