parseopt: handle malformed --expire arguments more nicely
[gitweb.git] / submodule.c
index 71d1773e2e19edf369f766d1784522b2b8732c2a..47ddc9b2739bf52d9263ea9cd90edde6e9d1c738 100644 (file)
@@ -1,3 +1,5 @@
+#define NO_THE_INDEX_COMPATIBILITY_MACROS
+
 #include "cache.h"
 #include "repository.h"
 #include "config.h"
@@ -55,14 +57,15 @@ int is_gitmodules_unmerged(const struct index_state *istate)
  * future version when we learn to stage the changes we do ourselves without
  * staging any previous modifications.
  */
-int is_staging_gitmodules_ok(const struct index_state *istate)
+int is_staging_gitmodules_ok(struct index_state *istate)
 {
        int pos = index_name_pos(istate, GITMODULES_FILE, strlen(GITMODULES_FILE));
 
        if ((pos >= 0) && (pos < istate->cache_nr)) {
                struct stat st;
                if (lstat(GITMODULES_FILE, &st) == 0 &&
-                   ce_match_stat(istate->cache[pos], &st, 0) & DATA_CHANGED)
+                   ie_match_stat(istate, istate->cache[pos], &st,
+                                 CE_MATCH_IGNORE_FSMONITOR) & DATA_CHANGED)
                        return 0;
        }
 
@@ -143,9 +146,9 @@ int remove_path_from_gitmodules(const char *path)
        return 0;
 }
 
-void stage_updated_gitmodules(void)
+void stage_updated_gitmodules(struct index_state *istate)
 {
-       if (add_file_to_cache(GITMODULES_FILE, 0))
+       if (add_file_to_index(istate, GITMODULES_FILE, 0))
                die(_("staging updated .gitmodules failed"));
 }
 
@@ -183,7 +186,7 @@ void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
                if (ignore)
                        handle_ignore_submodules_arg(diffopt, ignore);
                else if (is_gitmodules_unmerged(&the_index))
-                       DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
+                       diffopt->flags.ignore_submodules = 1;
        }
 }
 
