From: Andrea Stacchiotti <andreastacchiotti@xxxxxxxxx> Using either the 1-arg or 2-args form of --force it is possible to only move one branch at a time, to HEAD and <arg2> respectively. Allow moving multiple branches to a single target by giving 'git branch --force b1 b2 b3 ... dest' cp-like semantics, all the branches are moved/created to 'dest'. The convention extends the 2-args form in the same way 'cp a b c ... dest' would do. There could be another potential interpretation of `--force a b c`: moving all 3 to HEAD, but the 2-args form already changed the semantics to cp-like instead of appending an implicit HEAD, so this seems the least surprising way to support multiple moves. No such change is done to the move/copy paths, as such paths would error out anyway by trying to create multiple branches of the same name. Signed-off-by: Andrea Stacchiotti <andreastacchiotti@xxxxxxxxx> --- branch: Move multiple branches in a single --force Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1992%2F12345ieee%2Fmaster-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1992/12345ieee/master-v1 Pull-Request: https://github.com/git/git/pull/1992 Documentation/git-branch.adoc | 2 +- builtin/branch.c | 26 ++++++++++++++------------ t/t3200-branch.sh | 7 +++++++ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Documentation/git-branch.adoc b/Documentation/git-branch.adoc index c0afddc424d..817b4a5d3f6 100644 --- a/Documentation/git-branch.adoc +++ b/Documentation/git-branch.adoc @@ -17,7 +17,7 @@ git branch [--color[=<when>] | --no-color] [--show-current] [(-r|--remotes) | (-a|--all)] [--list] [<pattern>...] git branch [--track[=(direct|inherit)] | --no-track] [-f] - [--recurse-submodules] <branch-name> [<start-point>] + [--recurse-submodules] <branch-name>... [<start-point>] git branch (--set-upstream-to=<upstream>|-u <upstream>) [<branch-name>] git branch --unset-upstream [<branch-name>] git branch (-m|-M) [<old-branch>] <new-branch> diff --git a/builtin/branch.c b/builtin/branch.c index c150131bd9f..8ba04568c15 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -31,7 +31,7 @@ static const char * const builtin_branch_usage[] = { N_("git branch [<options>] [-r | -a] [--merged] [--no-merged]"), - N_("git branch [<options>] [-f] [--recurse-submodules] <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>"), @@ -992,9 +992,9 @@ int cmd_branch(int argc, 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 (!noncreate_actions && argc > 0 && argc <= 2) { - const char *branch_name = argv[0]; - const char *start_name = argc == 2 ? argv[1] : head; + } else if (!noncreate_actions && argc > 0) { + const char *start_name = argc == 1 ? head : argv[argc - 1]; + int iters = argc == 1 ? 1 : argc - 1; if (filter.kind != FILTER_REFS_BRANCHES) die(_("the -a, and -r, options to 'git branch' do not take a branch name.\n" @@ -1003,15 +1003,17 @@ int cmd_branch(int argc, if (track == BRANCH_TRACK_OVERRIDE) die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead")); - if (recurse_submodules) { - create_branches_recursively(the_repository, branch_name, - start_name, NULL, force, - reflog, quiet, track, 0); - ret = 0; - goto out; + for (int i = 0; i < iters; i++) { + const char *branch_name = argv[i]; + + if (recurse_submodules) + create_branches_recursively(the_repository, branch_name, + start_name, NULL, force, + reflog, quiet, track, 0); + else + create_branch(the_repository, branch_name, start_name, force, 0, + reflog, quiet, track, 0); } - create_branch(the_repository, branch_name, start_name, force, 0, - reflog, quiet, track, 0); } else usage_with_options(builtin_branch_usage, options); diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index f3e720dc10d..7cd31ca7820 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -60,6 +60,13 @@ test_expect_success 'git branch --force abc should succeed when abc exists' ' test_cmp expect actual ' +test_expect_success 'git branch --force br1 br2 abc should create 2 new branches' ' + git branch --force br1 br2 abc && + test_ref_exists refs/heads/br1 && + test_ref_exists refs/heads/br2 && + git branch -d br1 br2 +' + test_expect_success 'git branch a/b/c should create a branch' ' git branch a/b/c && test_ref_exists refs/heads/a/b/c base-commit: 4c0e625c091d4c648cec7319bafaed3cc81658e5 -- gitgitgadget