push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='check various push.default settings'
|
2020-11-18 23:44:33 +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
|
|
|
|
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success 'setup bare remotes' '
|
|
|
|
git init --bare repo1 &&
|
|
|
|
git remote add parent1 repo1 &&
|
|
|
|
git init --bare repo2 &&
|
|
|
|
git remote add parent2 repo2 &&
|
|
|
|
test_commit one &&
|
|
|
|
git push parent1 HEAD &&
|
|
|
|
git push parent2 HEAD
|
|
|
|
'
|
|
|
|
|
2012-04-24 07:50:02 +00:00
|
|
|
# $1 = local revision
|
|
|
|
# $2 = remote revision (tested to be equal to the local one)
|
2013-06-19 11:11:43 +00:00
|
|
|
# $3 = [optional] repo to check for actual output (repo1 by default)
|
2012-04-24 07:50:02 +00:00
|
|
|
check_pushed_commit () {
|
|
|
|
git log -1 --format='%h %s' "$1" >expect &&
|
2013-06-19 11:11:43 +00:00
|
|
|
git --git-dir="${3:-repo1}" log -1 --format='%h %s' "$2" >actual &&
|
2012-04-24 07:50:02 +00:00
|
|
|
test_cmp expect actual
|
|
|
|
}
|
|
|
|
|
|
|
|
# $1 = push.default value
|
|
|
|
# $2 = expected target branch for the push
|
2013-06-19 11:11:43 +00:00
|
|
|
# $3 = [optional] repo to check for actual output (repo1 by default)
|
2012-04-24 07:50:02 +00:00
|
|
|
test_push_success () {
|
2015-03-08 15:37:50 +00:00
|
|
|
git ${1:+-c} ${1:+push.default="$1"} push &&
|
2013-06-19 11:11:43 +00:00
|
|
|
check_pushed_commit HEAD "$2" "$3"
|
2012-04-24 07:50:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# $1 = push.default value
|
|
|
|
# check that push fails and does not modify any remote branch
|
|
|
|
test_push_failure () {
|
|
|
|
git --git-dir=repo1 log --no-walk --format='%h %s' --all >expect &&
|
2015-03-08 15:37:50 +00:00
|
|
|
test_must_fail git ${1:+-c} ${1:+push.default="$1"} push &&
|
2012-04-24 07:50:02 +00:00
|
|
|
git --git-dir=repo1 log --no-walk --format='%h %s' --all >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
}
|
|
|
|
|
2013-06-19 11:11:44 +00:00
|
|
|
# $1 = success or failure
|
|
|
|
# $2 = push.default value
|
2020-11-18 23:44:33 +00:00
|
|
|
# $3 = branch to check for actual output (main or foo)
|
2013-06-19 11:11:44 +00:00
|
|
|
# $4 = [optional] switch to triangular workflow
|
|
|
|
test_pushdefault_workflow () {
|
|
|
|
workflow=central
|
|
|
|
pushdefault=parent1
|
|
|
|
if test -n "${4-}"; then
|
|
|
|
workflow=triangular
|
|
|
|
pushdefault=parent2
|
|
|
|
fi
|
|
|
|
test_expect_success "push.default = $2 $1 in $workflow workflows" "
|
2020-11-18 23:44:33 +00:00
|
|
|
test_config branch.main.remote parent1 &&
|
|
|
|
test_config branch.main.merge refs/heads/foo &&
|
2013-06-19 11:11:44 +00:00
|
|
|
test_config remote.pushdefault $pushdefault &&
|
|
|
|
test_commit commit-for-$2${4+-triangular} &&
|
|
|
|
test_push_$1 $2 $3 ${4+repo2}
|
|
|
|
"
|
|
|
|
}
|
|
|
|
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
test_expect_success '"upstream" pushes to configured upstream' '
|
2020-11-18 23:44:33 +00:00
|
|
|
git checkout main &&
|
|
|
|
test_config branch.main.remote parent1 &&
|
|
|
|
test_config branch.main.merge refs/heads/foo &&
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
test_commit two &&
|
2012-04-24 07:50:02 +00:00
|
|
|
test_push_success upstream foo
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"upstream" does not push on unconfigured remote' '
|
2020-11-18 23:44:33 +00:00
|
|
|
git checkout main &&
|
|
|
|
test_unconfig branch.main.remote &&
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
test_commit three &&
|
2012-04-24 07:50:02 +00:00
|
|
|
test_push_failure upstream
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"upstream" does not push on unconfigured branch' '
|
2020-11-18 23:44:33 +00:00
|
|
|
git checkout main &&
|
|
|
|
test_config branch.main.remote parent1 &&
|
|
|
|
test_unconfig branch.main.merge &&
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
test_commit four &&
|
2012-04-24 07:50:02 +00:00
|
|
|
test_push_failure upstream
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"upstream" does not push when remotes do not match' '
|
2020-11-18 23:44:33 +00:00
|
|
|
git checkout main &&
|
|
|
|
test_config branch.main.remote parent1 &&
|
|
|
|
test_config branch.main.merge refs/heads/foo &&
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
test_config push.default upstream &&
|
|
|
|
test_commit five &&
|
|
|
|
test_must_fail git push parent2
|
|
|
|
'
|
|
|
|
|
push: default to single remote even when not named origin
With "push.default=current" configured, a simple "git push" will push to
the same-name branch on the current branch's branch.<name>.pushRemote, or
remote.pushDefault, or origin. If none of these are defined, the push will
fail with error "fatal: No configured push destination".
The same "default to origin if no config" behavior applies with
"push.default=matching".
Other commands use "origin" as a default when there are multiple options,
but default to the single remote when there is only one - for example,
"git checkout <something>". This "assume the single remote if there is
only one" behavior is more friendly/useful than a defaulting behavior
that only uses the name "origin" no matter what.
Update "git push" to also default to the single remote (and finally fall
back to "origin" as default if there are several), for
"push.default=current" and for other current and future remote-defaulting
push behaviors.
This change also modifies the behavior of ls-remote in a consistent way,
so defaulting not only supplies 'origin', but any single configured remote
also.
Document the change in behavior, correct incorrect assumptions in related
tests, and add test cases reflecting this new single-remote-defaulting
behavior.
Signed-off-by: Tao Klerks <tao@klerks.biz>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-29 09:56:45 +00:00
|
|
|
test_expect_success '"current" does not push when multiple remotes and none origin' '
|
|
|
|
git checkout main &&
|
|
|
|
test_config push.default current &&
|
|
|
|
test_commit current-multi &&
|
|
|
|
test_must_fail git push
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"current" pushes when remote explicitly specified' '
|
|
|
|
git checkout main &&
|
|
|
|
test_config push.default current &&
|
|
|
|
test_commit current-specified &&
|
|
|
|
git push parent1
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"current" pushes to origin when no remote specified among multiple' '
|
|
|
|
git checkout main &&
|
|
|
|
test_config remote.origin.url repo1 &&
|
|
|
|
test_config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" &&
|
|
|
|
test_commit current-origin &&
|
|
|
|
test_push_success current main
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '"current" pushes to single remote even when not specified' '
|
|
|
|
git checkout main &&
|
|
|
|
test_when_finished git remote add parent1 repo1 &&
|
|
|
|
git remote remove parent1 &&
|
|
|
|
test_commit current-implied &&
|
|
|
|
test_push_success current main repo2
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push from/to new branch with non-defaulted remote fails with upstream, matching, current and simple ' '
|
2012-04-24 07:50:03 +00:00
|
|
|
git checkout -b new-branch &&
|
|
|
|
test_push_failure simple &&
|
|
|
|
test_push_failure matching &&
|
push: default to single remote even when not named origin
With "push.default=current" configured, a simple "git push" will push to
the same-name branch on the current branch's branch.<name>.pushRemote, or
remote.pushDefault, or origin. If none of these are defined, the push will
fail with error "fatal: No configured push destination".
The same "default to origin if no config" behavior applies with
"push.default=matching".
Other commands use "origin" as a default when there are multiple options,
but default to the single remote when there is only one - for example,
"git checkout <something>". This "assume the single remote if there is
only one" behavior is more friendly/useful than a defaulting behavior
that only uses the name "origin" no matter what.
Update "git push" to also default to the single remote (and finally fall
back to "origin" as default if there are several), for
"push.default=current" and for other current and future remote-defaulting
push behaviors.
This change also modifies the behavior of ls-remote in a consistent way,
so defaulting not only supplies 'origin', but any single configured remote
also.
Document the change in behavior, correct incorrect assumptions in related
tests, and add test cases reflecting this new single-remote-defaulting
behavior.
Signed-off-by: Tao Klerks <tao@klerks.biz>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-29 09:56:45 +00:00
|
|
|
test_push_failure upstream &&
|
|
|
|
test_push_failure current
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push from/to new branch fails with upstream and simple ' '
|
|
|
|
git checkout -b new-branch-1 &&
|
|
|
|
test_config branch.new-branch-1.remote parent1 &&
|
|
|
|
test_push_failure simple &&
|
2012-04-24 07:50:03 +00:00
|
|
|
test_push_failure upstream
|
|
|
|
'
|
|
|
|
|
push: default to single remote even when not named origin
With "push.default=current" configured, a simple "git push" will push to
the same-name branch on the current branch's branch.<name>.pushRemote, or
remote.pushDefault, or origin. If none of these are defined, the push will
fail with error "fatal: No configured push destination".
The same "default to origin if no config" behavior applies with
"push.default=matching".
Other commands use "origin" as a default when there are multiple options,
but default to the single remote when there is only one - for example,
"git checkout <something>". This "assume the single remote if there is
only one" behavior is more friendly/useful than a defaulting behavior
that only uses the name "origin" no matter what.
Update "git push" to also default to the single remote (and finally fall
back to "origin" as default if there are several), for
"push.default=current" and for other current and future remote-defaulting
push behaviors.
This change also modifies the behavior of ls-remote in a consistent way,
so defaulting not only supplies 'origin', but any single configured remote
also.
Document the change in behavior, correct incorrect assumptions in related
tests, and add test cases reflecting this new single-remote-defaulting
behavior.
Signed-off-by: Tao Klerks <tao@klerks.biz>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-29 09:56:45 +00:00
|
|
|
# The behavior here is surprising but not entirely wrong:
|
|
|
|
# - the current branch is used to determine the target remote
|
|
|
|
# - the "matching" push default pushes matching branches, *ignoring* the
|
|
|
|
# current new branch as it does not have upstream tracking
|
|
|
|
# - the default push succeeds
|
|
|
|
#
|
|
|
|
# A previous test expected this to fail, but for the wrong reasons:
|
|
|
|
# it expected a fail becaause the branch is new and cannot be pushed, but
|
|
|
|
# in fact it was failing because of an ambiguous remote
|
|
|
|
#
|
|
|
|
test_expect_failure 'push from/to new branch fails with matching ' '
|
|
|
|
git checkout -b new-branch-2 &&
|
|
|
|
test_config branch.new-branch-2.remote parent1 &&
|
|
|
|
test_push_failure matching
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push from/to branch with tracking fails with nothing ' '
|
|
|
|
git checkout -b tracked-branch &&
|
|
|
|
test_config branch.tracked-branch.remote parent1 &&
|
|
|
|
test_config branch.tracked-branch.merge refs/heads/tracked-branch &&
|
|
|
|
test_push_failure nothing
|
|
|
|
'
|
|
|
|
|
push: new config option "push.autoSetupRemote" supports "simple" push
In some "simple" centralized workflows, users expect remote tracking
branch names to match local branch names. "git push" pushes to the
remote version/instance of the branch, and "git pull" pulls any changes
to the remote branch (changes made by the same user in another place, or
by other users).
This expectation is supported by the push.default default option "simple"
which refuses a default push for a mismatching tracking branch name, and
by the new branch.autosetupmerge option, "simple", which only sets up
remote tracking for same-name remote branches.
When a new branch has been created by the user and has not yet been
pushed (and push.default is not set to "current"), the user is prompted
with a "The current branch %s has no upstream branch" error, and
instructions on how to push and add tracking.
This error is helpful in that following the advice once per branch
"resolves" the issue for that branch forever, but inconvenient in that
for the "simple" centralized workflow, this is always the right thing to
do, so it would be better to just do it.
Support this workflow with a new config setting, push.autoSetupRemote,
which will cause a default push, when there is no remote tracking branch
configured, to push to the same-name on the remote and --set-upstream.
Also add a hint offering this new option when the "The current branch %s
has no upstream branch" error is encountered, and add corresponding tests.
Signed-off-by: Tao Klerks <tao@klerks.biz>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-04-29 09:56:46 +00:00
|
|
|
test_expect_success 'push from/to new branch succeeds with upstream if push.autoSetupRemote' '
|
|
|
|
git checkout -b new-branch-a &&
|
|
|
|
test_config push.autoSetupRemote true &&
|
|
|
|
test_config branch.new-branch-a.remote parent1 &&
|
|
|
|
test_push_success upstream new-branch-a
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push from/to new branch succeeds with simple if push.autoSetupRemote' '
|
|
|
|
git checkout -b new-branch-c &&
|
|
|
|
test_config push.autoSetupRemote true &&
|
|
|
|
test_config branch.new-branch-c.remote parent1 &&
|
|
|
|
test_push_success simple new-branch-c
|
|
|
|
'
|
|
|
|
|
2020-06-24 14:46:29 +00:00
|
|
|
test_expect_success '"matching" fails if none match' '
|
|
|
|
git init --bare empty &&
|
|
|
|
test_must_fail git push empty : 2>actual &&
|
|
|
|
test_i18ngrep "Perhaps you should specify a branch" actual
|
|
|
|
'
|
|
|
|
|
2016-10-31 20:38:35 +00:00
|
|
|
test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
|
|
|
|
git checkout -b ambiguous &&
|
|
|
|
test_config branch.ambiguous.remote parent1 &&
|
|
|
|
test_config branch.ambiguous.merge refs/heads/ambiguous &&
|
|
|
|
git tag ambiguous &&
|
|
|
|
test_push_success simple ambiguous &&
|
|
|
|
test_push_success matching ambiguous &&
|
|
|
|
test_push_success upstream ambiguous
|
|
|
|
'
|
|
|
|
|
2012-04-24 07:50:03 +00:00
|
|
|
test_expect_success 'push from/to new branch with current creates remote branch' '
|
|
|
|
test_config branch.new-branch.remote repo1 &&
|
|
|
|
git checkout new-branch &&
|
|
|
|
test_push_success current new-branch
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push to existing branch, with no upstream configured' '
|
2020-11-18 23:44:33 +00:00
|
|
|
test_config branch.main.remote repo1 &&
|
|
|
|
git checkout main &&
|
2012-04-24 07:50:03 +00:00
|
|
|
test_push_failure simple &&
|
|
|
|
test_push_failure upstream
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push to existing branch, upstream configured with same name' '
|
2020-11-18 23:44:33 +00:00
|
|
|
test_config branch.main.remote repo1 &&
|
|
|
|
test_config branch.main.merge refs/heads/main &&
|
|
|
|
git checkout main &&
|
2012-04-24 07:50:03 +00:00
|
|
|
test_commit six &&
|
2020-11-18 23:44:33 +00:00
|
|
|
test_push_success upstream main &&
|
2012-04-24 07:50:03 +00:00
|
|
|
test_commit seven &&
|
2020-11-18 23:44:33 +00:00
|
|
|
test_push_success simple main
|
2012-04-24 07:50:03 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'push to existing branch, upstream configured with different name' '
|
2020-11-18 23:44:33 +00:00
|
|
|
test_config branch.main.remote repo1 &&
|
|
|
|
test_config branch.main.merge refs/heads/other-name &&
|
|
|
|
git checkout main &&
|
2012-04-24 07:50:03 +00:00
|
|
|
test_commit eight &&
|
|
|
|
test_push_success upstream other-name &&
|
|
|
|
test_commit nine &&
|
|
|
|
test_push_failure simple &&
|
|
|
|
git --git-dir=repo1 log -1 --format="%h %s" "other-name" >expect-other-name &&
|
2020-11-18 23:44:33 +00:00
|
|
|
test_push_success current main &&
|
2012-04-24 07:50:03 +00:00
|
|
|
git --git-dir=repo1 log -1 --format="%h %s" "other-name" >actual-other-name &&
|
|
|
|
test_cmp expect-other-name actual-other-name
|
|
|
|
'
|
|
|
|
|
2020-11-18 23:44:33 +00:00
|
|
|
# We are on 'main', which integrates with 'foo' from parent1
|
2013-06-19 11:11:44 +00:00
|
|
|
# remote (set in test_pushdefault_workflow helper). Push to
|
|
|
|
# parent1 in centralized, and push to parent2 in triangular workflow.
|
2020-11-18 23:44:33 +00:00
|
|
|
# The parent1 repository has 'main' and 'foo' branches, while
|
|
|
|
# the parent2 repository has only 'main' branch.
|
2013-06-19 11:11:44 +00:00
|
|
|
#
|
|
|
|
# test_pushdefault_workflow() arguments:
|
|
|
|
# $1 = success or failure
|
|
|
|
# $2 = push.default value
|
2020-11-18 23:44:33 +00:00
|
|
|
# $3 = branch to check for actual output (main or foo)
|
2013-06-19 11:11:44 +00:00
|
|
|
# $4 = [optional] switch to triangular workflow
|
|
|
|
|
2020-11-18 23:44:33 +00:00
|
|
|
# update parent1's main (which is not our upstream)
|
|
|
|
test_pushdefault_workflow success current main
|
2013-06-19 11:11:44 +00:00
|
|
|
|
|
|
|
# update parent1's foo (which is our upstream)
|
|
|
|
test_pushdefault_workflow success upstream foo
|
|
|
|
|
2019-11-05 17:07:24 +00:00
|
|
|
# upstream is foo which is not the name of the current branch
|
2020-11-18 23:44:33 +00:00
|
|
|
test_pushdefault_workflow failure simple main
|
2013-06-19 11:11:44 +00:00
|
|
|
|
2020-11-18 23:44:33 +00:00
|
|
|
# main and foo are updated
|
|
|
|
test_pushdefault_workflow success matching main
|
2013-06-19 11:11:44 +00:00
|
|
|
|
2020-11-18 23:44:33 +00:00
|
|
|
# main is updated
|
|
|
|
test_pushdefault_workflow success current main triangular
|
2013-06-19 11:11:44 +00:00
|
|
|
|
|
|
|
# upstream mode cannot be used in triangular
|
|
|
|
test_pushdefault_workflow failure upstream foo triangular
|
|
|
|
|
|
|
|
# in triangular, 'simple' works as 'current' and update the branch
|
|
|
|
# with the same name.
|
2020-11-18 23:44:33 +00:00
|
|
|
test_pushdefault_workflow success simple main triangular
|
2013-06-19 11:11:44 +00:00
|
|
|
|
2020-11-18 23:44:33 +00:00
|
|
|
# main is updated (parent2 does not have foo)
|
|
|
|
test_pushdefault_workflow success matching main triangular
|
2013-06-19 11:11:44 +00:00
|
|
|
|
2014-11-27 03:43:06 +00:00
|
|
|
# default tests, when no push-default is specified. This
|
|
|
|
# should behave the same as "simple" in non-triangular
|
|
|
|
# settings, and as "current" otherwise.
|
|
|
|
|
|
|
|
test_expect_success 'default behavior allows "simple" push' '
|
2020-11-18 23:44:33 +00:00
|
|
|
test_config branch.main.remote parent1 &&
|
|
|
|
test_config branch.main.merge refs/heads/main &&
|
2014-11-27 03:43:06 +00:00
|
|
|
test_config remote.pushdefault parent1 &&
|
2020-11-18 23:44:33 +00:00
|
|
|
test_commit default-main-main &&
|
|
|
|
test_push_success "" main
|
2014-11-27 03:43:06 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'default behavior rejects non-simple push' '
|
2020-11-18 23:44:33 +00:00
|
|
|
test_config branch.main.remote parent1 &&
|
|
|
|
test_config branch.main.merge refs/heads/foo &&
|
2014-11-27 03:43:06 +00:00
|
|
|
test_config remote.pushdefault parent1 &&
|
2020-11-18 23:44:33 +00:00
|
|
|
test_commit default-main-foo &&
|
2014-11-27 03:43:06 +00:00
|
|
|
test_push_failure ""
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'default triangular behavior acts like "current"' '
|
2020-11-18 23:44:33 +00:00
|
|
|
test_config branch.main.remote parent1 &&
|
|
|
|
test_config branch.main.merge refs/heads/foo &&
|
2014-11-27 03:43:06 +00:00
|
|
|
test_config remote.pushdefault parent2 &&
|
|
|
|
test_commit default-triangular &&
|
2020-11-18 23:44:33 +00:00
|
|
|
test_push_success "" main repo2
|
2014-11-27 03:43:06 +00:00
|
|
|
'
|
|
|
|
|
push: error out when the "upstream" semantics does not make sense
The user can say "git push" without specifying any refspec. When using
the "upstream" semantics via the push.default configuration, the user
wants to update the "upstream" branch of the current branch, which is the
branch at a remote repository the current branch is set to integrate with,
with this command.
However, there are cases that such a "git push" that uses the "upstream"
semantics does not make sense:
- The current branch does not have branch.$name.remote configured. By
definition, "git push" that does not name where to push to will not
know where to push to. The user may explicitly say "git push $there",
but again, by definition, no branch at repository $there is set to
integrate with the current branch in this case and we wouldn't know
which remote branch to update.
- The current branch does have branch.$name.remote configured, but it
does not specify branch.$name.merge that names what branch at the
remote this branch integrates with. "git push" knows where to push in
this case (or the user may explicitly say "git push $remote" to tell us
where to push), but we do not know which remote branch to update.
- The current branch does have its remote and upstream branch configured,
but the user said "git push $there", where $there is not the remote
named by "branch.$name.remote". By definition, no branch at repository
$there is set to integrate with the current branch in this case, and
this push is not meant to update any branch at the remote repository
$there.
The first two cases were already checked correctly, but the third case was
not checked and we ended up updating the branch named branch.$name.merge
at repository $there, which was totally bogus.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-03-30 23:07:12 +00:00
|
|
|
test_done
|