зеркало из https://github.com/microsoft/git.git
Merge branch 'jc/push-upstream-sanity' into maint
The 'push to upstream' implementation was broken in some corner cases. "git push $there" without refspec, when the current branch is set to push to a remote different from $there, used to push to $there using the upstream information to a remote unreleated to $there. * jc/push-upstream-sanity: push: error out when the "upstream" semantics does not make sense
This commit is contained in:
Коммит
731673b15e
|
@ -65,6 +65,16 @@ static void set_refspecs(const char **refs, int nr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int push_url_of_remote(struct remote *remote, const char ***url_p)
|
||||||
|
{
|
||||||
|
if (remote->pushurl_nr) {
|
||||||
|
*url_p = remote->pushurl;
|
||||||
|
return remote->pushurl_nr;
|
||||||
|
}
|
||||||
|
*url_p = remote->url;
|
||||||
|
return remote->url_nr;
|
||||||
|
}
|
||||||
|
|
||||||
static void setup_push_upstream(struct remote *remote)
|
static void setup_push_upstream(struct remote *remote)
|
||||||
{
|
{
|
||||||
struct strbuf refspec = STRBUF_INIT;
|
struct strbuf refspec = STRBUF_INIT;
|
||||||
|
@ -76,7 +86,7 @@ static void setup_push_upstream(struct remote *remote)
|
||||||
"\n"
|
"\n"
|
||||||
" git push %s HEAD:<name-of-remote-branch>\n"),
|
" git push %s HEAD:<name-of-remote-branch>\n"),
|
||||||
remote->name);
|
remote->name);
|
||||||
if (!branch->merge_nr || !branch->merge)
|
if (!branch->merge_nr || !branch->merge || !branch->remote_name)
|
||||||
die(_("The current branch %s has no upstream branch.\n"
|
die(_("The current branch %s has no upstream branch.\n"
|
||||||
"To push the current branch and set the remote as upstream, use\n"
|
"To push the current branch and set the remote as upstream, use\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -87,6 +97,12 @@ static void setup_push_upstream(struct remote *remote)
|
||||||
if (branch->merge_nr != 1)
|
if (branch->merge_nr != 1)
|
||||||
die(_("The current branch %s has multiple upstream branches, "
|
die(_("The current branch %s has multiple upstream branches, "
|
||||||
"refusing to push."), branch->name);
|
"refusing to push."), branch->name);
|
||||||
|
if (strcmp(branch->remote_name, remote->name))
|
||||||
|
die(_("You are pushing to remote '%s', which is not the upstream of\n"
|
||||||
|
"your current branch '%s', without telling me what to push\n"
|
||||||
|
"to update which remote branch."),
|
||||||
|
remote->name, branch->name);
|
||||||
|
|
||||||
strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
|
strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
|
||||||
add_refspec(refspec.buf);
|
add_refspec(refspec.buf);
|
||||||
}
|
}
|
||||||
|
@ -196,13 +212,7 @@ static int do_push(const char *repo, int flags)
|
||||||
setup_default_push_refspecs(remote);
|
setup_default_push_refspecs(remote);
|
||||||
}
|
}
|
||||||
errs = 0;
|
errs = 0;
|
||||||
if (remote->pushurl_nr) {
|
url_nr = push_url_of_remote(remote, &url);
|
||||||
url = remote->pushurl;
|
|
||||||
url_nr = remote->pushurl_nr;
|
|
||||||
} else {
|
|
||||||
url = remote->url;
|
|
||||||
url_nr = remote->url_nr;
|
|
||||||
}
|
|
||||||
if (url_nr) {
|
if (url_nr) {
|
||||||
for (i = 0; i < url_nr; i++) {
|
for (i = 0; i < url_nr; i++) {
|
||||||
struct transport *transport =
|
struct transport *transport =
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
test_description='check various push.default settings'
|
||||||
|
. ./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
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '"upstream" pushes to configured upstream' '
|
||||||
|
git checkout master &&
|
||||||
|
test_config branch.master.remote parent1 &&
|
||||||
|
test_config branch.master.merge refs/heads/foo &&
|
||||||
|
test_config push.default upstream &&
|
||||||
|
test_commit two &&
|
||||||
|
git push &&
|
||||||
|
echo two >expect &&
|
||||||
|
git --git-dir=repo1 log -1 --format=%s foo >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '"upstream" does not push on unconfigured remote' '
|
||||||
|
git checkout master &&
|
||||||
|
test_unconfig branch.master.remote &&
|
||||||
|
test_config push.default upstream &&
|
||||||
|
test_commit three &&
|
||||||
|
test_must_fail git push
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '"upstream" does not push on unconfigured branch' '
|
||||||
|
git checkout master &&
|
||||||
|
test_config branch.master.remote parent1 &&
|
||||||
|
test_unconfig branch.master.merge &&
|
||||||
|
test_config push.default upstream
|
||||||
|
test_commit four &&
|
||||||
|
test_must_fail git push
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success '"upstream" does not push when remotes do not match' '
|
||||||
|
git checkout master &&
|
||||||
|
test_config branch.master.remote parent1 &&
|
||||||
|
test_config branch.master.merge refs/heads/foo &&
|
||||||
|
test_config push.default upstream &&
|
||||||
|
test_commit five &&
|
||||||
|
test_must_fail git push parent2
|
||||||
|
'
|
||||||
|
|
||||||
|
test_done
|
Загрузка…
Ссылка в новой задаче