Skip to content

Commit cfbd173

Browse files
rjustottaylorr
authored andcommitted
branch: force-copy a branch to itself via @{-1} is a no-op
Since 52d59cc (branch: add a --copy (-c) option to go with --move (-m), 2017-06-18) we can copy a branch to make a new branch with the '-c' (copy) option or to overwrite an existing branch using the '-C' (force copy) option. A no-op possibility is considered when we are asked to copy a branch to itself, to follow the same no-op introduced for the rename (-M) operation in 3f59481 (branch: allow a no-op "branch -M <current-branch> HEAD", 2011-11-25). To check for this, in 52d59cc we compared the branch names provided by the user, source (HEAD if omitted) and destination, and a match is considered as this no-op. Since ae5a6c3 (checkout: implement "@{-N}" shortcut name for N-th last branch, 2009-01-17) a branch can be specified using shortcuts like @{-1}. This allows this usage: $ git checkout -b test $ git checkout - $ git branch -C test test # no-op $ git branch -C test @{-1} # oops $ git branch -C @{-1} test # oops As we are using the branch name provided by the user to do the comparison, if one of the branches is provided using a shortcut we are not going to have a match and a call to git_config_copy_section() will happen. This will make a duplicate of the configuration for that branch, and with this progression the second call will produce four copies of the configuration, and so on. Let's use the interpreted branch name instead for this comparison. The rename operation is not affected. Signed-off-by: Rubén Justo <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent eea7033 commit cfbd173

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

builtin/branch.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -584,13 +584,13 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
584584
strbuf_release(&logmsg);
585585

586586
strbuf_addf(&oldsection, "branch.%s", interpreted_oldname);
587-
strbuf_release(&oldref);
588587
strbuf_addf(&newsection, "branch.%s", interpreted_newname);
589-
strbuf_release(&newref);
590588
if (!copy && git_config_rename_section(oldsection.buf, newsection.buf) < 0)
591589
die(_("Branch is renamed, but update of config-file failed"));
592-
if (copy && strcmp(oldname, newname) && git_config_copy_section(oldsection.buf, newsection.buf) < 0)
590+
if (copy && strcmp(interpreted_oldname, interpreted_newname) && git_config_copy_section(oldsection.buf, newsection.buf) < 0)
593591
die(_("Branch is copied, but update of config-file failed"));
592+
strbuf_release(&oldref);
593+
strbuf_release(&newref);
594594
strbuf_release(&oldsection);
595595
strbuf_release(&newsection);
596596
}

t/t3204-branch-name-interpretation.sh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,16 @@ test_expect_success 'create branch with pseudo-qualified name' '
5757
expect_branch refs/heads/refs/heads/qualified two
5858
'
5959

60+
test_expect_success 'force-copy a branch to itself via @{-1} is no-op' '
61+
git branch -t copiable main &&
62+
git checkout copiable &&
63+
git checkout - &&
64+
git branch -C @{-1} copiable &&
65+
git config --get-all branch.copiable.merge >actual &&
66+
echo refs/heads/main >expect &&
67+
test_cmp expect actual
68+
'
69+
6070
test_expect_success 'delete branch via @{-1}' '
6171
git branch previous-del &&
6272

0 commit comments

Comments
 (0)