When a nested submodule has untracked files, it would be reported as
"modified submodule" in the superproject, because submodules are not
parsed correctly in is_submodule_modified as they are bucketed into
the modified pile as "they are not an untracked file".

Signed-off-by: Stefan Beller <sbel...@google.com>
---
 submodule.c                 | 23 +++++++++++++++++++++--
 t/t3600-rm.sh               |  2 +-
 t/t7506-status-submodule.sh |  2 +-
 3 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/submodule.c b/submodule.c
index fa21c7bb72..730cc9513a 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1078,8 +1078,27 @@ unsigned is_submodule_modified(const char *path, int 
ignore_untracked)
                /* regular untracked files */
                if (buf.buf[0] == '?')
                        dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED;
-               else
-                       dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
+
+               if (buf.buf[0] == 'u' ||
+                   buf.buf[0] == '1' ||
+                   buf.buf[0] == '2') {
+                       /*
+                        * T XY SSSS:
+                        * T = line type, XY = status, SSSS = submodule state
+                        */
+                       if (buf.len < 1 + 1 + 2 + 1 + 4)
+                               die("BUG: invalid status --porcelain=2 line %s",
+                                   buf.buf);
+
+                       /* regular unmerged and renamed files */
+                       if (buf.buf[5] == 'S' && buf.buf[8] == 'U')
+                               /* nested untracked file */
+                               dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED;
+
+                       if (memcmp(buf.buf + 5, "S..U", 4))
+                               /* other change */
+                               dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
+               }
 
                if ((dirty_submodule & DIRTY_SUBMODULE_MODIFIED) &&
                    ((dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) ||
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index a6e5c5bd56..b58793448b 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -659,7 +659,7 @@ test_expect_success 'rm of a populated nested submodule 
with nested untracked fi
        test -d submod &&
        test -f submod/.git &&
        git status -s -uno --ignore-submodules=none >actual &&
-       test_cmp expect.modified_inside actual &&
+       test_cmp expect.modified_untracked actual &&
        git rm -f submod &&
        test ! -d submod &&
        git status -s -uno --ignore-submodules=none >actual &&
diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh
index 6d3acb4a5a..ab822c79e6 100755
--- a/t/t7506-status-submodule.sh
+++ b/t/t7506-status-submodule.sh
@@ -340,7 +340,7 @@ test_expect_success 'status with untracked file in nested 
submodule (porcelain)'
 test_expect_success 'status with untracked file in nested submodule (short)' '
        git -C super status --short >output &&
        diff output - <<-\EOF
-        m sub1
+        ? sub1
        EOF
 '
 
-- 
2.12.0.rc1.49.gdeb397943c.dirty

Reply via email to