branch: add --recurse-submodules option for branch creation
To improve the submodules UX, we would like to teach Git to handle
branches in submodules. Start this process by teaching "git branch" the
--recurse-submodules option so that "git branch --recurse-submodules
topic" will create the `topic` branch in the superproject and its
submodules.
Although this commit does not introduce breaking changes, it does not
work well with existing --recurse-submodules commands because "git
branch --recurse-submodules" writes to the submodule ref store, but most
commands only consider the superproject gitlink and ignore the submodule
ref store. For example, "git checkout --recurse-submodules" will check
out the commits in the superproject gitlinks (and put the submodules in
detached HEAD) instead of checking out the submodule branches.
Because of this, this commit introduces a new configuration value,
`submodule.propagateBranches`. The plan is for Git commands to
prioritize submodule ref store information over superproject gitlinks if
this value is true. Because "git branch --recurse-submodules" writes to
submodule ref stores, for the sake of clarity, it will not function
unless this configuration value is set.
This commit also includes changes that support working with submodules
from a superproject commit because "branch --recurse-submodules" (and
future commands) need to read .gitmodules and gitlinks from the
superproject commit, but submodules are typically read from the
filesystem's .gitmodules and the index's gitlinks. These changes are:
* add a submodules_of_tree() helper that gives the relevant
information of an in-tree submodule (e.g. path and oid) and
initializes the repository
* add is_tree_submodule_active() by adding a treeish_name parameter to
is_submodule_active()
* add the "submoduleNotUpdated" advice to advise users to update the
submodules in their trees
Incidentally, fix an incorrect usage string that combined the 'list'
usage of git branch (-l) with the 'create' usage; this string has been
incorrect since its inception, a8dfd5eac4
(Make builtin-branch.c use
parse_options., 2007-10-07).
Helped-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Glen Choo <chooglen@google.com>
Reviewed-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:

committed by
Junio C Hamano

parent
6e0a2ca027
commit
961b130d20
@ -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);
|
||||
}
|
||||
|
||||
@ -622,7 +634,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
const char *new_upstream = NULL;
|
||||
int noncreate_actions = 0;
|
||||
/* possible options */
|
||||
int reflog = 0, quiet = 0, icase = 0, force = 0;
|
||||
int reflog = 0, quiet = 0, icase = 0, force = 0,
|
||||
recurse_submodules_explicit = 0;
|
||||
enum branch_track track;
|
||||
struct ref_filter filter;
|
||||
static struct ref_sorting *sorting;
|
||||
@ -673,6 +686,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(),
|
||||
};
|
||||
@ -715,6 +729,17 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
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;
|
||||
@ -853,6 +878,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
|
||||
git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
|
||||
strbuf_release(&buf);
|
||||
} 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>?"));
|
||||
@ -860,10 +888,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, 0);
|
||||
|
||||
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);
|
||||
|
||||
|
Reference in New Issue
Block a user