Skip to content

Commit 51404e9

Browse files
committed
branch: move multiple branches in a single --force
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 <[email protected]>
1 parent 4c0e625 commit 51404e9

File tree

3 files changed

+22
-13
lines changed

3 files changed

+22
-13
lines changed

Documentation/git-branch.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ git branch [--color[=<when>] | --no-color] [--show-current]
1717
[(-r|--remotes) | (-a|--all)]
1818
[--list] [<pattern>...]
1919
git branch [--track[=(direct|inherit)] | --no-track] [-f]
20-
[--recurse-submodules] <branch-name> [<start-point>]
20+
[--recurse-submodules] <branch-name>... [<start-point>]
2121
git branch (--set-upstream-to=<upstream>|-u <upstream>) [<branch-name>]
2222
git branch --unset-upstream [<branch-name>]
2323
git branch (-m|-M) [<old-branch>] <new-branch>

builtin/branch.c

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
static const char * const builtin_branch_usage[] = {
3333
N_("git branch [<options>] [-r | -a] [--merged] [--no-merged]"),
34-
N_("git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-point>]"),
34+
N_("git branch [<options>] [-f] [--recurse-submodules] <branch-name>... [<start-point>]"),
3535
N_("git branch [<options>] [-l] [<pattern>...]"),
3636
N_("git branch [<options>] [-r] (-d | -D) <branch-name>..."),
3737
N_("git branch [<options>] (-m | -M) [<old-branch>] <new-branch>"),
@@ -992,9 +992,9 @@ int cmd_branch(int argc,
992992
strbuf_addf(&buf, "branch.%s.merge", branch->name);
993993
git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE);
994994
strbuf_release(&buf);
995-
} else if (!noncreate_actions && argc > 0 && argc <= 2) {
996-
const char *branch_name = argv[0];
997-
const char *start_name = argc == 2 ? argv[1] : head;
995+
} else if (!noncreate_actions && argc > 0) {
996+
const char *start_name = argc == 1 ? head : argv[argc - 1];
997+
int iters = argc == 1 ? 1 : argc - 1;
998998

999999
if (filter.kind != FILTER_REFS_BRANCHES)
10001000
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,
10031003
if (track == BRANCH_TRACK_OVERRIDE)
10041004
die(_("the '--set-upstream' option is no longer supported. Please use '--track' or '--set-upstream-to' instead"));
10051005

1006-
if (recurse_submodules) {
1007-
create_branches_recursively(the_repository, branch_name,
1008-
start_name, NULL, force,
1009-
reflog, quiet, track, 0);
1010-
ret = 0;
1011-
goto out;
1006+
for (int i = 0; i < iters; i++) {
1007+
const char *branch_name = argv[i];
1008+
1009+
if (recurse_submodules)
1010+
create_branches_recursively(the_repository, branch_name,
1011+
start_name, NULL, force,
1012+
reflog, quiet, track, 0);
1013+
else
1014+
create_branch(the_repository, branch_name, start_name, force, 0,
1015+
reflog, quiet, track, 0);
10121016
}
1013-
create_branch(the_repository, branch_name, start_name, force, 0,
1014-
reflog, quiet, track, 0);
10151017
} else
10161018
usage_with_options(builtin_branch_usage, options);
10171019

t/t3200-branch.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ test_expect_success 'git branch --force abc should succeed when abc exists' '
6060
test_cmp expect actual
6161
'
6262

63+
test_expect_success 'git branch --force br1 br2 abc should create 2 new branches' '
64+
git branch --force br1 br2 abc &&
65+
test_ref_exists refs/heads/br1 &&
66+
test_ref_exists refs/heads/br2 &&
67+
git branch -d br1 br2
68+
'
69+
6370
test_expect_success 'git branch a/b/c should create a branch' '
6471
git branch a/b/c &&
6572
test_ref_exists refs/heads/a/b/c

0 commit comments

Comments
 (0)