This is necessary before we can teach 'git bisect' this option, as that
calls the bisect--helper to do the actual work which then in turn calls
'git checkout'. The helper just passes the option given on the command
line on to checkout. The new recurse_submodules_enum_to_option() is added
to avoid having the helper learn the command line representation of the
different option values himself.

Signed-off-by: Jens Lehmann <jens.lehm...@web.de>
---
 bisect.c                 | 33 ++++++++++++++++++++++-----------
 bisect.h                 |  3 ++-
 builtin/bisect--helper.c |  9 ++++++++-
 submodule.c              | 21 +++++++++++++++++++++
 submodule.h              |  1 +
 5 files changed, 54 insertions(+), 13 deletions(-)

diff --git a/bisect.c b/bisect.c
index 37200b4..b84e607 100644
--- a/bisect.c
+++ b/bisect.c
@@ -11,13 +11,13 @@
 #include "bisect.h"
 #include "sha1-array.h"
 #include "argv-array.h"
+#include "submodule.h"

 static struct sha1_array good_revs;
 static struct sha1_array skipped_revs;

 static unsigned char *current_bad_sha1;

-static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
 static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
 static const char *argv_update_ref[] = {"update-ref", "--no-deref", 
"BISECT_HEAD", NULL, NULL};

@@ -683,22 +683,30 @@ static void mark_expected_rev(char *bisect_rev_hex)
                die("closing file %s: %s", filename, strerror(errno));
 }

-static int bisect_checkout(char *bisect_rev_hex, int no_checkout)
+static int bisect_checkout(char *bisect_rev_hex, int no_checkout,
+                          const char *recurse_submodules)
 {
        int res;

        mark_expected_rev(bisect_rev_hex);

-       argv_checkout[2] = bisect_rev_hex;
        if (no_checkout) {
                argv_update_ref[3] = bisect_rev_hex;
                if (run_command_v_opt(argv_update_ref, RUN_GIT_CMD))
                        die("update-ref --no-deref HEAD failed on %s",
                            bisect_rev_hex);
        } else {
-               res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
+               struct argv_array argv = ARGV_ARRAY_INIT;
+               argv_array_push(&argv, "checkout");
+               argv_array_push(&argv, "-q");
+               if (recurse_submodules)
+                   argv_array_push(&argv, recurse_submodules);
+               argv_array_push(&argv, bisect_rev_hex);
+               argv_array_push(&argv, "--");
+               res = run_command_v_opt(argv.argv, RUN_GIT_CMD);
                if (res)
                        exit(res);
+               argv_array_clear(&argv);
        }

        argv_show_branch[1] = bisect_rev_hex;
@@ -771,7 +779,7 @@ static void handle_skipped_merge_base(const unsigned char 
*mb)
  * - If one is "skipped", we can't know but we should warn.
  * - If we don't know, we should check it out and ask the user to test.
  */
-static void check_merge_bases(int no_checkout)
+static void check_merge_bases(int no_checkout, const char *recurse_submodules)
 {
        struct commit_list *result;
        int rev_nr;
@@ -789,7 +797,8 @@ static void check_merge_bases(int no_checkout)
                        handle_skipped_merge_base(mb);
                } else {
                        printf("Bisecting: a merge base must be tested\n");
-                       exit(bisect_checkout(sha1_to_hex(mb), no_checkout));
+                       exit(bisect_checkout(sha1_to_hex(mb), no_checkout,
+                                            recurse_submodules));
                }
        }

@@ -832,7 +841,8 @@ static int check_ancestors(const char *prefix)
  * If a merge base must be tested by the user, its source code will be
  * checked out to be tested by the user and we will exit.
  */
-static void check_good_are_ancestors_of_bad(const char *prefix, int 
no_checkout)
+static void check_good_are_ancestors_of_bad(const char *prefix, int 
no_checkout,
+                                           const char *recurse_submodules)
 {
        char *filename = git_pathdup("BISECT_ANCESTORS_OK");
        struct stat st;
@@ -851,7 +861,7 @@ static void check_good_are_ancestors_of_bad(const char 
*prefix, int no_checkout)

        /* Check if all good revs are ancestor of the bad rev. */
        if (check_ancestors(prefix))
-               check_merge_bases(no_checkout);
+               check_merge_bases(no_checkout, recurse_submodules);

        /* Create file BISECT_ANCESTORS_OK. */
        fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
@@ -897,7 +907,8 @@ static void show_diff_tree(const char *prefix, struct 
commit *commit)
  * If no_checkout is non-zero, the bisection process does not
  * checkout the trial commit but instead simply updates BISECT_HEAD.
  */
-int bisect_next_all(const char *prefix, int no_checkout)
+int bisect_next_all(const char *prefix, int no_checkout,
+                   const char *recurse_submodules)
 {
        struct rev_info revs;
        struct commit_list *tried;
@@ -908,7 +919,7 @@ int bisect_next_all(const char *prefix, int no_checkout)
        if (read_bisect_refs())
                die("reading bisect refs failed");

-       check_good_are_ancestors_of_bad(prefix, no_checkout);
+       check_good_are_ancestors_of_bad(prefix, no_checkout, 
recurse_submodules);

        bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
        revs.limited = 1;
@@ -954,7 +965,7 @@ int bisect_next_all(const char *prefix, int no_checkout)
               "(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"),
               steps, (steps == 1 ? "" : "s"));

