git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ben Boeckel <mathstuf@gmail.com>
To: git@vger.kernel.org
Cc: "Ben Boeckel" <mathstuf@gmail.com>,
	"Martin Ågren" <martin.agren@gmail.com>,
	"Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
	"Jeff Hostetler" <jeffhost@microsoft.com>,
	"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>,
	"Taylor Blau" <me@ttaylorr.com>
Subject: [PATCH 1/1] config: support setting up a remote tracking branch upon creation
Date: Wed, 28 Jul 2021 09:50:41 -0400	[thread overview]
Message-ID: <20210728135041.501850-2-mathstuf@gmail.com> (raw)
In-Reply-To: <20210728135041.501850-1-mathstuf@gmail.com>

The `branch.autoSetupMerge` works well for setting up tracking a local
branch, but there is no mechanism to automatically set up a remote
tracking situation. This patch adds the following configuration values:

  - `branch.defaultRemote`: initializes `branch.<name>.remote` if not
    otherwise given;
  - `branch.defaultPushRemote`: initializes `branch.<name>.pushRemote`
    (currently falls back on `remote.pushDefault` when pushing); and
  - `branch.defaultMerge`: initializes `branch.<name>.merge` if not
    otherwise given.

Signed-off-by: Ben Boeckel <mathstuf@gmail.com>
---
 Documentation/config/branch.txt | 15 +++++++++
 branch.c                        | 28 ++++++++++------
 branch.h                        |  3 ++
 config.c                        | 15 +++++++++
 environment.c                   |  3 ++
 t/t3200-branch.sh               | 57 +++++++++++++++++++++++++++++++++
 6 files changed, 111 insertions(+), 10 deletions(-)

diff --git a/Documentation/config/branch.txt b/Documentation/config/branch.txt
index cc5f3249fc..6e9d446066 100644
--- a/Documentation/config/branch.txt
+++ b/Documentation/config/branch.txt
@@ -1,3 +1,18 @@
+branch.defaultRemote::
+	When a new branch is created with 'git branch', 'git switch' or 'git
+	checkout', this value will be used to initialize the
+	"branch.<name>.remote" setting.
+
+branch.defaultPushRemote::
+	When a new branch is created with 'git branch', 'git switch' or 'git
+	checkout', this value will be used to initialize the
+	"branch.<name>.pushRemote" setting.
+
+branch.defaultMerge::
+	When a new branch is created with 'git branch', 'git switch' or 'git
+	checkout', this value will be used to initialize the
+	"branch.<name>.merge" setting.
+
 branch.autoSetupMerge::
 	Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
 	so that linkgit:git-pull[1] will appropriately merge from the
