[PATCH 0/1] Improve automatic setup of tracking for new branches

STALE1857d

Revision v1 of 2 in this series.

14 messages, 4 authors, 2021-08-02 · open the first message on its own page

[PATCH 0/1] Improve automatic setup of tracking for new branches

From: Ben Boeckel <hidden>
Date: 2021-07-28 13:53:05

Hi,

I recently discovered some of the nicer behaviors of the `--track`
option for local branches (courtesy of `vim-fugitive`'s status
rendering). However, after a few weeks of slowly working `-t
origin/master` into my workflow, I figured that Git could help me out
here.

This patch adds three new configuration variables to initialize the
`branch.<name>.*` settings for tracking remote branches.

I suspect there are more tests that should be added.

Thanks,

--Ben

Ben Boeckel (1):
  config: support setting up a remote tracking branch upon creation

 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(-)


base-commit: eb27b338a3e71c7c4079fbac8aeae3f8fbb5c687
-- 
2.31.1

[PATCH 1/1] config: support setting up a remote tracking branch upon creation

From: Ben Boeckel <hidden>
Date: 2021-07-28 13:53:38

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 <redacted>
---
 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

[PATCH 0/1] Improve automatic setup of tracking for new branches

From: Ben Boeckel <hidden>
Date: 2021-07-29 02:01:36

Hi,

I recently discovered some of the nicer behaviors of the `--track`
option for local branches (courtesy of `vim-fugitive`'s status
rendering). However, after a few weeks of slowly working `-t
origin/master` into my workflow, I figured that Git could help me out
here.

This patch adds two new configuration variables to initialize the
`branch.<name>.*` settings for tracking remote branches.

I searched the docs (including `Documentation/gitworkflows.txt`), but
didn't see anywhere to describe the fork-based workflow common on forges
(such as GitHub and GitLab) where this felt "at home". I suppose I could
describe the workflow I'm used to, but I think I'll hammer that out as
blog posts before submitting it as documentation.

I suspect there are more tests that should be added.

Thanks,

--Ben

---
v1 -> v2:
  - removed `branch.defaultPushRemote` (`remote.pushDefault` covers this
    case already)
  - improved the commit message with more background and an expanation
    of the intended uses

Ben Boeckel (1):
  config: support a default remote tracking setup upon branch creation

 Documentation/config/branch.txt | 14 ++++++++++++
 branch.c                        | 22 ++++++++++---------
 branch.h                        |  2 ++
 config.c                        | 10 +++++++++
 environment.c                   |  2 ++
 t/t3200-branch.sh               | 39 +++++++++++++++++++++++++++++++++
 6 files changed, 79 insertions(+), 10 deletions(-)


base-commit: eb27b338a3e71c7c4079fbac8aeae3f8fbb5c687
-- 
2.31.1

[PATCH 1/1] config: support a default remote tracking setup upon branch creation

From: Ben Boeckel <hidden>
Date: 2021-07-29 02:01:39

The `branch.autoSetupMerge` works well today for setting up tracking a
local branch, but there is no easy mechanism to automatically set up a
remote tracking situation for workflows which use a single set of
branches for integration without specifying `--track` to every branch
creation command or branching directly from the remote ref. This patch
adds the following configuration values:

  - `branch.defaultRemote`: initializes `branch.<name>.remote` if not
    otherwise given;
  - `branch.defaultMerge`: initializes `branch.<name>.merge` if not
    otherwise given.

These effectively make branch creation commands such as `git branch`,
`git switch`, and `git checkout -b` have an implicit `-t
${branch.defaultRemote}/${branch.defaultMerge}` argument and is
equivalent to doing:

    $ git branch new-topic      # or another branch creation command
    $ git branch --set-upstream-to=${branch.defaultRemote}/${branch.defaultMerge} new-topic

In a fork-based workflow where contributions to the main project flow in
through forks of the main repository rather than pushing directly to it
(not uncommon of forge-hosted projects), the following setup may be
used:

    $ git config remote.pushDefault myfork    # push to `myfork` by default
    $ git config push.default simple          # the default
    $ git config branch.autoSetupMerge always # always setup tracking
    $ git config branch.defaultRemote origin  # track from `origin`
    $ git config branch.defaultMerge main     # track the `main` branch

