2017-03-02 08:23:06 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='interpreting exotic branch name arguments
|
|
|
|
|
|
|
|
Branch name arguments are usually names which are taken to be inside of
|
|
|
|
refs/heads/, but we interpret some magic syntax like @{-1}, @{upstream}, etc.
|
|
|
|
This script aims to check the behavior of those corner cases.
|
|
|
|
'
|
2020-11-18 23:44:23 +00:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-18 23:44:19 +00:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2023-06-17 06:41:54 +00:00
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
2017-03-02 08:23:06 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
expect_branch() {
|
|
|
|
git log -1 --format=%s "$1" >actual &&
|
|
|
|
echo "$2" >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
}
|
|
|
|
|
|
|
|
expect_deleted() {
|
|
|
|
test_must_fail git rev-parse --verify "$1"
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'set up repo' '
|
|
|
|
test_commit one &&
|
|
|
|
test_commit two &&
|
|
|
|
git remote add origin foo.git
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'update branch via @{-1}' '
|
|
|
|
git branch previous one &&
|
|
|
|
|
|
|
|
git checkout previous &&
|
2020-11-18 23:44:23 +00:00
|
|
|
git checkout main &&
|
2017-03-02 08:23:06 +00:00
|
|
|
|
|
|
|
git branch -f @{-1} two &&
|
|
|
|
expect_branch previous two
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'update branch via local @{upstream}' '
|
|
|
|
git branch local one &&
|
|
|
|
git branch --set-upstream-to=local &&
|
|
|
|
|
|
|
|
git branch -f @{upstream} two &&
|
|
|
|
expect_branch local two
|
|
|
|
'
|
|
|
|
|
2017-03-02 08:23:14 +00:00
|
|
|
test_expect_success 'disallow updating branch via remote @{upstream}' '
|
2017-03-02 08:23:06 +00:00
|
|
|
git update-ref refs/remotes/origin/remote one &&
|
|
|
|
git branch --set-upstream-to=origin/remote &&
|
|
|
|
|
|
|
|
test_must_fail git branch -f @{upstream} two
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'create branch with pseudo-qualified name' '
|
|
|
|
git branch refs/heads/qualified two &&
|
|
|
|
expect_branch refs/heads/refs/heads/qualified two
|
|
|
|
'
|
|
|
|
|
branch: force-copy a branch to itself via @{-1} is a no-op
Since 52d59cc645 (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 3f59481e33 (branch: allow a no-op
"branch -M <current-branch> HEAD", 2011-11-25). To check for this, in
52d59cc645 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 ae5a6c3684 (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 <rjusto@gmail.com>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
2022-11-17 01:36:52 +00:00
|
|
|
test_expect_success 'force-copy a branch to itself via @{-1} is no-op' '
|
|
|
|
git branch -t copiable main &&
|
|
|
|
git checkout copiable &&
|
|
|
|
git checkout - &&
|
|
|
|
git branch -C @{-1} copiable &&
|
|
|
|
git config --get-all branch.copiable.merge >actual &&
|
|
|
|
echo refs/heads/main >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2017-03-02 08:23:06 +00:00
|
|
|
test_expect_success 'delete branch via @{-1}' '
|
|
|
|
git branch previous-del &&
|
|
|
|
|
|
|
|
git checkout previous-del &&
|
2020-11-18 23:44:23 +00:00
|
|
|
git checkout main &&
|
2017-03-02 08:23:06 +00:00
|
|
|
|
|
|
|
git branch -D @{-1} &&
|
|
|
|
expect_deleted previous-del
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'delete branch via local @{upstream}' '
|
|
|
|
git branch local-del &&
|
|
|
|
git branch --set-upstream-to=local-del &&
|
|
|
|
|
|
|
|
git branch -D @{upstream} &&
|
|
|
|
expect_deleted local-del
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'delete branch via remote @{upstream}' '
|
|
|
|
git update-ref refs/remotes/origin/remote-del two &&
|
|
|
|
git branch --set-upstream-to=origin/remote-del &&
|
|
|
|
|
|
|
|
git branch -r -D @{upstream} &&
|
|
|
|
expect_deleted origin/remote-del
|
|
|
|
'
|
|
|
|
|
|
|
|
# Note that we create two oddly named local branches here. We want to make
|
|
|
|
# sure that we do not accidentally delete either of them, even if
|
|
|
|
# shorten_unambiguous_ref() tweaks the name to avoid ambiguity.
|
2017-03-02 08:23:10 +00:00
|
|
|
test_expect_success 'delete @{upstream} expansion matches -r option' '
|
2017-03-02 08:23:06 +00:00
|
|
|
git update-ref refs/remotes/origin/remote-del two &&
|
|
|
|
git branch --set-upstream-to=origin/remote-del &&
|
|
|
|
git update-ref refs/heads/origin/remote-del two &&
|
|
|
|
git update-ref refs/heads/remotes/origin/remote-del two &&
|
|
|
|
|
|
|
|
test_must_fail git branch -D @{upstream} &&
|
|
|
|
expect_branch refs/heads/origin/remote-del two &&
|
|
|
|
expect_branch refs/heads/remotes/origin/remote-del two
|
|
|
|
'
|
|
|
|
|
2017-03-02 08:23:10 +00:00
|
|
|
test_expect_success 'disallow deleting remote branch via @{-1}' '
|
2017-03-02 08:23:06 +00:00
|
|
|
git update-ref refs/remotes/origin/previous one &&
|
|
|
|
|
|
|
|
git checkout -b origin/previous two &&
|
2020-11-18 23:44:23 +00:00
|
|
|
git checkout main &&
|
2017-03-02 08:23:06 +00:00
|
|
|
|
|
|
|
test_must_fail git branch -r -D @{-1} &&
|
|
|
|
expect_branch refs/remotes/origin/previous one &&
|
|
|
|
expect_branch refs/heads/origin/previous two
|
|
|
|
'
|
|
|
|
|
|
|
|
# The thing we are testing here is that "@" is the real branch refs/heads/@,
|
|
|
|
# and not refs/heads/HEAD. These tests should not imply that refs/heads/@ is a
|
|
|
|
# sane thing, but it _is_ technically allowed for now. If we disallow it, these
|
|
|
|
# can be switched to test_must_fail.
|
2017-03-02 08:23:14 +00:00
|
|
|
test_expect_success 'create branch named "@"' '
|
2017-03-02 08:23:06 +00:00
|
|
|
git branch -f @ one &&
|
|
|
|
expect_branch refs/heads/@ one
|
|
|
|
'
|
|
|
|
|
2017-03-02 08:23:10 +00:00
|
|
|
test_expect_success 'delete branch named "@"' '
|
2017-03-02 08:23:06 +00:00
|
|
|
git update-ref refs/heads/@ two &&
|
|
|
|
git branch -D @ &&
|
|
|
|
expect_deleted refs/heads/@
|
|
|
|
'
|
|
|
|
|
2017-03-02 08:23:18 +00:00
|
|
|
test_expect_success 'checkout does not treat remote @{upstream} as a branch' '
|
|
|
|
git update-ref refs/remotes/origin/checkout one &&
|
|
|
|
git branch --set-upstream-to=origin/checkout &&
|
|
|
|
git update-ref refs/heads/origin/checkout two &&
|
|
|
|
git update-ref refs/heads/remotes/origin/checkout two &&
|
|
|
|
|
|
|
|
git checkout @{upstream} &&
|
|
|
|
expect_branch HEAD one
|
|
|
|
'
|
|
|
|
|
2022-10-10 23:24:58 +00:00
|
|
|
test_expect_success 'edit-description via @{-1}' '
|
|
|
|
git checkout -b desc-branch &&
|
|
|
|
git checkout -b non-desc-branch &&
|
|
|
|
write_script editor <<-\EOF &&
|
|
|
|
echo "Branch description" >"$1"
|
|
|
|
EOF
|
|
|
|
EDITOR=./editor git branch --edit-description @{-1} &&
|
|
|
|
test_must_fail git config branch.non-desc-branch.description &&
|
|
|
|
git config branch.desc-branch.description >actual &&
|
|
|
|
printf "Branch description\n\n" >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'modify branch upstream via "@{-1}" and "@{-1}@{upstream}"' '
|
|
|
|
git checkout -b upstream-branch &&
|
|
|
|
git checkout -b upstream-other -t upstream-branch &&
|
|
|
|
git branch --set-upstream-to upstream-other @{-1} &&
|
|
|
|
git config branch.upstream-branch.merge >actual &&
|
|
|
|
echo "refs/heads/upstream-other" >expect &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
git branch --unset-upstream @{-1}@{upstream} &&
|
|
|
|
test_must_fail git config branch.upstream-other.merge
|
|
|
|
'
|
|
|
|
|
2017-03-02 08:23:06 +00:00
|
|
|
test_done
|