← Back to team overview

dulwich-users team mailing list archive

[PATCH 17/34] walk: Add option for rename detection.

 

From: Dave Borowitz <dborowitz@xxxxxxxxxx>

Change-Id: I639a30a9ff602ffb029b8feff9e841a1fdb62cfe
---
 dulwich/tests/test_walk.py |   18 ++++++++++++++++++
 dulwich/walk.py            |   27 +++++++++++++++++----------
 2 files changed, 35 insertions(+), 10 deletions(-)

diff --git a/dulwich/tests/test_walk.py b/dulwich/tests/test_walk.py
index fcb2a3c..36f0dbc 100644
--- a/dulwich/tests/test_walk.py
+++ b/dulwich/tests/test_walk.py
@@ -21,7 +21,9 @@
 from dulwich.diff_tree import (
     CHANGE_ADD,
     CHANGE_MODIFY,
+    CHANGE_RENAME,
     TreeChange,
+    RenameDetector,
     )
 from dulwich.object_store import (
     MemoryObjectStore,
@@ -221,3 +223,19 @@ class WalkerTest(TestCase):
                  4: [('a', blob_a1)]})  # Non-conflicting
         self.assertWalkYields([m3, y2, x1], [m3.id], paths=['a'])
         self.assertWalkYields([y2, x1], [m4.id], paths=['a'])
+
+    def test_changes_with_renames(self):
+        blob = make_object(Blob, data='blob')
+        c1, c2 = self.make_linear_commits(
+          2, trees={1: [('a', blob)], 2: [('b', blob)]})
+        entry_a = ('a', F, blob.id)
+        entry_b = ('b', F, blob.id)
+        changes_without_renames = [TreeChange.delete(entry_a),
+                                   TreeChange.add(entry_b)]
+        changes_with_renames = [TreeChange(CHANGE_RENAME, entry_a, entry_b)]
+        self.assertWalkYields(
+          [TestWalkEntry(c2, changes_without_renames)], [c2.id], max_entries=1)
+        detector = RenameDetector(self.store)
+        self.assertWalkYields(
+          [TestWalkEntry(c2, changes_with_renames)], [c2.id], max_entries=1,
+          rename_detector=detector)
diff --git a/dulwich/walk.py b/dulwich/walk.py
index a9d0e9c..5d2a573 100644
--- a/dulwich/walk.py
+++ b/dulwich/walk.py
@@ -33,10 +33,11 @@ ORDER_DATE = 'date'
 class WalkEntry(object):
     """Object encapsulating a single result from a walk."""
 
-    def __init__(self, store, commit):
+    def __init__(self, store, commit, rename_detector):
         self.commit = commit
         self._store = store
         self._changes = None
+        self._rename_detector = rename_detector
 
     def changes(self):
         """Get the tree changes for this entry.
@@ -49,15 +50,17 @@ class WalkEntry(object):
         if self._changes is None:
             commit = self.commit
             if not commit.parents:
-                changes = list(tree_changes(self._store, None, commit.tree))
+                changes_func = tree_changes
+                parent = None
             elif len(commit.parents) == 1:
-                ptree = self._store[commit.parents[0]].tree
-                changes = list(tree_changes(self._store, ptree, commit.tree))
+                changes_func = tree_changes
+                parent = self._store[commit.parents[0]].tree
             else:
-                ptrees = [self._store[p].tree for p in commit.parents]
-                changes = list(tree_changes_for_merge(self._store, ptrees,
-                                                      commit.tree))
-            self._changes = changes
+                changes_func = tree_changes_for_merge
+                parent = [self._store[p].tree for p in commit.parents]
+            self._changes = list(changes_func(
+              self._store, parent, commit.tree,
+              rename_detector=self._rename_detector))
         return self._changes
 
     def __repr__(self):
@@ -73,7 +76,8 @@ class Walker(object):
     """
 
     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):
         """Constructor.
 
         :param store: ObjectStore instance for looking up objects.
@@ -88,6 +92,8 @@ class Walker(object):
         :param max_entries: The maximum number of entries to yield, or None for
             no limit.
         :param paths: Iterable of file or subtree paths to show entries for.
+        :param rename_detector: diff.RenameDetector object for detecting
+            renames.
         """
         self._store = store
 
@@ -97,6 +103,7 @@ class Walker(object):
         self._reverse = reverse
         self._max_entries = max_entries
         self._num_entries = 0
+        self._rename_detector = rename_detector
 
         exclude = exclude or []
         self._excluded = set(exclude)
@@ -156,7 +163,7 @@ 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).
         """
-        entry = WalkEntry(self._store, commit)
+        entry = WalkEntry(self._store, commit, self._rename_detector)
         if self._paths is None:
             return entry
 
-- 
1.7.3.1



References