Quellcode durchsuchen

walk: Add options to limit by commit time.

Change-Id: I7c66997553361afdbd5ac9b2a6d5909559fedc2b
Dave Borowitz vor 13 Jahren
Ursprung
Commit
54aabb5405
2 geänderte Dateien mit 53 neuen und 3 gelöschten Zeilen
  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