@@ -402,16 +405,16 @@ const char *submodule_strategy_to_string(const struct submodule_update_strategy
 void handle_ignore_submodules_arg(struct diff_options *diffopt,
                                  const char *arg)
 {
-       DIFF_OPT_CLR(diffopt, IGNORE_SUBMODULES);
-       DIFF_OPT_CLR(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
-       DIFF_OPT_CLR(diffopt, IGNORE_DIRTY_SUBMODULES);
+       diffopt->flags.ignore_submodules = 0;
+       diffopt->flags.ignore_untracked_in_submodules = 0;
+       diffopt->flags.ignore_dirty_submodules = 0;
 
        if (!strcmp(arg, "all"))
-               DIFF_OPT_SET(diffopt, IGNORE_SUBMODULES);
+               diffopt->flags.ignore_submodules = 1;
        else if (!strcmp(arg, "untracked"))
-               DIFF_OPT_SET(diffopt, IGNORE_UNTRACKED_IN_SUBMODULES);
+               diffopt->flags.ignore_untracked_in_submodules = 1;
        else if (!strcmp(arg, "dirty"))
-               DIFF_OPT_SET(diffopt, IGNORE_DIRTY_SUBMODULES);
+               diffopt->flags.ignore_dirty_submodules = 1;
        else if (strcmp(arg, "none"))
                die("bad --ignore-submodules argument: %s", arg);
 }
@@ -587,7 +590,7 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
                struct object_id *one, struct object_id *two,
                unsigned dirty_submodule)
 {
-       const struct object_id *old = &empty_tree_oid, *new = &empty_tree_oid;
+       const struct object_id *old = the_hash_algo->empty_tree, *new = the_hash_algo->empty_tree;
        struct commit *left = NULL, *right = NULL;
        struct commit_list *merge_bases = NULL;
        struct child_process cp = CHILD_PROCESS_INIT;
@@ -616,7 +619,7 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path,
        argv_array_pushf(&cp.args, "--color=%s", want_color(o->use_color) ?
                         "always" : "never");
 
-       if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
+       if (o->flags.reverse_diff) {
                argv_array_pushf(&cp.args, "--src-prefix=%s%s/",
                                 o->b_prefix, path);
                argv_array_pushf(&cp.args, "--dst-prefix=%s%s/",
@@ -1057,7 +1060,7 @@ int push_unpushed_submodules(struct oid_array *commits,
                char *head;
                struct object_id head_oid;
 
-               head = resolve_refdup("HEAD", 0, head_oid.hash, NULL);
+               head = resolve_refdup("HEAD", 0, &head_oid, NULL);
                if (!head)
                        die(_("Failed to resolve HEAD as a valid ref."));
 
@@ -1178,7 +1181,7 @@ int submodule_touches_in_range(struct object_id *excl_oid,
 struct submodule_parallel_fetch {
        int count;
        struct argv_array args;
-       const char *work_tree;
+       struct repository *r;
        const char *prefix;
        int command_line_option;
        int default_option;
@@ -1187,17 +1190,42 @@ struct submodule_parallel_fetch {
 };
 #define SPF_INIT {0, ARGV_ARRAY_INIT, NULL, NULL, 0, 0, 0, 0}
 
+static int get_fetch_recurse_config(const struct submodule *submodule,
+                                   struct submodule_parallel_fetch *spf)
+{
+       if (spf->command_line_option != RECURSE_SUBMODULES_DEFAULT)
+               return spf->command_line_option;
+
+       if (submodule) {
+               char *key;
+               const char *value;
+
+               int fetch_recurse = submodule->fetch_recurse;
+               key = xstrfmt("submodule.%s.fetchRecurseSubmodules", submodule->name);
+               if (!repo_config_get_string_const(spf->r, key, &value)) {
+                       fetch_recurse = parse_fetch_recurse_submodules_arg(key, value);
+               }
+               free(key);
+
+               if (fetch_recurse != RECURSE_SUBMODULES_NONE)
+                       /* local config overrules everything except commandline */
+                       return fetch_recurse;
+       }
+
+       return spf->default_option;
+}
+
 static int get_next_submodule(struct child_process *cp,
                              struct strbuf *err, void *data, void **task_cb)
 {
        int ret = 0;
        struct submodule_parallel_fetch *spf = data;
 
-       for (; spf->count < active_nr; spf->count++) {
+       for (; spf->count < spf->r->index->cache_nr; spf->count++) {
                struct strbuf submodule_path = STRBUF_INIT;
                struct strbuf submodule_git_dir = STRBUF_INIT;
                struct strbuf submodule_prefix = STRBUF_INIT;
-               const struct cache_entry *ce = active_cache[spf->count];
+               const struct cache_entry *ce = spf->r->index->cache[spf->count];
                const char *git_dir, *default_argv;
                const struct submodule *submodule;
                struct submodule default_submodule = SUBMODULE_INIT;
@@ -1205,7 +1233,7 @@ static int get_next_submodule(struct child_process *cp,
                if (!S_ISGITLINK(ce->ce_mode))
                        continue;
 
-               submodule = submodule_from_path(&null_oid, ce->name);
+               submodule = submodule_from_cache(spf->r, &null_oid, ce->name);
                if (!submodule) {
                        const char *name = default_name_or_path(ce->name);
                        if (name) {
@@ -1214,49 +1242,24 @@ static int get_next_submodule(struct child_process *cp,
                        }
                }
 
-               default_argv = "yes";
-               if (spf->command_line_option == RECURSE_SUBMODULES_DEFAULT) {
-                       int fetch_recurse = RECURSE_SUBMODULES_NONE;
-
-                       if (submodule) {
-                               char *key;
-                               const char *value;
-
-                               fetch_recurse = submodule->fetch_recurse;
-                               key = xstrfmt("submodule.%s.fetchRecurseSubmodules", submodule->name);
-                               if (!repo_config_get_string_const(the_repository, key, &value)) {
-                                       fetch_recurse = parse_fetch_recurse_submodules_arg(key, value);
-                               }
-                               free(key);
-                       }
-
-                       if (fetch_recurse != RECURSE_SUBMODULES_NONE) {
-                               if (fetch_recurse == RECURSE_SUBMODULES_OFF)
-                                       continue;
-                               if (fetch_recurse == RECURSE_SUBMODULES_ON_DEMAND) {
-                                       if (!unsorted_string_list_lookup(&changed_submodule_names,
-                                                                        submodule->name))
-                                               continue;
-                                       default_argv = "on-demand";
-                               }
-                       } else {
-                               if (spf->default_option == RECURSE_SUBMODULES_OFF)
-                                       continue;
-                               if (spf->default_option == RECURSE_SUBMODULES_ON_DEMAND) {
-                                       if (!unsorted_string_list_lookup(&changed_submodule_names,
-                                                                         submodule->name))
-                                               continue;
-                                       default_argv = "on-demand";
-                               }
-                       }
-               } else if (spf->command_line_option == RECURSE_SUBMODULES_ON_DEMAND) {
-                       if (!unsorted_string_list_lookup(&changed_submodule_names,
+               switch (get_fetch_recurse_config(submodule, spf))
+               {
+               default:
+               case RECURSE_SUBMODULES_DEFAULT:
+               case RECURSE_SUBMODULES_ON_DEMAND:
+                       if (!submodule || !unsorted_string_list_lookup(&changed_submodule_names,
                                                         submodule->name))
                                continue;
                        default_argv = "on-demand";
+                       break;
+               case RECURSE_SUBMODULES_ON:
+                       default_argv = "yes";
+                       break;
+               case RECURSE_SUBMODULES_OFF:
+                       continue;
                }
 
-               strbuf_addf(&submodule_path, "%s/%s", spf->work_tree, ce->name);
+               strbuf_repo_worktree_path(&submodule_path, spf->r, "%s", ce->name);
                strbuf_addf(&submodule_git_dir, "%s/.git", submodule_path.buf);
                strbuf_addf(&submodule_prefix, "%s%s/", spf->prefix, ce->name);
                git_dir = read_gitfile(submodule_git_dir.buf);
@@ -1309,7 +1312,8 @@ static int fetch_finish(int retvalue, struct strbuf *err,
        return 0;
 }
 
-int fetch_populated_submodules(const struct argv_array *options,
+int fetch_populated_submodules(struct repository *r,
+                              const struct argv_array *options,
                               const char *prefix, int command_line_option,
                               int default_option,
                               int quiet, int max_parallel_jobs)
@@ -1317,16 +1321,16 @@ int fetch_populated_submodules(const struct argv_array *options,
        int i;
        struct submodule_parallel_fetch spf = SPF_INIT;
 
-       spf.work_tree = get_git_work_tree();
+       spf.r = r;
        spf.command_line_option = command_line_option;
        spf.default_option = default_option;
        spf.quiet = quiet;
        spf.prefix = prefix;
 
-       if (!spf.work_tree)
+       if (!r->worktree)
                goto out;
 
-       if (read_cache() < 0)
+       if (repo_read_index(r) < 0)
                die("index file corrupt");
 
        argv_array_push(&spf.args, "fetch");
@@ -1653,7 +1657,9 @@ int submodule_move_head(const char *path,
        else
                argv_array_push(&cp.args, "-m");
 
-       argv_array_push(&cp.args, old ? old : EMPTY_TREE_SHA1_HEX);
+       if (!(flags & SUBMODULE_MOVE_HEAD_FORCE))
+               argv_array_push(&cp.args, old ? old : EMPTY_TREE_SHA1_HEX);
+
        argv_array_push(&cp.args, new ? new : EMPTY_TREE_SHA1_HEX);
 
        if (run_command(&cp)) {
@@ -1670,7 +1676,8 @@ int submodule_move_head(const char *path,
                        cp.dir = path;
 
                        prepare_submodule_repo_env(&cp.env_array);
-                       argv_array_pushl(&cp.args, "update-ref", "HEAD", new, NULL);
+                       argv_array_pushl(&cp.args, "update-ref", "HEAD",
+                                        "--no-deref", new, NULL);
 
                        if (run_command(&cp)) {
                                ret = -1;