diff --git a/branch.c b/branch.c
index 7a88a4861e..0e8ece8259 100644
--- a/branch.c
+++ b/branch.c
@@ -60,6 +60,9 @@ int install_branch_config(int flag, const char *local, const char *origin, const
 	const char *shortname = NULL;
 	struct strbuf key = STRBUF_INIT;
 	int rebasing = should_setup_rebase(origin);
+	const char *actual_origin = origin ? origin : git_branch_remote;
+	const char *actual_push_origin = git_branch_push_remote;
+	const char *actual_remote = remote ? remote : git_branch_merge;
 
 	if (skip_prefix(remote, "refs/heads/", &shortname)
 	    && !strcmp(local, shortname)
@@ -70,12 +73,17 @@ int install_branch_config(int flag, const char *local, const char *origin, const
 	}
 
 	strbuf_addf(&key, "branch.%s.remote", local);
-	if (git_config_set_gently(key.buf, origin ? origin : ".") < 0)
+	if (git_config_set_gently(key.buf, actual_origin ? actual_origin : ".") < 0)
+		goto out_err;
+
+	strbuf_reset(&key);
+	strbuf_addf(&key, "branch.%s.pushremote", local);
+	if (git_config_set_gently(key.buf, actual_push_origin) < 0)
 		goto out_err;
 
 	strbuf_reset(&key);
 	strbuf_addf(&key, "branch.%s.merge", local);
-	if (git_config_set_gently(key.buf, remote) < 0)
+	if (git_config_set_gently(key.buf, actual_remote) < 0)
 		goto out_err;
 
 	if (rebasing) {
@@ -88,27 +96,27 @@ int install_branch_config(int flag, const char *local, const char *origin, const
 
 	if (flag & BRANCH_CONFIG_VERBOSE) {
 		if (shortname) {
-			if (origin)
+			if (actual_origin)
 				printf_ln(rebasing ?
 					  _("Branch '%s' set up to track remote branch '%s' from '%s' by rebasing.") :
 					  _("Branch '%s' set up to track remote branch '%s' from '%s'."),
-					  local, shortname, origin);
+					  local, shortname, actual_origin);
 			else
 				printf_ln(rebasing ?
 					  _("Branch '%s' set up to track local branch '%s' by rebasing.") :
 					  _("Branch '%s' set up to track local branch '%s'."),
 					  local, shortname);
 		} else {
-			if (origin)
+			if (actual_origin)
 				printf_ln(rebasing ?
 					  _("Branch '%s' set up to track remote ref '%s' by rebasing.") :
 					  _("Branch '%s' set up to track remote ref '%s'."),
-					  local, remote);
+					  local, actual_remote);
 			else
 				printf_ln(rebasing ?
 					  _("Branch '%s' set up to track local ref '%s' by rebasing.") :
 					  _("Branch '%s' set up to track local ref '%s'."),
-					  local, remote);
+					  local, actual_remote);
 		}
 	}
 
@@ -119,9 +127,9 @@ int install_branch_config(int flag, const char *local, const char *origin, const
 	error(_("Unable to write upstream branch configuration"));
 
 	advise(_(tracking_advice),
-	       origin ? origin : "",
-	       origin ? "/" : "",
-	       shortname ? shortname : remote);
+	       actual_origin ? actual_origin : "",
+	       actual_origin ? "/" : "",
+	       shortname ? shortname : actual_remote);
 
 	return -1;
 }
diff --git a/branch.h b/branch.h
index df0be61506..6ce978731d 100644
--- a/branch.h
+++ b/branch.h
@@ -14,6 +14,9 @@ enum branch_track {
 };
 
 extern enum branch_track git_branch_track;
+extern const char* git_branch_remote;
+extern const char* git_branch_push_remote;
+extern const char* git_branch_merge;
 
 /* Functions for acting on the information about branches. */
 
diff --git a/config.c b/config.c
index f33abeab85..42fc510a9f 100644
--- a/config.c
+++ b/config.c
@@ -1599,6 +1599,21 @@ static int git_default_branch_config(const char *var, const char *value)
 			return error(_("malformed value for %s"), var);
 		return 0;
 	}
+	if (!strcmp(var, "branch.defaultremote")) {
+		if (!value)
+			return config_error_nonbool(var);
+		return git_config_string(&git_branch_remote, var, value);
+	}
+	if (!strcmp(var, "branch.defaultpushremote")) {
+		if (!value)
+			return config_error_nonbool(var);
+		return git_config_string(&git_branch_push_remote, var, value);
+	}
+	if (!strcmp(var, "branch.defaultmerge")) {
+		if (!value)
+			return config_error_nonbool(var);
+		return git_config_string(&git_branch_merge, var, value);
+	}
 
 	/* Add other config variables here and to Documentation/config.txt. */
 	return 0;
diff --git a/environment.c b/environment.c
index 2f27008424..3b4d54e7dc 100644
--- a/environment.c
+++ b/environment.c
@@ -60,6 +60,9 @@ int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN;
 char *check_roundtrip_encoding = "SHIFT-JIS";
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
+const char* git_branch_remote = NULL;
+const char* git_branch_push_remote = NULL;
+const char* git_branch_merge = NULL;
 enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
 enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
 #ifndef OBJECT_CREATION_MODE
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index cc4b10236e..2edfb50872 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -797,6 +797,63 @@ test_expect_success 'test tracking setup via --track but deeper' '
 	test "$(git config branch.my7.merge)" = refs/heads/o/o
 '
 
