2009-09-10 23:25:57 +08:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='test <branch>@{upstream} syntax'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
|
|
|
|
test_expect_success 'setup' '
|
|
|
|
|
|
|
|
test_commit 1 &&
|
|
|
|
git checkout -b side &&
|
|
|
|
test_commit 2 &&
|
|
|
|
git checkout master &&
|
|
|
|
git clone . clone &&
|
|
|
|
test_commit 3 &&
|
|
|
|
(cd clone &&
|
|
|
|
test_commit 4 &&
|
2012-04-14 15:54:31 +08:00
|
|
|
git branch --track my-side origin/side &&
|
|
|
|
git branch --track local-master master &&
|
interpret_branch_name: find all possible @-marks
When we parse a string like "foo@{upstream}", we look for
the first "@"-sign, and check to see if it is an upstream
mark. However, since branch names can contain an @, we may
also see "@foo@{upstream}". In this case, we check only the
first @, and ignore the second. As a result, we do not find
the upstream.
We can solve this by iterating through all @-marks in the
string, and seeing if any is a legitimate upstream or
empty-at mark.
Another strategy would be to parse from the right-hand side
of the string. However, that does not work for the
"empty_at" case, which allows "@@{upstream}". We need to
find the left-most one in this case (and we then recurse as
"HEAD@{upstream}").
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-15 16:40:46 +08:00
|
|
|
git branch --track fun@ny origin/side &&
|
|
|
|
git branch --track @funny origin/side &&
|
|
|
|
git branch --track funny@ origin/side &&
|
2012-04-14 15:54:31 +08:00
|
|
|
git remote add -t master master-only .. &&
|
|
|
|
git fetch master-only &&
|
|
|
|
git branch bad-upstream &&
|
|
|
|
git config branch.bad-upstream.remote master-only &&
|
|
|
|
git config branch.bad-upstream.merge refs/heads/side
|
|
|
|
)
|
2009-09-10 23:25:57 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
full_name () {
|
|
|
|
(cd clone &&
|
|
|
|
git rev-parse --symbolic-full-name "$@")
|
|
|
|
}
|
|
|
|
|
|
|
|
commit_subject () {
|
|
|
|
(cd clone &&
|
|
|
|
git show -s --pretty=format:%s "$@")
|
|
|
|
}
|
|
|
|
|
2012-04-14 15:54:31 +08:00
|
|
|
error_message () {
|
|
|
|
(cd clone &&
|
2018-02-24 07:39:43 +08:00
|
|
|
test_must_fail git rev-parse --verify "$@" 2>../error)
|
2012-04-14 15:54:31 +08:00
|
|
|
}
|
|
|
|
|
2009-09-10 23:25:57 +08:00
|
|
|
test_expect_success '@{upstream} resolves to correct full name' '
|
2017-03-27 19:16:55 +08:00
|
|
|
test refs/remotes/origin/master = "$(full_name @{upstream})" &&
|
|
|
|
test refs/remotes/origin/master = "$(full_name @{UPSTREAM})" &&
|
|
|
|
test refs/remotes/origin/master = "$(full_name @{UpSTReam})"
|
2009-09-10 23:25:57 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '@{u} resolves to correct full name' '
|
2017-03-27 19:16:55 +08:00
|
|
|
test refs/remotes/origin/master = "$(full_name @{u})" &&
|
|
|
|
test refs/remotes/origin/master = "$(full_name @{U})"
|
2009-09-10 23:25:57 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'my-side@{upstream} resolves to correct full name' '
|
|
|
|
test refs/remotes/origin/side = "$(full_name my-side@{u})"
|
|
|
|
'
|
|
|
|
|
interpret_branch_name: find all possible @-marks
When we parse a string like "foo@{upstream}", we look for
the first "@"-sign, and check to see if it is an upstream
mark. However, since branch names can contain an @, we may
also see "@foo@{upstream}". In this case, we check only the
first @, and ignore the second. As a result, we do not find
the upstream.
We can solve this by iterating through all @-marks in the
string, and seeing if any is a legitimate upstream or
empty-at mark.
Another strategy would be to parse from the right-hand side
of the string. However, that does not work for the
"empty_at" case, which allows "@@{upstream}". We need to
find the left-most one in this case (and we then recurse as
"HEAD@{upstream}").
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-15 16:40:46 +08:00
|
|
|
test_expect_success 'upstream of branch with @ in middle' '
|
|
|
|
full_name fun@ny@{u} >actual &&
|
|
|
|
echo refs/remotes/origin/side >expect &&
|
2017-03-27 19:16:55 +08:00
|
|
|
test_cmp expect actual &&
|
|
|
|
full_name fun@ny@{U} >actual &&
|
interpret_branch_name: find all possible @-marks
When we parse a string like "foo@{upstream}", we look for
the first "@"-sign, and check to see if it is an upstream
mark. However, since branch names can contain an @, we may
also see "@foo@{upstream}". In this case, we check only the
first @, and ignore the second. As a result, we do not find
the upstream.
We can solve this by iterating through all @-marks in the
string, and seeing if any is a legitimate upstream or
empty-at mark.
Another strategy would be to parse from the right-hand side
of the string. However, that does not work for the
"empty_at" case, which allows "@@{upstream}". We need to
find the left-most one in this case (and we then recurse as
"HEAD@{upstream}").
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-15 16:40:46 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'upstream of branch with @ at start' '
|
|
|
|
full_name @funny@{u} >actual &&
|
|
|
|
echo refs/remotes/origin/side >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'upstream of branch with @ at end' '
|
|
|
|
full_name funny@@{u} >actual &&
|
|
|
|
echo refs/remotes/origin/side >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2013-03-18 06:17:09 +08:00
|
|
|
test_expect_success 'refs/heads/my-side@{upstream} does not resolve to my-side{upstream}' '
|
|
|
|
test_must_fail full_name refs/heads/my-side@{upstream}
|
|
|
|
'
|
|
|
|
|
2009-09-10 23:25:57 +08:00
|
|
|
test_expect_success 'my-side@{u} resolves to correct commit' '
|
|
|
|
git checkout side &&
|
|
|
|
test_commit 5 &&
|
|
|
|
(cd clone && git fetch) &&
|
|
|
|
test 2 = "$(commit_subject my-side)" &&
|
|
|
|
test 5 = "$(commit_subject my-side@{u})"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'not-tracking@{u} fails' '
|
|
|
|
test_must_fail full_name non-tracking@{u} &&
|
|
|
|
(cd clone && git checkout --no-track -b non-tracking) &&
|
|
|
|
test_must_fail full_name non-tracking@{u}
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '<branch>@{u}@{1} resolves correctly' '
|
|
|
|
test_commit 6 &&
|
|
|
|
(cd clone && git fetch) &&
|
2017-03-27 19:16:55 +08:00
|
|
|
test 5 = $(commit_subject my-side@{u}@{1}) &&
|
|
|
|
test 5 = $(commit_subject my-side@{U}@{1})
|
2009-09-10 23:25:57 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '@{u} without specifying branch fails on a detached HEAD' '
|
|
|
|
git checkout HEAD^0 &&
|
2017-03-27 19:16:55 +08:00
|
|
|
test_must_fail git rev-parse @{u} &&
|
|
|
|
test_must_fail git rev-parse @{U}
|
2009-09-10 23:25:57 +08:00
|
|
|
'
|
|
|
|
|
2010-01-20 17:08:48 +08:00
|
|
|
test_expect_success 'checkout -b new my-side@{u} forks from the same' '
|
|
|
|
(
|
|
|
|
cd clone &&
|
|
|
|
git checkout -b new my-side@{u} &&
|
|
|
|
git rev-parse --symbolic-full-name my-side@{u} >expect &&
|
|
|
|
git rev-parse --symbolic-full-name new@{u} >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2010-01-20 15:17:11 +08:00
|
|
|
test_expect_success 'merge my-side@{u} records the correct name' '
|
2010-01-20 17:08:48 +08:00
|
|
|
(
|
2018-07-02 08:23:41 +08:00
|
|
|
cd clone &&
|
|
|
|
git checkout master &&
|
|
|
|
test_might_fail git branch -D new &&
|
2010-01-20 17:08:48 +08:00
|
|
|
git branch -t new my-side@{u} &&
|
|
|
|
git merge -s ours new@{u} &&
|
2014-05-15 06:12:45 +08:00
|
|
|
git show -s --pretty=tformat:%s >actual &&
|
2019-09-06 06:10:05 +08:00
|
|
|
echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect &&
|
2010-01-20 17:08:48 +08:00
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2010-01-20 15:17:11 +08:00
|
|
|
test_expect_success 'branch -d other@{u}' '
|
2010-01-20 17:08:48 +08:00
|
|
|
git checkout -t -b other master &&
|
|
|
|
git branch -d @{u} &&
|
|
|
|
git for-each-ref refs/heads/master >actual &&
|
2018-07-28 01:48:11 +08:00
|
|
|
test_must_be_empty actual
|
2010-01-20 17:08:48 +08:00
|
|
|
'
|
|
|
|
|
2010-01-20 15:17:11 +08:00
|
|
|
test_expect_success 'checkout other@{u}' '
|
2010-01-20 17:08:48 +08:00
|
|
|
git branch -f master HEAD &&
|
|
|
|
git checkout -t -b another master &&
|
|
|
|
git checkout @{u} &&
|
|
|
|
git symbolic-ref HEAD >actual &&
|
|
|
|
echo refs/heads/master >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2012-04-14 15:54:31 +08:00
|
|
|
test_expect_success 'branch@{u} works when tracking a local branch' '
|
|
|
|
test refs/heads/master = "$(full_name local-master@{u})"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'branch@{u} error message when no upstream' '
|
|
|
|
cat >expect <<-EOF &&
|
2019-09-06 06:10:05 +08:00
|
|
|
fatal: no upstream configured for branch ${SQ}non-tracking${SQ}
|
2012-04-14 15:54:31 +08:00
|
|
|
EOF
|
2018-02-24 07:39:43 +08:00
|
|
|
error_message non-tracking@{u} &&
|
|
|
|
test_i18ncmp expect error
|
2012-04-14 15:54:31 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '@{u} error message when no upstream' '
|
|
|
|
cat >expect <<-EOF &&
|
2019-09-06 06:10:05 +08:00
|
|
|
fatal: no upstream configured for branch ${SQ}master${SQ}
|
2012-04-14 15:54:31 +08:00
|
|
|
EOF
|
|
|
|
test_must_fail git rev-parse --verify @{u} 2>actual &&
|
2012-04-14 15:54:35 +08:00
|
|
|
test_i18ncmp expect actual
|
2012-04-14 15:54:31 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'branch@{u} error message with misspelt branch' '
|
|
|
|
cat >expect <<-EOF &&
|
2019-09-06 06:10:05 +08:00
|
|
|
fatal: no such branch: ${SQ}no-such-branch${SQ}
|
2012-04-14 15:54:31 +08:00
|
|
|
EOF
|
2018-02-24 07:39:43 +08:00
|
|
|
error_message no-such-branch@{u} &&
|
|
|
|
test_i18ncmp expect error
|
2012-04-14 15:54:31 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '@{u} error message when not on a branch' '
|
|
|
|
cat >expect <<-EOF &&
|
sha1_name: fix error message for @{u}
Currently, when no (valid) upstream is configured for a branch, you get
an error like:
$ git show @{u}
error: No upstream configured for branch 'upstream-error'
error: No upstream configured for branch 'upstream-error'
fatal: ambiguous argument '@{u}': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
The "error: " line actually appears twice, and the rest of the error
message is useless. In sha1_name.c:interpret_branch_name(), there is
really no point in processing further if @{u} couldn't be resolved, and
we might as well die() instead of returning an error(). After making
this change, you get:
$ git show @{u}
fatal: No upstream configured for branch 'upstream-error'
Also tweak a few tests in t1507 to expect this output.
This only turns error() that may be called after we know we are
dealing with an @{upstream} marker into die(), without touching
silent error returns "return -1" from the function. Any caller that
wants to handle an error condition itself will not be hurt by this
change, unless they want to see the message from error() and then
exit silently without giving its own message, which needs to be
fixed anyway.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-05-22 18:39:54 +08:00
|
|
|
fatal: HEAD does not point to a branch
|
2012-04-14 15:54:31 +08:00
|
|
|
EOF
|
|
|
|
git checkout HEAD^0 &&
|
|
|
|
test_must_fail git rev-parse --verify @{u} 2>actual &&
|
2012-04-14 15:54:35 +08:00
|
|
|
test_i18ncmp expect actual
|
2012-04-14 15:54:31 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'branch@{u} error message if upstream branch not fetched' '
|
|
|
|
cat >expect <<-EOF &&
|
2019-09-06 06:10:05 +08:00
|
|
|
fatal: upstream branch ${SQ}refs/heads/side${SQ} not stored as a remote-tracking branch
|
2012-04-14 15:54:31 +08:00
|
|
|
EOF
|
2018-02-24 07:39:43 +08:00
|
|
|
error_message bad-upstream@{u} &&
|
|
|
|
test_i18ncmp expect error
|
2012-04-14 15:54:31 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'pull works when tracking a local branch' '
|
|
|
|
(
|
|
|
|
cd clone &&
|
|
|
|
git checkout local-master &&
|
|
|
|
git pull
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
# makes sense if the previous one succeeded
|
|
|
|
test_expect_success '@{u} works when tracking a local branch' '
|
|
|
|
test refs/heads/master = "$(full_name @{u})"
|
|
|
|
'
|
|
|
|
|
2018-03-26 03:20:51 +08:00
|
|
|
commit=$(git rev-parse HEAD)
|
2010-01-27 05:48:28 +08:00
|
|
|
cat >expect <<EOF
|
2018-03-26 03:20:51 +08:00
|
|
|
commit $commit
|
2010-01-27 05:48:28 +08:00
|
|
|
Reflog: master@{0} (C O Mitter <committer@example.com>)
|
|
|
|
Reflog message: branch: Created from HEAD
|
|
|
|
Author: A U Thor <author@example.com>
|
|
|
|
Date: Thu Apr 7 15:15:13 2005 -0700
|
|
|
|
|
|
|
|
3
|
|
|
|
EOF
|
|
|
|
test_expect_success 'log -g other@{u}' '
|
|
|
|
git log -1 -g other@{u} >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
cat >expect <<EOF
|
2018-03-26 03:20:51 +08:00
|
|
|
commit $commit
|
2010-01-27 05:48:28 +08:00
|
|
|
Reflog: master@{Thu Apr 7 15:17:13 2005 -0700} (C O Mitter <committer@example.com>)
|
|
|
|
Reflog message: branch: Created from HEAD
|
|
|
|
Author: A U Thor <author@example.com>
|
|
|
|
Date: Thu Apr 7 15:15:13 2005 -0700
|
|
|
|
|
|
|
|
3
|
|
|
|
EOF
|
|
|
|
|
|
|
|
test_expect_success 'log -g other@{u}@{now}' '
|
|
|
|
git log -1 -g other@{u}@{now} >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
interpret_branch_name: avoid @{upstream} past colon
get_sha1() cannot currently parse a valid object name like
"HEAD:@{upstream}" (assuming that such an oddly named file
exists in the HEAD commit). It takes two passes to parse the
string:
1. It first considers the whole thing as a ref, which
results in looking for the upstream of "HEAD:".
2. It finds the colon, parses "HEAD" as a tree-ish, and then
finds the path "@{upstream}" in the tree.
For a path that looks like a normal reflog (e.g.,
"HEAD:@{yesterday}"), the first pass is a no-op. We try to
dwim_ref("HEAD:"), that returns zero refs, and we proceed
with colon-parsing.
For "HEAD:@{upstream}", though, the first pass ends up in
interpret_upstream_mark, which tries to find the branch
"HEAD:". When it sees that the branch does not exist, it
actually dies rather than returning an error to the caller.
As a result, we never make it to the second pass.
One obvious way of fixing this would be to teach
interpret_upstream_mark to simply report "no, this isn't an
upstream" in such a case. However, that would make the
error-reporting for legitimate upstream cases significantly
worse. Something like "bogus@{upstream}" would simply report
"unknown revision: bogus@{upstream}", while the current code
diagnoses a wide variety of possible misconfigurations (no
such branch, branch exists but does not have upstream, etc).
However, we can take advantage of the fact that a branch
name cannot contain a colon. Therefore even if we find an
upstream mark, any prefix with a colon must mean that
the upstream mark we found is actually a pathname, and
should be disregarded completely. This patch implements that
logic.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-15 16:37:23 +08:00
|
|
|
test_expect_success '@{reflog}-parsing does not look beyond colon' '
|
|
|
|
echo content >@{yesterday} &&
|
|
|
|
git add @{yesterday} &&
|
|
|
|
git commit -m "funny reflog file" &&
|
|
|
|
git hash-object @{yesterday} >expect &&
|
|
|
|
git rev-parse HEAD:@{yesterday} >actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '@{upstream}-parsing does not look beyond colon' '
|
|
|
|
echo content >@{upstream} &&
|
|
|
|
git add @{upstream} &&
|
|
|
|
git commit -m "funny upstream file" &&
|
|
|
|
git hash-object @{upstream} >expect &&
|
|
|
|
git rev-parse HEAD:@{upstream} >actual
|
|
|
|
'
|
|
|
|
|
2009-09-10 23:25:57 +08:00
|
|
|
test_done
|