Sfoglia il codice sorgente

Cope with existing submodules during pull. Fixes #505.

Jelmer Vernooij 8 anni fa
parent
commit
fb60cacf55
3 ha cambiato i file con 56 aggiunte e 2 eliminazioni
  1. 5 0
      NEWS
  2. 10 2
      dulwich/index.py
  3. 41 0
      dulwich/tests/test_index.py

+ 5 - 0
NEWS

@@ -4,6 +4,11 @@
 
  * Add basic 'dulwich pull' command. (Jelmer Vernooij)
 
+ BUG FIXES
+
+ * Cope with existing submodules during pull.
+   (Jelmer Vernooij, #505)
+
 0.17.0	2017-03-01
 
  TEST FIXES

+ 10 - 2
dulwich/index.py

@@ -508,10 +508,12 @@ def build_index_from_tree(root_path, index_path, object_store, tree_id,
         if not os.path.exists(os.path.dirname(full_path)):
             os.makedirs(os.path.dirname(full_path))
 
-        # FIXME: Merge new index into working tree
+        # TODO(jelmer): Merge new index into working tree
         if S_ISGITLINK(entry.mode):
-            os.mkdir(full_path)
+            if not os.path.isdir(full_path):
+                os.mkdir(full_path)
             st = os.lstat(full_path)
+            # TODO(jelmer): record and return submodule paths
         else:
             obj = object_store[entry.sha]
             st = build_file_from_blob(obj, entry.mode, full_path,
@@ -560,6 +562,7 @@ def get_unstaged_changes(index, root_path):
 
     for tree_path, entry in index.iteritems():
         full_path = _tree_to_fs_path(root_path, tree_path)
+        # TODO(jelmer): handle S_ISGITLINK(entry.mode) here
         try:
             blob = blob_from_path_and_stat(full_path, os.lstat(full_path))
         except OSError as e:
@@ -568,6 +571,11 @@ def get_unstaged_changes(index, root_path):
             # The file was removed, so we assume that counts as
             # different from whatever file used to exist.
             yield tree_path
+        except IOError as e:
+            if e.errno != errno.EISDIR:
+                raise
+            # The file was changed to a directory, so consider it removed.
+            yield tree_path
         else:
             if blob.id != entry.sha:
                 yield tree_path

+ 41 - 0
dulwich/tests/test_index.py

@@ -512,6 +512,47 @@ class BuildIndexTests(TestCase):
             self.assertEqual(index[b'c'][4], S_IFGITLINK)  # mode
             self.assertEqual(index[b'c'][8], c.id)  # sha
 
+    def test_git_submodule_exists(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)
+
+            os.mkdir(os.path.join(repo_dir, 'c'))
+            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):