]> asedeno.scripts.mit.edu Git - git.git/blobdiff - submodule.c
t6200: modernize with test_tick
[git.git] / submodule.c
index 7d70c4f7bfe2749953726fecb27144a9588a326f..b3b8bc147909f81be6a387318ad0601dae50460f 100644 (file)
@@ -5,6 +5,7 @@
 #include "commit.h"
 #include "revision.h"
 #include "run-command.h"
+#include "diffcore.h"
 
 static int add_submodule_odb(const char *path)
 {
@@ -85,13 +86,21 @@ void show_submodule_summary(FILE *f, const char *path,
                        message = "(revision walker failed)";
        }
 
+       if (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)
+               fprintf(f, "Submodule %s contains untracked content\n", path);
+       if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED)
+               fprintf(f, "Submodule %s contains modified content\n", path);
+
+       if (!hashcmp(one, two)) {
+               strbuf_release(&sb);
+               return;
+       }
+
        strbuf_addf(&sb, "Submodule %s %s..", path,
                        find_unique_abbrev(one, DEFAULT_ABBREV));
        if (!fast_backward && !fast_forward)
                strbuf_addch(&sb, '.');
        strbuf_addf(&sb, "%s", find_unique_abbrev(two, DEFAULT_ABBREV));
-       if (dirty_submodule)
-               strbuf_add(&sb, "-dirty", 6);
        if (message)
                strbuf_addf(&sb, " %s\n", message);
        else
@@ -121,17 +130,24 @@ void show_submodule_summary(FILE *f, const char *path,
        strbuf_release(&sb);
 }
 
-int is_submodule_modified(const char *path)
+unsigned is_submodule_modified(const char *path, int ignore_untracked)
 {
-       int len;
+       int i;
+       ssize_t len;
        struct child_process cp;
        const char *argv[] = {
                "status",
                "--porcelain",
                NULL,
+               NULL,
        };
-       char *env[4];
+       const char *env[LOCAL_REPO_ENV_SIZE + 3];
        struct strbuf buf = STRBUF_INIT;
+       unsigned dirty_submodule = 0;
+       const char *line, *next_line;
+
+       for (i = 0; i < LOCAL_REPO_ENV_SIZE; i++)
+               env[i] = local_repo_env[i];
 
        strbuf_addf(&buf, "%s/.git/", path);
        if (!is_directory(buf.buf)) {
@@ -143,16 +159,17 @@ int is_submodule_modified(const char *path)
        strbuf_reset(&buf);
 
        strbuf_addf(&buf, "GIT_WORK_TREE=%s", path);
-       env[0] = strbuf_detach(&buf, NULL);
+       env[i++] = strbuf_detach(&buf, NULL);
        strbuf_addf(&buf, "GIT_DIR=%s/.git", path);
-       env[1] = strbuf_detach(&buf, NULL);
-       strbuf_addf(&buf, "GIT_INDEX_FILE");
-       env[2] = strbuf_detach(&buf, NULL);
-       env[3] = NULL;
+       env[i++] = strbuf_detach(&buf, NULL);
+       env[i] = NULL;
+
+       if (ignore_untracked)
+               argv[2] = "-uno";
 
        memset(&cp, 0, sizeof(cp));
        cp.argv = argv;
-       cp.env = (const char *const *)env;
+       cp.env = env;
        cp.git_cmd = 1;
        cp.no_stdin = 1;
        cp.out = -1;
@@ -160,14 +177,32 @@ int is_submodule_modified(const char *path)
                die("Could not run git status --porcelain");
 
        len = strbuf_read(&buf, cp.out, 1024);
+       line = buf.buf;
+       while (len > 2) {
+               if ((line[0] == '?') && (line[1] == '?')) {
+                       dirty_submodule |= DIRTY_SUBMODULE_UNTRACKED;
+                       if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED)
+                               break;
+               } else {
+                       dirty_submodule |= DIRTY_SUBMODULE_MODIFIED;
+                       if (ignore_untracked ||
+                           (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED))
+                               break;
+               }
+               next_line = strchr(line, '\n');
+               if (!next_line)
+                       break;
+               next_line++;
+               len -= (next_line - line);
+               line = next_line;
+       }
        close(cp.out);
 
        if (finish_command(&cp))
                die("git status --porcelain failed");
 
-       free(env[0]);
-       free(env[1]);
-       free(env[2]);
+       for (i = LOCAL_REPO_ENV_SIZE; env[i]; i++)
+               free((char *)env[i]);
        strbuf_release(&buf);
-       return len != 0;
+       return dirty_submodule;
 }