With this setup, branches will automatically be set up to track
`origin/main` while being pushed to `myfork` by default. Some tools
(at least Vim's fugitive plugin) will show the commit differences
between both the tracking branch and the default push target. This
allows such tools to easily show "what needs to be merged?", "what has
happened on the target branch since this topic has been created?", and
"what is my status against my fork's current status?" at a glance.

Additionally, with the `extensions.worktreeConfig` setting, when a
separate work tree which is used for changes against a different branch
(e.g., a branch tracking a prior release), the `branch.defaultMerge`
setting may be changed independently, e.g., to `maint`.

Signed-off-by: Ben Boeckel <redacted>
---
 Documentation/config/branch.txt | 14 ++++++++++++
 branch.c                        | 22 ++++++++++---------
 branch.h                        |  2 ++
 config.c                        | 10 +++++++++
 environment.c                   |  2 ++
 t/t3200-branch.sh               | 39 +++++++++++++++++++++++++++++++++
 6 files changed, 79 insertions(+), 10 deletions(-)
diff --git a/Documentation/config/branch.txt b/Documentation/config/branch.txt
index cc5f3249fc..ab5cd2c1ed 100644
--- a/Documentation/config/branch.txt
+++ b/Documentation/config/branch.txt
@@ -1,3 +1,17 @@
+branch.defaultRemote::
+	Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
+	so that it will track a branch on the specified remote. This can be
+	used, in conjunction with `branch.defaultMerge`, in projects where
+	branches tend to target a single branch. This will be used to
+	initialize the "branch.<name>.remote" setting.
+
+branch.defaultMerge::
+	Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
+	so that it will track a branch with this name. This can be used, in
+	conjunction with `branch.defaultRemote` in projects where branches tend
+	to target a single branch. This 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..097d5af647 100644
--- a/branch.c
+++ b/branch.c
@@ -60,6 +60,8 @@ 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_remote = remote ? remote : git_branch_merge;
 
 	if (skip_prefix(remote, "refs/heads/", &shortname)
 	    && !strcmp(local, shortname)
@@ -70,12 +72,12 @@ 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.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 +90,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 +121,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..7d7990dda7 100644
--- a/branch.h
+++ b/branch.h
@@ -14,6 +14,8 @@ enum branch_track {
 };
 
 extern enum branch_track git_branch_track;
+extern const char* git_branch_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..a46c5a43a1 100644
--- a/config.c
+++ b/config.c
@@ -1599,6 +1599,16 @@ 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.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..d550deabbd 100644
--- a/environment.c
+++ b/environment.c
@@ -60,6 +60,8 @@ 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_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..82137e8451 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -797,6 +797,45 @@ 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.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.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.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

Re: [PATCH 0/1] Improve automatic setup of tracking for new branches

From: Philippe Blain <hidden>
Date: 2021-07-30 13:35:44

Hi Ben,

Le 2021-07-28 à 22:01, Ben Boeckel a écrit :
Hi,

I recently discovered some of the nicer behaviors of the `--track`
option for local branches (courtesy of `vim-fugitive`'s status
rendering). However, after a few weeks of slowly working `-t
origin/master` into my workflow, I figured that Git could help me out
here.

This patch adds two new configuration variables to initialize the
`branch.<name>.*` settings for tracking remote branches.

I searched the docs (including `Documentation/gitworkflows.txt`), but
didn't see anywhere to describe the fork-based workflow common on forges
(such as GitHub and GitLab) where this felt "at home". I suppose I could
describe the workflow I'm used to, but I think I'll hammer that out as
blog posts before submitting it as documentation.
I'm in favor of a change like the one you propose, thanks for working on this!

The 'triangular' aka 'forking' workflow is, as you discovered, only explicitely
mentioned in the description of '@{push}' [1]. 'gitworkflows(5)' is mostly about
how the workflow used by the Git projet itself (from the description):

     This document attempts to write down and motivate some of the workflow
     elements used for git.git itself.
I suspect there are more tests that should be added.

Thanks,

--Ben

---
v1 -> v2:
   - removed `branch.defaultPushRemote` (`remote.pushDefault` covers this
     case already)
   - improved the commit message with more background and an expanation
     of the intended uses
Small nit: usually when sending a second version of a patch, you would use
the '-v2' argument to 'git format-patch' so that the patch and cover letter
is prefixed [PATCH v2].


[1] https://git-scm.com/docs/gitrevisions#Documentation/gitrevisions.txt-emltbranchnamegtpushemegemmasterpushemempushem

Re: [PATCH 1/1] config: support a default remote tracking setup upon branch creation

From: Philippe Blain <hidden>
Date: 2021-07-30 13:35:54


Le 2021-07-28 à 22:01, Ben Boeckel a écrit :
The `branch.autoSetupMerge` works well today for setting up tracking a
local branch, but there is no easy mechanism to automatically set up a
remote tracking situation for workflows which use a single set of
branches for integration without specifying `--track` to every branch
creation command or branching directly from the remote ref. This patch
adds the following configuration values:

   - `branch.defaultRemote`: initializes `branch.<name>.remote` if not
     otherwise given;
   - `branch.defaultMerge`: initializes `branch.<name>.merge` if not
     otherwise given.

These effectively make branch creation commands such as `git branch`,
`git switch`, and `git checkout -b` have an implicit `-t
${branch.defaultRemote}/${branch.defaultMerge}` argument and is
equivalent to doing:

     $ git branch new-topic      # or another branch creation command
     $ git branch --set-upstream-to=${branch.defaultRemote}/${branch.defaultMerge} new-topic

In a fork-based workflow where contributions to the main project flow in
through forks of the main repository rather than pushing directly to it
(not uncommon of forge-hosted projects), the following setup may be
used:

     $ git config remote.pushDefault myfork    # push to `myfork` by default
     $ git config push.default simple          # the default
     $ git config branch.autoSetupMerge always # always setup tracking
OK, so if I understand correctly this exisiting setting has to be changed
to 'always' for the new settings you are adding to take effect, right ?
I think this does make sense, reading the description of 'branch.autoSetupMerge',
but maybe it should be spelled explicitely in the text of the commit message,
and not just mentioned here in this terminal session excerpt.
     $ git config branch.defaultRemote origin  # track from `origin`
     $ git config branch.defaultMerge main     # track the `main` branch
Small nit: maybe I would invert these two, so it can read:

       $ git config branch.defaultMerge main     # track the `main` branch ...
       $ git config branch.defaultRemote origin  # ... from `origin`
With this setup, branches will automatically be set up to track
`origin/main` while being pushed to `myfork` by default. Some tools
(at least Vim's fugitive plugin) will show the commit differences
between both the tracking branch and the default push target. This
allows such tools to easily show "what needs to be merged?", "what has
happened on the target branch since this topic has been created?", and
"what is my status against my fork's current status?" at a glance.

Additionally, with the `extensions.worktreeConfig` setting, when a
separate work tree which is used for changes against a different branch
(e.g., a branch tracking a prior release), the `branch.defaultMerge`
setting may be changed independently, e.g., to `maint`.
This last paragraph is not explicitely needed, as nothing relating to
'extensions.worktreeConfig' is changed here right ? It's just the normal
way that this setting works.
quoted hunk
Signed-off-by: Ben Boeckel <redacted>
---
  Documentation/config/branch.txt | 14 ++++++++++++
  branch.c                        | 22 ++++++++++---------
  branch.h                        |  2 ++
  config.c                        | 10 +++++++++
  environment.c                   |  2 ++
  t/t3200-branch.sh               | 39 +++++++++++++++++++++++++++++++++
  6 files changed, 79 insertions(+), 10 deletions(-)
diff --git a/Documentation/config/branch.txt b/Documentation/config/branch.txt
index cc5f3249fc..ab5cd2c1ed 100644
--- a/Documentation/config/branch.txt
+++ b/Documentation/config/branch.txt
@@ -1,3 +1,17 @@
+branch.defaultRemote::
+	Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
+	so that it will track a branch on the specified remote. This can be
+	used, in conjunction with `branch.defaultMerge`, in projects where
+	branches tend to target a single branch. This will be used to
+	initialize the "branch.<name>.remote" setting.
+
+branch.defaultMerge::
+	Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
+	so that it will track a branch with this name. This can be used, in
+	conjunction with `branch.defaultRemote` in projects where branches tend
+	to target a single branch. This will be used to initialize the
+	"branch.<name>.merge" setting.
For the two setting above, if 'branch.autoSetupMerge' must be set to 'always' for
the settings to work, I think it should be explicitely mentioned.
quoted hunk
+
  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..097d5af647 100644
--- a/branch.c
+++ b/branch.c
@@ -60,6 +60,8 @@ 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_remote = remote ? remote : git_branch_merge;
  
  	if (skip_prefix(remote, "refs/heads/", &shortname)
  	    && !strcmp(local, shortname)
@@ -70,12 +72,12 @@ 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.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 +90,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 +121,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..7d7990dda7 100644
--- a/branch.h
+++ b/branch.h
@@ -14,6 +14,8 @@ enum branch_track {
  };
  
  extern enum branch_track git_branch_track;
+extern const char* git_branch_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..a46c5a43a1 100644
--- a/config.c
+++ b/config.c
@@ -1599,6 +1599,16 @@ 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.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..d550deabbd 100644
--- a/environment.c
+++ b/environment.c
@@ -60,6 +60,8 @@ 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_merge = NULL;
Can the new settings be implemented without adding more global variables ?
I think we are trying to move away from these. Apart from that the code
looks OK to me.
quoted hunk
  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..82137e8451 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -797,6 +797,45 @@ 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 &&
You can use 'test_config branch.autosetupmerge always' so that the
config is only active for the duration of the 'test_expect_success' block
(see t/test-lib-functions.sh).
+	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 &&
Here and for the following line you can use 'test_cmp_config'.
+	test "$(git config branch.my2.merge)" = refs/heads/foo
+'
This tests checks that an explicit '--track' argument overrides the new configs.
I would name it something like "'--track overrides 'branch.default{merge,remote}'"
or something like this. I would also add another test before this one that just
checks that the new settings by themselves work as expected;
i.e. a simple 'git checkout -b' and verifying that the
tracking info is correctly configured according to 'branch.default{merge,remote}'.
+
+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.merge)" = refs/heads/main
Here you expect the configs to be absent, so for more clarity you could
do

     git config branch.my2.remote >remote &&
     test_must_be_empty remote

and the same for merge.
+'
+
+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.merge)" = refs/heads/main
+'
+
  test_expect_success 'test deleting branch deletes branch config' '
  	git branch -d my7 &&
  	test -z "$(git config branch.my7.remote)" &&
Oh, so here is the 'just test the new settings' test. Let's move that
one to be before the two others.

Another test that could be added is one that does not change
'branch.autosetupmerge' but sets the new configs, and checks that the
tracking info is *not* set.

Cheers,

Philippe.

Re: [PATCH 0/1] Improve automatic setup of tracking for new branches

From: Ben Boeckel <hidden>
Date: 2021-07-30 13:57:52

On Fri, Jul 30, 2021 at 09:35:39 -0400, Philippe Blain wrote:
I'm in favor of a change like the one you propose, thanks for working on this!
Thanks :) . Nice to know it'll be of use for others.
The 'triangular' aka 'forking' workflow is, as you discovered, only explicitely
mentioned in the description of '@{push}' [1]. 'gitworkflows(5)' is mostly about
how the workflow used by the Git projet itself (from the description):

     This document attempts to write down and motivate some of the workflow
     elements used for git.git itself.
Ah, I missed that.
Le 2021-07-28 à 22:01, Ben Boeckel a écrit :
quoted
v1 -> v2:
   - removed `branch.defaultPushRemote` (`remote.pushDefault` covers this
     case already)
   - improved the commit message with more background and an expanation
     of the intended uses
Small nit: usually when sending a second version of a patch, you would use
the '-v2' argument to 'git format-patch' so that the patch and cover letter
is prefixed [PATCH v2].
Yes, I realized that I had forgotten the `--reroll-count=` argument when
making this patch (I suppose a way to store the Cc list for a topic
somewhere would be nice so I didn't lean so heavily on shell history
would help this).

FWIW, my main gripe with the email-based workflow is the lack of
coordinated metadata (LWN has numerous comments by me about my views if
you're curious, but I should really formalize them into blog posts). But
when in Rome :) .

Thanks,

--Ben

Re: [PATCH 1/1] config: support a default remote tracking setup upon branch creation

From: Ben Boeckel <hidden>
Date: 2021-07-30 14:08:04

On Fri, Jul 30, 2021 at 09:35:49 -0400, Philippe Blain wrote:
Le 2021-07-28 à 22:01, Ben Boeckel a écrit :
quoted
     $ git config remote.pushDefault myfork    # push to `myfork` by default
     $ git config push.default simple          # the default
     $ git config branch.autoSetupMerge always # always setup tracking
OK, so if I understand correctly this exisiting setting has to be changed
to 'always' for the new settings you are adding to take effect, right ?
I think this does make sense, reading the description of 'branch.autoSetupMerge',
but maybe it should be spelled explicitely in the text of the commit message,
and not just mentioned here in this terminal session excerpt.
Good point. I'll add it.
quoted
     $ git config branch.defaultRemote origin  # track from `origin`
     $ git config branch.defaultMerge main     # track the `main` branch
Small nit: maybe I would invert these two, so it can read:

       $ git config branch.defaultMerge main     # track the `main` branch ...
       $ git config branch.defaultRemote origin  # ... from `origin`
Agreed.
quoted
Additionally, with the `extensions.worktreeConfig` setting, when a
separate work tree which is used for changes against a different branch
(e.g., a branch tracking a prior release), the `branch.defaultMerge`
setting may be changed independently, e.g., to `maint`.
This last paragraph is not explicitely needed, as nothing relating to
'extensions.worktreeConfig' is changed here right ? It's just the normal
way that this setting works.
Yes. I'll mention more explicitly that this is the reason for preserving
split settings (rather than a single `branch.defaultTrack = origin/main`
setting that I had thought about until I saw the `--worktree` flag to
`git config` and was intrigued).
quoted
+branch.defaultRemote::
+	Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
+	so that it will track a branch on the specified remote. This can be
+	used, in conjunction with `branch.defaultMerge`, in projects where
+	branches tend to target a single branch. This will be used to
+	initialize the "branch.<name>.remote" setting.
+
+branch.defaultMerge::
+	Tells 'git branch', 'git switch' and 'git checkout' to set up new branches
+	so that it will track a branch with this name. This can be used, in
+	conjunction with `branch.defaultRemote` in projects where branches tend
+	to target a single branch. This will be used to initialize the
+	"branch.<name>.merge" setting.
For the two setting above, if 'branch.autoSetupMerge' must be set to 'always' for
the settings to work, I think it should be explicitely mentioned.
Will update.
quoted
diff --git a/environment.c b/environment.c
index 2f27008424..d550deabbd 100644
--- a/environment.c
+++ b/environment.c
@@ -60,6 +60,8 @@ 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_merge = NULL;
Can the new settings be implemented without adding more global variables ?
I think we are trying to move away from these. Apart from that the code
looks OK to me.
I'm all for that, but didn't see guidance on where such things should be
stored. There's not a "context" object passed around, but I guess
stuffing it into `repository` is fine? This also gives a nice place to
free them rather than just leaking them too.

Alas, after some cursory investigation,
`config.c@@git_default_branch_config` does not have access to "the
repository" and the `cb` in `git_default_config` seems to be ~always be
`NULL`. So maybe that will have to wait for further refactoring of the
configuration tracking logic?
quoted
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index cc4b10236e..82137e8451 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -797,6 +797,45 @@ 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 &&
You can use 'test_config branch.autosetupmerge always' so that the
config is only active for the duration of the 'test_expect_success' block
(see t/test-lib-functions.sh).
Nifty.
quoted
+	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 &&
Here and for the following line you can use 'test_cmp_config'.
quoted
+	test "$(git config branch.my2.merge)" = refs/heads/foo
+'
This tests checks that an explicit '--track' argument overrides the new configs.
I would name it something like "'--track overrides 'branch.default{merge,remote}'"
or something like this. I would also add another test before this one that just
checks that the new settings by themselves work as expected;
i.e. a simple 'git checkout -b' and verifying that the
tracking info is correctly configured according to 'branch.default{merge,remote}'.
quoted
+
+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.merge)" = refs/heads/main
Here you expect the configs to be absent, so for more clarity you could
do

     git config branch.my2.remote >remote &&
     test_must_be_empty remote