+test_expect_success 'test tracking setup via branch.default* and --track' '
+	git config branch.autosetupmerge always &&
+	git config branch.defaultremote local &&
+	git config branch.defaultmerge main &&
+	git config remote.local.url . &&
+	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+	(git show-ref -q refs/remotes/local/main || git fetch local) &&
+	git branch --track other/foo my2 &&
+	git config branch.autosetupmerge false &&
+	test "$(git config branch.my2.remote)" = other &&
+	! test "$(git config branch.my2.pushremote)" = other &&
+	test "$(git config branch.my2.merge)" = refs/heads/foo
+'
+
+test_expect_success 'test tracking setup via branch.default* and --no-track' '
+	git config branch.autosetupmerge always &&
+	git config branch.defaultremote local &&
+	git config branch.defaultmerge main &&
+	git config remote.local.url . &&
+	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+	(git show-ref -q refs/remotes/local/main || git fetch local) &&
+	git branch --no-track my2 &&
+	git config branch.autosetupmerge false &&
+	! test "$(git config branch.my2.remote)" = local &&
+	! test "$(git config branch.my2.pushremote)" = other &&
+	! test "$(git config branch.my2.merge)" = refs/heads/main
+'
+
+test_expect_success 'test tracking setup via branch.default*' '
+	git config branch.autosetupmerge always &&
+	git config branch.defaultremote local &&
+	git config branch.defaultmerge main &&
+	git config remote.local.url . &&
+	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+	(git show-ref -q refs/remotes/local/main || git fetch local) &&
+	git branch my2 &&
+	git config branch.autosetupmerge false &&
+	test "$(git config branch.my2.remote)" = local &&
+	! test "$(git config branch.my2.pushremote)" = other &&
+	test "$(git config branch.my2.merge)" = refs/heads/main
+'
+
+test_expect_success 'test tracking setup via branch.default* with pushremote' '
+	git config branch.autosetupmerge always &&
+	git config branch.defaultremote local &&
+	git config branch.defaultpushremote other &&
+	git config branch.defaultmerge main &&
+	git config remote.local.url . &&
+	git config remote.local.fetch refs/heads/*:refs/remotes/local/* &&
+	(git show-ref -q refs/remotes/local/main || git fetch local) &&
+	git branch my2 &&
+	git config branch.autosetupmerge false &&
+	test "$(git config branch.my2.remote)" = local &&
+	test "$(git config branch.my2.pushremote)" = other &&
+	test "$(git config branch.my2.merge)" = refs/heads/main
+'
+
 test_expect_success 'test deleting branch deletes branch config' '
 	git branch -d my7 &&
 	test -z "$(git config branch.my7.remote)" &&
-- 
2.31.1


  reply	other threads:[~2021-07-28 13:53 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-28 13:50 [PATCH 0/1] Improve automatic setup of tracking for new branches Ben Boeckel
2021-07-28 13:50 ` Ben Boeckel [this message]
2021-07-28 17:48   ` [PATCH 1/1] config: support setting up a remote tracking branch upon creation Junio C Hamano
2021-07-28 18:26     ` Ben Boeckel
2021-07-28 18:39       ` Junio C Hamano
2021-07-29  2:01 ` [PATCH 0/1] Improve automatic setup of tracking for new branches Ben Boeckel
2021-07-29  2:01   ` [PATCH 1/1] config: support a default remote tracking setup upon branch creation Ben Boeckel
2021-07-30 13:35     ` Philippe Blain
2021-07-30 14:07       ` Ben Boeckel
2021-07-30 17:32       ` Junio C Hamano
2021-08-02 13:02     ` Ævar Arnfjörð Bjarmason
2021-08-02 13:16       ` Ben Boeckel
2021-08-02 15:20         ` Ævar Arnfjörð Bjarmason
2021-07-30  1:04   ` [PATCH 0/1] Improve automatic setup of tracking for new branches Junio C Hamano
2021-07-30  1:33     ` Ben Boeckel
2021-07-30 13:35   ` Philippe Blain
2021-07-30 13:57     ` Ben Boeckel
2021-07-30 16:01       ` Philippe Blain
2021-07-30 17:45         ` Ben Boeckel
2021-08-02 21:17         ` Johannes Schindelin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210728135041.501850-2-mathstuf@gmail.com \
    --to=mathstuf@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=jeffhost@microsoft.com \
    --cc=martin.agren@gmail.com \
    --cc=me@ttaylorr.com \
    --cc=pclouds@gmail.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).