Browse Source

Properly support submodules in ``porcelain.status``. Fixes #517

Jelmer Vernooij 7 years ago
parent
commit
e174472fe9
2 changed files with 16 additions and 3 deletions
  1. 3 0
      NEWS
  2. 13 3
      dulwich/index.py

+ 3 - 0
NEWS

@@ -14,6 +14,9 @@
    add from current working directory rather than repository root.
    (Jelmer Vernooij, #521)
 
+  * Properly deal with submodules in 'porcelain.status'.
+   (Jelmer Vernooij, #517)
+
  IMPROVEMENTS
 
   * Add basic support for reading ignore files in ``dulwich.ignore``.

+ 13 - 3
dulwich/index.py

@@ -579,7 +579,6 @@ 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:
@@ -591,8 +590,19 @@ def get_unstaged_changes(index, root_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
+            # This is actually a directory
+            if os.path.exists(os.path.join(tree_path, '.git')):
+                # Submodule
+                from dulwich.errors import NotGitRepository
+                from dulwich.repo import Repo
+                try:
+                    if entry.sha != Repo(tree_path).head():
+                        yield tree_path
+                except NotGitRepository:
+                    yield tree_path
+            else:
+                # The file was changed to a directory, so consider it removed.
+                yield tree_path
         else:
             if blob.id != entry.sha:
                 yield tree_path