Remove the serial implementation of status inside of is_submodule_modified since the parallel implementation of status with one job accomplishes the same task. Combine parse_status_porcelain and parse_status_porcelain_strbuf since the only other caller of parse_status_porcelain was in is_submodule_modified Signed-off-by: Calvin Wan <calvinwan@xxxxxxxxxx> --- submodule.c | 146 ++++++++++++++++++---------------------------------- 1 file changed, 51 insertions(+), 95 deletions(-) diff --git a/submodule.c b/submodule.c index da95ea1f5e..2009748d9f 100644 --- a/submodule.c +++ b/submodule.c @@ -1887,46 +1887,7 @@ int fetch_submodules(struct repository *r, return spf.result; } -static int parse_status_porcelain(char *str, size_t len, - unsigned *dirty_submodule, - int ignore_untracked) -{ - /* regular untracked files */ - if (str[0] == '?') - *dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED; - - if (str[0] == 'u' || - str[0] == '1' || - str[0] == '2') { - /* T = line type, XY = status, SSSS = submodule state */ - if (len < strlen("T XY SSSS")) - BUG("invalid status --porcelain=2 line %s", - str); - - if (str[5] == 'S' && str[8] == 'U') - /* nested untracked file */ - *dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED; - - if (str[0] == 'u' || - str[0] == '2' || - memcmp(str + 5, "S..U", 4)) - /* other change */ - *dirty_submodule |= DIRTY_SUBMODULE_MODIFIED; - } - - if ((*dirty_submodule & DIRTY_SUBMODULE_MODIFIED) && - ((*dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) || - ignore_untracked)) { - /* - * We're not interested in any further information from - * the child any more, neither output nor its exit code. - */ - return 1; - } - return 0; -} - -static void parse_status_porcelain_strbuf(struct strbuf *buf, +static void parse_status_porcelain(struct strbuf *buf, unsigned *dirty_submodule, int ignore_untracked) { @@ -1936,65 +1897,60 @@ static void parse_status_porcelain_strbuf(struct strbuf *buf, string_list_split(&list, buf->buf, '\n', -1); for_each_string_list_item(item, &list) { - if (parse_status_porcelain(item->string, - strlen(item->string), - dirty_submodule, - ignore_untracked)) + char *str = item->string; + /* regular untracked files */ + if (str[0] == '?') + *dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED; + + if (str[0] == 'u' || + str[0] == '1' || + str[0] == '2') { + /* T = line type, XY = status, SSSS = submodule state */ + if (strlen(str) < strlen("T XY SSSS")) + BUG("invalid status --porcelain=2 line %s", + str); + + if (str[5] == 'S' && str[8] == 'U') + /* nested untracked file */ + *dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED; + + if (str[0] == 'u' || + str[0] == '2' || + memcmp(str + 5, "S..U", 4)) + /* other change */ + *dirty_submodule |= DIRTY_SUBMODULE_MODIFIED; + } + + if ((*dirty_submodule & DIRTY_SUBMODULE_MODIFIED) && + ((*dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) || + ignore_untracked)) { + /* + * We're not interested in any further information from + * the child any more, neither output nor its exit code. + */ break; + } } string_list_clear(&list, 0); } unsigned is_submodule_modified(const char *path, int ignore_untracked) { - struct child_process cp = CHILD_PROCESS_INIT; - struct strbuf buf = STRBUF_INIT; - FILE *fp; - unsigned dirty_submodule = 0; - const char *git_dir; - int ignore_cp_exit_code = 0; - - strbuf_addf(&buf, "%s/.git", path); - git_dir = read_gitfile(buf.buf); - if (!git_dir) - git_dir = buf.buf; - 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); - - strvec_pushl(&cp.args, "status", "--porcelain=2", NULL); - if (ignore_untracked) - strvec_push(&cp.args, "-uno"); - - prepare_submodule_repo_env(&cp.env); - cp.git_cmd = 1; - cp.no_stdin = 1; - cp.out = -1; - cp.dir = path; - if (start_command(&cp)) - die(_("Could not run 'git status --porcelain=2' in submodule %s"), path); - - fp = xfdopen(cp.out, "r"); - while (strbuf_getwholeline(&buf, fp, '\n') != EOF) { - char *str = buf.buf; - const size_t len = buf.len; - - ignore_cp_exit_code = parse_status_porcelain(str, len, &dirty_submodule, - ignore_untracked); - if (ignore_cp_exit_code) - break; - } - fclose(fp); - - if (finish_command(&cp) && !ignore_cp_exit_code) - die(_("'git status --porcelain=2' failed in submodule %s"), path); - - strbuf_release(&buf); + struct submodule_status_util util = { + .dirty_submodule = 0, + .ignore_untracked = ignore_untracked, + .path = path, + }; + struct string_list sub = STRING_LIST_INIT_NODUP; + struct string_list_item *item; + int dirty_submodule; + + item = string_list_append(&sub, path); + item->util = &util; + if (get_submodules_status(&sub, 1)) + die(_("submodule status failed")); + dirty_submodule = util.dirty_submodule; + string_list_clear(&sub, 0); return dirty_submodule; } @@ -2096,9 +2052,9 @@ static int status_finish(int retvalue, struct strbuf *err, task->path); } - parse_status_porcelain_strbuf(&task->out, - &util->dirty_submodule, - util->ignore_untracked); + parse_status_porcelain(&task->out, + &util->dirty_submodule, + util->ignore_untracked); strbuf_release(&task->out); free(task); -- 2.39.0.314.g84b9a713c41-goog