]> git.ipfire.org Git - thirdparty/git.git/blobdiff - builtin/branch.c
Merge branch 'gc/branch-recurse-submodules-fix'
[thirdparty/git.git] / builtin / branch.c
index 4ce2a247542ba07012a954dacd7ed2c5284e61d1..5d00d0b8d327c5cc048ac0baf997e3670d5ff3df 100644 (file)
@@ -27,7 +27,8 @@
 
 static const char * const builtin_branch_usage[] = {
        N_("git branch [<options>] [-r | -a] [--merged] [--no-merged]"),
-       N_("git branch [<options>] [-l] [-f] <branch-name> [<start-point>]"),
+       N_("git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-point>]"),
+       N_("git branch [<options>] [-l] [<pattern>...]"),
        N_("git branch [<options>] [-r] (-d | -D) <branch-name>..."),
        N_("git branch [<options>] (-m | -M) [<old-branch>] <new-branch>"),
        N_("git branch [<options>] (-c | -C) [<old-branch>] <new-branch>"),
@@ -38,6 +39,8 @@ static const char * const builtin_branch_usage[] = {
 
 static const char *head;
 static struct object_id head_oid;
+static int recurse_submodules = 0;
+static int submodule_propagate_branches = 0;
 
 static int branch_use_color = -1;
 static char branch_colors[][COLOR_MAXLEN] = {
@@ -99,6 +102,15 @@ static int git_branch_config(const char *var, const char *value, void *cb)
                        return config_error_nonbool(var);
                return color_parse(value, branch_colors[slot]);
        }
+       if (!strcmp(var, "submodule.recurse")) {
+               recurse_submodules = git_config_bool(var, value);
+               return 0;
+       }
+       if (!strcasecmp(var, "submodule.propagateBranches")) {
+               submodule_propagate_branches = git_config_bool(var, value);
+               return 0;
+       }
+
        return git_color_default_config(var, value, cb);
 }
 
@@ -621,14 +633,16 @@ static int edit_branch_description(const char *branch_name)
 
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
-       int delete = 0, rename = 0, copy = 0, force = 0, list = 0;
-       int show_current = 0;
-       int reflog = 0, edit_description = 0;
-       int quiet = 0, unset_upstream = 0;
+       /* possible actions */
+       int delete = 0, rename = 0, copy = 0, list = 0,
+           unset_upstream = 0, show_current = 0, edit_description = 0;
        const char *new_upstream = NULL;
+       int noncreate_actions = 0;
+       /* possible options */
+       int reflog = 0, quiet = 0, icase = 0, force = 0,
+           recurse_submodules_explicit = 0;
        enum branch_track track;
        struct ref_filter filter;
-       int icase = 0;
        static struct ref_sorting *sorting;
        struct string_list sorting_options = STRING_LIST_INIT_DUP;
        struct ref_format format = REF_FORMAT_INIT;
@@ -677,6 +691,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                OPT_CALLBACK(0, "points-at", &filter.points_at, N_("object"),
                        N_("print only branches of the object"), parse_opt_object_name),
                OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
+               OPT_BOOL(0, "recurse-submodules", &recurse_submodules_explicit, N_("recurse through submodules")),
                OPT_STRING(  0 , "format", &format.format, N_("format"), N_("format to use for the output")),
                OPT_END(),
        };
@@ -713,10 +728,23 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
            filter.reachable_from || filter.unreachable_from || filter.points_at.nr)
                list = 1;
 
-       if (!!delete + !!rename + !!copy + !!new_upstream + !!show_current +
-           list + edit_description + unset_upstream > 1)
+       noncreate_actions = !!delete + !!rename + !!copy + !!new_upstream +
+                           !!show_current + !!list + !!edit_description +
+                           !!unset_upstream;
+       if (noncreate_actions > 1)
                usage_with_options(builtin_branch_usage, options);
 
+       if (recurse_submodules_explicit) {
+               if (!submodule_propagate_branches)
+                       die(_("branch with --recurse-submodules can only be used if submodule.propagateBranches is enabled"));
+               if (noncreate_actions)
+                       die(_("--recurse-submodules can only be used to create branches"));
+       }
+
+       recurse_submodules =
+               (recurse_submodules || recurse_submodules_explicit) &&
+               submodule_propagate_branches;
+
        if (filter.abbrev == -1)
                filter.abbrev = DEFAULT_ABBREV;
        filter.ignore_case = icase;
@@ -828,12 +856,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                if (!ref_exists(branch->refname))
                        die(_("branch '%s' does not exist"), branch->name);
 
-               /*
-                * create_branch takes care of setting up the tracking
-                * info and making sure new_upstream is correct
-                */
-               create_branch(the_repository, branch->name, new_upstream,
-                             0, 0, 0, quiet, BRANCH_TRACK_OVERRIDE);
+               dwim_and_setup_tracking(the_repository, branch->name,
+                                       new_upstream, BRANCH_TRACK_OVERRIDE,
+                                       quiet);
        } else if (unset_upstream) {
                struct branch *branch = branch_get(argv[0]);
                struct strbuf buf = STRBUF_INIT;
@@ -857,7 +882,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                strbuf_addf(&buf, "branch.%s.merge", branch->name);
                git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
                strbuf_release(&buf);
-       } else if (argc > 0 && argc <= 2) {
+       } else if (!noncreate_actions && argc > 0 && argc <= 2) {
+               const char *branch_name = argv[0];
+               const char *start_name = argc == 2 ? argv[1] : head;
+
                if (filter.kind != FILTER_REFS_BRANCHES)
                        die(_("The -a, and -r, options to 'git branch' do not take a branch name.\n"
                                  "Did you mean to use: -a|-r --list <pattern>?"));
@@ -865,10 +893,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                if (track == BRANCH_TRACK_OVERRIDE)
                        die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead."));
 
-               create_branch(the_repository,
-                             argv[0], (argc == 2) ? argv[1] : head,
-                             force, 0, reflog, quiet, track);
-
+               if (recurse_submodules) {
+                       create_branches_recursively(the_repository, branch_name,
+                                                   start_name, NULL, force,
+                                                   reflog, quiet, track, 0);
+                       return 0;
+               }
+               create_branch(the_repository, branch_name, start_name, force, 0,
+                             reflog, quiet, track, 0);
        } else
                usage_with_options(builtin_branch_usage, options);