Code

Merge branch 'jc/maint-diffstat-numstat-context' into maint
[git.git] / submodule.c
index 45f508c6fd5b64d423d1e3722c3def0cfb94fa92..0b709bc2914335853e7525076f5e1d026d5dd779 100644 (file)
@@ -8,12 +8,18 @@
 #include "diffcore.h"
 #include "refs.h"
 #include "string-list.h"
+#include "sha1-array.h"
+#include "argv-array.h"
 
 static struct string_list config_name_for_path;
 static struct string_list config_fetch_recurse_submodules_for_name;
 static struct string_list config_ignore_for_name;
 static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND;
 static struct string_list changed_submodule_paths;
+static int initialized_fetch_ref_tips;
+static struct sha1_array ref_tips_before_fetch;
+static struct sha1_array ref_tips_after_fetch;
+
 /*
  * The following flag is set if the .gitmodules file is unmerged. We then
  * disable recursion for all submodules where .git/config doesn't have a
@@ -32,7 +38,7 @@ static int add_submodule_odb(const char *path)
        const char *git_dir;
 
        strbuf_addf(&objects_directory, "%s/.git", path);
-       git_dir = read_gitfile_gently(objects_directory.buf);
+       git_dir = read_gitfile(objects_directory.buf);
        if (git_dir) {
                strbuf_reset(&objects_directory);
                strbuf_addstr(&objects_directory, git_dir);
@@ -474,16 +480,46 @@ static void submodule_collect_changed_cb(struct diff_queue_struct *q,
        }
 }
 
+static int add_sha1_to_array(const char *ref, const unsigned char *sha1,
+                            int flags, void *data)
+{
+       sha1_array_append(data, sha1);
+       return 0;
+}
+
 void check_for_new_submodule_commits(unsigned char new_sha1[20])
+{
+       if (!initialized_fetch_ref_tips) {
+               for_each_ref(add_sha1_to_array, &ref_tips_before_fetch);
+               initialized_fetch_ref_tips = 1;
+       }
+
+       sha1_array_append(&ref_tips_after_fetch, new_sha1);
+}
+
+static void add_sha1_to_argv(const unsigned char sha1[20], void *data)
+{
+       argv_array_push(data, sha1_to_hex(sha1));
+}
+
+static void calculate_changed_submodule_paths(void)
 {
        struct rev_info rev;
        struct commit *commit;
-       const char *argv[] = {NULL, NULL, "--not", "--all", NULL};
-       int argc = ARRAY_SIZE(argv) - 1;
+       struct argv_array argv = ARGV_ARRAY_INIT;
+
+       /* No need to check if there are no submodules configured */
+       if (!config_name_for_path.nr)
+               return;
 
        init_revisions(&rev, NULL);
-       argv[1] = xstrdup(sha1_to_hex(new_sha1));
-       setup_revisions(argc, argv, &rev, NULL);
+       argv_array_push(&argv, "--"); /* argv[0] program name */
+       sha1_array_for_each_unique(&ref_tips_after_fetch,
+                                  add_sha1_to_argv, &argv);
+       argv_array_push(&argv, "--not");
+       sha1_array_for_each_unique(&ref_tips_before_fetch,
+                                  add_sha1_to_argv, &argv);
+       setup_revisions(argv.argc, argv.argv, &rev, NULL);
        if (prepare_revision_walk(&rev))
                die("revision walk setup failed");
 
@@ -507,7 +543,11 @@ void check_for_new_submodule_commits(unsigned char new_sha1[20])
                        parent = parent->next;
                }
        }
-       free((char *)argv[1]);
+
+       argv_array_clear(&argv);
+       sha1_array_clear(&ref_tips_before_fetch);
+       sha1_array_clear(&ref_tips_after_fetch);
+       initialized_fetch_ref_tips = 0;
 }
 
 int fetch_populated_submodules(int num_options, const char **options,
@@ -541,6 +581,8 @@ int fetch_populated_submodules(int num_options, const char **options,
        cp.git_cmd = 1;
        cp.no_stdin = 1;
 
+       calculate_changed_submodule_paths();
+
        for (i = 0; i < active_nr; i++) {
                struct strbuf submodule_path = STRBUF_INIT;
                struct strbuf submodule_git_dir = STRBUF_INIT;
@@ -587,7 +629,7 @@ int fetch_populated_submodules(int num_options, const char **options,
                strbuf_addf(&submodule_path, "%s/%s", work_tree, ce->name);
                strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
                strbuf_addf(&submodule_prefix, "%s%s/", prefix, ce->name);
-               git_dir = read_gitfile_gently(submodule_git_dir.buf);
+               git_dir = read_gitfile(submodule_git_dir.buf);
                if (!git_dir)
                        git_dir = submodule_git_dir.buf;
                if (is_directory(git_dir)) {
@@ -625,7 +667,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
        const char *git_dir;
 
        strbuf_addf(&buf, "%s/.git", path);
-       git_dir = read_gitfile_gently(buf.buf);
+       git_dir = read_gitfile(buf.buf);
        if (!git_dir)
                git_dir = buf.buf;
        if (!is_directory(git_dir)) {