[PATCH 2 of 2 WIP] [mq]: filteredcl

Idan Kamara idankk86 at gmail.com
Fri Jun 29 12:07:35 CDT 2012


# HG changeset patch
# User Idan Kamara <idankk86 at gmail.com>
# Date 1340987683 -10800
# Node ID e49830e1159a56d865b0529dd4fe0fe67c1bdbde
# Parent  f9c24a3d3a570bc93070490190bd0c87bb4c88e9
[mq]: filteredcl

diff --git a/mercurial/changelog.py b/mercurial/changelog.py
--- a/mercurial/changelog.py
+++ b/mercurial/changelog.py
@@ -254,3 +254,10 @@
         l = [hex(manifest), user, parseddate] + sorted(files) + ["", desc]
         text = "\n".join(l)
         return self.addrevision(text, transaction, len(self), p1, p2)
+
+class filteredchangelog(revlog.filteredrevlog):
+    def __init__(self, *args):
+        revlog.filteredrevlog.__init__(self, *args)
+
+    def __getattr__(self, attr):
+        return getattr(self.rl, attr)
diff --git a/mercurial/hg.py b/mercurial/hg.py
--- a/mercurial/hg.py
+++ b/mercurial/hg.py
@@ -289,7 +289,7 @@
             dircleanup = DirCleanup(dest)
 
         copy = False
-        if srcrepo.cancopy() and islocal(dest) and not srcrepo.revs("secret()"):
+        if srcrepo.cancopy() and islocal(dest) and not srcrepo.revs("secret()") and not srcrepo._filteredrevs:
             copy = not pull and not rev
 
         if copy:
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -119,6 +119,9 @@
         # Maps a property name to its util.filecacheentry
         self._filecache = {}
 
+        self._filteredrevs = set()
+        self._filterednodes = set()
+
     def _applyrequirements(self, requirements):
         self.requirements = requirements
         openerreqs = set(('revlogv1', 'generaldelta'))
@@ -199,8 +202,30 @@
             p = os.environ['HG_PENDING']
             if p.startswith(self.root):
                 c.readpending('00changelog.i.a')
+        if self._filteredrevs:
+            c = changelog.filteredchangelog(c, self._filteredrevs,
+                                            self._filterednodes)
         return c
 
+    def filter(self, revs=[]):
+        if not isinstance(self.changelog, changelog.filteredchangelog):
+            fcl = getattr(self, '_oldchangelog', None)
+            if fcl is None:
+                fcl = changelog.filteredchangelog(self.changelog,
+                                                  self._filteredrevs,
+                                                  self._filterednodes)
+
+            self.changelog, self._oldchangelog = fcl, self.changelog
+        for r in revs:
+            self._filteredrevs.add(r)
+            self._filterednodes.add(self.changelog.node(r))
+
+    def unfilter(self):
+        if not isinstance(self.changelog, changelog.filteredchangelog):
+            return
+
+        self.changelog, self._oldchangelog = self._oldchangelog, self.changelog
+
     @storecache('00manifest.i')
     def manifest(self):
         return manifest.manifest(self.sopener)
@@ -239,7 +264,7 @@
         return len(self.changelog)
 
     def __iter__(self):
-        for i in xrange(len(self)):
+        for i in self.changelog:
             yield i
 
     def revs(self, expr, *args):
@@ -578,6 +603,7 @@
         missing heads, and a generator of nodes that are at least a superset of
         heads missing, this function updates partial to be correct.
         """
+        # XXX check how this interacts with the filtering
         # collect new branch entries
         newbranches = {}
         for c in ctxgen:
diff --git a/tests/test-filteredcl.t b/tests/test-filteredcl.t
new file mode 100644
--- /dev/null
+++ b/tests/test-filteredcl.t
@@ -0,0 +1,65 @@
+  $ cat > $HGTMP/testhidden.py << EOF
+  > def reposetup(ui, repo):
+  >     revs = []
+  >     for line in repo.opener.tryread('hidden').splitlines(True):
+  >         revs.append(int(line.strip()))
+  >     repo.filter(revs)
+  > EOF
+  $ echo '[extensions]' >> $HGRCPATH
+  $ echo "hidden=$HGTMP/testhidden.py" >> $HGRCPATH
+
+  $ hg init 1
+  $ cd 1
+  $ touch .hg/hidden
+
+  $ echo a >> a
+  $ hg ci -qAm.
+  $ echo a >> a
+  $ hg ci -Am.
+  $ echo a >> a
+  $ hg ci -Am.
+  $ hg log --template "{rev} {tags} {desc}\n"
+  2 tip .
+  1  .
+  0  .
+  $ echo 2 >> .hg/hidden
+  $ echo 1 >> .hg/hidden
+  $ hg log --template "{rev} {tags} {desc}\n"
+  0 tip .
+  $ hg init ../2
+  $ cd ../2
+  $ hg inc ../1
+  comparing with ../1
+  changeset:   0:122254ef8a92
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     .
+  
+  $ hg pull ../1
+  pulling from ../1
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  (run 'hg update' to get a working copy)
+  $ hg log --template "{rev} {tags} {desc}\n"
+  0 tip .
+  $ cd ..
+  $ hg clone 1 3
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  updating to branch default
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg log -R 3 --template "{rev} {tags} {desc}\n"
+  0 tip .
+  $ cd 1
+  $ hg push ../2
+  pushing to ../2
+  searching for changes
+  no changes found
+  [1]


More information about the Mercurial-devel mailing list