submodule.c: convert is_submodule_modified to use strbuf_getwholeline
[gitweb.git] / submodule.c
index 3200b7bb2b2360c7efab86b680ed5d0cafa5e9d3..e72781d9f21d6c2745e6679726dfc698aa3d1720 100644 (file)
@@ -1041,18 +1041,12 @@ int fetch_populated_submodules(const struct argv_array *options,
 
 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;
+       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);
@@ -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;
@@ -1078,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;
-                       if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED)
-                               break;
-               } else {
+               else
                        dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
-                       if (ignore_untracked ||
-                           (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED))
-                               break;
-               }
-               next_line = strchr(line, '\n');
-               if (!next_line)
+
+               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.
+                        */
+                       ignore_cp_exit_code = 1;
                        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);