and the same for merge.
quoted
+'
+
+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.merge)" = refs/heads/main
+'
+
  test_expect_success 'test deleting branch deletes branch config' '
  	git branch -d my7 &&
  	test -z "$(git config branch.my7.remote)" &&
Oh, so here is the 'just test the new settings' test. Let's move that
one to be before the two others.

Another test that could be added is one that does not change
'branch.autosetupmerge' but sets the new configs, and checks that the
tracking info is *not* set.
I'll make the test suite updates as well.

Thanks for the review,

--Ben

Re: [PATCH 0/1] Improve automatic setup of tracking for new branches

From: Philippe Blain <hidden>
Date: 2021-07-30 16:01:41

Hi again,

Le 2021-07-30 à 09:57, Ben Boeckel a écrit :
On Fri, Jul 30, 2021 at 09:35:39 -0400, Philippe Blain wrote:
quoted
Le 2021-07-28 à 22:01, Ben Boeckel a écrit :

Small nit: usually when sending a second version of a patch, you would use
the '-v2' argument to 'git format-patch' so that the patch and cover letter
is prefixed [PATCH v2].
Yes, I realized that I had forgotten the `--reroll-count=` argument when
making this patch (I suppose a way to store the Cc list for a topic
somewhere would be nice so I didn't lean so heavily on shell history
would help this).
There is 'format.cc', but it's not branch-specific, so you would have to
use one worktree per branch with extension.worktreeConfig...
FWIW, my main gripe with the email-based workflow is the lack of
coordinated metadata (LWN has numerous comments by me about my views if
you're curious, but I should really formalize them into blog posts). But
when in Rome :) .
I agree. I almost always use Gitgitgadget [1], which keeps track of the CC list for
me, of updating the re-roll count, of adding the in-reply-to header such that subsequent
versions of the series are sent as a response to the cover letter of the previous version,
generating a range-diff against the previous version,
commenting on the PR when the series is mentioned in "What's cooking", etc.

