← Back to team overview

dulwich-users team mailing list archive

[PATCH 19/34] walk: Raise MissingCommitError instead of KeyError.

 

From: Dave Borowitz <dborowitz@xxxxxxxxxx>

Change-Id: I675597821a9eae6055240b76893c53756fd11215
---
 dulwich/errors.py          |    1 +
 dulwich/tests/test_walk.py |   22 ++++++++++++++++++++++
 dulwich/walk.py            |   20 +++++++++++++-------
 3 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/dulwich/errors.py b/dulwich/errors.py
index bb7ce9b..8783fc7 100644
--- a/dulwich/errors.py
+++ b/dulwich/errors.py
@@ -83,6 +83,7 @@ class MissingCommitError(Exception):
     """Indicates that a commit was not found in the repository"""
 
     def __init__(self, sha, *args, **kwargs):
+        self.sha = sha
         Exception.__init__(self, "%s is not in the revision store" % sha)
 
 
diff --git a/dulwich/tests/test_walk.py b/dulwich/tests/test_walk.py
index 2db99b3..525318f 100644
--- a/dulwich/tests/test_walk.py
+++ b/dulwich/tests/test_walk.py
@@ -26,6 +26,9 @@ from dulwich.diff_tree import (
     TreeChange,
     RenameDetector,
     )
+from dulwich.errors import (
+    MissingCommitError,
+    )
 from dulwich.object_store import (
     MemoryObjectStore,
     )
@@ -98,6 +101,25 @@ class WalkerTest(TestCase):
         self.assertWalkYields([c3, c2], [c3.id, c1.id], exclude=[c1.id])
         self.assertWalkYields([c3], [c3.id, c1.id], exclude=[c2.id])
 
+    def assertNextFails(self, walk_iter, missing_sha):
+        try:
+            next(walk_iter)
+            self.fail('Failed to error on missing sha %s' % missing_sha)
+        except MissingCommitError, e:
+            self.assertEqual(missing_sha, e.sha)
+
+    def test_missing(self):
+        c1, c2, c3 = self.make_linear_commits(3)
+        self.assertWalkYields([c3, c2, c1], [c3.id])
+
+        del self.store[c1.id]
+        self.assertWalkYields([c3], [c3.id], max_entries=1)
+        walk_iter = iter(Walker(self.store, [c3.id]))
+        self.assertEqual(TestWalkEntry(c3, None), next(walk_iter))
+        self.assertNextFails(walk_iter, c1.id)
+        self.assertNextFails(iter(Walker(self.store, [c2.id])), c1.id)
+        self.assertRaises(MissingCommitError, Walker, self.store, c1.id)
+
     def test_branch(self):
         c1, x2, x3, y4 = self.make_commits([[1], [2, 1], [3, 2], [4, 1]])
         self.assertWalkYields([x3, x2, c1], [x3.id])
diff --git a/dulwich/walk.py b/dulwich/walk.py
index 9bc16a4..9352bc9 100644
--- a/dulwich/walk.py
+++ b/dulwich/walk.py
@@ -28,6 +28,9 @@ from dulwich.diff_tree import (
     tree_changes_for_merge,
     RenameDetector,
     )
+from dulwich.errors import (
+    MissingCommitError,
+    )
 
 ORDER_DATE = 'date'
 
@@ -120,13 +123,16 @@ class Walker(object):
         self._follow = follow
 
         for commit_id in itertools.chain(include, exclude):
-            self._push(store[commit_id])
-
-    def _push(self, commit):
-        sha = commit.id
-        if sha not in self._pq_set and sha not in self._done:
+            self._push(commit_id)
+
+    def _push(self, commit_id):
+        try:
+            commit = self._store[commit_id]
+        except KeyError:
+            raise MissingCommitError(commit_id)
+        if commit_id not in self._pq_set and commit_id not in self._done:
             heapq.heappush(self._pq, (-commit.commit_time, commit))
-            self._pq_set.add(sha)
+            self._pq_set.add(commit_id)
 
     def _pop(self):
         while self._pq:
@@ -142,7 +148,7 @@ class Walker(object):
 
             self._done.add(commit.id)
             for parent_id in commit.parents:
-                self._push(self._store[parent_id])
+                self._push(parent_id)
 
             if not is_excluded:
                 return commit
-- 
1.7.3.1



References