Quellcode durchsuchen

Cope with submodules in build_index_from_tree.

Fixes #477
Jelmer Vernooij vor 8 Jahren
Ursprung
Commit
95112015b2
3 geänderte Dateien mit 52 neuen und 4 gelöschten Zeilen
  1. 3 0
      NEWS
  2. 7 4
      dulwich/index.py
  3. 42 0
      dulwich/tests/test_index.py

+ 3 - 0
NEWS

@@ -39,6 +39,9 @@
   * Fix unquoting of credentials before passing to urllib2.
     (#475, Volodymyr Holovko)
 
+  * Cope with submodules in `build_index_from_tree`.
+    (#477, Jelmer Vernooij)
+
 0.16.1	2016-12-25
 
  BUG FIXES

+ 7 - 4
dulwich/index.py

@@ -499,12 +499,15 @@ def build_index_from_tree(root_path, index_path, object_store, tree_id,
             os.makedirs(os.path.dirname(full_path))
 
         # FIXME: Merge new index into working tree
-        obj = object_store[entry.sha]
-        build_file_from_blob(obj, entry.mode, full_path,
-            honor_filemode=honor_filemode)
+        if S_ISGITLINK(entry.mode):
+            os.mkdir(full_path)
+        else:
+            obj = object_store[entry.sha]
+            build_file_from_blob(obj, entry.mode, full_path,
+                honor_filemode=honor_filemode)
         # Add file to index
         st = os.lstat(full_path)
-        if not honor_filemode:
+        if not honor_filemode or S_ISGITLINK(entry.mode):
             st = st.__class__((entry.mode, ) + st[1:])
         index[entry.path] = index_entry_from_stat(st, entry.sha, 0)
 

+ 42 - 0
dulwich/tests/test_index.py

@@ -53,7 +53,9 @@ from dulwich.object_store import (
     )
 from dulwich.objects import (
     Blob,
+    Commit,
     Tree,
+    S_IFGITLINK,
     )
 from dulwich.repo import Repo
 from dulwich.tests import (
@@ -429,6 +431,46 @@ class BuildIndexTests(TestCase):
             utf8_path = os.path.join(repo_dir_bytes, utf8_name)
             self.assertTrue(os.path.exists(utf8_path))
 
+    def test_git_submodule(self):
+        repo_dir = tempfile.mkdtemp()
+        self.addCleanup(shutil.rmtree, repo_dir)
+        with Repo.init(repo_dir) as repo:
+            filea = Blob.from_string(b'file alalala')
+
+            subtree = Tree()
+            subtree[b'a'] = (stat.S_IFREG | 0o644, filea.id)
+
+            c = Commit()
+            c.tree = subtree.id
+            c.committer = c.author = b'Somebody <somebody@example.com>'
+            c.commit_time = c.author_time = 42342
+            c.commit_timezone = c.author_timezone = 0
+            c.parents = []
+            c.message = b'Subcommit'
+
+            tree = Tree()
+            tree[b'c'] = (S_IFGITLINK, c.id)
+
+            repo.object_store.add_objects(
+                [(o, None) for o in [tree]])
+
+            build_index_from_tree(repo.path, repo.index_path(),
+                    repo.object_store, tree.id)
+
+            # Verify index entries
+            index = repo.open_index()
+            self.assertEqual(len(index), 1)
+
+            # filea
+            apath = os.path.join(repo.path, 'c/a')
+            self.assertFalse(os.path.exists(apath))
+
+            # dir c
+            cpath = os.path.join(repo.path, 'c')
+            self.assertTrue(os.path.isdir(cpath))
+            self.assertEqual(index[b'c'][4], S_IFGITLINK)  # mode
+            self.assertEqual(index[b'c'][8], c.id)  # sha
+
 
 class GetUnstagedChangesTests(TestCase):