context: add walk method
authorMatt Mackall <mpm@selenic.com>
Fri, 27 Jun 2008 19:25:48 -0500
changeset 6764 8db64464d136
parent 6763 403682f1c678
child 6765 be142cb994ff
context: add walk method
mercurial/commands.py
mercurial/context.py
mercurial/localrepo.py
--- a/mercurial/commands.py	Fri Jun 27 18:44:43 2008 -0500
+++ b/mercurial/commands.py	Fri Jun 27 19:25:48 2008 -0500
@@ -110,8 +110,8 @@
     ctx = repo[opts['rev']]
 
     m = cmdutil.match(repo, pats, opts)
-    for abs in repo.walk(m, ctx.node()):
-        fctx = ctx.filectx(abs)
+    for abs in ctx.walk(m):
+        fctx = ctx[abs]
         if not opts['text'] and util.binary(fctx.data()):
             ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
             continue
@@ -485,9 +485,9 @@
     ctx = repo[opts['rev']]
     err = 1
     m = cmdutil.match(repo, (file1,) + pats, opts)
-    for abs in repo.walk(m, ctx.node()):
+    for abs in ctx.walk(m):
         fp = cmdutil.make_file(repo, opts['output'], ctx.node(), pathname=abs)
-        data = ctx.filectx(abs).data()
+        data = ctx[abs].data()
         if opts.get('decode'):
             data = repo.wwritedata(abs, data)
         fp.write(data)
@@ -907,8 +907,8 @@
 
     ctx = repo[opts.get('rev')]
     m = cmdutil.match(repo, (file1,) + pats, opts)
-    for abs in repo.walk(m, ctx.node()):
-        fctx = ctx.filectx(abs)
+    for abs in ctx.walk(m):
+        fctx = ctx[abs]
         o = fctx.filelog().renamed(fctx.filenode())
         rel = m.rel(abs)
         if o:
@@ -1693,17 +1693,13 @@
     that contain white space as multiple filenames.
     """
     end = opts['print0'] and '\0' or '\n'
-    rev = opts['rev']
-    if rev:
-        node = repo.lookup(rev)
-    else:
-        node = None
+    rev = opts.get('rev') or None
 
     ret = 1
     m = cmdutil.match(repo, pats, opts, default='relglob')
     m.bad = lambda x,y: False
-    for abs in repo.walk(m, node):
-        if not node and abs not in repo.dirstate:
+    for abs in repo[rev].walk(m):
+        if not rev and abs not in repo.dirstate:
             continue
         if opts['fullpath']:
             ui.write(os.path.join(repo.root, abs), end)
@@ -2350,7 +2346,7 @@
 
         m = cmdutil.match(repo, pats, opts)
         m.bad = badfn
-        for abs in repo.walk(m, node=node):
+        for abs in repo[node].walk(m):
             if abs not in names:
                 names[abs] = m.rel(abs), m.exact(abs)
 
--- a/mercurial/context.py	Fri Jun 27 18:44:43 2008 -0500
+++ b/mercurial/context.py	Fri Jun 27 19:25:48 2008 -0500
@@ -146,6 +146,23 @@
         n = self._repo.changelog.ancestor(self._node, c2._node)
         return changectx(self._repo, n)
 
+    def walk(self, match):
+        fdict = dict.fromkeys(match.files())
+        # for dirstate.walk, files=['.'] means "walk the whole tree".
+        # follow that here, too
+        fdict.pop('.', None)
+        for fn in self:
+            for ffn in fdict:
+                # match if the file is the exact name or a directory
+                if ffn == fn or fn.startswith("%s/" % ffn):
+                    del fdict[ffn]
+                    break
+            if match(fn):
+                yield fn
+        for fn in util.sort(fdict):
+            if match.bad(fn, 'No such file in rev ' + str(self)) and match(fn):
+                yield fn
+
 class filectx(object):
     """A filecontext object makes access to data related to a particular
        filerevision convenient."""
@@ -576,6 +593,10 @@
         """return the ancestor context of self and c2"""
         return self._parents[0].ancestor(c2) # punt on two parents for now
 
+    def walk(self, match):
+        for src, fn, st in self._repo.dirstate.walk(match, True, False):
+            yield fn
+
 class workingfilectx(filectx):
     """A workingfilectx object makes access to data related to a particular
        file in the working directory convenient."""
--- a/mercurial/localrepo.py	Fri Jun 27 18:44:43 2008 -0500
+++ b/mercurial/localrepo.py	Fri Jun 27 19:25:48 2008 -0500
@@ -941,27 +941,7 @@
         changeset, finding all files matched by the match
         function
         '''
-
-        if node:
-            fdict = dict.fromkeys(match.files())
-            # for dirstate.walk, files=['.'] means "walk the whole tree".
-            # follow that here, too
-            fdict.pop('.', None)
-            for fn in self[node]:
-                for ffn in fdict:
-                    # match if the file is the exact name or a directory
-                    if ffn == fn or fn.startswith("%s/" % ffn):
-                        del fdict[ffn]
-                        break
-                if match(fn):
-                    yield fn
-            for fn in util.sort(fdict):
-                if match.bad(fn, 'No such file in rev ' + short(node)) \
-                        and match(fn):
-                    yield fn
-        else:
-            for src, fn, st in self.dirstate.walk(match, True, False):
-                yield fn
+        return self[node].walk(match)
 
     def status(self, node1=None, node2=None, match=None,
                ignored=False, clean=False, unknown=False):