From d0d7fed1a2522cc82dfa934df0cdd362a66058b1 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 24 Mar 2017 17:36:04 -0700 Subject: [PATCH 1/7] submodule.c: use argv_array in is_submodule_modified struct argv_array is easier to use and maintain. Signed-off-by: Stefan Beller Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- submodule.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/submodule.c b/submodule.c index 3200b7bb2b..2c667ac95a 100644 --- a/submodule.c +++ b/submodule.c @@ -1043,12 +1043,6 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) { ssize_t len; struct child_process cp = CHILD_PROCESS_INIT; - const char *argv[] = { - "status", - "--porcelain", - NULL, - NULL, - }; struct strbuf buf = STRBUF_INIT; unsigned dirty_submodule = 0; const char *line, *next_line; @@ -1066,10 +1060,10 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) } strbuf_reset(&buf); + argv_array_pushl(&cp.args, "status", "--porcelain", NULL); if (ignore_untracked) - argv[2] = "-uno"; + argv_array_push(&cp.args, "-uno"); - cp.argv = argv; prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.no_stdin = 1; From 64f9a946f07d2ca00b34c466654a3f608c78b6af Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 24 Mar 2017 17:36:05 -0700 Subject: [PATCH 2/7] submodule.c: factor out early loop termination in is_submodule_modified This makes it easier for a follow up patch. Signed-off-by: Stefan Beller Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- submodule.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/submodule.c b/submodule.c index 2c667ac95a..93e3fefd39 100644 --- a/submodule.c +++ b/submodule.c @@ -1075,16 +1075,16 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) len = strbuf_read(&buf, cp.out, 1024); line = buf.buf; while (len > 2) { - if ((line[0] == '?') && (line[1] == '?')) { + if ((line[0] == '?') && (line[1] == '?')) dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED; - if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED) - break; - } else { + else dirty_submodule |= DIRTY_SUBMODULE_MODIFIED; - if (ignore_untracked || - (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)) - break; - } + + if ((dirty_submodule & DIRTY_SUBMODULE_MODIFIED) && + ((dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) || + ignore_untracked)) + break; + next_line = strchr(line, '\n'); if (!next_line) break; From af6865a7f1e1d915d3b63e998226028ca4abb6ee Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 24 Mar 2017 17:36:06 -0700 Subject: [PATCH 3/7] submodule.c: convert is_submodule_modified to use strbuf_getwholeline Instead of implementing line reading yet again, make use of our beautiful library function to read one line. By using strbuf_getwholeline instead of strbuf_read, we avoid having to allocate memory for the entire child process output at once. That is, we limit maximum memory usage. Also we can start processing the output as it comes in, no need to wait for all of it. Once we know all information that we care about, we can terminate the child early. In that case we do not care about its exit code as well. By just closing our side of the pipe the child process will get a SIGPIPE signal, which it will not report nor do we report it in finish_command, ac78663b0d (run-command: don't warn on SIGPIPE deaths, 2015-12-29). Helped-by: Jonathan Nieder Signed-off-by: Stefan Beller Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- submodule.c | 30 ++++++++++++++---------------- t/t7506-status-submodule.sh | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/submodule.c b/submodule.c index 93e3fefd39..e72781d9f2 100644 --- a/submodule.c +++ b/submodule.c @@ -1041,12 +1041,12 @@ out: unsigned is_submodule_modified(const char *path, int ignore_untracked) { - ssize_t len; struct child_process cp = CHILD_PROCESS_INIT; struct strbuf buf = STRBUF_INIT; + FILE *fp; unsigned dirty_submodule = 0; - const char *line, *next_line; const char *git_dir; + int ignore_cp_exit_code = 0; strbuf_addf(&buf, "%s/.git", path); git_dir = read_gitfile(buf.buf); @@ -1072,29 +1072,27 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) if (start_command(&cp)) die("Could not run 'git status --porcelain' in submodule %s", path); - len = strbuf_read(&buf, cp.out, 1024); - line = buf.buf; - while (len > 2) { - if ((line[0] == '?') && (line[1] == '?')) + fp = xfdopen(cp.out, "r"); + while (strbuf_getwholeline(&buf, fp, '\n') != EOF) { + if ((buf.buf[0] == '?') && (buf.buf[1] == '?')) dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED; else dirty_submodule |= DIRTY_SUBMODULE_MODIFIED; if ((dirty_submodule & DIRTY_SUBMODULE_MODIFIED) && ((dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) || - ignore_untracked)) + ignore_untracked)) { + /* + * We're not interested in any further information from + * the child any more, neither output nor its exit code. + */ + ignore_cp_exit_code = 1; break; - - next_line = strchr(line, '\n'); - if (!next_line) - break; - next_line++; - len -= (next_line - line); - line = next_line; + } } - close(cp.out); + fclose(fp); - if (finish_command(&cp)) + if (finish_command(&cp) && !ignore_cp_exit_code) die("'git status --porcelain' failed in submodule %s", path); strbuf_release(&buf); diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh index d31b34da83..51f8d0d034 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -177,8 +177,24 @@ test_expect_success 'status with added file in modified submodule with .git file test_i18ngrep "modified: sub (new commits, modified content)" output ' +test_expect_success 'status with a lot of untracked files in the submodule' ' + ( + cd sub + i=0 && + while test $i -lt 1024 + do + >some-file-$i + i=$(( $i + 1 )) + done + ) && + git status --porcelain sub 2>err.actual && + test_must_be_empty err.actual && + rm err.actual +' + test_expect_success 'rm submodule contents' ' - rm -rf sub/* sub/.git + rm -rf sub && + mkdir sub ' test_expect_success 'status clean (empty submodule dir)' ' From fcecf0b968b5e262200426ccf1d0b82495c261fe Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 24 Mar 2017 17:36:07 -0700 Subject: [PATCH 4/7] submodule.c: port is_submodule_modified to use porcelain 2 Migrate 'is_submodule_modified' to the new porcelain format of git-status. This conversion attempts to convert faithfully, i.e. the behavior ought to be exactly the same. As the output in the parsing only distinguishes between untracked files and the rest, this is easy to port to the new format, as we only need to identify untracked files and the rest is handled in the "else" case. untracked files are indicated by only a single question mark instead of two question marks, so the conversion is easy. Signed-off-by: Stefan Beller Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- submodule.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/submodule.c b/submodule.c index e72781d9f2..5865795b9f 100644 --- a/submodule.c +++ b/submodule.c @@ -1060,7 +1060,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) } strbuf_reset(&buf); - argv_array_pushl(&cp.args, "status", "--porcelain", NULL); + argv_array_pushl(&cp.args, "status", "--porcelain=2", NULL); if (ignore_untracked) argv_array_push(&cp.args, "-uno"); @@ -1070,11 +1070,12 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) cp.out = -1; cp.dir = path; if (start_command(&cp)) - die("Could not run 'git status --porcelain' in submodule %s", path); + die("Could not run 'git status --porcelain=2' in submodule %s", path); fp = xfdopen(cp.out, "r"); while (strbuf_getwholeline(&buf, fp, '\n') != EOF) { - if ((buf.buf[0] == '?') && (buf.buf[1] == '?')) + /* regular untracked files */ + if (buf.buf[0] == '?') dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED; else dirty_submodule |= DIRTY_SUBMODULE_MODIFIED; @@ -1093,7 +1094,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) fclose(fp); if (finish_command(&cp) && !ignore_cp_exit_code) - die("'git status --porcelain' failed in submodule %s", path); + die("'git status --porcelain=2' failed in submodule %s", path); strbuf_release(&buf); return dirty_submodule; From 5c896f7c3ec69f017d1e1be4164d558918f3ae4c Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Fri, 24 Mar 2017 17:36:08 -0700 Subject: [PATCH 5/7] submodule.c: stricter checking for submodules in is_submodule_modified By having a stricter check in the superproject we catch errors earlier, instead of spawning a child process to tell us. Signed-off-by: Stefan Beller Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- submodule.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/submodule.c b/submodule.c index 5865795b9f..fa21c7bb72 100644 --- a/submodule.c +++ b/submodule.c @@ -1052,11 +1052,12 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) git_dir = read_gitfile(buf.buf); if (!git_dir) git_dir = buf.buf; - if (!is_directory(git_dir)) { + if (!is_git_directory(git_dir)) { + if (is_directory(git_dir)) + die(_("'%s' not recognized as a git repository"), git_dir); strbuf_release(&buf); /* The submodule is not checked out, so it is not modified */ return 0; - } strbuf_reset(&buf); From dd6962dd731e6ec679f772d2bb14657f79062580 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 29 Mar 2017 15:26:15 -0700 Subject: [PATCH 6/7] short status: improve reporting for submodule changes If I add an untracked file to a submodule or modify a tracked file, currently "git status --short" treats the change in the same way as changes to the current HEAD of the submodule: $ git clone --quiet --recurse-submodules https://gerrit.googlesource.com/gerrit $ echo hello >gerrit/plugins/replication/stray-file $ sed -i -e 's/.*//' gerrit/plugins/replication/.mailmap $ git -C gerrit status --short M plugins/replication This is by analogy with ordinary files, where "M" represents a change that has not been added yet to the index. But this change cannot be added to the index without entering the submodule, "git add"-ing it, and running "git commit", so the analogy is counterproductive. Introduce new status letters " ?" and " m" for this. These are similar to the existing "??" and " M" but mean that the submodule (not the parent project) has new untracked files and modified files, respectively. The user can use "git add" and "git commit" from within the submodule to add them. Changes to the submodule's HEAD commit can be recorded in the index with a plain "git add -u" and are shown with " M", like today. To avoid excessive clutter, show at most one of " ?", " m", and " M" for the submodule. They represent increasing levels of change --- the last one that applies is shown (e.g., " m" if there are both modified files and untracked files in the submodule, or " M" if the submodule's HEAD has been modified and it has untracked files). While making these changes, we need to make sure to not break porcelain level 1, which shares code with "status --short". We only change "git status --short". Non-short "git status" and "git status --porcelain=2" already handle these cases by showing more detail: $ git -C gerrit status --porcelain=2 1 .M S.MU 160000 160000 160000 305c864db28eb0c77c8499bc04c87de3f849cf3c 305c864db28eb0c77c8499bc04c87de3f849cf3c plugins/replication $ git -C gerrit status [...] modified: plugins/replication (modified content, untracked content) Scripts caring about these distinctions should use --porcelain=2. Helped-by: Jonathan Nieder Signed-off-by: Stefan Beller Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/git-status.txt | 11 ++++ t/t3600-rm.sh | 18 ++++-- t/t7506-status-submodule.sh | 117 +++++++++++++++++++++++++++++++++++ wt-status.c | 17 ++++- 4 files changed, 156 insertions(+), 7 deletions(-) diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index ba873657cf..67f1a910f3 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -181,6 +181,15 @@ in which case `XY` are `!!`. ! ! ignored ------------------------------------------------- +Submodules have more state and instead report + M the submodule has a different HEAD than + 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. + + If -b is used the short-format status is preceded by a line ## branchname tracking info @@ -210,6 +219,8 @@ field from the first filename). Third, filenames containing special characters are not specially formatted; no quoting or backslash-escaping is performed. +Any submodule changes are reported as modified `M` instead of `m` or single `?`. + Porcelain Format Version 2 ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 5aa6db584c..a6e5c5bd56 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -268,6 +268,14 @@ cat >expect.modified <expect.modified_inside <expect.modified_untracked <expect.cached <actual && - test_cmp expect.modified actual && + test_cmp expect.modified_inside actual && git rm -f submod && test ! -d submod && git status -s -uno --ignore-submodules=none >actual && @@ -436,7 +444,7 @@ test_expect_success 'rm of a populated submodule with untracked files fails unle test -d submod && test -f submod/.git && git status -s -uno --ignore-submodules=none >actual && - test_cmp expect.modified actual && + test_cmp expect.modified_untracked actual && git rm -f submod && test ! -d submod && git status -s -uno --ignore-submodules=none >actual && @@ -621,7 +629,7 @@ test_expect_success 'rm of a populated nested submodule with different nested HE test -d submod && test -f submod/.git && git status -s -uno --ignore-submodules=none >actual && - test_cmp expect.modified actual && + test_cmp expect.modified_inside actual && git rm -f submod && test ! -d submod && git status -s -uno --ignore-submodules=none >actual && @@ -636,7 +644,7 @@ test_expect_success 'rm of a populated nested submodule with nested modification test -d submod && test -f submod/.git && git status -s -uno --ignore-submodules=none >actual && - test_cmp expect.modified actual && + test_cmp expect.modified_inside actual && git rm -f submod && test ! -d submod && git status -s -uno --ignore-submodules=none >actual && @@ -651,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 actual && + test_cmp expect.modified_inside 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 51f8d0d034..1fa2ff2909 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 && @@ -50,6 +56,15 @@ test_expect_success 'status with modified file in submodule (porcelain)' ' EOF ' +test_expect_success 'status with modified file in submodule (short)' ' + (cd sub && git reset --hard) && + echo "changed" >sub/foo && + git status --short >output && + diff output - <<-\EOF + m sub + EOF +' + test_expect_success 'status with added file in submodule' ' (cd sub && git reset --hard && echo >foo && git add foo) && git status >output && @@ -64,6 +79,14 @@ test_expect_success 'status with added file in submodule (porcelain)' ' EOF ' +test_expect_success 'status with added file in submodule (short)' ' + (cd sub && git reset --hard && echo >foo && git add foo) && + git status --short >output && + diff output - <<-\EOF + m sub + EOF +' + test_expect_success 'status with untracked file in submodule' ' (cd sub && git reset --hard) && echo "content" >sub/new-file && @@ -83,6 +106,13 @@ test_expect_success 'status with untracked file in submodule (porcelain)' ' EOF ' +test_expect_success 'status with untracked file in submodule (short)' ' + git status --short >output && + diff output - <<-\EOF + ? sub + EOF +' + test_expect_success 'status with added and untracked file in submodule' ' (cd sub && git reset --hard && echo >foo && git add foo) && echo "content" >sub/new-file && @@ -287,4 +317,91 @@ 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 && + git clean -dfx && + 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 && + git submodule add ../sub2 && + git commit -a -m "add sub2 to sub1" + ) && + git add sub1 && + git commit -a -m "update sub1 to contain nested sub" + ) && + 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.M. 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 +' + +test_expect_success 'status with untracked file in nested submodule (short)' ' + git -C super status --short >output && + diff output - <<-\EOF + m 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 +' + test_done diff --git a/wt-status.c b/wt-status.c index 308cf3779e..0375484962 100644 --- a/wt-status.c +++ b/wt-status.c @@ -407,6 +407,16 @@ static void wt_longstatus_print_change_data(struct wt_status *s, strbuf_release(&twobuf); } +static char short_submodule_status(struct wt_status_change_data *d) { + if (d->new_submodule_commits) + return 'M'; + if (d->dirty_submodule & DIRTY_SUBMODULE_MODIFIED) + return 'm'; + if (d->dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) + return '?'; + return d->worktree_status; +} + static void wt_status_collect_changed_cb(struct diff_queue_struct *q, struct diff_options *options, void *data) @@ -431,10 +441,13 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q, } if (!d->worktree_status) d->worktree_status = p->status; - d->dirty_submodule = p->two->dirty_submodule; - if (S_ISGITLINK(p->two->mode)) + if (S_ISGITLINK(p->two->mode)) { + d->dirty_submodule = p->two->dirty_submodule; d->new_submodule_commits = !!oidcmp(&p->one->oid, &p->two->oid); + if (s->status_format == STATUS_FORMAT_SHORT) + d->worktree_status = short_submodule_status(d); + } switch (p->status) { case DIFF_STATUS_ADDED: From 40069d6e3a195c8c2414ea60ed75b84ae47f88a1 Mon Sep 17 00:00:00 2001 From: Stefan Beller Date: Wed, 29 Mar 2017 15:26:16 -0700 Subject: [PATCH 7/7] submodule.c: correctly handle nested submodules in is_submodule_modified Suppose I have a superproject 'super', with two submodules 'super/sub' and 'super/sub1'. 'super/sub' itself contains a submodule 'super/sub/subsub'. Now suppose I run, from within 'super': echo hi >sub/subsub/stray-file echo hi >sub1/stray-file Currently we get would see the following output in git-status: git status --short m sub ? sub1 With this patch applied, the untracked file in the nested submodule is displayed as an untracked file on the 'super' level as well. git status --short ? sub ? sub1 This doesn't change the output of 'git status --porcelain=1' for nested submodules, because its output is always ' M' for either untracked files or local modifications no matter the nesting level of the submodule. 'git status --porcelain=2' is affected by this change in a nested submodule, though. Without this patch it would report the direct submodule as modified and having no untracked files. With this patch it would report untracked files. Chalk this up as a bug fix. This bug fix also affects the default output (non-short, non-porcelain) of git-status, which is not tested here. Signed-off-by: Stefan Beller Reviewed-by: Jonathan Nieder Signed-off-by: Junio C Hamano --- Documentation/git-status.txt | 2 ++ submodule.c | 21 +++++++++++++++++++-- t/t3600-rm.sh | 2 +- t/t7506-status-submodule.sh | 4 ++-- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index 67f1a910f3..d70abc6afe 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -189,6 +189,8 @@ Submodules have more state and instead report 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 fa21c7bb72..3da65100e3 100644 --- a/submodule.c +++ b/submodule.c @@ -1078,8 +1078,25 @@ 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 = line type, XY = status, SSSS = submodule state */ + if (buf.len < strlen("T XY SSSS")) + die("BUG: invalid status --porcelain=2 line %s", + buf.buf); + + if (buf.buf[5] == 'S' && buf.buf[8] == 'U') + /* nested untracked file */ + dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED; + + if (buf.buf[0] == 'u' || + buf.buf[0] == '2' || + 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 1fa2ff2909..055c90736e 100755 --- a/t/t7506-status-submodule.sh +++ b/t/t7506-status-submodule.sh @@ -356,7 +356,7 @@ 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.M. 160000 160000 160000 HASH HASH sub1 + 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 @@ -365,7 +365,7 @@ test_expect_success 'status with untracked file in nested submodule (porcelain=2 test_expect_success 'status with untracked file in nested submodule (short)' ' git -C super status --short >output && diff output - <<-\EOF - m sub1 + ? sub1 ? sub2 ? sub3 EOF