Some things it does not support are: sending a patch as a response to some random
mail on the list, which is sometimes useful, reading the commit notes to generate
in-patch commentaries [2], customizing the diff generated by 'format-patch'.
Other things are listed at [3].

Recently I've even been using only the terminal with Gitgitgadget:
I use 'git branch --edit-description'
to write my cover letter, and then use the 'gh' GitHub CLI to open my PR:

$ git config --get-regexp alias.desc*
alias.desc-title !git config branch.$(git branch --show-current).description | head -1
alias.desc-body !git config branch.$(git branch --show-current).description | tail -n+3
$ gh pr create --title "$(git desc-title)" --body "$(git desc-body)" --head phil-blain:$(git branch --show-current)


Cheers,
Philippe.

[1] https://gitgitgadget.github.io/
[2] https://github.com/gitgitgadget/gitgitgadget/issues/173
[3] https://github.com/gitgitgadget/gitgitgadget/issues

Re: [PATCH 0/1] Improve automatic setup of tracking for new branches

From: Ben Boeckel <hidden>
Date: 2021-07-30 17:45:49

On Fri, Jul 30, 2021 at 12:01:36 -0400, Philippe Blain wrote:
Hi again,

Le 2021-07-30 à 09:57, Ben Boeckel a écrit :
quoted
On Fri, Jul 30, 2021 at 09:35:39 -0400, Philippe Blain wrote:
quoted
Le 2021-07-28 à 22:01, Ben Boeckel a écrit :

