From: Dave Borowitz <dborow...@google.com> Change-Id: Ic600c657e50712b464c5b16604850491e15cf845 --- dulwich/tests/test_walk.py | 14 ++++++++++++++ dulwich/walk.py | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/dulwich/tests/test_walk.py b/dulwich/tests/test_walk.py index 67d07f7..90e7553 100644 --- a/dulwich/tests/test_walk.py +++ b/dulwich/tests/test_walk.py @@ -395,3 +395,17 @@ class WalkerTest(TestCase): times=[2, 1, 3, 4, 5]) self.assertWalkYields([c5, c4, c3, c1, c2], [c5.id]) self.assertWalkYields([c5, c4, c3, c2, c1], [c5.id], order=ORDER_TOPO) + + def test_out_of_order_with_exclude(self): + # Create the following graph: + # c1-------x2---m6 + # \ / + # \-y3--y4-/--y5 + # Due to skew, y5 is the oldest commit. + c1, x2, y3, y4, y5, m6 = cs = self.make_commits( + [[1], [2, 1], [3, 1], [4, 3], [5, 4], [6, 2, 4]], + times=[2, 3, 4, 5, 1, 6]) + self.assertWalkYields([m6, y4, y3, x2, c1], [m6.id]) + # Ensure that c1..y4 get excluded even though they're popped from the + # priority queue long before y5. + self.assertWalkYields([m6, x2], [m6.id], exclude=[y5.id]) diff --git a/dulwich/walk.py b/dulwich/walk.py index 6bea788..e4f2b75 100644 --- a/dulwich/walk.py +++ b/dulwich/walk.py @@ -29,6 +29,9 @@ import heapq import itertools import os +from dulwich._compat import ( + all, + ) from dulwich.diff_tree import ( RENAME_CHANGE_TYPES, tree_changes, @@ -148,6 +151,18 @@ class _CommitTimeQueue(object): is_excluded = sha in self._excluded if is_excluded: self._exclude_parents(commit) + if self._pq and all(c.id in self._excluded + for _, c in self._pq): + _, n = self._pq[0] + if n.commit_time >= self._last.commit_time: + # If the next commit is newer than the last one, we need + # to keep walking in case its parents (which we may not + # have seen yet) are excluded. This gives the excluded + # set a chance to "catch up" while the commit is still + # in the Walker's output queue. + reset_extra_commits = True + else: + reset_extra_commits = False if (self._min_time is not None and commit.commit_time < self._min_time): @@ -262,6 +277,8 @@ class Walker(object): return False if self.until is not None and commit.commit_time > self.until: return False + if commit.id in self.excluded: + return False if self.paths is None: return True -- 1.7.3.1 _______________________________________________ Mailing list: https://launchpad.net/~dulwich-users Post to : dulwich-users@lists.launchpad.net Unsubscribe : https://launchpad.net/~dulwich-users More help : https://help.launchpad.net/ListHelp