Re: push.default: current vs upstream

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jeff King <peff@xxxxxxxx> writes:

> Has somebody volunteered to make the necessary fixes to "push.default =
> upstream" in the first place? At the very least we need the fixes you
> mentioned in your mail[2] before it can become the default.
> ...
> [2] http://article.gmane.org/gmane.comp.version-control.git/194295

There were two issues I raised in that message.  It turns out that we
already have the code for the first one.  The second one should look
something like this:

-- >8 --
Subject: push: detect nonsense "upstream" check more carefully

The user can say "git push" without specifying any refspec.  When using
"upstream" semantics via the push.default configuration, the user wants to
update the "upstream" branch, which is the branch at a remote repository
the current branch is set to integrate with, with this command.

There are cases that "git push" do not make sense when push.default is set
to "upstream":

 - 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 both branch.$name.remote and
   branch.$name.merge configured, but the user said "git push $there",
   where $there does not match what "branch.$name.remote" is configured
   to.  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 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@xxxxxxxxx>
---
 builtin/push.c |   32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/builtin/push.c b/builtin/push.c
index d315475..3e18cd3 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -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)
 {
 	struct strbuf refspec = STRBUF_INIT;
@@ -76,7 +86,7 @@ static void setup_push_upstream(struct remote *remote)
 		    "\n"
 		    "    git push %s HEAD:<name-of-remote-branch>\n"),
 		    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"
 		    "To push the current branch and set the remote as upstream, use\n"
 		    "\n"
@@ -87,6 +97,18 @@ static void setup_push_upstream(struct remote *remote)
 	if (branch->merge_nr != 1)
 		die(_("The current branch %s has multiple upstream branches, "
 		    "refusing to push."), branch->name);
+	if (strcmp(branch->remote_name, remote->name)) {
+		struct remote *branch_dest = remote_get(branch->remote_name);
+		const char **branch_dest_url, **dest_url;
+
+		if (!push_url_of_remote(remote, &dest_url) ||
+		    !push_url_of_remote(branch_dest, &branch_dest_url) ||
+		    strcmp(dest_url[0], branch_dest_url[0]))
+			die(_("You are pushing to remote '%s', which is not the "
+			      "upstream of your\ncurrent branch '%s'.\n"),
+			    remote->name, branch->name);
+	}
+
 	strbuf_addf(&refspec, "%s:%s", branch->name, branch->merge[0]->src);
 	add_refspec(refspec.buf);
 }
@@ -196,13 +218,7 @@ static int do_push(const char *repo, int flags)
 			setup_default_push_refspecs(remote);
 	}
 	errs = 0;
-	if (remote->pushurl_nr) {
-		url = remote->pushurl;
-		url_nr = remote->pushurl_nr;
-	} else {
-		url = remote->url;
-		url_nr = remote->url_nr;
-	}
+	url_nr = push_url_of_remote(remote, &url);
 	if (url_nr) {
 		for (i = 0; i < url_nr; i++) {
 			struct transport *transport =
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]