← Back to team overview

dulwich-users team mailing list archive

[PATCH 21/34] walk: Add options to limit by commit time.

 

From: Dave Borowitz <dborowitz@xxxxxxxxxx>

Change-Id: I7c66997553361afdbd5ac9b2a6d5909559fedc2b
---
 dulwich/tests/test_walk.py |   39 +++++++++++++++++++++++++++++++++++++++
 dulwich/walk.py            |   17 ++++++++++++++---
 2 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/dulwich/tests/test_walk.py b/dulwich/tests/test_walk.py
index 525318f..ca2e2fc 100644
--- a/dulwich/tests/test_walk.py
+++ b/dulwich/tests/test_walk.py
@@ -295,3 +295,42 @@ class WalkerTest(TestCase):
            TestWalkEntry(c5, [TreeChange(CHANGE_RENAME, e('b'), e('a'))]),
            TestWalkEntry(c4, [TreeChange.add(e('b'))])],
           [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)
diff --git a/dulwich/walk.py b/dulwich/walk.py
index 9352bc9..502951a 100644
--- a/dulwich/walk.py
+++ b/dulwich/walk.py
@@ -82,7 +82,7 @@ class Walker(object):
 
     def __init__(self, store, include, exclude=None, order=ORDER_DATE,
                  reverse=False, max_entries=None, paths=None,
-                 rename_detector=None, follow=False):
+                 rename_detector=None, follow=False, since=None, until=None):
         """Constructor.
 
         :param store: ObjectStore instance for looking up objects.
@@ -101,6 +101,8 @@ class Walker(object):
             renames.
         :param follow: If True, follow path across renames/copies. Forces a
             default rename_detector.
+        :param since: Timestamp to list commits after.
+        :param until: Timestamp to list commits before.
         """
         self._store = store
 
@@ -122,6 +124,9 @@ class Walker(object):
         self._paths = paths and set(paths) or None
         self._follow = follow
 
+        self._since = since
+        self._until = until
+
         for commit_id in itertools.chain(include, exclude):
             self._push(commit_id)
 
@@ -147,8 +152,9 @@ class Walker(object):
                 self._excluded.update(commit.parents)
 
             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:
                 return commit
@@ -184,6 +190,11 @@ class Walker(object):
         :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).
         """
+        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)
         if self._paths is None:
             return entry
-- 
1.7.3.1



References