Browse Source

walk: Add options to limit by commit time.

Change-Id: I7c66997553361afdbd5ac9b2a6d5909559fedc2b
Dave Borowitz 14 years ago
parent
commit
d7c175d40f
2 changed files with 53 additions and 3 deletions
  1. 39 0
      dulwich/tests/test_walk.py
  2. 14 3
      dulwich/walk.py

+ 39 - 0
dulwich/tests/test_walk.py

@@ -295,3 +295,42 @@ class WalkerTest(TestCase):
            TestWalkEntry(c5, [TreeChange(CHANGE_RENAME, e('b'), e('a'))]),
            TestWalkEntry(c5, [TreeChange(CHANGE_RENAME, e('b'), e('a'))]),
            TestWalkEntry(c4, [TreeChange.add(e('b'))])],
            TestWalkEntry(c4, [TreeChange.add(e('b'))])],
           [c6.id], paths=['c'], follow=True)
           [c6.id], paths=['c'], follow=True)
+
+    def test_since(self):
+        c1, c2, c3 = self.make_linear_commits(3)
+        self.assertWalkYields([c3, c2, c1], [c3.id], since=-1)
+        self.assertWalkYields([c3, c2, c1], [c3.id], since=0)
+        self.assertWalkYields([c3, c2], [c3.id], since=1)
+        self.assertWalkYields([c3, c2], [c3.id], since=99)
+        self.assertWalkYields([c3, c2], [c3.id], since=100)
+        self.assertWalkYields([c3], [c3.id], since=101)
+        self.assertWalkYields([c3], [c3.id], since=199)
+        self.assertWalkYields([c3], [c3.id], since=200)
+        self.assertWalkYields([], [c3.id], since=201)
+        self.assertWalkYields([], [c3.id], since=300)
+
+    def test_until(self):
+        c1, c2, c3 = self.make_linear_commits(3)
+        self.assertWalkYields([], [c3.id], until=-1)
+        self.assertWalkYields([c1], [c3.id], until=0)
+        self.assertWalkYields([c1], [c3.id], until=1)
+        self.assertWalkYields([c1], [c3.id], until=99)
+        self.assertWalkYields([c2, c1], [c3.id], until=100)
+        self.assertWalkYields([c2, c1], [c3.id], until=101)
+        self.assertWalkYields([c2, c1], [c3.id], until=199)
+        self.assertWalkYields([c3, c2, c1], [c3.id], until=200)
+        self.assertWalkYields([c3, c2, c1], [c3.id], until=201)
+        self.assertWalkYields([c3, c2, c1], [c3.id], until=300)
+
+    def test_since_until(self):
+        c1, c2, c3 = self.make_linear_commits(3)
+        self.assertWalkYields([], [c3.id], since=100, until=99)
+        self.assertWalkYields([c3, c2, c1], [c3.id], since=-1, until=201)
+        self.assertWalkYields([c2], [c3.id], since=100, until=100)
+        self.assertWalkYields([c2], [c3.id], since=50, until=150)
+
+    def test_since_prune(self):
+        c1, c2, c3 = self.make_linear_commits(3)
+        del self.store[c1.id]
+        self.assertRaises(MissingCommitError, list, Walker(self.store, [c3.id]))
+        self.assertWalkYields([c3], [c3.id], since=101)

+ 14 - 3
dulwich/walk.py

@@ -82,7 +82,7 @@ class Walker(object):
 
 
     def __init__(self, store, include, exclude=None, order=ORDER_DATE,
     def __init__(self, store, include, exclude=None, order=ORDER_DATE,
                  reverse=False, max_entries=None, paths=None,
                  reverse=False, max_entries=None, paths=None,
-                 rename_detector=None, follow=False):
+                 rename_detector=None, follow=False, since=None, until=None):
         """Constructor.
         """Constructor.
 
 
         :param store: ObjectStore instance for looking up objects.
         :param store: ObjectStore instance for looking up objects.
@@ -101,6 +101,8 @@ class Walker(object):
             renames.
             renames.
         :param follow: If True, follow path across renames/copies. Forces a
         :param follow: If True, follow path across renames/copies. Forces a
             default rename_detector.
             default rename_detector.
+        :param since: Timestamp to list commits after.
+        :param until: Timestamp to list commits before.
         """
         """
         self._store = store
         self._store = store
 
 
@@ -122,6 +124,9 @@ class Walker(object):
         self._paths = paths and set(paths) or None
         self._paths = paths and set(paths) or None
         self._follow = follow
         self._follow = follow
 
 
+        self._since = since
+        self._until = until
+
         for commit_id in itertools.chain(include, exclude):
         for commit_id in itertools.chain(include, exclude):
             self._push(commit_id)
             self._push(commit_id)
 
 
@@ -147,8 +152,9 @@ class Walker(object):
                 self._excluded.update(commit.parents)
                 self._excluded.update(commit.parents)
 
 
             self._done.add(commit.id)
             self._done.add(commit.id)
-            for parent_id in commit.parents:
-                self._push(parent_id)
+            if self._since is None or commit.commit_time >= self._since:
+                for parent_id in commit.parents:
+                    self._push(parent_id)
 
 
             if not is_excluded:
             if not is_excluded:
                 return commit
                 return commit
@@ -184,6 +190,11 @@ class Walker(object):
         :return: A WalkEntry object, or None if no entry should be returned for
         :return: A WalkEntry object, or None if no entry should be returned for
             this commit (e.g. if it doesn't match any requested paths).
             this commit (e.g. if it doesn't match any requested paths).
         """
         """
+        if self._since is not None and commit.commit_time < self._since:
+            return None
+        if self._until is not None and commit.commit_time > self._until:
+            return None
+
         entry = WalkEntry(self._store, commit, self._rename_detector)
         entry = WalkEntry(self._store, commit, self._rename_detector)
         if self._paths is None:
         if self._paths is None:
             return entry
             return entry