-       return bisect_checkout(bisect_rev_hex, no_checkout);
+       return bisect_checkout(bisect_rev_hex, no_checkout, recurse_submodules);
 }

 static inline int log2i(int n)
diff --git a/bisect.h b/bisect.h
index 2a6c831..5c1ea9c 100644
--- a/bisect.h
+++ b/bisect.h
@@ -22,7 +22,8 @@ struct rev_list_info {
        const char *header_prefix;
 };

-extern int bisect_next_all(const char *prefix, int no_checkout);
+extern int bisect_next_all(const char *prefix, int no_checkout,
+                          const char *recurse_submodules);

 extern int estimate_bisect_steps(int all);

diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 3324229..b30087a 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -2,6 +2,7 @@
 #include "cache.h"
 #include "parse-options.h"
 #include "bisect.h"
+#include "submodule.h"

 static const char * const git_bisect_helper_usage[] = {
        N_("git bisect--helper --next-all [--no-checkout]"),
@@ -12,11 +13,16 @@ int cmd_bisect__helper(int argc, const char **argv, const 
char *prefix)
 {
        int next_all = 0;
        int no_checkout = 0;
+       int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
+
        struct option options[] = {
                OPT_BOOL(0, "next-all", &next_all,
                         N_("perform 'git bisect next'")),
                OPT_BOOL(0, "no-checkout", &no_checkout,
                         N_("update BISECT_HEAD instead of checking out the 
current commit")),
+               { OPTION_CALLBACK, 0, "recurse-submodules", &recurse_submodules,
+                       "checkout", "control recursive updating of submodules",
+                       PARSE_OPT_OPTARG, option_parse_update_submodules },
                OPT_END()
        };

@@ -27,5 +33,6 @@ int cmd_bisect__helper(int argc, const char **argv, const 
char *prefix)
                usage_with_options(git_bisect_helper_usage, options);

        /* next-all */
-       return bisect_next_all(prefix, no_checkout);
+       return bisect_next_all(prefix, no_checkout,
+                              
recurse_submodules_enum_to_option(recurse_submodules));
 }
diff --git a/submodule.c b/submodule.c
index b3eb28d..448b645 100644
--- a/submodule.c
+++ b/submodule.c
@@ -44,6 +44,27 @@ static int gitmodules_is_unmerged;
 static int gitmodules_is_modified;


+/*
+ * Convert values defined in the RECURSE_SUBMODULES_* enum to the string
+ * representation usable as command parameter. Returns NULL if no parameter
+ * is necessary.
+ */
+const char *recurse_submodules_enum_to_option(int recurse_submodules)
+{
+       switch(recurse_submodules) {
+       case RECURSE_SUBMODULES_ON_DEMAND:
+               return "--recurse-submodules=on-demand";
+       case RECURSE_SUBMODULES_OFF:
+               return "--no-recurse-submodules";
+       case RECURSE_SUBMODULES_ON:
+               return "--recurse-submodules";
+       case RECURSE_SUBMODULES_DEFAULT:
+               return NULL;
+       default:
+               die("Invalid recurse submodule value: %d", recurse_submodules);
+       }
+}
+
 int is_staging_gitmodules_ok(void)
 {
        return !gitmodules_is_modified;
diff --git a/submodule.h b/submodule.h
index 79b336b..5958010 100644
--- a/submodule.h
+++ b/submodule.h
@@ -11,6 +11,7 @@ enum {
        RECURSE_SUBMODULES_DEFAULT = 1,
        RECURSE_SUBMODULES_ON = 2
 };
+const char *recurse_submodules_enum_to_option(int recurse_submodules);

 int is_staging_gitmodules_ok(void);
 int update_path_in_gitmodules(const char *oldpath, const char *newpath);
-- 
1.9.rc0.28.ge3363ff


--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to