git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/6] push: change `simple` to accommodate triangular workflows

From
Ramkumar Ramachandra <artagnon@gmail.com>
Date
Jun 19, 2013, 11:11 UTC
Message-ID
<1371640304-26019-4-git-send-email-artagnon@gmail.com>
In-Reply-To
<1371640304-26019-1-git-send-email-artagnon@gmail.com>

When remote.pushdefault or branch.<name>.pushremote is set (a triangular workflow feature), master@{u} != origin, and push.default is set to `upstream` or `simple`:

  $ git push
  fatal: You are pushing to remote 'origin', which is not the upstream of
  your current branch 'master', without telling me what to push
  to update which remote branch.

Unfortunately, in the case of `upstream`, the very name indicates that it is only suitable for use in central workflows; let us not even attempt to give it a new meaning in triangular workflows, and error out as usual. However, the `simple` does not have this problem: it is poised to be the default for Git 2.0, and we would definitely like it to do something sensible in triangular workflows.

Decouple `simple` from `upstream` completely, and change it to mean `current` with a safety feature: a `push` and `pull` should not be asymmetrical in the special case of central workflows.

Reported-by: Leandro Lucarella <leandro.lucarella@sociomantic.com>
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
 Documentation/config.txt | 10 ++++++----
 builtin/push.c           | 21 ++++++++++++++++++++-
 t/t5528-push-default.sh  |  2 +-
 3 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 9f04f74..81628e8 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1850,10 +1850,12 @@ push.default::
   symmetrical to `pull` in central workflows, and cannot be used in
   non-central workflows.
 
-* `simple` - like `upstream`, but refuses to push if the upstream
-  branch's name is different from the local one. This is the safest
-  option and is well-suited for beginners. It will become the default
-  in Git 2.0.
+* `simple` - a safer version of `current`; push the current branch to
+  update a branch with the same name on the receiving end, with a
+  safety feature: in central workflows, error out if
+  branch.$branch.merge is set and not equal to $branch, to make sure
+  that a `push` and `push` are never asymmetrical.  It will become the
+  default in Git 2.0.
 
 * `matching` - push all branches having the same name on both ends
   (essentially ignoring all newly created local branches).
diff --git a/builtin/push.c b/builtin/push.c
index 2d84d10..d8d27d9 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -120,6 +120,25 @@ static const char message_detached_head_die[] =
 	   "\n"
 	   "    git push %s HEAD:<name-of-remote-branch>\n");
 
+static void setup_push_simple(struct remote *remote)
+{
+	struct branch *branch = branch_get(NULL);
+	if (!branch)
+		die(_(message_detached_head_die), remote->name);
+	if (!branch->merge_nr || !branch->merge || !branch->remote_name)
+		/* No upstream configured */
+		goto end;
+	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) &&
+		strcmp(branch->refname, branch->merge[0]->src))
+		/* Central workflow safety feature */
+		die_push_simple(branch, remote);
+end:
+	add_refspec(branch->name);
+}
+
 static void setup_push_upstream(struct remote *remote, int simple)
 {
 	struct strbuf refspec = STRBUF_INIT;
@@ -188,7 +207,7 @@ static void setup_default_push_refspecs(struct remote *remote)
 		break;
 
 	case PUSH_DEFAULT_SIMPLE:
-		setup_push_upstream(remote, 1);
+		setup_push_simple(remote);
 		break;
 
 	case PUSH_DEFAULT_UPSTREAM:
diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh
index 69ce6bf..e54dd02 100755
--- a/t/t5528-push-default.sh
+++ b/t/t5528-push-default.sh
@@ -85,7 +85,7 @@ test_expect_success 'push from/to new branch with current creates remote branch'
 test_expect_success 'push to existing branch, with no upstream configured' '
 	test_config branch.master.remote repo1 &&
 	git checkout master &&
-	test_push_failure simple &&
+	test_push_success simple master &&
 	test_push_failure upstream
 '
 
-- 
1.8.3.1.454.g30263f3.dirty
Previous: Johan HerlandNext: Junio C Hamano
Message 8 of 24 in “push.default in the triangular world”
  1. 0/6 push.default in the triangular worldRamkumar Ramachandra, Jun 19, 2013
  2. 1/6 t/t5528-push-default: remove redundant test_config linesRamkumar Ramachandra, Jun 19, 2013
  3. Junio C HamanoJun 19, 2013
  4. 2/6 config doc: rewrite push.default sectionRamkumar Ramachandra, Jun 19, 2013
  5. Junio C HamanoJun 19, 2013
  6. Junio C HamanoJun 20, 2013
  7. Johan HerlandJun 20, 2013
  8. 3/6 push: change `simple` to accommodate triangular workflowsRamkumar Ramachandra, Jun 19, 2013
  9. Junio C HamanoJun 19, 2013
  10. Junio C HamanoJun 20, 2013
  11. Ramkumar RamachandraJun 20, 2013
  12. Junio C HamanoJun 20, 2013
  13. Philip OakleyJun 20, 2013
  14. Junio C HamanoJun 20, 2013
  15. Ramkumar RamachandraJun 20, 2013
  16. Junio C HamanoJun 20, 2013
  17. Junio C HamanoJun 20, 2013
  18. Junio C HamanoJun 20, 2013
  19. 4/6 push: remove dead code in setup_push_upstream()Ramkumar Ramachandra, Jun 19, 2013
  20. Junio C HamanoJun 19, 2013
  21. 5/6 t/t5528-push-default: generalize test_push_*Ramkumar Ramachandra, Jun 19, 2013
  22. Junio C HamanoJun 19, 2013
  23. 6/6 t/t5528-push-default: test pushdefault workflowsRamkumar Ramachandra, Jun 19, 2013
  24. Junio C HamanoJun 19, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.