Small nit: usually when sending a second version of a patch, you would use
the '-v2' argument to 'git format-patch' so that the patch and cover letter
is prefixed [PATCH v2].
Yes, I realized that I had forgotten the `--reroll-count=` argument when
making this patch (I suppose a way to store the Cc list for a topic
somewhere would be nice so I didn't lean so heavily on shell history
would help this).
There is 'format.cc', but it's not branch-specific, so you would have to
use one worktree per branch with extension.worktreeConfig...
I suppose a `branch.<name>.cc` configuration might be in order :) .
Though at that point, `branch.<name>.rerollCount` and
`branch.<name>.sendEmailTo` also make sense…

More brainstorming below too.
quoted
FWIW, my main gripe with the email-based workflow is the lack of
coordinated metadata (LWN has numerous comments by me about my views if
you're curious, but I should really formalize them into blog posts). But
when in Rome :) .
I agree. I almost always use Gitgitgadget [1], which keeps track of the CC list for
me, of updating the re-roll count, of adding the in-reply-to header such that subsequent
versions of the series are sent as a response to the cover letter of the previous version,
generating a range-diff against the previous version,
commenting on the PR when the series is mentioned in "What's cooking", etc.
That's nifty. I guess since I started here, things are a bit messy for
this patch though?
Some things it does not support are: sending a patch as a response to some random
mail on the list, which is sometimes useful, reading the commit notes to generate
in-patch commentaries [2], customizing the diff generated by 'format-patch'.
Other things are listed at [3].

