v9:
* This is a resend of the last two patches, i.e. these two patches apply
  at 5c896f7c3ec (origin/sb/submodule-short-status^^)
* below is a diff of this patch series against origin/sb/submodule-short-status
* better tests, refined documentation, thanks for the review, Jonathan!

Thanks,
Stefan

previous work:
https://public-inbox.org/git/20170328230938.9887-1-sbel...@google.com/

Stefan Beller (2):
  short status: improve reporting for submodule changes
  submodule.c: correctly handle nested submodules in
    is_submodule_modified

 Documentation/git-status.txt |  13 +++++
 submodule.c                  |  21 +++++++-
 t/t3600-rm.sh                |  18 +++++--
 t/t7506-status-submodule.sh  | 117 +++++++++++++++++++++++++++++++++++++++++++
 wt-status.c                  |  17 ++++++-
 5 files changed, 177 insertions(+), 9 deletions(-)

diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt
index 01b457c322..d70abc6afe 100644
--- a/Documentation/git-status.txt
+++ b/Documentation/git-status.txt
@@ -186,7 +186,11 @@ Submodules have more state and instead report
                     recorded in the index
                m    the submodule has modified content
                ?    the submodule has untracked files
+since modified content or untracked files in a submodule cannot be added
+via `git add` in the superproject to prepare a commit.
 
+'m' and '?' are applied recursively. For example if a nested submodule
+in a submodule contains an untracked file, this is reported as '?' as well.
 
 If -b is used the short-format status is preceded by a line
 
diff --git a/submodule.c b/submodule.c
index 730cc9513a..3da65100e3 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1082,20 +1082,18 @@ unsigned is_submodule_modified(const char *path, int 
ignore_untracked)
                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)
+                       /* T = line type, XY = status, SSSS = submodule state */
+                       if (buf.len < strlen("T XY SSSS"))
                                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))
+                       if (buf.buf[0] == 'u' ||
+                           buf.buf[0] == '2' ||
+                           memcmp(buf.buf + 5, "S..U", 4))
                                /* other change */
                                dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
                }
diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh
index ab822c79e6..055c90736e 100755
--- a/t/t7506-status-submodule.sh
+++ b/t/t7506-status-submodule.sh
@@ -17,6 +17,12 @@ test_create_repo_with_commit () {
        )
 }
 
+sanitize_output () {
+       sed -e "s/$_x40/HASH/" -e "s/$_x40/HASH/" output >output2 &&
+       mv output2 output
+}
+
+
 test_expect_success 'setup' '
        test_create_repo_with_commit sub &&
        echo output > .gitignore &&
@@ -311,6 +317,10 @@ test_expect_success 'diff --submodule with merge conflict 
in .gitmodules' '
        test_cmp diff_submodule_actual diff_submodule_expect
 '
 
+# We'll setup different cases for further testing:
+# sub1 will contain a nested submodule,
+# sub2 will have an untracked file
+# sub3 will have an untracked repository
 test_expect_success 'setup superproject with untracked file in nested 
submodule' '
        (
                cd super &&
@@ -318,6 +328,7 @@ test_expect_success 'setup superproject with untracked file 
in nested submodule'
                rm .gitmodules &&
                git submodule add -f ./sub1 &&
                git submodule add -f ./sub2 &&
+               git submodule add -f ./sub1 sub3 &&
                git commit -a -m "messy merge in superproject" &&
                (
                        cd sub1 &&
@@ -327,13 +338,27 @@ test_expect_success 'setup superproject with untracked 
file in nested submodule'
                git add sub1 &&
                git commit -a -m "update sub1 to contain nested sub"
        ) &&
-       echo untracked >super/sub1/sub2/untracked
+       echo content >super/sub1/sub2/file &&
+       echo content >super/sub2/file &&
+       git -C super/sub3 clone ../../sub2 untracked_repository
 '
 
 test_expect_success 'status with untracked file in nested submodule 
(porcelain)' '
        git -C super status --porcelain >output &&
        diff output - <<-\EOF
         M sub1
+        M sub2
+        M sub3
+       EOF
+'
+
+test_expect_success 'status with untracked file in nested submodule 
(porcelain=2)' '
+       git -C super status --porcelain=2 >output &&
+       sanitize_output output &&
+       diff output - <<-\EOF
+       1 .M S..U 160000 160000 160000 HASH HASH sub1
+       1 .M S..U 160000 160000 160000 HASH HASH sub2
+       1 .M S..U 160000 160000 160000 HASH HASH sub3
        EOF
 '
 
@@ -341,6 +366,41 @@ test_expect_success 'status with untracked file in nested 
submodule (short)' '
        git -C super status --short >output &&
        diff output - <<-\EOF
         ? sub1
+        ? sub2
+        ? sub3
+       EOF
+'
+
+test_expect_success 'setup superproject with modified file in nested 
submodule' '
+       git -C super/sub1/sub2 add file &&
+       git -C super/sub2 add file
+'
+
+test_expect_success 'status with added file in nested submodule (porcelain)' '
+       git -C super status --porcelain >output &&
+       diff output - <<-\EOF
+        M sub1
+        M sub2
+        M sub3
+       EOF
+'
+
+test_expect_success 'status with added file in nested submodule (porcelain=2)' 
'
+       git -C super status --porcelain=2 >output &&
+       sanitize_output output &&
+       diff output - <<-\EOF
+       1 .M S.M. 160000 160000 160000 HASH HASH sub1
+       1 .M S.M. 160000 160000 160000 HASH HASH sub2
+       1 .M S..U 160000 160000 160000 HASH HASH sub3
+       EOF
+'
+
+test_expect_success 'status with added file in nested submodule (short)' '
+       git -C super status --short >output &&
+       diff output - <<-\EOF
+        m sub1
+        m sub2
+        ? sub3
        EOF
 '
 


Reply via email to