Recently I've even been using only the terminal with Gitgitgadget:
I use 'git branch --edit-description'
to write my cover letter, and then use the 'gh' GitHub CLI to open my PR:
I think having `branch.<name>.coverLetter` and/or
`branch.coverLetterDirectory` (defaulting to reading `<name>` or
`<name>.txt`) to store the cover letter contents would be nice. I know
I've blown away enough `0000-*.patch` edits with an ill-timed `git
format-patch` before…

Forges could use this to hook in with their push options[1] through
their wrappers or other tools.

--Ben

[1]https://docs.gitlab.com/ee/user/project/push_options.html#push-options-for-merge-requests

Re: [PATCH 1/1] config: support a default remote tracking setup upon branch creation

From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2021-08-02 13:10:40

On Wed, Jul 28 2021, Ben Boeckel wrote:
The `branch.autoSetupMerge` works well today for setting up tracking a
local branch, but there is no easy mechanism to automatically set up a
remote tracking situation for workflows which use a single set of
branches for integration without specifying `--track` to every branch
creation command or branching directly from the remote ref. This patch
adds the following configuration values:

  - `branch.defaultRemote`: initializes `branch.<name>.remote` if not
    otherwise given;
  - `branch.defaultMerge`: initializes `branch.<name>.merge` if not
    otherwise given.
Not a new issue per-se, but what if you've got a branch called
defaultRemote? It seems to me that any new branch.<name>.* config closes
the door for a <name> we squat on.

Given that we have checkout.defaultRemote and this also affects
switch/checkout it seems better to continue in the checkout.* namespace
even if it wasn't for that, but given the config squatting issue
especially so....

For what it's worth I usually use the checkout.defaultRemote option
(which I added) and:

    git checkout master &&
    git branch -m master <topic-name>

See 8d7b558baeb (checkout & worktree: introduce checkout.defaultRemote,
2018-06-05). It seems to me from that patch diff that you could modify
some docs / tests for this, no? E.g. how it interacts with git-worktree.

I like this direction, but just have a concern that this is a place
where we need to consider all the UX in the area overall, and that any
options/config don't overtly interact in a bad way.

Re: [PATCH 1/1] config: support a default remote tracking setup upon branch creation

From: Ben Boeckel <hidden>
Date: 2021-08-02 13:16:26

On Mon, Aug 02, 2021 at 15:02:41 +0200, Ævar Arnfjörð Bjarmason wrote:
On Wed, Jul 28 2021, Ben Boeckel wrote:
quoted
The `branch.autoSetupMerge` works well today for setting up tracking a
local branch, but there is no easy mechanism to automatically set up a
remote tracking situation for workflows which use a single set of
branches for integration without specifying `--track` to every branch
creation command or branching directly from the remote ref. This patch
adds the following configuration values:

  - `branch.defaultRemote`: initializes `branch.<name>.remote` if not
    otherwise given;
  - `branch.defaultMerge`: initializes `branch.<name>.merge` if not
    otherwise given.
Not a new issue per-se, but what if you've got a branch called
defaultRemote? It seems to me that any new branch.<name>.* config closes
the door for a <name> we squat on.
It doesn't seem that shadowing is actually a thing:

    % git init
    Initialized empty Git repository in …/git-shadow/.git/
    % git config foo.bar true
    % git config foo.bar.baz true
    % git config --get foo.bar
    true
    % git config --get foo.bar.baz
    true
Given that we have checkout.defaultRemote and this also affects
switch/checkout it seems better to continue in the checkout.* namespace
even if it wasn't for that, but given the config squatting issue
especially so....

For what it's worth I usually use the checkout.defaultRemote option
(which I added) and:

    git checkout master &&
    git branch -m master <topic-name>

See 8d7b558baeb (checkout & worktree: introduce checkout.defaultRemote,
2018-06-05). It seems to me from that patch diff that you could modify
some docs / tests for this, no? E.g. how it interacts with git-worktree.
I think it would be weird for `checkout.*` to affect `git branch` which
does no checkout at all. I want it to set up for simple branch creation
as well, so this would be a hole in my use case.
I like this direction, but just have a concern that this is a place
where we need to consider all the UX in the area overall, and that any
options/config don't overtly interact in a bad way.
I'll have to look at adding test cases as to how it interacts with
`checkout.defaultRemote`.

Thanks,

--Ben

Re: [PATCH 1/1] config: support a default remote tracking setup upon branch creation

From: Ævar Arnfjörð Bjarmason <hidden>
Date: 2021-08-02 15:36:49

On Mon, Aug 02 2021, Ben Boeckel wrote:
On Mon, Aug 02, 2021 at 15:02:41 +0200, Ævar Arnfjörð Bjarmason wrote:
quoted
On Wed, Jul 28 2021, Ben Boeckel wrote:
quoted
The `branch.autoSetupMerge` works well today for setting up tracking a
local branch, but there is no easy mechanism to automatically set up a
remote tracking situation for workflows which use a single set of
branches for integration without specifying `--track` to every branch
creation command or branching directly from the remote ref. This patch
adds the following configuration values:

  - `branch.defaultRemote`: initializes `branch.<name>.remote` if not
    otherwise given;
  - `branch.defaultMerge`: initializes `branch.<name>.merge` if not
    otherwise given.
Not a new issue per-se, but what if you've got a branch called
defaultRemote? It seems to me that any new branch.<name>.* config closes
the door for a <name> we squat on.
It doesn't seem that shadowing is actually a thing:

    % git init
    Initialized empty Git repository in …/git-shadow/.git/
    % git config foo.bar true
    % git config foo.bar.baz true
    % git config --get foo.bar
    true
    % git config --get foo.bar.baz
    true
You're right, I was misrecalling (or mis-imagining) some edge case there
that doesn't exist. I also tested setting branch.defaultRemote=true and
moving a branch.defaultRemote.* branch with "git branch -m", but it also
does the right thing. Nevermind.
quoted
Given that we have checkout.defaultRemote and this also affects
switch/checkout it seems better to continue in the checkout.* namespace
even if it wasn't for that, but given the config squatting issue
especially so....

For what it's worth I usually use the checkout.defaultRemote option
(which I added) and:

    git checkout master &&
    git branch -m master <topic-name>

See 8d7b558baeb (checkout & worktree: introduce checkout.defaultRemote,
2018-06-05). It seems to me from that patch diff that you could modify
some docs / tests for this, no? E.g. how it interacts with git-worktree.
I think it would be weird for `checkout.*` to affect `git branch` which
does no checkout at all. I want it to set up for simple branch creation
as well, so this would be a hole in my use case.
*nod*, although your approach has the opposite problem of making branch
creation with "checkout" and "switch" (and presumably "worktree")
impacted by "branch.*' config.

In a way that's more sensible, in that we can imagine those commands
calling "git branch" under the hood (which msotly doesn't actually
happen, except I think in the worktree case, but it's the same
underlying APIs).

..
quoted
I like this direction, but just have a concern that this is a place
where we need to consider all the UX in the area overall, and that any
options/config don't overtly interact in a bad way.
I'll have to look at adding test cases as to how it interacts with
`checkout.defaultRemote`.

Thanks,
....right, none of that mess is a showstopper, I'm just prodding you to
look at if any of those edge cases are made better/worse by these
additions. Thanks!

Re: [PATCH 0/1] Improve automatic setup of tracking for new branches

From: Johannes Schindelin <hidden>
Date: 2021-08-02 21:17:33

Hi Philippe,

On Fri, 30 Jul 2021, Philippe Blain wrote:
Recently I've even been using only the terminal with Gitgitgadget:
I use 'git branch --edit-description'
to write my cover letter, and then use the 'gh' GitHub CLI to open my PR:

$ git config --get-regexp alias.desc*
alias.desc-title !git config branch.$(git branch --show-current).description |
head -1
alias.desc-body !git config branch.$(git branch --show-current).description |
tail -n+3
$ gh pr create --title "$(git desc-title)" --body "$(git desc-body)" --head
phil-blain:$(git branch --show-current)
I bet you could streamline this even further by defining a `gh` alias:
https://cli.github.com/manual/gh_alias_set

Ciao,
Dscho
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help