git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / Atom feed
* [PATCH 0/9] Allow overriding the default name of the default branch
@ 2020-06-10 21:19 Johannes Schindelin via GitGitGadget
  2020-06-10 21:19 ` [PATCH 1/9] init: allow overriding the default branch name for new repositories Don Goodman-Wilson via GitGitGadget
                   ` (14 more replies)
  0 siblings, 15 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin

A growing number of open source projects aims to avoid the branch name 
master due to its negative connotation. See [1] for an existing discussion
on this. The links [2], [3], and [4] describe community-driven ways for
users to rename their default branches or use template edits to set a new
default branch name.

[1] 
https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/

[2] https://twitter.com/mislav/status/1270388510684598272

[3] 
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx

[4] https://github.com/ethomson/retarget_prs

By necessity, existing repositories require a lot of manual work to move
away from that branch name, but it should be much easier for new
repositories.

This patch series allows overriding the branch name being used for new
repositories' main branch. The main way to do this is the new 
core.defaultBranchName config option. This first patch was contributed by
newcomer Dan Goodman-Wilson. Thanks for the contribution!

The other patches follow other places where "master" is hard-coded and use
the new git_default_branch_name() method to consume the config option before
falling back to "master".

The last patch updates documentation only after the config option is ready
to apply to all of these scenarios.

This series DOES NOT change the default automatically, but only provides an
opt-in mechanism for interested users. It also presents a way forward for
such a transition, if and when we decide to do so. Specifically, the new
GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
test scripts on an individual basis instead of all-at-once.

Don Goodman-Wilson (1):
  init: allow overriding the default branch name for new repositories

Johannes Schindelin (8):
  remote: respect `core.defaultBranchName`
  send-pack/transport-helper: respect `core.defaultBranchName`
  testsvn: respect `core.defaultBranchName`
  submodule: use the (possibly overridden) default branch name
  clone: learn about the possibly-configured default branch name
  fmt-merge-msg: learn about the possibly-configured default branch name
  fast-export: respect the possibly-overridden default branch name
  Document how the default branch name can be overridden

 Documentation/config/core.txt |  4 ++++
 builtin/clone.c               | 14 +++++++++++---
 builtin/fast-export.c         | 10 +++++++---
 builtin/init-db.c             |  8 +++++---
 builtin/submodule--helper.c   | 10 ++++++++--
 fmt-merge-msg.c               |  6 ++++--
 refs.c                        | 34 ++++++++++++++++++++++++++++++++++
 refs.h                        |  6 ++++++
 remote-testsvn.c              | 11 ++++++++---
 remote.c                      | 12 ++++++++----
 send-pack.c                   |  6 +++++-
 t/README                      |  4 ++++
 t/t0001-init.sh               | 20 ++++++++++++++++++++
 t/t5609-clone-branch.sh       |  9 +++++++++
 t/t6200-fmt-merge-msg.sh      |  8 ++++++++
 transport-helper.c            |  6 +++++-
 16 files changed, 146 insertions(+), 22 deletions(-)


base-commit: 0313f36c6ebecb3bffe6f15cf25a4883100f0214
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-656%2Fdscho%2Fdefault-branch-name-option-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-656/dscho/default-branch-name-option-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/656
-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:19 ` Don Goodman-Wilson via GitGitGadget
  2020-06-10 23:22   ` brian m. carlson
                     ` (3 more replies)
  2020-06-10 21:19 ` [PATCH 2/9] remote: respect `core.defaultBranchName` Johannes Schindelin via GitGitGadget
                   ` (13 subsequent siblings)
  14 siblings, 4 replies; 178+ messages in thread
From: Don Goodman-Wilson via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Don Goodman-Wilson

From: Don Goodman-Wilson <don@goodman-wilson.com>

There is a growing number of projects trying to avoid the non-inclusive
name `master` in their repositories. For existing repositories, this
requires manual work. For new repositories, the only way to do that
automatically is by copying all of Git's template directory, then
hard-coding the desired default branch name into the `.git/HEAD` file,
and then configuring `init.templateDir` to point to those copied
template files.

To make this process much less cumbersome, let's introduce support for
`core.defaultBranchName`. That way, users won't need to keep their
copied template files up to date, and won't interfere with default hooks
installed by their administrators.

While at it, also let users set the default branch name via the
environment variable `GIT_TEST_DEFAULT_BRANCH_NAME`, in preparation for
adjusting Git's test suite to a more inclusive default branch name. As
is common in Git, the `GIT_TEST_*` variable takes precedence over the
config setting.

Note: we use the prefix `core.` instead of `init.` because we want to
adjust also `git clone`, `git fmt-merge-msg` and other commands over the
course of the next commits to respect this setting.

Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
---
 builtin/init-db.c |  8 +++++---
 refs.c            | 34 ++++++++++++++++++++++++++++++++++
 refs.h            |  6 ++++++
 t/t0001-init.sh   | 20 ++++++++++++++++++++
 4 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/builtin/init-db.c b/builtin/init-db.c
index 0b7222e7188..99792adfd43 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -258,15 +258,17 @@ static int create_default_files(const char *template_path,
 		die("failed to set up refs db: %s", err.buf);
 
 	/*
-	 * Create the default symlink from ".git/HEAD" to the "master"
-	 * branch, if it does not exist yet.
+	 * Create the default symlink from ".git/HEAD" to the default
+	 * branch name, if it does not exist yet.
 	 */
 	path = git_path_buf(&buf, "HEAD");
 	reinit = (!access(path, R_OK)
 		  || readlink(path, junk, sizeof(junk)-1) != -1);
 	if (!reinit) {
-		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
+		char *default_ref = git_default_branch_name(0);
+		if (create_symref("HEAD", default_ref, NULL) < 0)
 			exit(1);
+		free(default_ref);
 	}
 
 	initialize_repository_version(fmt->hash_algo);
diff --git a/refs.c b/refs.c
index 224ff66c7bb..8499b3865cb 100644
--- a/refs.c
+++ b/refs.c
@@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
 		argv_array_pushf(prefixes, *p, len, prefix);
 }
 
+char *git_default_branch_name(int short_name)
+{
+	const char *branch_name = getenv("GIT_TEST_DEFAULT_BRANCH_NAME");
+	char *from_config = NULL, *prefixed;
+
+	/*
+	 * If the default branch name was not specified via the environment
+	 * variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config
+	 * setting core.defaultBranchName. If neither are set, fall back to the
+	 * hard-coded default.
+	 */
+	if (!branch_name || !*branch_name) {
+		if (git_config_get_string("core.defaultbranchname",
+					  &from_config) < 0)
+			die(_("Could not retrieve `core.defaultBranchName`"));
+
+		if (from_config)
+			branch_name = from_config;
+		else
+			branch_name = "master";
+	}
+
+	if (short_name)
+		return from_config ? from_config : xstrdup(branch_name);
+
+	/* prepend "refs/heads/" to the branch name */
+	prefixed = xstrfmt("refs/heads/%s", branch_name);
+	if (check_refname_format(prefixed, 0))
+		die(_("invalid default branch name: '%s'"), branch_name);
+
+	free(from_config);
+	return prefixed;
+}
+
 /*
  * *string and *len will only be substituted, and *string returned (for
  * later free()ing) if the string passed in is a magic short-hand form
diff --git a/refs.h b/refs.h
index a92d2c74c83..e8d4f6e2f13 100644
--- a/refs.h
+++ b/refs.h
@@ -154,6 +154,12 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
 int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
 int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
 
+/*
+ * Retrieves the name of the default branch. If `short_name` is non-zero, the
+ * branch name will be prefixed with "refs/heads/".
+ */
+char *git_default_branch_name(int short_name);
+
 /*
  * A ref_transaction represents a collection of reference updates that
  * should succeed or fail together.
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 1edd5aeb8f0..b144cd8f46b 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -464,4 +464,24 @@ test_expect_success MINGW 'redirect std handles' '
 	grep "Needed a single revision" output.txt
 '
 
+test_expect_success 'custom default branch name from config' '
+	git config --global core.defaultbranchname nmb &&
+	GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config &&
+	git config --global --unset core.defaultbranchname &&
+	git -C custom-config symbolic-ref HEAD >actual &&
+	grep nmb actual
+'
+
+test_expect_success 'custom default branch name from env' '
+	GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env &&
+	git -C custom-env symbolic-ref HEAD >actual &&
+	grep nmb actual
+'
+
+test_expect_success 'invalid custom default branch name' '
+	test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \
+		git init custom-invalid 2>err &&
+	test_i18ngrep "invalid default branch name" err
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 2/9] remote: respect `core.defaultBranchName`
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  2020-06-10 21:19 ` [PATCH 1/9] init: allow overriding the default branch name for new repositories Don Goodman-Wilson via GitGitGadget
@ 2020-06-10 21:19 ` Johannes Schindelin via GitGitGadget
  2020-06-16 12:35   ` Jeff King
  2020-06-10 21:19 ` [PATCH 3/9] send-pack/transport-helper: " Johannes Schindelin via GitGitGadget
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When guessing the default branch name of a remote, and there are no refs
to guess from, we want to go with the preference specified by the user
for the fall-back.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 remote.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/remote.c b/remote.c
index 534c6426f1e..95fa8cc78e0 100644
--- a/remote.c
+++ b/remote.c
@@ -256,7 +256,7 @@ static void read_remotes_file(struct remote *remote)
 
 static void read_branches_file(struct remote *remote)
 {
-	char *frag;
+	char *frag, *default_branch_name = NULL;
 	struct strbuf buf = STRBUF_INIT;
 	FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r");
 
@@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)
 
 	/*
 	 * The branches file would have URL and optionally
-	 * #branch specified.  The "master" (or specified) branch is
+	 * #branch specified.  The default (or specified) branch is
 	 * fetched and stored in the local branch matching the
 	 * remote name.
 	 */
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
 	if (frag)
 		*(frag++) = '\0';
 	else
-		frag = "master";
+		frag = default_branch_name = git_default_branch_name(1);
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
 	strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ -299,6 +299,7 @@ static void read_branches_file(struct remote *remote)
 	strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
 	refspec_append(&remote->push, buf.buf);
 	remote->fetch_tags = 1; /* always auto-follow */
+	free(default_branch_name);
 	strbuf_release(&buf);
 }
 
@@ -2099,7 +2100,10 @@ struct ref *guess_remote_head(const struct ref *head,
 
 	/* If refs/heads/master could be right, it is. */
 	if (!all) {
-		r = find_ref_by_name(refs, "refs/heads/master");
+		char *name = git_default_branch_name(0);
+
+		r = find_ref_by_name(refs, name);
+		free(name);
 		if (r && oideq(&r->old_oid, &head->old_oid))
 			return copy_ref(r);
 	}
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 3/9] send-pack/transport-helper: respect `core.defaultBranchName`
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  2020-06-10 21:19 ` [PATCH 1/9] init: allow overriding the default branch name for new repositories Don Goodman-Wilson via GitGitGadget
  2020-06-10 21:19 ` [PATCH 2/9] remote: respect `core.defaultBranchName` Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:19 ` Johannes Schindelin via GitGitGadget
  2020-06-10 21:19 ` [PATCH 4/9] testsvn: " Johannes Schindelin via GitGitGadget
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When mentioning the default branch name in an error message, we want to
go with the preference specified by the user.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 send-pack.c        | 6 +++++-
 transport-helper.c | 6 +++++-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/send-pack.c b/send-pack.c
index 0abee22283d..f7747bed1c9 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -405,8 +405,12 @@ int send_pack(struct send_pack_args *args,
 	}
 
 	if (!remote_refs) {
+		char *branch_name = git_default_branch_name(1);
+
 		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
-			"Perhaps you should specify a branch such as 'master'.\n");
+			"Perhaps you should specify a branch such as '%s'.\n",
+			branch_name);
+		free(branch_name);
 		return 0;
 	}
 	if (args->atomic && !atomic_supported)
diff --git a/transport-helper.c b/transport-helper.c
index a46afcb69db..cc8ae5c67ca 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -1044,9 +1044,13 @@ static int push_refs(struct transport *transport,
 	}
 
 	if (!remote_refs) {
+		char *branch_name = git_default_branch_name(1);
+
 		fprintf(stderr,
 			_("No refs in common and none specified; doing nothing.\n"
-			  "Perhaps you should specify a branch such as 'master'.\n"));
+			  "Perhaps you should specify a branch such as '%s'.\n"),
+			branch_name);
+		free(branch_name);
 		return 0;
 	}
 
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 4/9] testsvn: respect `core.defaultBranchName`
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (2 preceding siblings ...)
  2020-06-10 21:19 ` [PATCH 3/9] send-pack/transport-helper: " Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:19 ` Johannes Schindelin via GitGitGadget
  2020-06-10 21:19 ` [PATCH 5/9] submodule: use the (possibly overridden) default branch name Johannes Schindelin via GitGitGadget
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

Since the default branch name can now be configured, the `testsvn`
remote helper needs to be told about it.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 remote-testsvn.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/remote-testsvn.c b/remote-testsvn.c
index 3af708c5b67..a48d74f35cd 100644
--- a/remote-testsvn.c
+++ b/remote-testsvn.c
@@ -13,7 +13,7 @@
 static const char *url;
 static int dump_from_file;
 static const char *private_ref;
-static const char *remote_ref = "refs/heads/master";
+static char *remote_ref;
 static const char *marksfilename, *notes_ref;
 struct rev_note { unsigned int rev_nr; };
 
@@ -286,7 +286,7 @@ int cmd_main(int argc, const char **argv)
 			private_ref_sb = STRBUF_INIT, marksfilename_sb = STRBUF_INIT,
 			notes_ref_sb = STRBUF_INIT;
 	static struct remote *remote;
-	const char *url_in;
+	const char *url_in, *default_branch;
 
 	setup_git_directory();
 	if (argc < 2 || argc > 3) {
@@ -294,6 +294,10 @@ int cmd_main(int argc, const char **argv)
 		return 1;
 	}
 
+	remote_ref = git_default_branch_name(0);
+	if (!skip_prefix(remote_ref, "refs/heads/", &default_branch))
+		BUG("unexpected remote_ref '%s'", remote_ref);
+
 	remote = remote_get(argv[1]);
 	url_in = (argc == 3) ? argv[2] : remote->url[0];
 
@@ -306,7 +310,8 @@ int cmd_main(int argc, const char **argv)
 		url = url_sb.buf;
 	}
 
-	strbuf_addf(&private_ref_sb, "refs/svn/%s/master", remote->name);
+	strbuf_addf(&private_ref_sb, "refs/svn/%s/%s",
+		    remote->name, default_branch);
 	private_ref = private_ref_sb.buf;
 
 	strbuf_addf(&notes_ref_sb, "refs/notes/%s/revs", remote->name);
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 5/9] submodule: use the (possibly overridden) default branch name
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (3 preceding siblings ...)
  2020-06-10 21:19 ` [PATCH 4/9] testsvn: " Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:19 ` Johannes Schindelin via GitGitGadget
  2020-06-15 10:46   ` Denton Liu
  2020-06-10 21:19 ` [PATCH 6/9] clone: learn about the possibly-configured " Johannes Schindelin via GitGitGadget
                   ` (9 subsequent siblings)
  14 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

To allow for overriding the default branch name, we have introduced a
config setting. With this patch, the `git submodule` command learns
about this, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/submodule--helper.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 46c03d2a126..0b4abb5a64b 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1980,8 +1980,14 @@ static const char *remote_submodule_branch(const char *path)
 		branch = sub->branch;
 	free(key);
 
-	if (!branch)
-		return "master";
+	if (!branch) {
+		static char *default_branch;
+
+		if (!default_branch)
+			default_branch = git_default_branch_name(1);
+
+		return default_branch;
+	}
 
 	if (!strcmp(branch, ".")) {
 		const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 6/9] clone: learn about the possibly-configured default branch name
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (4 preceding siblings ...)
  2020-06-10 21:19 ` [PATCH 5/9] submodule: use the (possibly overridden) default branch name Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:19 ` Johannes Schindelin via GitGitGadget
  2020-06-10 22:58   ` Junio C Hamano
  2020-06-10 21:19 ` [PATCH 7/9] fmt-merge-msg: " Johannes Schindelin via GitGitGadget
                   ` (8 subsequent siblings)
  14 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When cloning a repository without any branches, Git chooses a default
branch name for the as-yet unborn branch.

Now that we can configure what the default branch name should be, we
will want `git clone` to respect that setting.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/clone.c         | 14 +++++++++++---
 t/t5609-clone-branch.sh |  9 +++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index cb48a291caf..a21d3e99f82 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1263,9 +1263,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head_points_at = NULL;
 		remote_head = NULL;
 		option_no_checkout = 1;
-		if (!option_bare)
-			install_branch_config(0, "master", option_origin,
-					      "refs/heads/master");
+		if (!option_bare) {
+			char *default_branch = git_default_branch_name(0);
+			const char *nick;
+
+			if (!skip_prefix(default_branch, "refs/heads/", &nick))
+				BUG("unexpected default branch '%s'",
+				    default_branch);
+			install_branch_config(0, nick, option_origin,
+					      default_branch);
+			free(default_branch);
+		}
 	}
 
 	write_refspec_config(src_ref_prefix, our_head_points_at,
diff --git a/t/t5609-clone-branch.sh b/t/t5609-clone-branch.sh
index 6e7a7be0522..66af3ac2669 100755
--- a/t/t5609-clone-branch.sh
+++ b/t/t5609-clone-branch.sh
@@ -67,4 +67,13 @@ test_expect_success 'clone -b not allowed with empty repos' '
 	test_must_fail git clone -b branch empty clone-branch-empty
 '
 
+test_expect_success 'chooses correct default branch name' '
+	GIT_TEST_DEFAULT_BRANCH_NAME= \
+		git -c core.defaultBranchName=up clone empty whats-up &&
+	test_write_lines refs/heads/up refs/heads/up >expect &&
+	git -C whats-up symbolic-ref HEAD >actual &&
+	git -C whats-up config branch.up.merge >>actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 7/9] fmt-merge-msg: learn about the possibly-configured default branch name
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (5 preceding siblings ...)
  2020-06-10 21:19 ` [PATCH 6/9] clone: learn about the possibly-configured " Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:19 ` Johannes Schindelin via GitGitGadget
  2020-06-10 22:59   ` Junio C Hamano
  2020-06-10 21:19 ` [PATCH 8/9] fast-export: respect the possibly-overridden " Johannes Schindelin via GitGitGadget
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When formatting the commit message for merge commits, Git appends "into
<branch-name>" unless the current branch is the default branch.

Now that we can configure what the default branch name should be, we
will want to respect that setting in that scenario rather than using the
compiled-in default branch name.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 fmt-merge-msg.c          | 6 ++++--
 t/t6200-fmt-merge-msg.sh | 8 ++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
index 72d32bd73b1..5e5c1d86f1c 100644
--- a/fmt-merge-msg.c
+++ b/fmt-merge-msg.c
@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
 				const char *current_branch)
 {
 	int i = 0;
-	char *sep = "";
+	char *sep = "", *default_branch_name;
 
 	strbuf_addstr(out, "Merge ");
 	for (i = 0; i < srcs.nr; i++) {
@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
 			strbuf_addf(out, " of %s", srcs.items[i].string);
 	}
 
-	if (!strcmp("master", current_branch))
+	default_branch_name = git_default_branch_name(1);
+	if (!strcmp(default_branch_name, current_branch))
 		strbuf_addch(out, '\n');
 	else
 		strbuf_addf(out, " into %s\n", current_branch);
+	free(default_branch_name);
 }
 
 static void fmt_tag_signature(struct strbuf *tagbuf,
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index e4c2a6eca43..a23cd157ffd 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -158,6 +158,14 @@ test_expect_success 'setup FETCH_HEAD' '
 	git fetch . left
 '
 
+test_expect_success 'with overridden default branch name' '
+	test_config core.defaultBranchName default &&
+	test_when_finished "git switch master" &&
+	git switch -c default &&
+	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
+	! grep "into default" actual
+'
+
 test_expect_success 'merge.log=3 limits shortlog length' '
 	cat >expected <<-EOF &&
 	Merge branch ${apos}left${apos}
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (6 preceding siblings ...)
  2020-06-10 21:19 ` [PATCH 7/9] fmt-merge-msg: " Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:19 ` Johannes Schindelin via GitGitGadget
  2020-06-10 21:54   ` Matt Rogers
  2020-06-10 21:19 ` [PATCH 9/9] Document how the default branch name can be overridden Johannes Schindelin via GitGitGadget
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When anonymizing commit history, we are careful to leave the branch name
of the default branch alone.

When the default branch name is overridden via the config or via the
environment variable, we will want `git fast-export` to use that
overridden name instead.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/fast-export.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 85868162eec..028dd9969a2 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -515,13 +515,17 @@ static const char *anonymize_refname(const char *refname)
 	};
 	static struct hashmap refs;
 	static struct strbuf anon = STRBUF_INIT;
+	static char *default_branch_name;
 	int i;
 
 	/*
-	 * We also leave "master" as a special case, since it does not reveal
-	 * anything interesting.
+	 * We also leave the default branch name as a special case, since it
+	 * does not reveal anything interesting.
 	 */
-	if (!strcmp(refname, "refs/heads/master"))
+	if (!default_branch_name)
+		default_branch_name = git_default_branch_name(0);
+
+	if (!strcmp(refname, default_branch_name))
 		return refname;
 
 	strbuf_reset(&anon);
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH 9/9] Document how the default branch name can be overridden
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (7 preceding siblings ...)
  2020-06-10 21:19 ` [PATCH 8/9] fast-export: respect the possibly-overridden " Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:19 ` Johannes Schindelin via GitGitGadget
  2020-06-11  0:18   ` Junio C Hamano
  2020-06-10 23:11 ` [PATCH 0/9] Allow overriding the default name of the default branch Junio C Hamano
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-10 21:19 UTC (permalink / raw)
  To: git; +Cc: don, stolee, peff, sandals, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

There is a `GIT_TEST_*` environment variable and a `core.` config
setting (with the former taking precendence over the latter) to allow
overriding what name Git uses by default as main branch of new
repositories.

Now that all kinds of Git operations have learned to respect those,
let's document them.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/config/core.txt | 4 ++++
 t/README                      | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt
index 74619a9c03b..a11e1abdf59 100644
--- a/Documentation/config/core.txt
+++ b/Documentation/config/core.txt
@@ -626,3 +626,7 @@ core.abbrev::
 	in your repository, which hopefully is enough for
 	abbreviated object names to stay unique for some time.
 	The minimum length is 4.
+
+core.defaultBranchName::
+	Allows overriding the default branch name e.g. when initializing
+	a new repository or when cloning an empty repository.
diff --git a/t/README b/t/README
index cf863837ab9..b32f520a27f 100644
--- a/t/README
+++ b/t/README
@@ -421,6 +421,10 @@ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is
 the default when running tests), errors out when an abbreviated option
 is used.
 
+GIT_TEST_DEFAULT_BRANCH_NAME allows overriding the default branch name
+that is used for example when initializing new repositories, or when
+cloning a repository that has no branches yet.
+
 Naming Tests
 ------------
 
-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-10 21:19 ` [PATCH 8/9] fast-export: respect the possibly-overridden " Johannes Schindelin via GitGitGadget
@ 2020-06-10 21:54   ` Matt Rogers
  2020-06-10 23:25     ` Junio C Hamano
                       ` (2 more replies)
  0 siblings, 3 replies; 178+ messages in thread
From: Matt Rogers @ 2020-06-10 21:54 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: Git Mailing List, don, stolee, Jeff King, sandals, Johannes Schindelin

> -        * We also leave "master" as a special case, since it does not reveal
> -        * anything interesting.
> +        * We also leave the default branch name as a special case, since it
> +        * does not reveal anything interesting.
>          */
I feel this is a weird thing to do, since you're trying to anonymize the branch
name,and now the default branch is identifiable with your config file.  For
example, if the default branch contains the name of my project/repo then this
sounds like a recipe for accidentally sharing it. I feel a better
alternative would
be to exclude nothing from the anonymization or the proposed default default
branch name


> -       if (!strcmp(refname, "refs/heads/master"))
> +       if (!default_branch_name)
> +               default_branch_name = git_default_branch_name(0);
> +
> +       if (!strcmp(refname, default_branch_name))
>                 return refname;
>
>         strbuf_reset(&anon);
> --
> gitgitgadget
>


-- 
Matthew Rogers

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 6/9] clone: learn about the possibly-configured default branch name
  2020-06-10 21:19 ` [PATCH 6/9] clone: learn about the possibly-configured " Johannes Schindelin via GitGitGadget
@ 2020-06-10 22:58   ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-10 22:58 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> @@ -1263,9 +1263,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
>  		remote_head_points_at = NULL;
>  		remote_head = NULL;
>  		option_no_checkout = 1;
> -		if (!option_bare)
> -			install_branch_config(0, "master", option_origin,
> -					      "refs/heads/master");
> +		if (!option_bare) {
> +			char *default_branch = git_default_branch_name(0);
> +			const char *nick;
> +
> +			if (!skip_prefix(default_branch, "refs/heads/", &nick))
> +				BUG("unexpected default branch '%s'",
> +				    default_branch);
> +			install_branch_config(0, nick, option_origin,
> +					      default_branch);
> +			free(default_branch);
> +		}

Good catch.  Normal clone would follow whatever primary branch the
other side uses by pointing at it with its "HEAD" but this codepath
to deal with a clone of an empty repository needs to use a default,
so this is an appropriate change.

>  	write_refspec_config(src_ref_prefix, our_head_points_at,
> diff --git a/t/t5609-clone-branch.sh b/t/t5609-clone-branch.sh
> index 6e7a7be0522..66af3ac2669 100755
> --- a/t/t5609-clone-branch.sh
> +++ b/t/t5609-clone-branch.sh
> @@ -67,4 +67,13 @@ test_expect_success 'clone -b not allowed with empty repos' '
>  	test_must_fail git clone -b branch empty clone-branch-empty
>  '
>  
> +test_expect_success 'chooses correct default branch name' '
> +	GIT_TEST_DEFAULT_BRANCH_NAME= \
> +		git -c core.defaultBranchName=up clone empty whats-up &&
> +	test_write_lines refs/heads/up refs/heads/up >expect &&
> +	git -C whats-up symbolic-ref HEAD >actual &&
> +	git -C whats-up config branch.up.merge >>actual &&
> +	test_cmp expect actual
> +'
> +
>  test_done

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 7/9] fmt-merge-msg: learn about the possibly-configured default branch name
  2020-06-10 21:19 ` [PATCH 7/9] fmt-merge-msg: " Johannes Schindelin via GitGitGadget
@ 2020-06-10 22:59   ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-10 22:59 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> When formatting the commit message for merge commits, Git appends "into
> <branch-name>" unless the current branch is the default branch.
>
> Now that we can configure what the default branch name should be, we
> will want to respect that setting in that scenario rather than using the
> compiled-in default branch name.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  fmt-merge-msg.c          | 6 ++++--
>  t/t6200-fmt-merge-msg.sh | 8 ++++++++
>  2 files changed, 12 insertions(+), 2 deletions(-)
>
> diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
> index 72d32bd73b1..5e5c1d86f1c 100644
> --- a/fmt-merge-msg.c
> +++ b/fmt-merge-msg.c
> @@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
>  				const char *current_branch)
>  {
>  	int i = 0;
> -	char *sep = "";
> +	char *sep = "", *default_branch_name;
>  
>  	strbuf_addstr(out, "Merge ");
>  	for (i = 0; i < srcs.nr; i++) {
> @@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
>  			strbuf_addf(out, " of %s", srcs.items[i].string);
>  	}
>  
> -	if (!strcmp("master", current_branch))
> +	default_branch_name = git_default_branch_name(1);
> +	if (!strcmp(default_branch_name, current_branch))
>  		strbuf_addch(out, '\n');
>  	else
>  		strbuf_addf(out, " into %s\n", current_branch);
> +	free(default_branch_name);
>  }

Good.  J6t reminded me earlier about this one when I said "except
for 'init' and 'clone' (when it cannot tell what primary branch the
source of the clone uses), we do not need a hardcoded 'master'", and
the series covers this case.  Very pleased.


>  static void fmt_tag_signature(struct strbuf *tagbuf,
> diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
> index e4c2a6eca43..a23cd157ffd 100755
> --- a/t/t6200-fmt-merge-msg.sh
> +++ b/t/t6200-fmt-merge-msg.sh
> @@ -158,6 +158,14 @@ test_expect_success 'setup FETCH_HEAD' '
>  	git fetch . left
>  '
>  
> +test_expect_success 'with overridden default branch name' '
> +	test_config core.defaultBranchName default &&
> +	test_when_finished "git switch master" &&
> +	git switch -c default &&
> +	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
> +	! grep "into default" actual
> +'
> +
>  test_expect_success 'merge.log=3 limits shortlog length' '
>  	cat >expected <<-EOF &&
>  	Merge branch ${apos}left${apos}

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (8 preceding siblings ...)
  2020-06-10 21:19 ` [PATCH 9/9] Document how the default branch name can be overridden Johannes Schindelin via GitGitGadget
@ 2020-06-10 23:11 ` Junio C Hamano
  2020-06-11  5:42   ` Junio C Hamano
  2020-06-11 13:44   ` Johannes Schindelin
  2020-06-10 23:41 ` brian m. carlson
                   ` (4 subsequent siblings)
  14 siblings, 2 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-10 23:11 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> A growing number of open source projects aims to avoid the branch name 
> master due to its negative connotation. See [1] for an existing discussion
> on this. The links [2], [3], and [4] describe community-driven ways for
> users to rename their default branches or use template edits to set a new
> default branch name.

I scanned the series quickly and the patches seem to cover all the
places I was aware of that has the hard-coded knowledge of the
default branch name being 'master'.  Looking good.

> This series DOES NOT change the default automatically, but only provides an
> opt-in mechanism for interested users. It also presents a way forward for
> such a transition, if and when we decide to do so. Specifically, the new
> GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
> test scripts on an individual basis instead of all-at-once.

Yes.  I've been thinking about a way that does not hurt workflows
used in existing projects while allowing a "git init" that is run to
create a new repository by a new user who does not have any special
customization in ~/.gitconfig to use the branch name that replaces
the 'master' (I do not mind changing away from 'master', but I am
not yet convinced it should be 'main', by the way---the actual
choice of the final name does not matter at this point of the design
of backward compatibility plan).  

I think "git init" that is creating a new repository (iow, do not do
anything when reinitializing an existing repostiory) can

 - look at config.defaultBranchName in /etc/gitconfig or
   ~/.gitconfig before initializing the per-repository config in
   $GIT_DIR/config it just created (or it is about to create).

 - if there is no config.defaultBranchName configured, then set the
   per-repository configuration to 'main' in the per-repository
   configuration.  Otherwise do not do anything.

And then we make sure Don's git_default_branch_name() works this
way:

 (0) if there is config.defaultBranchName in relevant config file
     (i.e. /etc/gitconfig, ~/.gitconfig or per-repo config), use the
     specified name.

 (1) otherwise use 'master' (not 'main').

That way, an existing repository will keep using 'master' unless the
user shows the preference (and accepts responsibilities for possible
fallouts) in ~/.gitconfig or the repository's .git/config, while a
new repository created by a user who does not show any particular
preference will use 'main'.



^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-10 21:19 ` [PATCH 1/9] init: allow overriding the default branch name for new repositories Don Goodman-Wilson via GitGitGadget
@ 2020-06-10 23:22   ` brian m. carlson
  2020-06-11  0:16   ` Eric Sunshine
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 178+ messages in thread
From: brian m. carlson @ 2020-06-10 23:22 UTC (permalink / raw)
  To: Don Goodman-Wilson via GitGitGadget
  Cc: git, don, stolee, peff, Johannes Schindelin

[-- Attachment #1: Type: text/plain, Size: 726 bytes --]

On 2020-06-10 at 21:19:22, Don Goodman-Wilson via GitGitGadget wrote:
> +	/* prepend "refs/heads/" to the branch name */
> +	prefixed = xstrfmt("refs/heads/%s", branch_name);
> +	if (check_refname_format(prefixed, 0))
> +		die(_("invalid default branch name: '%s'"), branch_name);

I'm glad to see this part and a check for it in the test below.  We
wouldn't want a typo to create a broken branch name.

> +test_expect_success 'invalid custom default branch name' '
> +	test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \
> +		git init custom-invalid 2>err &&
> +	test_i18ngrep "invalid default branch name" err
> +'
> +
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-10 21:54   ` Matt Rogers
@ 2020-06-10 23:25     ` Junio C Hamano
  2020-06-10 23:39     ` brian m. carlson
  2020-06-11 13:57     ` Johannes Schindelin
  2 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-10 23:25 UTC (permalink / raw)
  To: Matt Rogers
  Cc: Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King, sandals, Johannes Schindelin

Matt Rogers <mattr94@gmail.com> writes:

>> -        * We also leave "master" as a special case, since it does not reveal
>> -        * anything interesting.
>> +        * We also leave the default branch name as a special case, since it
>> +        * does not reveal anything interesting.
>>          */
> I feel this is a weird thing to do, since you're trying to anonymize the branch
> name,and now the default branch is identifiable with your config file.  For
> example, if the default branch contains the name of my project/repo then this
> sounds like a recipe for accidentally sharing it. I feel a better
> alternative would
> be to exclude nothing from the anonymization or the proposed default default
> branch name

I wonder if anything bad happens if we keep *no* refs intact in this
function.  "Since it does not reveal anything interesting" is an
excuse why not munging it may be OK, but it does not explain why we
prefer not munging it actively.

If there is no reason to keep _some_ refs as-is, I agree that it is
perfectly sensible not to have this special case at all.

Thanks.

>> -       if (!strcmp(refname, "refs/heads/master"))
>> +       if (!default_branch_name)
>> +               default_branch_name = git_default_branch_name(0);
>> +
>> +       if (!strcmp(refname, default_branch_name))
>>                 return refname;
>>
>>         strbuf_reset(&anon);
>> --
>> gitgitgadget
>>

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-10 21:54   ` Matt Rogers
  2020-06-10 23:25     ` Junio C Hamano
@ 2020-06-10 23:39     ` brian m. carlson
  2020-06-11  0:20       ` Matt Rogers
  2020-06-11 13:57     ` Johannes Schindelin
  2 siblings, 1 reply; 178+ messages in thread
From: brian m. carlson @ 2020-06-10 23:39 UTC (permalink / raw)
  To: Matt Rogers
  Cc: Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King, Johannes Schindelin

[-- Attachment #1: Type: text/plain, Size: 2054 bytes --]

On 2020-06-10 at 21:54:01, Matt Rogers wrote:
> > -        * We also leave "master" as a special case, since it does not reveal
> > -        * anything interesting.
> > +        * We also leave the default branch name as a special case, since it
> > +        * does not reveal anything interesting.
> >          */
> I feel this is a weird thing to do, since you're trying to anonymize the branch
> name,and now the default branch is identifiable with your config file.  For
> example, if the default branch contains the name of my project/repo then this
> sounds like a recipe for accidentally sharing it. I feel a better
> alternative would
> be to exclude nothing from the anonymization or the proposed default default
> branch name

I think this is fine because it only reveals the name of your particular
choice of default branch.  The goal of the --anonymize option is to
allow people to maintain the structure of their repositories while
stripping private information from them, primarily for debugging
purposes (e.g., providing to us for troubleshooting).

The things people want to prevent exposing are their code, data, project
names, user names, etc.: that is, anything identifying, privileged, or
private.  The default branch name isn't any of those things; we know you
have one, and for troubleshooting purposes, we aren't that interested in
what you called it.  You've almost certainly picked it out of a set of
one of 20 words that people use for this purpose, none of which are
private, and all of which are shared by millions of other repositories.

In the extremely unlikely case that it does matter, invoking git with
something like "-c default.branch=$(git hash-object /dev/null)" would be
sufficient to anonymize all branches.

I should point out that people frequently ask for the output of "git
config -l" for troubleshooting, and most people wouldn't consider their
default branch name to be worth sanitizing there.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (9 preceding siblings ...)
  2020-06-10 23:11 ` [PATCH 0/9] Allow overriding the default name of the default branch Junio C Hamano
@ 2020-06-10 23:41 ` brian m. carlson
  2020-06-11  1:07 ` Taylor Blau
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 178+ messages in thread
From: brian m. carlson @ 2020-06-10 23:41 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, Johannes Schindelin

[-- Attachment #1: Type: text/plain, Size: 2187 bytes --]

On 2020-06-10 at 21:19:21, Johannes Schindelin via GitGitGadget wrote:
> A growing number of open source projects aims to avoid the branch name 
> master due to its negative connotation. See [1] for an existing discussion
> on this. The links [2], [3], and [4] describe community-driven ways for
> users to rename their default branches or use template edits to set a new
> default branch name.
> 
> [1] 
> https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/
> 
> [2] https://twitter.com/mislav/status/1270388510684598272
> 
> [3] 
> https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx
> 
> [4] https://github.com/ethomson/retarget_prs
> 
> By necessity, existing repositories require a lot of manual work to move
> away from that branch name, but it should be much easier for new
> repositories.
> 
> This patch series allows overriding the branch name being used for new
> repositories' main branch. The main way to do this is the new 
> core.defaultBranchName config option. This first patch was contributed by
> newcomer Dan Goodman-Wilson. Thanks for the contribution!
> 
> The other patches follow other places where "master" is hard-coded and use
> the new git_default_branch_name() method to consume the config option before
> falling back to "master".
> 
> The last patch updates documentation only after the config option is ready
> to apply to all of these scenarios.
> 
> This series DOES NOT change the default automatically, but only provides an
> opt-in mechanism for interested users. It also presents a way forward for
> such a transition, if and when we decide to do so. Specifically, the new
> GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
> test scripts on an individual basis instead of all-at-once.

I've looked over this series, and I have no additional comments beyond
what I've mentioned and what Junio pointed out at the end of the series.
With those provisos, I'm generally happy with it, and glad to see these
patches hit the list.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-10 21:19 ` [PATCH 1/9] init: allow overriding the default branch name for new repositories Don Goodman-Wilson via GitGitGadget
  2020-06-10 23:22   ` brian m. carlson
@ 2020-06-11  0:16   ` Eric Sunshine
  2020-06-11 14:09     ` Johannes Schindelin
  2020-06-16 12:45     ` Jeff King
  2020-06-11  9:35   ` Phillip Wood
  2020-06-11 10:23   ` Alban Gruin
  3 siblings, 2 replies; 178+ messages in thread
From: Eric Sunshine @ 2020-06-11  0:16 UTC (permalink / raw)
  To: Don Goodman-Wilson via GitGitGadget
  Cc: Git List, Derrick Stolee, Jeff King, brian m. carlson,
	Johannes Schindelin, Don Goodman-Wilson

On Wed, Jun 10, 2020 at 5:19 PM Don Goodman-Wilson via GitGitGadget
<gitgitgadget@gmail.com> wrote:
> [...]
> To make this process much less cumbersome, let's introduce support for
> `core.defaultBranchName`. That way, users won't need to keep their
> copied template files up to date, and won't interfere with default hooks
> installed by their administrators.
> [...]
> Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
> ---
> diff --git a/refs.c b/refs.c
> @@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
> +                       die(_("Could not retrieve `core.defaultBranchName`"));

Nit: here the error message is capitalized...

> +               if (from_config)
> +                       branch_name = from_config;
> +               else
> +                       branch_name = "master";

Non-actionable nit: could be written:

    branch_name = from_config ? from_config : "master";

> +       }
> +
> +       if (short_name)
> +               return from_config ? from_config : xstrdup(branch_name);

The logic overall is a bit difficult to follow when trying to
understand when and when not to duplicate the string and when and when
not to free(), but seems to be correct.

> +       /* prepend "refs/heads/" to the branch name */
> +       prefixed = xstrfmt("refs/heads/%s", branch_name);
> +       if (check_refname_format(prefixed, 0))
> +               die(_("invalid default branch name: '%s'"), branch_name);

Here, the error message is not capitalized. It would be nice for both
messages to share a common capitalization scheme. These days, we tend
to favor _not_ capitalizing error messages, so perhaps remove
capitalization from the earlier one.

> +/*
> + * Retrieves the name of the default branch. If `short_name` is non-zero, the
> + * branch name will be prefixed with "refs/heads/".
> + */
> +char *git_default_branch_name(int short_name);

Overall, the internal logic regarding duplicating/freeing strings
would probably be easier to grok if there were two separate functions:

    char *git_default_branch_name(void);
    char *git_default_ref_name(void);

but that's subjective.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 9/9] Document how the default branch name can be overridden
  2020-06-10 21:19 ` [PATCH 9/9] Document how the default branch name can be overridden Johannes Schindelin via GitGitGadget
@ 2020-06-11  0:18   ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11  0:18 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt
> index 74619a9c03b..a11e1abdf59 100644
> --- a/Documentation/config/core.txt
> +++ b/Documentation/config/core.txt
> @@ -626,3 +626,7 @@ core.abbrev::
>  	in your repository, which hopefully is enough for
>  	abbreviated object names to stay unique for some time.
>  	The minimum length is 4.
> +
> +core.defaultBranchName::
> +	Allows overriding the default branch name e.g. when initializing
> +	a new repository or when cloning an empty repository.

As we saw in [PATCH 7/9], it also affects for which branch an
auto-generated merge message omits "into $branch" at the end.

The behaviour change of "merge" might matter more than we think here
in a hand-wavy way, and it certainly does affect more than 'init'
and 'clone' (both of which are one time operation per repository),
because setting this in ~/.gitconfig would affect all the
repositories, whose merges into their 'master' suddenly starts
saying "into master" at the end, unlike existing merges.  So it
probably is worth highlighting it here.

> diff --git a/t/README b/t/README
> index cf863837ab9..b32f520a27f 100644
> --- a/t/README
> +++ b/t/README
> @@ -421,6 +421,10 @@ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is
>  the default when running tests), errors out when an abbreviated option
>  is used.
>  
> +GIT_TEST_DEFAULT_BRANCH_NAME allows overriding the default branch name
> +that is used for example when initializing new repositories, or when
> +cloning a repository that has no branches yet.
> +
>  Naming Tests
>  ------------

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-10 23:39     ` brian m. carlson
@ 2020-06-11  0:20       ` Matt Rogers
  2020-06-11  5:26         ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Matt Rogers @ 2020-06-11  0:20 UTC (permalink / raw)
  To: brian m. carlson, Matt Rogers,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King, Johannes Schindelin

> I think this is fine because it only reveals the name of your particular
> choice of default branch.  The goal of the --anonymize option is to
> allow people to maintain the structure of their repositories while
> stripping private information from them, primarily for debugging
> purposes (e.g., providing to us for troubleshooting).
>
> The things people want to prevent exposing are their code, data, project
> names, user names, etc.: that is, anything identifying, privileged, or
> private.  The default branch name isn't any of those things; we know you
> have one, and for troubleshooting purposes, we aren't that interested in
> what you called it.  You've almost certainly picked it out of a set of
> one of 20 words that people use for this purpose, none of which are
> private, and all of which are shared by millions of other repositories.
>

I think that's not very convincing.  If branch names in general are identifying
enough to warrant anonymization then shouldn't the default name be too?

> In the extremely unlikely case that it does matter, invoking git with
> something like "-c default.branch=$(git hash-object /dev/null)" would be
> sufficient to anonymize all branches.
>
> I should point out that people frequently ask for the output of "git
> config -l" for troubleshooting, and most people wouldn't consider their
> default branch name to be worth sanitizing there.

I think this is a little presumptuous, most people wouldn't consider it to be
worth sanitizing because there isn't currently such a config setting.  If I give
you the the output of "git config -l" then I think it's obvious that all of my
configuration settings will be included (and therefore I can choose to sanitize
accordingly), but if I'm giving an exported repository I think should be
anonymized, but my default branch, which someone could innocently base on a
project or company name, could easily be accidentally included in that output
which could lead to a frustrating experience


> --
> brian m. carlson: Houston, Texas, US
> OpenPGP: https://keybase.io/bk2204



-- 
Matthew Rogers

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (10 preceding siblings ...)
  2020-06-10 23:41 ` brian m. carlson
@ 2020-06-11  1:07 ` Taylor Blau
  2020-06-11 14:33   ` Johannes Schindelin
  2020-06-15 10:03 ` Pratyush Yadav
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 178+ messages in thread
From: Taylor Blau @ 2020-06-11  1:07 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin

Hi Johannes (and Dan)

On Wed, Jun 10, 2020 at 09:19:21PM +0000, Johannes Schindelin via GitGitGadget wrote:
> A growing number of open source projects aims to avoid the branch name
> master due to its negative connotation. See [1] for an existing discussion
> on this. The links [2], [3], and [4] describe community-driven ways for
> users to rename their default branches or use template edits to set a new
> default branch name.
>
> [1]
> https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/
>
> [2] https://twitter.com/mislav/status/1270388510684598272
>
> [3]
> https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx
>
> [4] https://github.com/ethomson/retarget_prs
>
> By necessity, existing repositories require a lot of manual work to move
> away from that branch name, but it should be much easier for new
> repositories.

This is (somewhat) orthogonal to the topic here, but I wonder if we
could be doing anything to make this easier for users.

Could servers remember that a branch has ``moved'' and alert users as
such when they pull? Even better, it would be nice if this alert from
the server could allow clients to automatically rename their refs
appropriately so that this transition is as easy as possible, even for
existing repositories.

> This patch series allows overriding the branch name being used for new
> repositories' main branch. The main way to do this is the new
> core.defaultBranchName config option. This first patch was contributed by
> newcomer Dan Goodman-Wilson. Thanks for the contribution!

Welcome, Dan! This is a fantastic first contribution, and I would be
honored to help and move this forward in anyway that I can.

I should note that I am technically "out of office" (which normally
wouldn't mean much, but this time means that I am on a road-trip, and so
am only at my computer infrequently). I am catching up on just a few
emails here, but I'll be able to help out more (and would be honored to
do so) once I am really back next Monday.

> The other patches follow other places where "master" is hard-coded and use
> the new git_default_branch_name() method to consume the config option before
> falling back to "master".
>
> The last patch updates documentation only after the config option is ready
> to apply to all of these scenarios.
>
> This series DOES NOT change the default automatically, but only provides an
> opt-in mechanism for interested users. It also presents a way forward for
> such a transition, if and when we decide to do so. Specifically, the new
> GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
> test scripts on an individual basis instead of all-at-once.

Provided that the eventual plan is to seriously evaluate a name other
than "master", I think that this is a good way forward that clears the
way for us to make this change easily, without forcing us to come to a
conclusion on what name will replace "master" today.

For what it's worth, I am completely in favor of abandoning this term.
My colleagues at GitHub (as has been mentioned previously on the list)
are in favor of this as well, and it is my understanding that other
providers feel similarly.

I would be in favor of any non-offensive name that we can reach
consensus on. "trunk" sounds nice to me, but I think that it may cause
problems for non-native English speakers, so perhaps "main" or
"default" would suffice (maybe "main" is better, since it retains muscle
memory for the first two characters without being offensive--at least,
as far as I can tell. If I am wrong, please correct me and we should
consider something else).

All of that said, I can't emphasize enough how little I care about
*what* name we replace "master" with, so long as it is (1) replaced with
a non-offensive term, (2) that that change is done uniformly throughout
the "Git Ecosystem" and (3) that the community can reach consensus on
the new term in a respectful, appropriate, and considerate way. I only
provided a few suggestions to get the conversation flowing, although I
suspect that my help isn't needed there.

> Don Goodman-Wilson (1):
>   init: allow overriding the default branch name for new repositories
>
> Johannes Schindelin (8):
>   remote: respect `core.defaultBranchName`
>   send-pack/transport-helper: respect `core.defaultBranchName`
>   testsvn: respect `core.defaultBranchName`
>   submodule: use the (possibly overridden) default branch name
>   clone: learn about the possibly-configured default branch name
>   fmt-merge-msg: learn about the possibly-configured default branch name
>   fast-export: respect the possibly-overridden default branch name
>   Document how the default branch name can be overridden
>
>  Documentation/config/core.txt |  4 ++++
>  builtin/clone.c               | 14 +++++++++++---
>  builtin/fast-export.c         | 10 +++++++---
>  builtin/init-db.c             |  8 +++++---
>  builtin/submodule--helper.c   | 10 ++++++++--
>  fmt-merge-msg.c               |  6 ++++--
>  refs.c                        | 34 ++++++++++++++++++++++++++++++++++
>  refs.h                        |  6 ++++++
>  remote-testsvn.c              | 11 ++++++++---
>  remote.c                      | 12 ++++++++----
>  send-pack.c                   |  6 +++++-
>  t/README                      |  4 ++++
>  t/t0001-init.sh               | 20 ++++++++++++++++++++
>  t/t5609-clone-branch.sh       |  9 +++++++++
>  t/t6200-fmt-merge-msg.sh      |  8 ++++++++
>  transport-helper.c            |  6 +++++-
>  16 files changed, 146 insertions(+), 22 deletions(-)
>
>
> base-commit: 0313f36c6ebecb3bffe6f15cf25a4883100f0214
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-656%2Fdscho%2Fdefault-branch-name-option-v1
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-656/dscho/default-branch-name-option-v1
> Pull-Request: https://github.com/gitgitgadget/git/pull/656
> --
> gitgitgadget

Thanks,
Taylor

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11  0:20       ` Matt Rogers
@ 2020-06-11  5:26         ` Junio C Hamano
  2020-06-11 14:05           ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11  5:26 UTC (permalink / raw)
  To: Matt Rogers
  Cc: brian m. carlson, Johannes Schindelin via GitGitGadget,
	Git Mailing List, don, stolee, Jeff King, Johannes Schindelin

Matt Rogers <mattr94@gmail.com> writes:

> I think that's not very convincing.  If branch names in general are identifying
> enough to warrant anonymization then shouldn't the default name be too?

It is a good argument.  I also heard a rumor that often branch names
contain codewords given to pre-released hardware that are highly
confidential in certain circles, and heard that it is one of the
reasons why Gerrit has server side ACL that lets you hide some
branches from authenticated users that can access other branches.

Again, the original comment explains why 'master' without such a
configuration knob was not worth protecting, but what it does not
explain is why keeping it (and only that branch name) unmunged gives
a more useful result than munging everything.  From the point of
view of "I want to debug the shape of the DAG, without the actual
user data", munging 'master' to 'ref47' while other branches like
'next' are munged to 'ref%d' does not make it harder to use or less
useful for the debugging than only 'master' is kept intact in the
output stream.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-10 23:11 ` [PATCH 0/9] Allow overriding the default name of the default branch Junio C Hamano
@ 2020-06-11  5:42   ` Junio C Hamano
  2020-06-11 13:44   ` Johannes Schindelin
  1 sibling, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11  5:42 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin

Junio C Hamano <gitster@pobox.com> writes:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
> ...
>> This series DOES NOT change the default automatically, but only provides an
>> opt-in mechanism for interested users. It also presents a way forward for
>> such a transition, if and when we decide to do so. Specifically, the new
>> GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
>> test scripts on an individual basis instead of all-at-once.
>
> Yes.  I've been thinking about a way that does not hurt workflows
> used in existing projects while allowing a "git init" that is run to
> create a new repository by a new user who does not have any special
> customization in ~/.gitconfig to use the branch name that replaces
> the 'master' (I do not mind changing away from 'master', but I am
> not yet convinced it should be 'main', by the way---the actual
> choice of the final name does not matter at this point of the design
> of backward compatibility plan).  
>
> I think "git init" that is creating a new repository (iow, do not do
> anything when reinitializing an existing repostiory) can
>
>  - look at config.defaultBranchName in /etc/gitconfig or
>    ~/.gitconfig before initializing the per-repository config in
>    $GIT_DIR/config it just created (or it is about to create).
>
>  - if there is no config.defaultBranchName configured, then set the
>    per-repository configuration to 'main' in the per-repository
>    configuration.  Otherwise do not do anything.
>
> And then we make sure Don's git_default_branch_name() works this
> way:
>
>  (0) if there is config.defaultBranchName in relevant config file
>      (i.e. /etc/gitconfig, ~/.gitconfig or per-repo config), use the
>      specified name.
>
>  (1) otherwise use 'master' (not 'main').
>
> That way, an existing repository will keep using 'master' unless the
> user shows the preference (and accepts responsibilities for possible
> fallouts) in ~/.gitconfig or the repository's .git/config, while a
> new repository created by a user who does not show any particular
> preference will use 'main'.

A useful addition to these 9-patch series (i.e. even before the
default for vanilla usage gets changed) might be to give an example
to use "git config" to grab the default branch name, e.g.

    name=$(git config core.defaultBranchName || echo master)

Better yet (because the above forces the end users to write 'master'
in their script), we might want to teach "git var" about the
variable, so that the above can be written like so:

    name=$(git var defaultBranchName)

For those not so familiar with "git var", it is a command to query
"magic" variables whose value can be retrieved from different places
and is backed by non-trivial logic.  "What's the editor to be used?"
is queried by "git var GIT_EDITOR", but that is not a simple:

    if test -n "$GIT_EDITOR"
    then
	echo "$GIT_EDITOR"
    else
	echo vi
    fi

It takes the fallback `EDITOR` environment variable, and core.editor
configuration variable, into account, for example.

Similarly, "what is the default branch name" is not just about the
value of one configuration variable.  GIT_TEST_DEFAULT_BRANCH_NAME
environment needs to be consulted, and when there is nothing
configured, it needs to say 'master', so that end-users who use "git
var" do not have to hardcode the string 'master' in their script.



^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-10 21:19 ` [PATCH 1/9] init: allow overriding the default branch name for new repositories Don Goodman-Wilson via GitGitGadget
  2020-06-10 23:22   ` brian m. carlson
  2020-06-11  0:16   ` Eric Sunshine
@ 2020-06-11  9:35   ` Phillip Wood
  2020-06-12 11:55     ` Johannes Schindelin
  2020-06-11 10:23   ` Alban Gruin
  3 siblings, 1 reply; 178+ messages in thread
From: Phillip Wood @ 2020-06-11  9:35 UTC (permalink / raw)
  To: Don Goodman-Wilson via GitGitGadget, git
  Cc: don, stolee, peff, sandals, Johannes Schindelin

On 10/06/2020 22:19, Don Goodman-Wilson via GitGitGadget wrote:
> From: Don Goodman-Wilson <don@goodman-wilson.com>
> 
> There is a growing number of projects trying to avoid the non-inclusive
> name `master` in their repositories.

I think it would be helpful to explain why 'master' is no-inclusive even
if it originates from the concept of a master copy. i.e. it suggests
master/slave even if git is not based on that concept.

Have you got some examples of projects that have changed and the names
that they are using? I think it would be helpful if we can agree on a
replacement for master - if every repository uses a different name for
its main branch it adds an extra complication for new contributors to
those projects.

 For existing repositories, this
> requires manual work. For new repositories, the only way to do that
> automatically is by copying all of Git's template directory, then
> hard-coding the desired default branch name into the `.git/HEAD` file,
> and then configuring `init.templateDir` to point to those copied
> template files.
> 
> To make this process much less cumbersome, let's introduce support for
> `core.defaultBranchName`. That way, users won't need to keep their
> copied template files up to date, and won't interfere with default hooks
> installed by their administrators.
> 
> While at it, also let users set the default branch name via the
> environment variable `GIT_TEST_DEFAULT_BRANCH_NAME`,

I'm not sure we usually promote the use of GIT_TEST_... environment
variables outside of the test suite.

> in preparation for
> adjusting Git's test suite to a more inclusive default branch name. As
> is common in Git, the `GIT_TEST_*` variable takes precedence over the
> config setting.
> 
> Note: we use the prefix `core.` instead of `init.` because we want to
> adjust also `git clone`, `git fmt-merge-msg` and other commands over the
> course of the next commits to respect this setting.
> 
> Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> Helped-by: Derrick Stolee <dstolee@microsoft.com>
> Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
> ---
>  builtin/init-db.c |  8 +++++---
>  refs.c            | 34 ++++++++++++++++++++++++++++++++++
>  refs.h            |  6 ++++++
>  t/t0001-init.sh   | 20 ++++++++++++++++++++
>  4 files changed, 65 insertions(+), 3 deletions(-)
> 
> diff --git a/builtin/init-db.c b/builtin/init-db.c
> index 0b7222e7188..99792adfd43 100644
> --- a/builtin/init-db.c
> +++ b/builtin/init-db.c
> @@ -258,15 +258,17 @@ static int create_default_files(const char *template_path,
>  		die("failed to set up refs db: %s", err.buf);
>  
>  	/*
> -	 * Create the default symlink from ".git/HEAD" to the "master"
> -	 * branch, if it does not exist yet.
> +	 * Create the default symlink from ".git/HEAD" to the default
> +	 * branch name, if it does not exist yet.
>  	 */
>  	path = git_path_buf(&buf, "HEAD");
>  	reinit = (!access(path, R_OK)
>  		  || readlink(path, junk, sizeof(junk)-1) != -1);
>  	if (!reinit) {
> -		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
> +		char *default_ref = git_default_branch_name(0);
> +		if (create_symref("HEAD", default_ref, NULL) < 0)
>  			exit(1);
> +		free(default_ref);
>  	}
>  
>  	initialize_repository_version(fmt->hash_algo);
> diff --git a/refs.c b/refs.c
> index 224ff66c7bb..8499b3865cb 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
>  		argv_array_pushf(prefixes, *p, len, prefix);
>  }
>  
> +char *git_default_branch_name(int short_name)
> +{
> +	const char *branch_name = getenv("GIT_TEST_DEFAULT_BRANCH_NAME");
> +	char *from_config = NULL, *prefixed;
> +
> +	/*
> +	 * If the default branch name was not specified via the environment
> +	 * variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config
> +	 * setting core.defaultBranchName. If neither are set, fall back to the
> +	 * hard-coded default.
> +	 */
> +	if (!branch_name || !*branch_name) {
> +		if (git_config_get_string("core.defaultbranchname",
> +					  &from_config) < 0)
> +			die(_("Could not retrieve `core.defaultBranchName`"));
> +
> +		if (from_config)
> +			branch_name = from_config;
> +		else
> +			branch_name = "master";
> +	}
> +
> +	if (short_name)
> +		return from_config ? from_config : xstrdup(branch_name);

If short_name is set we return without validating the name is that
intentional?

> +
> +	/* prepend "refs/heads/" to the branch name */
> +	prefixed = xstrfmt("refs/heads/%s", branch_name);
> +	if (check_refname_format(prefixed, 0))
> +		die(_("invalid default branch name: '%s'"), branch_name);
> +
> +	free(from_config);
> +	return prefixed;
> +}
> +
>  /*
>   * *string and *len will only be substituted, and *string returned (for
>   * later free()ing) if the string passed in is a magic short-hand form
> diff --git a/refs.h b/refs.h
> index a92d2c74c83..e8d4f6e2f13 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -154,6 +154,12 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
>  int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
>  int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
>  
> +/*
> + * Retrieves the name of the default branch. If `short_name` is non-zero, the
> + * branch name will be prefixed with "refs/heads/".

Isn't the other way around - the branch name is prefixed with
"refs/heads/" if short is zero.

> + */
> +char *git_default_branch_name(int short_name);
> +
>  /*
>   * A ref_transaction represents a collection of reference updates that
>   * should succeed or fail together.
> diff --git a/t/t0001-init.sh b/t/t0001-init.sh
> index 1edd5aeb8f0..b144cd8f46b 100755
> --- a/t/t0001-init.sh
> +++ b/t/t0001-init.sh
> @@ -464,4 +464,24 @@ test_expect_success MINGW 'redirect std handles' '
>  	grep "Needed a single revision" output.txt
>  '
>  
> +test_expect_success 'custom default branch name from config' '
> +	git config --global core.defaultbranchname nmb &&

In tests we usually use 'test_config' rather than 'git config' as the
former automatically cleans up the config at the end of the test.

> +	GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config &&
> +	git config --global --unset core.defaultbranchname &&
> +	git -C custom-config symbolic-ref HEAD >actual &&
> +	grep nmb actual
> +'
> +
> +test_expect_success 'custom default branch name from env' '
> +	GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env &&

It would be good to test that this overrides the config setting

Best Wishes

Phillip

> +	git -C custom-env symbolic-ref HEAD >actual &&
> +	grep nmb actual
> +'
> +
> +test_expect_success 'invalid custom default branch name' '
> +	test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \
> +		git init custom-invalid 2>err &&
> +	test_i18ngrep "invalid default branch name" err
> +'
> +
>  test_done
> 


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-10 21:19 ` [PATCH 1/9] init: allow overriding the default branch name for new repositories Don Goodman-Wilson via GitGitGadget
                     ` (2 preceding siblings ...)
  2020-06-11  9:35   ` Phillip Wood
@ 2020-06-11 10:23   ` Alban Gruin
  2020-06-11 23:14     ` Junio C Hamano
  3 siblings, 1 reply; 178+ messages in thread
From: Alban Gruin @ 2020-06-11 10:23 UTC (permalink / raw)
  To: Don Goodman-Wilson via GitGitGadget, git
  Cc: don, stolee, peff, sandals, Johannes Schindelin

Hi Don & Johannes,

Le 10/06/2020 à 23:19, Don Goodman-Wilson via GitGitGadget a écrit :
> From: Don Goodman-Wilson <don@goodman-wilson.com>
> 
> There is a growing number of projects trying to avoid the non-inclusive
> name `master` in their repositories. For existing repositories, this
> requires manual work. For new repositories, the only way to do that
> automatically is by copying all of Git's template directory, then
> hard-coding the desired default branch name into the `.git/HEAD` file,
> and then configuring `init.templateDir` to point to those copied
> template files.
> 
> To make this process much less cumbersome, let's introduce support for
> `core.defaultBranchName`. That way, users won't need to keep their
> copied template files up to date, and won't interfere with default hooks
> installed by their administrators.
> 
> While at it, also let users set the default branch name via the
> environment variable `GIT_TEST_DEFAULT_BRANCH_NAME`, in preparation for
> adjusting Git's test suite to a more inclusive default branch name. As
> is common in Git, the `GIT_TEST_*` variable takes precedence over the
> config setting.
> 

Why adding yet another environment variable instead of relying only on a
config option?  I understand it's for the tests, but can't we add a
shell function in test-lib.sh (and friends) that tries to read
`GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets
`core.defaultBranchName'?

Cheers,
Alban


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-10 23:11 ` [PATCH 0/9] Allow overriding the default name of the default branch Junio C Hamano
  2020-06-11  5:42   ` Junio C Hamano
@ 2020-06-11 13:44   ` Johannes Schindelin
  2020-06-11 14:44     ` Junio C Hamano
  1 sibling, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-11 13:44 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff, sandals

Hi Junio,

On Wed, 10 Jun 2020, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > A growing number of open source projects aims to avoid the branch name
> > master due to its negative connotation. See [1] for an existing discussion
> > on this. The links [2], [3], and [4] describe community-driven ways for
> > users to rename their default branches or use template edits to set a new
> > default branch name.
>
> I scanned the series quickly and the patches seem to cover all the
> places I was aware of that has the hard-coded knowledge of the
> default branch name being 'master'.  Looking good.

Thanks!

> > This series DOES NOT change the default automatically, but only
> > provides an opt-in mechanism for interested users. It also presents a
> > way forward for such a transition, if and when we decide to do so.
> > Specifically, the new GIT_TEST_DEFAULT_BRANCH_NAME environment
> > variable could be used to update test scripts on an individual basis
> > instead of all-at-once.
>
> Yes.  I've been thinking about a way that does not hurt workflows
> used in existing projects while allowing a "git init" that is run to
> create a new repository by a new user who does not have any special
> customization in ~/.gitconfig to use the branch name that replaces
> the 'master' (I do not mind changing away from 'master', but I am
> not yet convinced it should be 'main', by the way---the actual
> choice of the final name does not matter at this point of the design
> of backward compatibility plan).
>
> I think "git init" that is creating a new repository (iow, do not do
> anything when reinitializing an existing repostiory) can
>
>  - look at config.defaultBranchName in /etc/gitconfig or
>    ~/.gitconfig before initializing the per-repository config in
>    $GIT_DIR/config it just created (or it is about to create).
>
>  - if there is no config.defaultBranchName configured, then set the
>    per-repository configuration to 'main' in the per-repository
>    configuration.  Otherwise do not do anything.
>
> And then we make sure Don's git_default_branch_name() works this
> way:
>
>  (0) if there is config.defaultBranchName in relevant config file
>      (i.e. /etc/gitconfig, ~/.gitconfig or per-repo config), use the
>      specified name.
>
>  (1) otherwise use 'master' (not 'main').
>
> That way, an existing repository will keep using 'master' unless the
> user shows the preference (and accepts responsibilities for possible
> fallouts) in ~/.gitconfig or the repository's .git/config, while a
> new repository created by a user who does not show any particular
> preference will use 'main'.

I read this (way too late) last night and slept over it. Together with
your comment on the `fmt-merge-msg` patch, I think you are really on to
something: we need _two_ config settings, as there are two distinct
concepts at play here:

- One setting to specify the default branch name for newly-initialized
  repositories (such as `git init`, unless it re-initializes, and `git
  clone` when the cloned repository does not yet contain any branches).

  This should probably be called `init.defaultBranchName` (even if `git
  clone` picks it up, too), and be overrideable by
  `GIT_TEST_DEFAULT_BRANCH_NAME`.

- And another one, to define the default branch name for the _current_
  repository. This setting would be configured implicitly upon `git init`
  and `git clone`. For repositories where it is not set, we would assume
  `master` for backwards-compatibility.

  Technically, this should probably not even be a config option because it
  is _strictly_ per-repo. But maybe it is not _so_ much per-repo: if I
  want to rename all my main branches in all of my local repositories, I
  might opt to configure this in `~/.gitconfig`.

  Maybe a good name for this would be `repo.mainBranch` (and it would
  contain the full ref name, e.g. `refs/heads/main`, not just `main`).

And then `git fmt-merge-msg` (and your proposed `git var` addition, which
I like a lot, maybe `git var mainBranch`?) will pick up the latter.

That way, existing repositories would not be affected by
`GIT_TEST_DEFAULT_BRANCH_NAME` or `init.defaultBranchName` at all. Only
new repositories would pick it up.

Does that sound like a plan?

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-10 21:54   ` Matt Rogers
  2020-06-10 23:25     ` Junio C Hamano
  2020-06-10 23:39     ` brian m. carlson
@ 2020-06-11 13:57     ` Johannes Schindelin
  2020-06-11 18:19       ` Junio C Hamano
  2 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-11 13:57 UTC (permalink / raw)
  To: Matt Rogers
  Cc: Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King, sandals

Hi Matt,

On Wed, 10 Jun 2020, Matt Rogers wrote:

> > -        * We also leave "master" as a special case, since it does not reveal
> > -        * anything interesting.
> > +        * We also leave the default branch name as a special case, since it
> > +        * does not reveal anything interesting.
> >          */
> I feel this is a weird thing to do, since you're trying to anonymize the branch
> name,and now the default branch is identifiable with your config file.  For
> example, if the default branch contains the name of my project/repo then this
> sounds like a recipe for accidentally sharing it. I feel a better
> alternative would
> be to exclude nothing from the anonymization or the proposed default default
> branch name

I don't think that the name of the main branch should be subject to
anonymizing, whether it be `master` or anything else.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11  5:26         ` Junio C Hamano
@ 2020-06-11 14:05           ` Johannes Schindelin
  2020-06-11 15:05             ` Re* " Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-11 14:05 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi,

On Wed, 10 Jun 2020, Junio C Hamano wrote:

> Matt Rogers <mattr94@gmail.com> writes:
>
> > I think that's not very convincing.  If branch names in general are identifying
> > enough to warrant anonymization then shouldn't the default name be too?
>
> It is a good argument.  I also heard a rumor that often branch names
> contain codewords given to pre-released hardware that are highly
> confidential in certain circles, and heard that it is one of the
> reasons why Gerrit has server side ACL that lets you hide some
> branches from authenticated users that can access other branches.

Yes, branch names in general _can_ contain information users may prefer to
keep private.

However, we're not talking about branch names in general. We are talking
about the default name of the main branch, to be picked in _all_ of your
new repositories.

> Again, the original comment explains why 'master' without such a
> configuration knob was not worth protecting, but what it does not
> explain is why keeping it (and only that branch name) unmunged gives
> a more useful result than munging everything.  From the point of
> view of "I want to debug the shape of the DAG, without the actual
> user data", munging 'master' to 'ref47' while other branches like
> 'next' are munged to 'ref%d' does not make it harder to use or less
> useful for the debugging than only 'master' is kept intact in the
> output stream.

Yes. And you're unlikely to configure the default name to be used for all
of your future `git init` operations to be something non-generic.

I am still highly doubtful of Matt's suggestion that it would be worth
protecting the default name of the main branch to be used for _each_ and
_any_ new repository.

Now, if you suggest that `git fast-export --anonymize` should either not
special-case the main branch, or at least have a configurable set of names
it skips from protecting, then I will be much more in favor of those
suggestions. However, those suggestions are quite a bit orthogonal to the
patch series at hand, so I would want to discuss them in their own code
contribution instead of here.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-11  0:16   ` Eric Sunshine
@ 2020-06-11 14:09     ` Johannes Schindelin
  2020-06-11 15:28       ` Junio C Hamano
  2020-06-16 12:45     ` Jeff King
  1 sibling, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-11 14:09 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Don Goodman-Wilson via GitGitGadget, Git List, Derrick Stolee,
	Jeff King, brian m. carlson, Don Goodman-Wilson

Hi Eric,

On Wed, 10 Jun 2020, Eric Sunshine wrote:

> On Wed, Jun 10, 2020 at 5:19 PM Don Goodman-Wilson via GitGitGadget
> <gitgitgadget@gmail.com> wrote:
> > [...]
> > To make this process much less cumbersome, let's introduce support for
> > `core.defaultBranchName`. That way, users won't need to keep their
> > copied template files up to date, and won't interfere with default hooks
> > installed by their administrators.
> > [...]
> > Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
> > ---
> > diff --git a/refs.c b/refs.c
> > @@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
> > +                       die(_("Could not retrieve `core.defaultBranchName`"));
>
> Nit: here the error message is capitalized...

I downcased it...

> > +               if (from_config)
> > +                       branch_name = from_config;
> > +               else
> > +                       branch_name = "master";
>
> Non-actionable nit: could be written:
>
>     branch_name = from_config ? from_config : "master";

Good call.

> > +       }
> > +
> > +       if (short_name)
> > +               return from_config ? from_config : xstrdup(branch_name);
>
> The logic overall is a bit difficult to follow when trying to
> understand when and when not to duplicate the string and when and when
> not to free(), but seems to be correct.

I agree that it is a bit hard to follow, but then, the function is really
short, so I hoped it is okay.

> > +       /* prepend "refs/heads/" to the branch name */
> > +       prefixed = xstrfmt("refs/heads/%s", branch_name);
> > +       if (check_refname_format(prefixed, 0))
> > +               die(_("invalid default branch name: '%s'"), branch_name);
>
> Here, the error message is not capitalized. It would be nice for both
> messages to share a common capitalization scheme. These days, we tend
> to favor _not_ capitalizing error messages, so perhaps remove
> capitalization from the earlier one.
>
> > +/*
> > + * Retrieves the name of the default branch. If `short_name` is non-zero, the
> > + * branch name will be prefixed with "refs/heads/".
> > + */
> > +char *git_default_branch_name(int short_name);
>
> Overall, the internal logic regarding duplicating/freeing strings
> would probably be easier to grok if there were two separate functions:
>
>     char *git_default_branch_name(void);
>     char *git_default_ref_name(void);
>
> but that's subjective.

For such a tiny nuance, I'd rather keep it as one function...

Thank you,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-11  1:07 ` Taylor Blau
@ 2020-06-11 14:33   ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-11 14:33 UTC (permalink / raw)
  To: Taylor Blau
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff, sandals

Hi Taylor,

On Wed, 10 Jun 2020, Taylor Blau wrote:

> On Wed, Jun 10, 2020 at 09:19:21PM +0000, Johannes Schindelin via GitGitGadget wrote:
> > A growing number of open source projects aims to avoid the branch name
> > master due to its negative connotation. See [1] for an existing discussion
> > on this. The links [2], [3], and [4] describe community-driven ways for
> > users to rename their default branches or use template edits to set a new
> > default branch name.
> >
> > [1]
> > https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/
> >
> > [2] https://twitter.com/mislav/status/1270388510684598272
> >
> > [3]
> > https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx
> >
> > [4] https://github.com/ethomson/retarget_prs
> >
> > By necessity, existing repositories require a lot of manual work to move
> > away from that branch name, but it should be much easier for new
> > repositories.
>
> This is (somewhat) orthogonal to the topic here, but I wonder if we
> could be doing anything to make this easier for users.
>
> Could servers remember that a branch has ``moved'' and alert users as
> such when they pull? Even better, it would be nice if this alert from
> the server could allow clients to automatically rename their refs
> appropriately so that this transition is as easy as possible, even for
> existing repositories.

I would _love_ to have `git fetch origin master` work, spitting out a
message `the main branch name changed to [...] please update your
configuration`.

And then maybe an easy way to update the configuration (`git remote
set-main-branch <nick> <refname>` might make sense).

As you say, it is orthogonal to this here patch series, but definitely
related in spirit because we _want_ to make it easier for users to move
away from the current main branch name.

> > This patch series allows overriding the branch name being used for new
> > repositories' main branch. The main way to do this is the new
> > core.defaultBranchName config option. This first patch was contributed by
> > newcomer Dan Goodman-Wilson. Thanks for the contribution!
>
> Welcome, Dan! This is a fantastic first contribution, and I would be
> honored to help and move this forward in anyway that I can.

Sorry, my typo: it's Don, not Dan ;-)

> I should note that I am technically "out of office" (which normally
> wouldn't mean much, but this time means that I am on a road-trip, and so
> am only at my computer infrequently). I am catching up on just a few
> emails here, but I'll be able to help out more (and would be honored to
> do so) once I am really back next Monday.

Well, go back enjoying your road trip! :-P See you on Monday.

> > The other patches follow other places where "master" is hard-coded and use
> > the new git_default_branch_name() method to consume the config option before
> > falling back to "master".
> >
> > The last patch updates documentation only after the config option is ready
> > to apply to all of these scenarios.
> >
> > This series DOES NOT change the default automatically, but only provides an
> > opt-in mechanism for interested users. It also presents a way forward for
> > such a transition, if and when we decide to do so. Specifically, the new
> > GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
> > test scripts on an individual basis instead of all-at-once.
>
> Provided that the eventual plan is to seriously evaluate a name other
> than "master", I think that this is a good way forward that clears the
> way for us to make this change easily, without forcing us to come to a
> conclusion on what name will replace "master" today.

That is exactly the intention of this patch series.

I _do_ want to put my weight behind changing the default. Obviously, this
will take quite a bit of time (but maybe less than I originally thought,
as we are only talking about changing the default for _new_ repositories).

Even if this endeavor fails, though, this here patch series will be good
to have.

> For what it's worth, I am completely in favor of abandoning this term.
> My colleagues at GitHub (as has been mentioned previously on the list)
> are in favor of this as well, and it is my understanding that other
> providers feel similarly.

From what I read at https://gitlab.com/gitlab-org/gitlab/-/issues/221164,
GitLab is on board, too.

> I would be in favor of any non-offensive name that we can reach
> consensus on. "trunk" sounds nice to me, but I think that it may cause
> problems for non-native English speakers, so perhaps "main" or
> "default" would suffice (maybe "main" is better, since it retains muscle
> memory for the first two characters without being offensive--at least,
> as far as I can tell. If I am wrong, please correct me and we should
> consider something else).

My personal preference was "default" on Monday, and "main" ever since.

> All of that said, I can't emphasize enough how little I care about
> *what* name we replace "master" with, so long as it is (1) replaced with
> a non-offensive term, (2) that that change is done uniformly throughout
> the "Git Ecosystem" and (3) that the community can reach consensus on
> the new term in a respectful, appropriate, and considerate way. I only
> provided a few suggestions to get the conversation flowing, although I
> suspect that my help isn't needed there.

Indeed. I laid out the patch series in such a way that we should be able
to pick a different default main branch name than "main", even if it is my
current working hypothesis that this will prevail.

As I said, my preference was "default", and that's how my big patch series
looked like, so I know how much work it is to change to a different name
(because I changed it to "main"). It is quite a bit of work, but
manageable.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-11 13:44   ` Johannes Schindelin
@ 2020-06-11 14:44     ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11 14:44 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff, sandals

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> I read this (way too late) last night and slept over it. Together with
> your comment on the `fmt-merge-msg` patch, I think you are really on to
> something: we need _two_ config settings, as there are two distinct
> concepts at play here:
>
> - One setting to specify the default branch name for newly-initialized
>   repositories (such as `git init`, unless it re-initializes, and `git
>   clone` when the cloned repository does not yet contain any branches).
>
>   This should probably be called `init.defaultBranchName` (even if `git
>   clone` picks it up, too), and be overrideable by
>   `GIT_TEST_DEFAULT_BRANCH_NAME`.

Yes.


> - And another one, to define the default branch name for the _current_
>   repository. This setting would be configured implicitly upon `git init`

Nit.  This is not the "default" branch name.  It is "which branch is
the primary one in this repository?"  There is no default.

>   and `git clone`. For repositories where it is not set, we would assume
>   `master` for backwards-compatibility.
>
>   Technically, this should probably not even be a config option because it
>   is _strictly_ per-repo. But maybe it is not _so_ much per-repo: if I
>   want to rename all my main branches in all of my local repositories, I
>   might opt to configure this in `~/.gitconfig`.
>
>   Maybe a good name for this would be `repo.mainBranch` (and it would
>   contain the full ref name, e.g. `refs/heads/main`, not just `main`).

I think core.* namespace originally were supposed to be about "this"
repository, so instead of introducing "repo.*", I'd recommend just
sticking it in "core.*", perhaps "core.primaryBranchName".

And for help the scripts in t/, GIT_TEST_PRIMARY_BRANCH_NAME would
be a handy thing to have.

> And then `git fmt-merge-msg` (and your proposed `git var` addition, which
> I like a lot, maybe `git var mainBranch`?) will pick up the latter.

You may need "git fast-export" to know about it (I do not think you
should special case the primary branch but that is a topic of
another thread).

> That way, existing repositories would not be affected by
> `GIT_TEST_DEFAULT_BRANCH_NAME` or `init.defaultBranchName` at all. Only
> new repositories would pick it up.
>
> Does that sound like a plan?

So the idea is that init.* one affects "init" and "clone" (and any
other operation that creates a new repository and have to pick a
branch to point the HEAD at), lack of which defaults to 'main', and
the other one affects "fmt-merge-msg", "fast-export" (and any other
operation that wants to know which branch is the primary one in the
repository), lack of which defaults to 'master'?  

And an updated version of Git would record the latter in the
repository it just created, based on the former, so that things
won't get broken when the user sets the latter in ~/.gitconfig?

I think such a two-variable configuration would also work.  

I was aiming at not needing any configuration for new people and the
approach I illustrated for you with just a single variable was an
outcome from it.  One possible downside of the one-variable approach
is that existing users with repositories whose primary branch needs
to stay 'master' cannot set the core.defaultBrnachName in
~/.gitconfig until they iterate over all the "sticking to 'master'"
repositories and set the core.defaultBrnachName variable in them,
but with the two variable approach, that particular downside is
eliminated, which I like.  I haven't thought things through to see
if there are downside in the two variable approach, but just like
"If you have some repositories that want to stick to 'master', set
the config in them before you set the config globally to something
different from 'master'" would be a semi-workable workaround for the
downside in the one variable approach, I suspect any downside in the
two variable approach we will identify would have an easy
workaround, too.

Thanks.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11 14:05           ` Johannes Schindelin
@ 2020-06-11 15:05             ` Junio C Hamano
  2020-06-11 16:44               ` Junio C Hamano
                                 ` (2 more replies)
  0 siblings, 3 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11 15:05 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> It is a good argument.  I also heard a rumor that often branch names
>> contain codewords given to pre-released hardware that are highly
>> confidential in certain circles, and heard that it is one of the
>> reasons why Gerrit has server side ACL that lets you hide some
>> branches from authenticated users that can access other branches.
>
> Yes, branch names in general _can_ contain information users may prefer to
> keep private.
>
> However, we're not talking about branch names in general. We are talking
> about the default name of the main branch, to be picked in _all_ of your
> new repositories.

No, we are talking about the name of the branch, chosen to be the
primary one, in one particular repository whose contents are
exported via fast-export with explicit request from the user to
anonymize end-user data.

> Yes. And you're unlikely to configure the default name to be used for all
> of your future `git init` operations to be something non-generic.
>
> Now, if you suggest that `git fast-export --anonymize` should either not
> special-case the main branch, or at least have a configurable set of names
> it skips from protecting, then I will be much more in favor of those
> suggestions. However, those suggestions are quite a bit orthogonal to the
> patch series at hand, so I would want to discuss them in their own code
> contribution instead of here.


I think after writing the message about your "two variable"
approach, you would retract the "something non-generic" part in the
above sentence.  The original "we redact branch names but 'master'
is used by and known by everybody so there is no need to redact"
would have been a good argument.  Perhaps there is a value to keep
the primary branch identifiable even in an export stream that has
all the refnames and payload anonymized, and leaving 'master' intact
would have been a viable approach for solving that issue.

That trick NO LONGER applies once you allow the name of the primary
branch customizable, and the end user has used a name that is not to
be exposed.  Yes, "we want to ensure that readers of the export
stream can identify which ref is the primary branch of the
repository" is orthogonal from "how do we make primary branch
configurable in a live repository?" and "how do we make the default
name used for the primary branch in repositories newly created?".
But because the old solution would not work in the new world order
this topic created, a new solution needs to be found when you move
the world to the new order.

An easy solution would be to reserve "ref0" for the primary branch
in the repository and anonymize other refs "ref1", "ref2", ...

That can be done as a preparatory step regardless of the "'master'
may not be in the name of the primary branch in this repository"
topic.

-- >8 --
Subject: [PATCH] fast-export: do anonymize the primary branch name

In a fast-export stream with --anonymize option, all the end-user
data including refnames are munged to prevent exposure, but the
'master' branch is left intact.

There is a comment that explains why it is OK to leave 'master'
unanonymized (because everybody calls the primary branch 'master'
and it is no secret), but that does not justify why it is bad to
anonymize 'master' and make it undistinguishable from other
branches.  Assuming there _is_ a need to allow the readers of the
output to tell where the tip of the primary branch is, let's keep
the special casing of 'master', but still anonymize it to "ref0".
Because all other branches will be given ref+N where N is a positive
integer, this will keep the primary branch identifiable in the
output stream, without exposing what the name of the primary branch
is in the repository the export stream was taken from.

This is in preparation for introducing a mechanism to affect the
name of the primary branch used in the repository.  Once the
mechanism is in use, the name of the primary branch won't be
'master', and may not be allowed to be exposed.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/fast-export.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 85868162ee..a306a60d25 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len)
 {
 	static int counter;
 	struct strbuf out = STRBUF_INIT;
-	strbuf_addf(&out, "ref%d", counter++);
+	strbuf_addf(&out, "ref%d", ++counter);
 	return strbuf_detach(&out, len);
 }
 
@@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)
 	 * anything interesting.
 	 */
 	if (!strcmp(refname, "refs/heads/master"))
-		return refname;
+		return "ref0";
 
 	strbuf_reset(&anon);
 	for (i = 0; i < ARRAY_SIZE(prefixes); i++) {

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-11 14:09     ` Johannes Schindelin
@ 2020-06-11 15:28       ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11 15:28 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Eric Sunshine, Don Goodman-Wilson via GitGitGadget, Git List,
	Derrick Stolee, Jeff King, brian m. carlson, Don Goodman-Wilson

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> Overall, the internal logic regarding duplicating/freeing strings
>> would probably be easier to grok if there were two separate functions:
>>
>>     char *git_default_branch_name(void);
>>     char *git_default_ref_name(void);
>>
>> but that's subjective.
>
> For such a tiny nuance, I'd rather keep it as one function...

And you'd need two functions, default and primary, possibly full and
short.  Splitting these into two here would mean you'd need four.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11 15:05             ` Re* " Junio C Hamano
@ 2020-06-11 16:44               ` Junio C Hamano
  2020-06-11 18:18                 ` Junio C Hamano
  2020-06-12 12:03               ` Johannes Schindelin
  2020-06-12 12:53               ` Johannes Schindelin
  2 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11 16:44 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Junio C Hamano <gitster@pobox.com> writes:

> But because the old solution would not work in the new world order
> this topic created, a new solution needs to be found when you move
> the world to the new order.
>
> An easy solution would be to reserve "ref0" for the primary branch
> in the repository and anonymize other refs "ref1", "ref2", ...
>
> That can be done as a preparatory step regardless of the "'master'
> may not be in the name of the primary branch in this repository"
> topic.
> ...
> diff --git a/builtin/fast-export.c b/builtin/fast-export.c
> index 85868162ee..a306a60d25 100644
> --- a/builtin/fast-export.c
> +++ b/builtin/fast-export.c
> @@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len)
>  {
>  	static int counter;
>  	struct strbuf out = STRBUF_INIT;
> -	strbuf_addf(&out, "ref%d", counter++);
> +	strbuf_addf(&out, "ref%d", ++counter);
>  	return strbuf_detach(&out, len);
>  }
>  
> @@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)
>  	 * anything interesting.
>  	 */
>  	if (!strcmp(refname, "refs/heads/master"))
> -		return refname;
> +		return "ref0";

This is obviously wrong.  It should return "refs/heads/ref0".

But another thing we could do, which is probably more backward
compatible, is to return "refs/heads/master" from here.  That way,
consumers of "fast-export" stream that expect 'master' to be the
primary branch would not get upset when the data source runs a newer
version of Git that allows the primary branch name to be customized.

Which means that, before such a change to allow the primary branch
name to be customized happens, there is no need for such a
preparatory patch, because the status quo is just fine.  So, I'm OK
with retracting the above.  "ref0" is not special, so there is no
need to have the first hunk above, either.

However, when the customization being discussed is implemented via
the "get_default_branch_name()" and "get_primary_branch_name()"
functions, we should update these lines like so:

-	if (!strcmp(refname, "refs/heads/master"))
-		return "refs/heads/master";
+	if (!strcmp(refname, get_primary_branch_name(DO_NOT_ABBREV)))
+		return get_default_branch_name(DO_NOT_ABBREV);

That is, the name of the "primary" branch used at the data source is
replaced by the more generic "this is the default" branch name used
in a random "git init" repository.

Imagine that there is a project that has an integration branch per
each device type, named after the confidential device name, owned by
a company.  An employee of the company works on one device type in
his own clone of the repository, and the primary branch in the
repository is set to that confidential device's name.

The employee can create an anonymized output, replacing the
confidential name with a generic "default" name that is not
confidential, like 'main' in the new world order or 'master' in the
backward compatible world order, with such an updated code.

After having thought about it a bit longer, I actually do prefer to
use the "ref0" approach, as it is possible for the employee in the
above example to have the "default" branch name tied to the primary
branch for the hardware type the emploee works on in the ~/.gitconfig
so the "alternative" I suggested in this message will reveal the
confidential name.

So, I guess we should just fix the patch I am responding to to
return "refs/heads/ref0" instead of "ref0", and queue it as one of
the preparatory steps.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11 16:44               ` Junio C Hamano
@ 2020-06-11 18:18                 ` Junio C Hamano
  2020-06-12 12:07                   ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11 18:18 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Junio C Hamano <gitster@pobox.com> writes:

>> diff --git a/builtin/fast-export.c b/builtin/fast-export.c
>> index 85868162ee..a306a60d25 100644
>> --- a/builtin/fast-export.c
>> +++ b/builtin/fast-export.c
>> @@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len)
>>  {
>>  	static int counter;
>>  	struct strbuf out = STRBUF_INIT;
>> -	strbuf_addf(&out, "ref%d", counter++);
>> +	strbuf_addf(&out, "ref%d", ++counter);
>>  	return strbuf_detach(&out, len);
>>  }
>>  
>> @@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)
>>  	 * anything interesting.
>>  	 */
>>  	if (!strcmp(refname, "refs/heads/master"))
>> -		return refname;
>> +		return "ref0";
>
> This is obviously wrong.  It should return "refs/heads/ref0".
> ...
> So, I guess we should just fix the patch I am responding to to
> return "refs/heads/ref0" instead of "ref0", and queue it as one of
> the preparatory steps.

... and the follow-up step to become part of the series you are
working on to allow customing what the primary branch is called
would turn the second hunk to

	-	if (!strcmp(refname, "refs/heads/master"))
	+	if (!strcmp(refname, get_primary_branch_name(0)))
			return "refs/heads/ref0";

By the way, with your "two variables" approach to make both the
"default" (for 'init' and 'clone') and the "primary" (for
'fmt-merge-msg' and 'fast-export') configurable, we'd need accessor
function(s) for the primary branch name for the given repository.
The get_primary_branch_name() helper function might want to take a
"struct repository *" argument in addition to "please give me an
abbreviated refname" boolean, given the recent push to pass the
struct to everybody.



^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11 13:57     ` Johannes Schindelin
@ 2020-06-11 18:19       ` Junio C Hamano
  2020-06-12 12:07         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11 18:19 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, Johannes Schindelin via GitGitGadget,
	Git Mailing List, don, stolee, Jeff King, sandals

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Hi Matt,
>
> On Wed, 10 Jun 2020, Matt Rogers wrote:
>
>> > -        * We also leave "master" as a special case, since it does not reveal
>> > -        * anything interesting.
>> > +        * We also leave the default branch name as a special case, since it
>> > +        * does not reveal anything interesting.
>> >          */
>> I feel this is a weird thing to do, since you're trying to anonymize the branch
>> name,and now the default branch is identifiable with your config file.  For
>> example, if the default branch contains the name of my project/repo then this
>> sounds like a recipe for accidentally sharing it. I feel a better
>> alternative would
>> be to exclude nothing from the anonymization or the proposed default default
>> branch name
>
> I don't think that the name of the main branch should be subject to
> anonymizing, whether it be `master` or anything else.

"Here is why" is missing ;-)  I think you realized that it needs to
be, after you wrote the "ah, we need two, the default for new ones
and the name of the primary branch in a particular repository", as
we are dealing with the latter here.

Thanks.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-11 10:23   ` Alban Gruin
@ 2020-06-11 23:14     ` Junio C Hamano
  2020-06-11 23:46       ` brian m. carlson
  2020-06-13 18:01       ` Alban Gruin
  0 siblings, 2 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-11 23:14 UTC (permalink / raw)
  To: Alban Gruin
  Cc: Don Goodman-Wilson via GitGitGadget, git, don, stolee, peff,
	sandals, Johannes Schindelin

Alban Gruin <alban.gruin@gmail.com> writes:

> Why adding yet another environment variable instead of relying only on a
> config option?  I understand it's for the tests, but can't we add a
> shell function in test-lib.sh (and friends) that tries to read
> `GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets
> `core.defaultBranchName'?

Can you produce such a patch that does it cleanly?  My knee jerk
reaction is that I would suspect that you end up having to touch
many places in the t/ scripts, but if you prove otherwise, that
would certainly be appreciated.

And no, 

    git () { command git -c core.defaultBranchName=master "$@" }

is not an acceptable solution.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-11 23:14     ` Junio C Hamano
@ 2020-06-11 23:46       ` brian m. carlson
  2020-06-12 12:45         ` Johannes Schindelin
  2020-06-13 18:01       ` Alban Gruin
  1 sibling, 1 reply; 178+ messages in thread
From: brian m. carlson @ 2020-06-11 23:46 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Alban Gruin, Don Goodman-Wilson via GitGitGadget, git, don,
	stolee, peff, Johannes Schindelin

[-- Attachment #1: Type: text/plain, Size: 1406 bytes --]

On 2020-06-11 at 23:14:46, Junio C Hamano wrote:
> Alban Gruin <alban.gruin@gmail.com> writes:
> 
> > Why adding yet another environment variable instead of relying only on a
> > config option?  I understand it's for the tests, but can't we add a
> > shell function in test-lib.sh (and friends) that tries to read
> > `GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets
> > `core.defaultBranchName'?
> 
> Can you produce such a patch that does it cleanly?  My knee jerk
> reaction is that I would suspect that you end up having to touch
> many places in the t/ scripts, but if you prove otherwise, that
> would certainly be appreciated.
> 
> And no, 
> 
>     git () { command git -c core.defaultBranchName=master "$@" }
> 
> is not an acceptable solution.

I would also be delighted to see such a solution, but my experience with
the SHA-256 work tells me there's unlikely to be one.  We do a lot of
"git init" operations in random places in the test suite and as a
consequence it's very hard to make a change without touching a large
number of tests.

If we were writing things today, perhaps we would use a function (e.g.,
test_init_repo or such) to wrap this case, but we unfortunately didn't
think about that and we're stuck with what we have now unless someone
retrofits the test suite.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-11  9:35   ` Phillip Wood
@ 2020-06-12 11:55     ` Johannes Schindelin
  2020-06-12 16:51       ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-12 11:55 UTC (permalink / raw)
  To: Phillip Wood
  Cc: Don Goodman-Wilson via GitGitGadget, git, don, stolee, peff, sandals

Hi Phillip,

On Thu, 11 Jun 2020, Phillip Wood wrote:

> On 10/06/2020 22:19, Don Goodman-Wilson via GitGitGadget wrote:
> > From: Don Goodman-Wilson <don@goodman-wilson.com>
> >
> > There is a growing number of projects trying to avoid the non-inclusive
> > name `master` in their repositories.
>
> I think it would be helpful to explain why 'master' is no-inclusive even
> if it originates from the concept of a master copy. i.e. it suggests
> master/slave even if git is not based on that concept.

Unfortunately, we do not even have that defense: the term `master` was
copied from BitKeeper, which firmly uses it in the `master/slave` context.
See e.g.
https://mail.gnome.org/archives/desktop-devel-list/2019-May/msg00066.html

I added a _brief_ extension to the context to the first commit's commit
message. However, I do not want to go into details here because _this_
patch series is only about empowering users to change their default main
branch name.

> Have you got some examples of projects that have changed and the names
> that they are using?

Yes, there are plenty examples, and I do not want to pick a tiny subset to
demonstrate that. A more useful resource is probably this post:
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx

> I think it would be helpful if we can agree on a replacement for master
> - if every repository uses a different name for its main branch it adds
> an extra complication for new contributors to those projects.

Sure, and that's what I thought we'd discuss, too, maybe at the meeting I
proposed elsewhere (Emily started a new thread about it:
https://lore.kernel.org/git/20200610222719.GE148632@google.com/).

> >  For existing repositories, this
> > requires manual work. For new repositories, the only way to do that
> > automatically is by copying all of Git's template directory, then
> > hard-coding the desired default branch name into the `.git/HEAD` file,
> > and then configuring `init.templateDir` to point to those copied
> > template files.
> >
> > To make this process much less cumbersome, let's introduce support for
> > `core.defaultBranchName`. That way, users won't need to keep their
> > copied template files up to date, and won't interfere with default hooks
> > installed by their administrators.
> >
> > While at it, also let users set the default branch name via the
> > environment variable `GIT_TEST_DEFAULT_BRANCH_NAME`,
>
> I'm not sure we usually promote the use of GIT_TEST_... environment
> variables outside of the test suite.

True. Together with Alban's suggestion to make this purely work in the
test suite (i.e. not even adjust the C code to respect that environment
variable), you convinced me to (re-)move that part of the commit.

> > diff --git a/refs.c b/refs.c
> > index 224ff66c7bb..8499b3865cb 100644
> > --- a/refs.c
> > +++ b/refs.c
> > @@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
> >  		argv_array_pushf(prefixes, *p, len, prefix);
> >  }
> >
> > +char *git_default_branch_name(int short_name)
> > +{
> > +	const char *branch_name = getenv("GIT_TEST_DEFAULT_BRANCH_NAME");
> > +	char *from_config = NULL, *prefixed;
> > +
> > +	/*
> > +	 * If the default branch name was not specified via the environment
> > +	 * variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config
> > +	 * setting core.defaultBranchName. If neither are set, fall back to the
> > +	 * hard-coded default.
> > +	 */
> > +	if (!branch_name || !*branch_name) {
> > +		if (git_config_get_string("core.defaultbranchname",
> > +					  &from_config) < 0)
> > +			die(_("Could not retrieve `core.defaultBranchName`"));
> > +
> > +		if (from_config)
> > +			branch_name = from_config;
> > +		else
> > +			branch_name = "master";
> > +	}
> > +
> > +	if (short_name)
> > +		return from_config ? from_config : xstrdup(branch_name);
>
> If short_name is set we return without validating the name is that
> intentional?

No, unintentional. Thank you for pointing this out. It will be fixed in v2
(still working on it).

> > +
> > +	/* prepend "refs/heads/" to the branch name */
> > +	prefixed = xstrfmt("refs/heads/%s", branch_name);
> > +	if (check_refname_format(prefixed, 0))
> > +		die(_("invalid default branch name: '%s'"), branch_name);
> > +
> > +	free(from_config);
> > +	return prefixed;
> > +}
> > +
> >  /*
> >   * *string and *len will only be substituted, and *string returned (for
> >   * later free()ing) if the string passed in is a magic short-hand form
> > diff --git a/refs.h b/refs.h
> > index a92d2c74c83..e8d4f6e2f13 100644
> > --- a/refs.h
> > +++ b/refs.h
> > @@ -154,6 +154,12 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
> >  int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
> >  int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
> >
> > +/*
> > + * Retrieves the name of the default branch. If `short_name` is non-zero, the
> > + * branch name will be prefixed with "refs/heads/".
>
> Isn't the other way around - the branch name is prefixed with
> "refs/heads/" if short is zero.

Absolutely. Thank you for your careful review, I read past this at least
half a dozen times.

> > + */
> > +char *git_default_branch_name(int short_name);
> > +
> >  /*
> >   * A ref_transaction represents a collection of reference updates that
> >   * should succeed or fail together.
> > diff --git a/t/t0001-init.sh b/t/t0001-init.sh
> > index 1edd5aeb8f0..b144cd8f46b 100755
> > --- a/t/t0001-init.sh
> > +++ b/t/t0001-init.sh
> > @@ -464,4 +464,24 @@ test_expect_success MINGW 'redirect std handles' '
> >  	grep "Needed a single revision" output.txt
> >  '
> >
> > +test_expect_success 'custom default branch name from config' '
> > +	git config --global core.defaultbranchname nmb &&
>
> In tests we usually use 'test_config' rather than 'git config' as the
> former automatically cleans up the config at the end of the test.

Right, and in this instance it is `test_config_global`.

> > +	GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config &&
> > +	git config --global --unset core.defaultbranchname &&
> > +	git -C custom-config symbolic-ref HEAD >actual &&
> > +	grep nmb actual
> > +'
> > +
> > +test_expect_success 'custom default branch name from env' '
> > +	GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env &&
>
> It would be good to test that this overrides the config setting

Except that we'll make this a thing that is internal to the test suite
now. So this test case can go.

Thank you for helping me improve the patch series!
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11 15:05             ` Re* " Junio C Hamano
  2020-06-11 16:44               ` Junio C Hamano
@ 2020-06-12 12:03               ` Johannes Schindelin
  2020-06-12 12:50                 ` Junio C Hamano
  2020-06-12 12:53               ` Johannes Schindelin
  2 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-12 12:03 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio,

On Thu, 11 Jun 2020, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> >> It is a good argument.  I also heard a rumor that often branch names
> >> contain codewords given to pre-released hardware that are highly
> >> confidential in certain circles, and heard that it is one of the
> >> reasons why Gerrit has server side ACL that lets you hide some
> >> branches from authenticated users that can access other branches.
> >
> > Yes, branch names in general _can_ contain information users may prefer to
> > keep private.
> >
> > However, we're not talking about branch names in general. We are talking
> > about the default name of the main branch, to be picked in _all_ of your
> > new repositories.
>
> No, we are talking about the name of the branch, chosen to be the
> primary one, in one particular repository whose contents are
> exported via fast-export with explicit request from the user to
> anonymize end-user data.
>
> > Yes. And you're unlikely to configure the default name to be used for all
> > of your future `git init` operations to be something non-generic.
> >
> > Now, if you suggest that `git fast-export --anonymize` should either not
> > special-case the main branch, or at least have a configurable set of names
> > it skips from protecting, then I will be much more in favor of those
> > suggestions. However, those suggestions are quite a bit orthogonal to the
> > patch series at hand, so I would want to discuss them in their own code
> > contribution instead of here.
>
>
> I think after writing the message about your "two variable"
> approach, you would retract the "something non-generic" part in the
> above sentence.

You are absolutely correct!

> [...]
> -- >8 --
> Subject: [PATCH] fast-export: do anonymize the primary branch name

I like this approach a lot. Do you want me to integrate it into this patch
series, or rather have it as a stand-alone patch?

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11 18:18                 ` Junio C Hamano
@ 2020-06-12 12:07                   ` Johannes Schindelin
  2020-06-12 12:32                     ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-12 12:07 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio,

On Thu, 11 Jun 2020, Junio C Hamano wrote:

> Junio C Hamano <gitster@pobox.com> writes:
>
> >> diff --git a/builtin/fast-export.c b/builtin/fast-export.c
> >> index 85868162ee..a306a60d25 100644
> >> --- a/builtin/fast-export.c
> >> +++ b/builtin/fast-export.c
> >> @@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len)
> >>  {
> >>  	static int counter;
> >>  	struct strbuf out = STRBUF_INIT;
> >> -	strbuf_addf(&out, "ref%d", counter++);
> >> +	strbuf_addf(&out, "ref%d", ++counter);
> >>  	return strbuf_detach(&out, len);
> >>  }
> >>
> >> @@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)
> >>  	 * anything interesting.
> >>  	 */
> >>  	if (!strcmp(refname, "refs/heads/master"))
> >> -		return refname;
> >> +		return "ref0";
> >
> > This is obviously wrong.  It should return "refs/heads/ref0".
> > ...
> > So, I guess we should just fix the patch I am responding to to
> > return "refs/heads/ref0" instead of "ref0", and queue it as one of
> > the preparatory steps.
>
> ... and the follow-up step to become part of the series you are
> working on to allow customing what the primary branch is called
> would turn the second hunk to
>
> 	-	if (!strcmp(refname, "refs/heads/master"))
> 	+	if (!strcmp(refname, get_primary_branch_name(0)))
> 			return "refs/heads/ref0";

Right.

> By the way, with your "two variables" approach to make both the
> "default" (for 'init' and 'clone') and the "primary" (for
> 'fmt-merge-msg' and 'fast-export') configurable, we'd need accessor
> function(s) for the primary branch name for the given repository.
> The get_primary_branch_name() helper function might want to take a
> "struct repository *" argument in addition to "please give me an
> abbreviated refname" boolean, given the recent push to pass the
> struct to everybody.

My current state defines a `repo_main_branch_name(flags)` function where
the flags can be `MAIN_BRANCH_SHORT_NAME` and `MAIN_BRANCH_FOR_INIT`.

So I think we're on the same page.

BTW I heard from a couple sides that "primary" would imply that there is
also a "secondary" branch, and potentially an ordering of all branches,
which is why I did not really consider "primary" as candidate. Besides, it
is so much more awkward to type than "main" (especially when you're as
tired as I am right now...).

That's why I try to stay with "main" for the moment.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11 18:19       ` Junio C Hamano
@ 2020-06-12 12:07         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-12 12:07 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Matt Rogers, Johannes Schindelin via GitGitGadget,
	Git Mailing List, don, stolee, Jeff King, sandals

Hi Junio,

On Thu, 11 Jun 2020, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > Hi Matt,
> >
> > On Wed, 10 Jun 2020, Matt Rogers wrote:
> >
> >> > -        * We also leave "master" as a special case, since it does not reveal
> >> > -        * anything interesting.
> >> > +        * We also leave the default branch name as a special case, since it
> >> > +        * does not reveal anything interesting.
> >> >          */
> >> I feel this is a weird thing to do, since you're trying to anonymize the branch
> >> name,and now the default branch is identifiable with your config file.  For
> >> example, if the default branch contains the name of my project/repo then this
> >> sounds like a recipe for accidentally sharing it. I feel a better
> >> alternative would
> >> be to exclude nothing from the anonymization or the proposed default default
> >> branch name
> >
> > I don't think that the name of the main branch should be subject to
> > anonymizing, whether it be `master` or anything else.
>
> "Here is why" is missing ;-)  I think you realized that it needs to
> be, after you wrote the "ah, we need two, the default for new ones
> and the name of the primary branch in a particular repository", as
> we are dealing with the latter here.

Yep, absolutely.

Thanks,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 12:07                   ` Johannes Schindelin
@ 2020-06-12 12:32                     ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-12 12:32 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> BTW I heard from a couple sides that "primary" would imply that there is
> also a "secondary" branch, and potentially an ordering of all branches,
> which is why I did not really consider "primary" as candidate. Besides, it
> is so much more awkward to type than "main" (especially when you're as
> tired as I am right now...).
>
> That's why I try to stay with "main" for the moment.

You are reading too much into it.  I used "primary" because I needed
a word that clearly conveys the concept of being a special among
others, a word that is about the concept which is different from the
concept of "default", and that is clearly different from any of the
candidates floated as concrete words to replace 'master'.  Because I
wanted to say things like:

    In the context of fast-export, you'd want to special case the
    "primary" branch name, because unlike the "default" branch name
    (which we envision to be 'main' for most people in the new world
    order, so it may be less worth anonymizing because of the same
    reason the current code keeps 'master' as-is), its name can be
    sensitive.

without becoming unnecessarily ambiguous (replace 'primary' with
'main' in the above).

It was not because I do not want us to pick 'main' as the
replacement word for 'master' as the default branch name.

And a set of things, among which there is a concept of "one thing
that is special and different from all the others", does not
necessarily have to be a totally ordered set.  When cloning, we say
that the (often bare) repository at the other end indicates which
branch is the primary branch of the project by pointing at it with
its HEAD (which is the reason why we try to fork it to our local
branch namespace and check it out after cloning).  There is no
"secondary" in such a use case, and there is no need to have one.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-11 23:46       ` brian m. carlson
@ 2020-06-12 12:45         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-12 12:45 UTC (permalink / raw)
  To: brian m. carlson
  Cc: Junio C Hamano, Alban Gruin, Don Goodman-Wilson via GitGitGadget,
	git, don, stolee, peff

Hi brian,

On Thu, 11 Jun 2020, brian m. carlson wrote:

> On 2020-06-11 at 23:14:46, Junio C Hamano wrote:
> > Alban Gruin <alban.gruin@gmail.com> writes:
> >
> > > Why adding yet another environment variable instead of relying only on a
> > > config option?  I understand it's for the tests, but can't we add a
> > > shell function in test-lib.sh (and friends) that tries to read
> > > `GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets
> > > `core.defaultBranchName'?
> >
> > Can you produce such a patch that does it cleanly?  My knee jerk
> > reaction is that I would suspect that you end up having to touch
> > many places in the t/ scripts, but if you prove otherwise, that
> > would certainly be appreciated.
> >
> > And no,
> >
> >     git () { command git -c core.defaultBranchName=master "$@" }
> >
> > is not an acceptable solution.
>
> I would also be delighted to see such a solution, but my experience with
> the SHA-256 work tells me there's unlikely to be one.  We do a lot of
> "git init" operations in random places in the test suite and as a
> consequence it's very hard to make a change without touching a large
> number of tests.

That's a valid point, indeed.

> If we were writing things today, perhaps we would use a function (e.g.,
> test_init_repo or such) to wrap this case, but we unfortunately didn't
> think about that and we're stuck with what we have now unless someone
> retrofits the test suite.

There is actually `test_create_repo` (see
https://github.com/git/git/blob/v2.27.0/t/test-lib-functions.sh#L1145-L1159):

	# Most tests can use the created repository, but some may need to create
	# more.
	# Usage: test_create_repo <directory>
	test_create_repo () {
		test "$#" = 1 ||
		BUG "not 1 parameter to test-create-repo"
		repo="$1"
		mkdir -p "$repo"
		(
			cd "$repo" || error "Cannot setup test environment"
			"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
				"--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
			error "cannot run git init -- have you built things yet?"
			mv .git/hooks .git/hooks-disabled
		) || exit
	}

But I agree that few test scripts use it:

	$ git grep 'git init' v2.27.0 -- t/ | wc -l
	765

	$ git grep 'test_create_repo' v2.27.0 -- t/ | wc -l
	296

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 12:03               ` Johannes Schindelin
@ 2020-06-12 12:50                 ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-12 12:50 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> Subject: [PATCH] fast-export: do anonymize the primary branch name
>
> I like this approach a lot. Do you want me to integrate it into this patch
> series, or rather have it as a stand-alone patch?

I do not see any need for an off-series preparation step.  Without
configurable primary branch, keeping 'master' as 'master' used in
the current code is an OK way to anonymize refs and still keep the
primary line of development in the output identifyable.  The "ref0"
trick becomes necessary only when we introduce configurable primary;
even though it would not hurt to switch to the "ref0" approach to
anonymize-but-still-the-primary-is-identifiable early, it just is
not necessary to do so.

I'd say that we should take <xmqqpna5bq2l.fsf_-_@gitster.c.googlers.com>
with two changes,

 - see if the "refname" matches the fully
   spelled primary branch name by asking repo_main_branch_name(repo,
   0), instead of comparing with "refs/heads/master", and

 - if matches return "refs/heads/ref0" instead of "ref0".

and replace your [PATCH 8/9] (or whichever the counterpart patch is
in the rerolled series) with it.

Thanks.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-11 15:05             ` Re* " Junio C Hamano
  2020-06-11 16:44               ` Junio C Hamano
  2020-06-12 12:03               ` Johannes Schindelin
@ 2020-06-12 12:53               ` Johannes Schindelin
  2020-06-12 13:18                 ` Johannes Schindelin
  2020-06-12 15:14                 ` Junio C Hamano
  2 siblings, 2 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-12 12:53 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio,

On Thu, 11 Jun 2020, Junio C Hamano wrote:

> diff --git a/builtin/fast-export.c b/builtin/fast-export.c
> index 85868162ee..a306a60d25 100644
> --- a/builtin/fast-export.c
> +++ b/builtin/fast-export.c
> @@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)
>  	 * anything interesting.
>  	 */
>  	if (!strcmp(refname, "refs/heads/master"))
> -		return refname;
> +		return "ref0";

I just realized that the comment above reads:

        /*
         * We also leave "master" as a special case, since it does not reveal
         * anything interesting.
         */


Obviously, we need to change that comment here because we do not leave the
name unchanged. How about this?

        /*
         * We special-case the main branch, anonymizing it to `ref0`.
         */

Ciao,
Dscho

>
>  	strbuf_reset(&anon);
>  	for (i = 0; i < ARRAY_SIZE(prefixes); i++) {
>

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 12:53               ` Johannes Schindelin
@ 2020-06-12 13:18                 ` Johannes Schindelin
  2020-06-12 15:19                   ` Junio C Hamano
  2020-06-12 15:14                 ` Junio C Hamano
  1 sibling, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-12 13:18 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio,

On Fri, 12 Jun 2020, Johannes Schindelin wrote:

> On Thu, 11 Jun 2020, Junio C Hamano wrote:
>
> > diff --git a/builtin/fast-export.c b/builtin/fast-export.c
> > index 85868162ee..a306a60d25 100644
> > --- a/builtin/fast-export.c
> > +++ b/builtin/fast-export.c
> > @@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)
> >  	 * anything interesting.
> >  	 */
> >  	if (!strcmp(refname, "refs/heads/master"))
> > -		return refname;
> > +		return "ref0";
>
> I just realized that the comment above reads:
>
>         /*
>          * We also leave "master" as a special case, since it does not reveal
>          * anything interesting.
>          */
>
>
> Obviously, we need to change that comment here because we do not leave the
> name unchanged. How about this?
>
>         /*
>          * We special-case the main branch, anonymizing it to `ref0`.
>          */

Also, t9351 obviously needs to be adjusted. This one works for me:

-- snipsnap --
From: Junio C Hamano <gitster@pobox.com>
Date: Thu, 11 Jun 2020 08:05:38 -0700
Subject: [PATCH] fast-export: do anonymize the primary branch name

In a fast-export stream with --anonymize option, all the end-user
data including refnames are munged to prevent exposure, but the
'master' branch is left intact.

There is a comment that explains why it is OK to leave 'master'
unanonymized (because everybody calls the primary branch 'master'
and it is no secret), but that does not justify why it is bad to
anonymize 'master' and make it undistinguishable from other
branches.  Assuming there _is_ a need to allow the readers of the
output to tell where the tip of the primary branch is, let's keep
the special casing of 'master', but still anonymize it to "ref0".
Because all other branches will be given ref+N where N is a positive
integer, this will keep the primary branch identifiable in the
output stream, without exposing what the name of the primary branch
is in the repository the export stream was taken from.

This is in preparation for introducing a mechanism to affect the
name of the primary branch used in the repository.  Once the
mechanism is in use, the name of the primary branch won't be
'master', and may not be allowed to be exposed.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/fast-export.c            | 7 +++----
 t/t9351-fast-export-anonymize.sh | 9 +++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 85868162eec..f10e3b35e5b 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len)
 {
 	static int counter;
 	struct strbuf out = STRBUF_INIT;
-	strbuf_addf(&out, "ref%d", counter++);
+	strbuf_addf(&out, "ref%d", ++counter);
 	return strbuf_detach(&out, len);
 }

@@ -518,11 +518,10 @@ static const char *anonymize_refname(const char *refname)
 	int i;

 	/*
-	 * We also leave "master" as a special case, since it does not reveal
-	 * anything interesting.
+	 * We special-case the main branch, anonymizing it to `ref0`.
 	 */
 	if (!strcmp(refname, "refs/heads/master"))
-		return refname;
+		return "refs/heads/ref0";

 	strbuf_reset(&anon);
 	for (i = 0; i < ARRAY_SIZE(prefixes); i++) {
diff --git a/t/t9351-fast-export-anonymize.sh b/t/t9351-fast-export-anonymize.sh
index 897dc509075..2415f0ec213 100755
--- a/t/t9351-fast-export-anonymize.sh
+++ b/t/t9351-fast-export-anonymize.sh
@@ -26,8 +26,9 @@ test_expect_success 'stream omits path names' '
 	! grep xyzzy stream
 '

-test_expect_success 'stream allows master as refname' '
-	grep master stream
+test_expect_success 'stream translates master to ref0' '
+	grep refs/heads/ref0 stream &&
+	! grep master stream
 '

 test_expect_success 'stream omits other refnames' '
@@ -57,7 +58,7 @@ test_expect_success 'import stream to new repository' '
 test_expect_success 'result has two branches' '
 	git for-each-ref --format="%(refname)" refs/heads >branches &&
 	test_line_count = 2 branches &&
-	other_branch=$(grep -v refs/heads/master branches)
+	other_branch=$(grep -v refs/heads/ref0 branches)
 '

 test_expect_success 'repo has original shape and timestamps' '
@@ -65,7 +66,7 @@ test_expect_success 'repo has original shape and timestamps' '
 		git log --format="%m %ct" --left-right --boundary "$@"
 	} &&
 	(cd .. && shape master...other) >expect &&
-	shape master...$other_branch >actual &&
+	shape ref0...$other_branch >actual &&
 	test_cmp expect actual
 '

--
2.26.0.windows.1


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 12:53               ` Johannes Schindelin
  2020-06-12 13:18                 ` Johannes Schindelin
@ 2020-06-12 15:14                 ` Junio C Hamano
  2020-06-13 11:49                   ` Johannes Sixt
  2020-06-13 14:44                   ` Johannes Schindelin
  1 sibling, 2 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-12 15:14 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> I just realized that the comment above reads:
>
>         /*
>          * We also leave "master" as a special case, since it does not reveal
>          * anything interesting.
>          */
>
>
> Obviously, we need to change that comment here because we do not leave the
> name unchanged. How about this?
>
>         /*
>          * We special-case the main branch, anonymizing it to `ref0`.
>          */

If you are going to update it, why not make it useful?

I complained number of times during the discussion that the original
comment explains why leaving 'master' as-is does not reveal anything
useful to adversaries but does not justify what the code attempts to
achieve by special casing 'master' in the first place.  

It is not an improvement to literally adjust that inadequate comment
to the new world order to just parrot what the code already says
without explaining why it does so.

	/*
	 * Anonymize the name used for the primary branch in this
	 * repository, but reserve `ref0` for it, so that it can
	 * be identified among other refs in the output.
	 */

is the minimum I would expect before calling it an improvement.  We
could add

	It is often `main` for new repositories (and `master` for
	aged ones) and such well-known names may not need
	anonymizing, but it could be configured to use a secret word
	that the user may not want to reveal.

at the end to explain the motivation behind anonymizing even more,
if we wanted to.

Now, "so that ..." part is totally a fabrication based on my best
guess.  I do not know what the original author was thinking when the
decision to leave the master as-is was made.

Thanks.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 13:18                 ` Johannes Schindelin
@ 2020-06-12 15:19                   ` Junio C Hamano
  2020-06-12 15:22                     ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-12 15:19 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Also, t9351 obviously needs to be adjusted. This one works for me:
>
> -- snipsnap --
> From: Junio C Hamano <gitster@pobox.com>
> Date: Thu, 11 Jun 2020 08:05:38 -0700
> Subject: [PATCH] fast-export: do anonymize the primary branch name
>
> In a fast-export stream with --anonymize option, all the end-user
> data including refnames are munged to prevent exposure, but the
> 'master' branch is left intact.
> ...
> This is in preparation for introducing a mechanism to affect the
> name of the primary branch used in the repository.  Once the
> mechanism is in use, the name of the primary branch won't be
> 'master', and may not be allowed to be exposed.
>
> Signed-off-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  builtin/fast-export.c            | 7 +++----
>  t/t9351-fast-export-anonymize.sh | 9 +++++----
>  2 files changed, 8 insertions(+), 8 deletions(-)
> ...
>  	if (!strcmp(refname, "refs/heads/master"))
> -		return refname;
> +		return "refs/heads/ref0";

As I said already, I personally do not think that this needs to be a
preparatory patch to anonymize 'master' that cannot be configured to
something else into 'ref0'.  This will become necessary when we make
the primary branch configurable, so I think it is easier to replace
the counterpart to your [PATCH 8/9] in the original series with it
in the v2 series.

Regarding the update to the comment before this "special case", I
would suggest to explain "why" not just "what".

Thanks.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 15:19                   ` Junio C Hamano
@ 2020-06-12 15:22                     ` Junio C Hamano
  2020-06-13  5:00                       ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-12 15:22 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Junio C Hamano <gitster@pobox.com> writes:

> As I said already, I personally do not think that this needs to be a
> preparatory patch to anonymize 'master' that cannot be configured to
> something else into 'ref0'.  This will become necessary when we make
> the primary branch configurable, so I think it is easier to replace
> the counterpart to your [PATCH 8/9] in the original series with it
> in the v2 series.

Ah, I forgot to say, if you think it is easier to manage the main
set of patches for the topic to eject as much preparatory changes as
possible, I do not at all mind treating this as one of the
preparatory step and queue it separately, making the main series
depend on it.  I just wanted to say that it is not necessary, even
though it does not hurt.



> Regarding the update to the comment before this "special case", I
> would suggest to explain "why" not just "what".
>
> Thanks.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-12 11:55     ` Johannes Schindelin
@ 2020-06-12 16:51       ` Junio C Hamano
  2020-06-14 22:00         ` Johannes Schindelin
  2020-06-15 10:00         ` Phillip Wood
  0 siblings, 2 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-12 16:51 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Phillip Wood, Don Goodman-Wilson via GitGitGadget, git, don,
	stolee, peff, sandals

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> I added a _brief_ extension to the context to the first commit's commit
> message. However, I do not want to go into details here because _this_
> patch series is only about empowering users to change their default main
> branch name.

Sensible.

And I do not think the planned follow-up work to rename 'master' to
something else needs to be defended with lengthy history lessons.

Sufficiently large part of the user population are unhappy with the
use of the word 'master' as the default name of the primary branch
in a newly created repository, and the mere fact that we are aware
of that is good enough justification to move _away_ from 'master'.
In other words, we do not have to explain why 'master' was bad, as
it does not have to be bad for everybody to be replaced.

But you need to defend that the new word you picked is something
everybody is happy with.  That is much harder ;-).

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 15:22                     ` Junio C Hamano
@ 2020-06-13  5:00                       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-13  5:00 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio,

On Fri, 12 Jun 2020, Junio C Hamano wrote:

> Junio C Hamano <gitster@pobox.com> writes:
>
> > As I said already, I personally do not think that this needs to be a
> > preparatory patch to anonymize 'master' that cannot be configured to
> > something else into 'ref0'.  This will become necessary when we make
> > the primary branch configurable, so I think it is easier to replace
> > the counterpart to your [PATCH 8/9] in the original series with it
> > in the v2 series.
>
> Ah, I forgot to say, if you think it is easier to manage the main
> set of patches for the topic to eject as much preparatory changes as
> possible, I do not at all mind treating this as one of the
> preparatory step and queue it separately, making the main series
> depend on it.  I just wanted to say that it is not necessary, even
> though it does not hurt.

Due to the need to adjust t9351, I think it is clearer if it is a two-part
change: one to introduce the "main branch -> ref0" change, and another one
to respect `core.mainBranch`. Those are separate concerns in my mind.

I moved the first one to the beginning of the patch series so that you're
still at liberty to take it early vs keeping it within the topic branch.

Thanks,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 15:14                 ` Junio C Hamano
@ 2020-06-13 11:49                   ` Johannes Sixt
  2020-06-13 16:25                     ` Junio C Hamano
  2020-06-13 14:44                   ` Johannes Schindelin
  1 sibling, 1 reply; 178+ messages in thread
From: Johannes Sixt @ 2020-06-13 11:49 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Schindelin, Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Am 12.06.20 um 17:14 schrieb Junio C Hamano:
> 	/*
> 	 * Anonymize the name used for the primary branch in this
> 	 * repository, but reserve `ref0` for it, so that it can
> 	 * be identified among other refs in the output.
> 	 */
> 
> is the minimum I would expect before calling it an improvement.  We
> could add
> 
> 	It is often `main` for new repositories (and `master` for
> 	aged ones) and such well-known names may not need
> 	anonymizing, but it could be configured to use a secret word
> 	that the user may not want to reveal.
> 
> at the end to explain the motivation behind anonymizing even more,
> if we wanted to.

IMO, making the primary branch identifiable is a reasonable
justification to treat it specially. But then, why does it have to be
renamed to 'ref0'? Couldn't it just be renamed to Git's default primary
branch name, be it 'master' today or 'main' or whatever in the future?
After the anonymization, nobody will know whether that was the real name
of the primary branch or not. Leaving it at 'master'/'main' reduces the
mental burden of the recipient of the anonymous repo.

-- Hannes

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-12 15:14                 ` Junio C Hamano
  2020-06-13 11:49                   ` Johannes Sixt
@ 2020-06-13 14:44                   ` Johannes Schindelin
  1 sibling, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-13 14:44 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio,

On Fri, 12 Jun 2020, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > I just realized that the comment above reads:
> >
> >         /*
> >          * We also leave "master" as a special case, since it does not reveal
> >          * anything interesting.
> >          */
> >
> >
> > Obviously, we need to change that comment here because we do not leave the
> > name unchanged. How about this?
> >
> >         /*
> >          * We special-case the main branch, anonymizing it to `ref0`.
> >          */
>
> If you are going to update it, why not make it useful?
>
> I complained number of times during the discussion that the original
> comment explains why leaving 'master' as-is does not reveal anything
> useful to adversaries but does not justify what the code attempts to
> achieve by special casing 'master' in the first place.

True. Sorry about forgetting that when adjusting the code comment.

In my defense, I am/was much more worried about transmogrifying the patch
series to reflect the separation between `init.defaultBranch` and
`core.mainBranch` and the associated fall-out (I highly doubt that the
range-diff between v1 and v2 will be useful...).

> It is not an improvement to literally adjust that inadequate comment
> to the new world order to just parrot what the code already says
> without explaining why it does so.
>
> 	/*
> 	 * Anonymize the name used for the primary branch in this
> 	 * repository, but reserve `ref0` for it, so that it can
> 	 * be identified among other refs in the output.
> 	 */

That is indeed an improvement, thank you so much.

> is the minimum I would expect before calling it an improvement.  We
> could add
>
> 	It is often `main` for new repositories (and `master` for
> 	aged ones) and such well-known names may not need
> 	anonymizing, but it could be configured to use a secret word
> 	that the user may not want to reveal.
>
> at the end to explain the motivation behind anonymizing even more,
> if we wanted to.

Maybe we add that to the comment in the patch that teaches `fast-export`
about `core.mainBranch`? Yeah, I think I like that idea best.

> Now, "so that ..." part is totally a fabrication based on my best
> guess.  I do not know what the original author was thinking when the
> decision to leave the master as-is was made.

This comment comes from a8722750985 (teach fast-export an --anonymize
option, 2014-08-27), and I agree that there is no explicit explanation why
the main branch is special-cased.

However, I think that your guess is a good one: it might be an interesting
aspect to identify the commits from the main branch, without necessarily
needing to know the actual name of said branch, e.g. to reproduce a
reported issue.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-13 16:25                     ` Junio C Hamano
@ 2020-06-13 14:47                       ` Johannes Schindelin
  2020-06-13 18:49                         ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-13 14:47 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Sixt, Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio & Hannes,

On Sat, 13 Jun 2020, Junio C Hamano wrote:

> Johannes Sixt <j6t@kdbg.org> writes:
>
> > Am 12.06.20 um 17:14 schrieb Junio C Hamano:
> >> 	/*
> >> 	 * Anonymize the name used for the primary branch in this
> >> 	 * repository, but reserve `ref0` for it, so that it can
> >> 	 * be identified among other refs in the output.
> >> 	 */
> >>
> >> is the minimum I would expect before calling it an improvement.  We
> >> could add
> >>
> >> 	It is often `main` for new repositories (and `master` for
> >> 	aged ones) and such well-known names may not need
> >> 	anonymizing, but it could be configured to use a secret word
> >> 	that the user may not want to reveal.
> >>
> >> at the end to explain the motivation behind anonymizing even more,
> >> if we wanted to.
> >
> > IMO, making the primary branch identifiable is a reasonable
> > justification to treat it specially. But then, why does it have to be
> > renamed to 'ref0'? Couldn't it just be renamed to Git's default primary
> > branch name, be it 'master' today or 'main' or whatever in the future?
>
> That comes from https://lore.kernel.org/git/xmqqtuzha6xn.fsf@gitster.c.googlers.com/
>
> But I agree with you 100% if you literally mean 'master' (or 'main')
> hardcoded without any end-user customization.  What I rejected and
> replaced with the vanilla "ref0" was to return the configured name
> that will be used for the primary branch in new repositories.  The
> above proposal suggested a faulty:
>
> -	if (!strcmp(refname, "refs/heads/master"))
> -		return refname;
> +	if (!strcmp(refname, get_primary_branch_name(DO_NOT_ABBREV)))
> +		return get_default_branch_name(DO_NOT_ABBREV);
>
> A corrected code should return a hardwired constant 'main' (it
> probably gets behind a C preprocessor macro, but the point is that
> we do not want end-user customization) for the reason stated in that
> message.

I like `ref0` better, for two reasons:

- it is more consistent to just have all anonymized branches be named
  `ref<N>`, and

- using `main` both for an original `main` and an original `master` can be
  a bit confusing, as the reader might assume that this branch name (as it
  does not follow the `ref<N>` convention) was _not_ anonymized, when it
  very well might have been.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-13 11:49                   ` Johannes Sixt
@ 2020-06-13 16:25                     ` Junio C Hamano
  2020-06-13 14:47                       ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-13 16:25 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: Johannes Schindelin, Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Sixt <j6t@kdbg.org> writes:

> Am 12.06.20 um 17:14 schrieb Junio C Hamano:
>> 	/*
>> 	 * Anonymize the name used for the primary branch in this
>> 	 * repository, but reserve `ref0` for it, so that it can
>> 	 * be identified among other refs in the output.
>> 	 */
>> 
>> is the minimum I would expect before calling it an improvement.  We
>> could add
>> 
>> 	It is often `main` for new repositories (and `master` for
>> 	aged ones) and such well-known names may not need
>> 	anonymizing, but it could be configured to use a secret word
>> 	that the user may not want to reveal.
>> 
>> at the end to explain the motivation behind anonymizing even more,
>> if we wanted to.
>
> IMO, making the primary branch identifiable is a reasonable
> justification to treat it specially. But then, why does it have to be
> renamed to 'ref0'? Couldn't it just be renamed to Git's default primary
> branch name, be it 'master' today or 'main' or whatever in the future?

That comes from https://lore.kernel.org/git/xmqqtuzha6xn.fsf@gitster.c.googlers.com/

But I agree with you 100% if you literally mean 'master' (or 'main')
hardcoded without any end-user customization.  What I rejected and
replaced with the vanilla "ref0" was to return the configured name
that will be used for the primary branch in new repositories.  The
above proposal suggested a faulty:

-	if (!strcmp(refname, "refs/heads/master"))
-		return refname;
+	if (!strcmp(refname, get_primary_branch_name(DO_NOT_ABBREV)))
+		return get_default_branch_name(DO_NOT_ABBREV);

A corrected code should return a hardwired constant 'main' (it
probably gets behind a C preprocessor macro, but the point is that
we do not want end-user customization) for the reason stated in that
message.

Thanks.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-11 23:14     ` Junio C Hamano
  2020-06-11 23:46       ` brian m. carlson
@ 2020-06-13 18:01       ` Alban Gruin
  2020-06-14  8:57         ` Johannes Schindelin
  1 sibling, 1 reply; 178+ messages in thread
From: Alban Gruin @ 2020-06-13 18:01 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Don Goodman-Wilson via GitGitGadget, git, don, stolee, peff,
	sandals, Johannes Schindelin

Hi Junio,

Le 12/06/2020 à 01:14, Junio C Hamano a écrit :
> Alban Gruin <alban.gruin@gmail.com> writes:
> 
>> Why adding yet another environment variable instead of relying only on a
>> config option?  I understand it's for the tests, but can't we add a
>> shell function in test-lib.sh (and friends) that tries to read
>> `GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets
>> `core.defaultBranchName'?
> 
> Can you produce such a patch that does it cleanly?  My knee jerk
> reaction is that I would suspect that you end up having to touch
> many places in the t/ scripts, but if you prove otherwise, that
> would certainly be appreciated.
> 
> And no, 
> 
>     git () { command git -c core.defaultBranchName=master "$@" }
> 
> is not an acceptable solution.
> 

I wanted to to do something like this:

  if test -n "$GIT_TEST_DEFAULT_BRANCH_NAME";
  then
      git config core.defaultBranchName "$GIT_TEST_DEFAULT_BRANCH_NAME"
  fi

But since we do not have a repository to store the config, it won't
work.  Sorry for the noise.

Alban


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-13 14:47                       ` Johannes Schindelin
@ 2020-06-13 18:49                         ` Junio C Hamano
  2020-06-14  8:55                           ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-13 18:49 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Johannes Sixt, Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> A corrected code should return a hardwired constant 'main' (it
>> probably gets behind a C preprocessor macro, but the point is that
>> we do not want end-user customization) for the reason stated in that
>> message.
>
> I like `ref0` better, for two reasons:
>
> - it is more consistent to just have all anonymized branches be named
>   `ref<N>`, and
>
> - using `main` both for an original `main` and an original `master` can be
>   a bit confusing, as the reader might assume that this branch name (as it
>   does not follow the `ref<N>` convention) was _not_ anonymized, when it
>   very well might have been.

A pro for keeping a hardcoded 'master' is that it is compatible with
the current world order, and flipping it to hardcoded 'main' upon
transition is just to use the moral equivalent, so we do not need to
immediately have to change anything.  The _new_ consistency across
ref<N> does feel attractive, but because it is new, there always is
a pushback not to "fix" what is not broken.

I am personally OK either way.  

By the way, we'd need to devise a transition plan for switching the
default branch name (i.e. the name used for the primary branch in a
newly created repository unless the user configures it to some other
value) to 'main' (oh, I just found one reason why I will not want to
use that name in my project(s)---it is too close to 'maint').  

It might roughly go like:

 1. We introduce core.defaultBranchName; when it is not set, its
    value defaults to 'master' in the 1st phase of the transition.
    "git init" and "git clone" however issue a warning that says
    "unless you configure core.defaultBranchName, we use 'master'
    for now for backward compatibility but we will start using
    'main' in three major releases of Git in the future".  These
    commands use the default branch name when creating a new
    repository in the 1st phase, and set core.primaryBranchName to
    that name in the resulting repository.

    This is to encourage early adopters to set it to 'maint'^W'main'
    (eek, see, I again made that typo), while allowing those who
    have toolset that depends more heavily on the current default
    branch name than other people to set it to 'master' for
    stability.

    In the 1st phase, a few commands that care about what the
    primary branch is in a repository (i.e. fmt-merge-msg and
    fast-export are the two we have identified so far) pay attention
    to the core.primaryBranchName configuration, and default to
    'master' if the configuration does not exist.  

    These commands issue a warning that says "unless you configure
    core.primaryBranchName in the repository, we use 'master' for
    now but we will start using 'main' in three major releases of
    Git in the future".

    The above two warning messages will be squelched once the user
    sets respective configuration variable.

 2. We flip the default for the two variables from 'master' to
    'main' in three major releases of Git (i.e. 24-30 weeks from the
    1st phase).  The two warning messages added for the 1st phase
    will be reworded for the updated default.  We no longer need to
    say "in three major releases" in there.

 3. After long time passes, remove the warning.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-13 18:49                         ` Junio C Hamano
@ 2020-06-14  8:55                           ` Johannes Schindelin
  2020-06-17 20:06                             ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-14  8:55 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Sixt, Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio,

On Sat, 13 Jun 2020, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> >> A corrected code should return a hardwired constant 'main' (it
> >> probably gets behind a C preprocessor macro, but the point is that
> >> we do not want end-user customization) for the reason stated in that
> >> message.
> >
> > I like `ref0` better, for two reasons:
> >
> > - it is more consistent to just have all anonymized branches be named
> >   `ref<N>`, and
> >
> > - using `main` both for an original `main` and an original `master` can be
> >   a bit confusing, as the reader might assume that this branch name (as it
> >   does not follow the `ref<N>` convention) was _not_ anonymized, when it
> >   very well might have been.
>
> A pro for keeping a hardcoded 'master' is that it is compatible with
> the current world order, and flipping it to hardcoded 'main' upon
> transition is just to use the moral equivalent, so we do not need to
> immediately have to change anything.  The _new_ consistency across
> ref<N> does feel attractive, but because it is new, there always is
> a pushback not to "fix" what is not broken.
>
> I am personally OK either way.
>
> By the way, we'd need to devise a transition plan for switching the
> default branch name (i.e. the name used for the primary branch in a
> newly created repository unless the user configures it to some other
> value) to 'main' (oh, I just found one reason why I will not want to
> use that name in my project(s)---it is too close to 'maint').

Yes, the trouble with `maint` did cross my mind, but I try not to
"overfit" to git/git. :-)

> It might roughly go like:
>
>  1. We introduce core.defaultBranchName; when it is not set, its
>     value defaults to 'master' in the 1st phase of the transition.
>     "git init" and "git clone" however issue a warning that says
>     "unless you configure core.defaultBranchName, we use 'master'
>     for now for backward compatibility but we will start using
>     'main' in three major releases of Git in the future".  These
>     commands use the default branch name when creating a new
>     repository in the 1st phase, and set core.primaryBranchName to
>     that name in the resulting repository.
>
>     This is to encourage early adopters to set it to 'maint'^W'main'
>     (eek, see, I again made that typo), while allowing those who
>     have toolset that depends more heavily on the current default
>     branch name than other people to set it to 'master' for
>     stability.
>
>     In the 1st phase, a few commands that care about what the
>     primary branch is in a repository (i.e. fmt-merge-msg and
>     fast-export are the two we have identified so far) pay attention
>     to the core.primaryBranchName configuration, and default to
>     'master' if the configuration does not exist.
>
>     These commands issue a warning that says "unless you configure
>     core.primaryBranchName in the repository, we use 'master' for
>     now but we will start using 'main' in three major releases of
>     Git in the future".
>
>     The above two warning messages will be squelched once the user
>     sets respective configuration variable.
>
>  2. We flip the default for the two variables from 'master' to
>     'main' in three major releases of Git (i.e. 24-30 weeks from the
>     1st phase).  The two warning messages added for the 1st phase
>     will be reworded for the updated default.  We no longer need to
>     say "in three major releases" in there.
>
>  3. After long time passes, remove the warning.

Yes, that's what I had in my mind, too (modulo the concrete part about the
three major versions, which is something I would have asked about at some
stage, thank you for answering that question already!).

Thank you,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-13 18:01       ` Alban Gruin
@ 2020-06-14  8:57         ` Johannes Schindelin
  2020-06-16 12:25           ` Jeff King
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-14  8:57 UTC (permalink / raw)
  To: Alban Gruin
  Cc: Junio C Hamano, Don Goodman-Wilson via GitGitGadget, git, don,
	stolee, peff, sandals

[-- Attachment #1: Type: text/plain, Size: 1569 bytes --]

Hi Alban,

On Sat, 13 Jun 2020, Alban Gruin wrote:

> Hi Junio,
>
> Le 12/06/2020 à 01:14, Junio C Hamano a écrit :
> > Alban Gruin <alban.gruin@gmail.com> writes:
> >
> >> Why adding yet another environment variable instead of relying only on a
> >> config option?  I understand it's for the tests, but can't we add a
> >> shell function in test-lib.sh (and friends) that tries to read
> >> `GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets
> >> `core.defaultBranchName'?
> >
> > Can you produce such a patch that does it cleanly?  My knee jerk
> > reaction is that I would suspect that you end up having to touch
> > many places in the t/ scripts, but if you prove otherwise, that
> > would certainly be appreciated.
> >
> > And no,
> >
> >     git () { command git -c core.defaultBranchName=master "$@" }
> >
> > is not an acceptable solution.
> >
>
> I wanted to to do something like this:
>
>   if test -n "$GIT_TEST_DEFAULT_BRANCH_NAME";
>   then
>       git config core.defaultBranchName "$GIT_TEST_DEFAULT_BRANCH_NAME"
>   fi
>
> But since we do not have a repository to store the config, it won't
> work.  Sorry for the noise.

We actually would have `~/.gitconfig` because `HOME` is set to `t/trash
directory.<test-name>/`.

However, that would cause all kinds of issues when test scripts expect the
directory to be pristine, containing only `.git/` but not `.gitconfig`.

It was a good idea to bring up; I share brian's sentiment that it would
have been nice if it would have worked out.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-12 16:51       ` Junio C Hamano
@ 2020-06-14 22:00         ` Johannes Schindelin
  2020-06-15 10:00         ` Phillip Wood
  1 sibling, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-14 22:00 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Phillip Wood, Don Goodman-Wilson via GitGitGadget, git, don,
	stolee, peff, sandals

Hi Junio,

On Fri, 12 Jun 2020, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > I added a _brief_ extension to the context to the first commit's commit
> > message. However, I do not want to go into details here because _this_
> > patch series is only about empowering users to change their default main
> > branch name.
>
> Sensible.
>
> And I do not think the planned follow-up work to rename 'master' to
> something else needs to be defended with lengthy history lessons.

Yes, I agree. It is probably sufficient to just point at a couple
high-profile projects that already made the switch to `main`.

> Sufficiently large part of the user population are unhappy with the
> use of the word 'master' as the default name of the primary branch
> in a newly created repository, and the mere fact that we are aware
> of that is good enough justification to move _away_ from 'master'.

Yes, even Pasky says he regrets the choice of term (see
https://twitter.com/xpasky/status/1271477451756056577):

	I picked the names "master" (and "origin") in the early Git tooling
	back in 2005.

	(this probably means you shouldn't give much weight to my name
	preferences :) )

	I have wished many times I would have named them "main" (and
	"upstream") instead.

> In other words, we do not have to explain why 'master' was bad, as
> it does not have to be bad for everybody to be replaced.
>
> But you need to defend that the new word you picked is something
> everybody is happy with.  That is much harder ;-).

To be honest, I stopped looking for got arguments in favor of one
name after a couple days, and instead focused on the consensus I
saw: Chrome [*1*] and node.js [*2*] apparently stated publicly that
they want to change their main branches to `main`, and GitLab [*3*]
and GitHub [*4*] seem to intend to change the default for new
repositories accordingly.

It is not like we have to decide for the community (as we did back
in 2005). I am actually quite relieved about that.

Ciao,
Dscho

URL *1*: https://twitter.com/Una/status/1271180494944829441
URL *2*: https://github.com/nodejs/node/issues/33864
URL *3*: https://gitlab.com/gitlab-org/gitlab/-/issues/221164
URL *4*: https://twitter.com/natfriedman/status/1271253144442253312
(this is not really a public announcement, I agree, but it is a
public Tweet by the CEO)

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-15 10:03 ` Pratyush Yadav
@ 2020-06-14 22:26   ` Johannes Schindelin
  2020-06-16  0:19     ` Denton Liu
  2020-06-15 23:10   ` brian m. carlson
  1 sibling, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-14 22:26 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff, sandals

Hi Pratyush,

On Mon, 15 Jun 2020, Pratyush Yadav wrote:

> On 10/06/20 09:19PM, Johannes Schindelin via GitGitGadget wrote:
>
> > This series DOES NOT change the default automatically, but only provides an
> > opt-in mechanism for interested users. It also presents a way forward for
> > such a transition, if and when we decide to do so. Specifically, the new
> > GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
> > test scripts on an individual basis instead of all-at-once.
>
> Many people have expressed reservations against this change.

From what you wrote below, I take it that you are not talking about this
patch series, nor the follow-up one(s) to change the default main branch
name for new repositories.

> One argument from those in favor of this change is that it doesn't
> affect you if you don't care about the default branch name. You can just
> go on using 'master' for all _your_ repos. I'd like to highlight the
> "your" here. Sure, I can keep on using 'master' if I so prefer, but I
> don't just use my repos. I also pull repos from other people, and I have
> no control over what they call their main/primary/master branch (I'll
> use "main" for the rest of the email). The cost here is that people now
> need to update their scripts and workflow to account for other people's
> naming preferences.

This talks about the scenario where a project you use decides to change
their main branch name.

While this is a scenario that my patch series tries to support (by
introducing the concept of `core.mainBranch`), it is not something my
patch series _causes_.

All _this_ patch series does is to _allow_ changing the main branch name
(manually) in an existing repository, and to change the default main
branch name to use in new repositories.

Even the follow-up patch series I plan on contributing that changes the
hard-coded default for the default main branch name to use in new
repositories won't affect any existing repository.

So I think this example...

> For example, my vim plugins are submodules in the '~/.vim/bundle'
> directory. When I want to update them, I run:
>
>   git submodule foreach 'git remote update && git reset --hard origin/master'
>
> With this change hitting a Git release, more and more people would call
> their main branch different names they like. So what is the recommended
> way to do something like this now? How do I checkout the tip of the main
> branch? How do I push to the main branch? How do I pull from the main
> branch? And so on...

... has less to do with a new Git release, but more with the decision of
an existing project to change their main branch name.

That's something users already had to deal with, of course. For example,
projects switching to the Git Flow model will start to use the main branch
name `development`.

GitHub Desktop changed their main branch name to `development`, and it did
not require any new Git release.

GitHub CLI changed their main branch name to `trunk`.

Chrome and node.js stated their intention to change their main branch name
to `main`.

And https://github.com/microsoft/git uses `vfs-<version>` where
`<version>` corresponds to the Git (for Windows) version on which it is
based, therefore the main branch name changes whenever there is a new Git
version.

These challenges have existed for every project that chooses to change
their main branch name, for whatever reason.

In other words, I think you are talking about a challenge that is
orthogonal (if related, on a high level) to the subject this patch series
tries to address.

Ciao,
Johannes

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-12 16:51       ` Junio C Hamano
  2020-06-14 22:00         ` Johannes Schindelin
@ 2020-06-15 10:00         ` Phillip Wood
  1 sibling, 0 replies; 178+ messages in thread
From: Phillip Wood @ 2020-06-15 10:00 UTC (permalink / raw)
  To: Junio C Hamano, Johannes Schindelin
  Cc: Don Goodman-Wilson via GitGitGadget, git, don, stolee, peff, sandals

On 12/06/2020 17:51, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
>> I added a _brief_ extension to the context to the first commit's commit
>> message. However, I do not want to go into details here because _this_
>> patch series is only about empowering users to change their default main
>> branch name.
> 
> [...]
> 
> Sufficiently large part of the user population are unhappy with the
> use of the word 'master' as the default name of the primary branch
> in a newly created repository, and the mere fact that we are aware
> of that is good enough justification to move _away_ from 'master'.
> In other words, we do not have to explain why 'master' was bad, as
> it does not have to be bad for everybody to be replaced.

This expresses what I was trying to get at with my comments much more
clearly than I managed - Thank you

> 
> But you need to defend that the new word you picked is something
> everybody is happy with.  That is much harder ;-).

Indeed, though I am more optimistic about that having seen a couple of
people have indicated that they don't mind too much what we choose so
long as it unlikely to cause future problems.

Best Wishes

Phillip



^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (11 preceding siblings ...)
  2020-06-11  1:07 ` Taylor Blau
@ 2020-06-15 10:03 ` Pratyush Yadav
  2020-06-14 22:26   ` Johannes Schindelin
  2020-06-15 23:10   ` brian m. carlson
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
  2020-06-16  9:47 ` [PATCH " Ævar Arnfjörð Bjarmason
  14 siblings, 2 replies; 178+ messages in thread
From: Pratyush Yadav @ 2020-06-15 10:03 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin

Hi,

On 10/06/20 09:19PM, Johannes Schindelin via GitGitGadget wrote:
> A growing number of open source projects aims to avoid the branch name 
> master due to its negative connotation. See [1] for an existing discussion
> on this. The links [2], [3], and [4] describe community-driven ways for
> users to rename their default branches or use template edits to set a new
> default branch name.
> 
> [1] 
> https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/
> 
> [2] https://twitter.com/mislav/status/1270388510684598272
> 
> [3] 
> https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx
> 
> [4] https://github.com/ethomson/retarget_prs
> 
> By necessity, existing repositories require a lot of manual work to move
> away from that branch name, but it should be much easier for new
> repositories.
> 
> This patch series allows overriding the branch name being used for new
> repositories' main branch. The main way to do this is the new 
> core.defaultBranchName config option. This first patch was contributed by
> newcomer Dan Goodman-Wilson. Thanks for the contribution!
> 
> The other patches follow other places where "master" is hard-coded and use
> the new git_default_branch_name() method to consume the config option before
> falling back to "master".
> 
> The last patch updates documentation only after the config option is ready
> to apply to all of these scenarios.
> 
> This series DOES NOT change the default automatically, but only provides an
> opt-in mechanism for interested users. It also presents a way forward for
> such a transition, if and when we decide to do so. Specifically, the new
> GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
> test scripts on an individual basis instead of all-at-once.

Many people have expressed reservations against this change. Some on the 
list here, others in private conversation. I personally don't have a 
strong opinion on either side. So I'll refrain from saying too much on 
the issue. Reading through the list, I sense that the Git maintainer has 
already decided it is something good for the project. And so I think 
this change has a high chance of making it in a near future Git release.  

One argument from those in favor of this change is that it doesn't 
affect you if you don't care about the default branch name. You can just 
go on using 'master' for all _your_ repos. I'd like to highlight the 
"your" here. Sure, I can keep on using 'master' if I so prefer, but I 
don't just use my repos. I also pull repos from other people, and I have 
no control over what they call their main/primary/master branch (I'll 
use "main" for the rest of the email). The cost here is that people now 
need to update their scripts and workflow to account for other people's 
naming preferences.

For example, my vim plugins are submodules in the '~/.vim/bundle' 
directory. When I want to update them, I run:

  git submodule foreach 'git remote update && git reset --hard origin/master'

With this change hitting a Git release, more and more people would call 
their main branch different names they like. So what is the recommended 
way to do something like this now? How do I checkout the tip of the main 
branch? How do I push to the main branch? How do I pull from the main 
branch? And so on...

-- 
Regards,
Pratyush Yadav

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 5/9] submodule: use the (possibly overridden) default branch name
  2020-06-10 21:19 ` [PATCH 5/9] submodule: use the (possibly overridden) default branch name Johannes Schindelin via GitGitGadget
@ 2020-06-15 10:46   ` Denton Liu
  0 siblings, 0 replies; 178+ messages in thread
From: Denton Liu @ 2020-06-15 10:46 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin

On Wed, Jun 10, 2020 at 09:19:26PM +0000, Johannes Schindelin via GitGitGadget wrote:
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> To allow for overriding the default branch name, we have introduced a
> config setting. With this patch, the `git submodule` command learns
> about this, too.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>

One thing to consider: in the future, if we move away from "master"
or even allow the value to be configurable, we're gonna end up breaking
a lot of repositories this way.

If a developer regularly pulls in submodule updates via
`git submodule update --remote`, when the default branch name changes,
this will suddenly stop working. This will require developers who use
submodules to "fix" their .gitmodules file.

If it's configurable, this problem might be even worse. It could lead to
scenarios where one developer might go "works for me" while another
developer (who may set the configuration and forget about it) would be
confused about why it's not working for them.

Just a couple thoughts I had while looking at this patch.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 00/12] Allow overriding the default name of the default branch
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (12 preceding siblings ...)
  2020-06-15 10:03 ` Pratyush Yadav
@ 2020-06-15 12:50 ` Johannes Schindelin via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 01/12] fast-export: do anonymize the primary branch name Junio C Hamano via GitGitGadget
                     ` (12 more replies)
  2020-06-16  9:47 ` [PATCH " Ævar Arnfjörð Bjarmason
  14 siblings, 13 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin

A growing number of open source projects aims to avoid the branch name 
master due to its negative connotation. See [1] for an existing discussion
on this. The links [2], [3], and [4] describe community-driven ways for
users to rename their default branches or use template edits to set a new
default branch name.

[1] 
https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/

[2] https://twitter.com/mislav/status/1270388510684598272

[3] 
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx

[4] https://github.com/ethomson/retarget_prs

By necessity, existing repositories require a lot of manual work to move
away from that branch name, but it should be much easier for new
repositories.

This patch series allows overriding the branch name being used for new
repositories' main branch, as well as telling Git about a renamed main
branch in an already-existing repository. The former would be configured via 
init.defaultBranch and the latter via core.mainBranch (which is now
automatically configured in git init).

Shell scripts can find out what the current repository's main branch name is
called via

main_branch=$(git config core.mainBranch || echo master)

This is even future proof because all future git init invocations will
configure that setting.

The initial patch was started by newcomer Don Goodman-Wilson, as well as the
bigger change that morphed into #655, where we demonstrate how to change
Git's hard-coded default main branch name to main based on this here patch
series, verifying the approach. Thanks for the contribution!

This series DOES NOT change the default automatically, but only provides an
opt-in mechanism for interested users. The plan for that is to convert the
test scripts incrementally (by introducing GIT_TEST_DEFAULT_MAIN_BRANCH_NAME
, which overrides init.defaultBranch, and then converting the tricky test
scripts first, one by one, using that environment variable).

Changes since v1:

 * The modifications to respect GIT_TEST_DEFAULT_BRANCH_NAME have been
   backed out from this patch series, as they are only relevant once we
   start converting the test suite to accommodate for a new default main
   branch name.
   
   
 * An error message that started with an upper-case letter was downcased.
   
   
 * git_default_branch_name()'s logic was simplified by replacing an if ...
   else ... by a ternary assignment.
   
   
 * The git_default_branch_name() function was renamed to 
   git_main_branch_name() and a corresponding repo_main_branch_name() was
   introduced.
   
   
 * The "init" commit message's first paragraph now elaborates a little bit
   on the reasoning why projects want to move away from the current default
   branch name.
   
   
 * The "init" commit was split into two.
   
   
 * There are now two config settings: init.defaultBranch (defining the
   branch name to use when initializing new repositories) and 
   core.mainBranch (which is now configured by init_db(), declaring what the
   name of the main branch is in this repository).
   
   
 * The commits were re-ordered to introduce the concept of core.mainBranch 
   first because technically, this is something that we could do even
   without changing git init at all.
   
   
 * git fast-export --anonymize now always uses the ref name ref0 for the
   main branch, no matter whether it was overridden or whether the fall-back
   is in effect.
   
   
 * The code comment regarding anonymizing the main branch to ref0 in git
   fast-export --anonymize was enhanced.
   
   
 * A new patch was added to rename core.mainBranch if the main branch is
   renamed via git branch -m.
   
   
 * Added a patch that introduces support for git init
   --main-branch=<branch-name>.
   
   
 * Where possible, I added tests (although I did not try to extend test
   coverage to all changes: the send-pack.c/transport-helper.c patch only
   adds a test for the send-pack.c adjustment, for example).

Don Goodman-Wilson (1):
  init: allow overriding the default main branch name via the config

Johannes Schindelin (10):
  fmt-merge-msg: introduce a way to override the main branch name
  send-pack/transport-helper: respect `core.mainBranch`
  git_main_branch_name(): optionally report the full ref name
  fast-export: handle overridden main branch names correctly
  branch -m: adjust `core.mainBranch` if necessary
  init: allow specifying the main branch name for the new repository
  clone: handle overridden main branch names
  remote: learn about the possibly-overridden default main branch name
  submodule: use the correct default for the main branch name
  testsvn: respect `init.defaultBranch`

Junio C Hamano (1):
  fast-export: do anonymize the primary branch name

 Documentation/config/core.txt    |  5 +++++
 Documentation/config/init.txt    |  4 ++++
 Documentation/git-init.txt       |  7 +++++++
 builtin/branch.c                 |  9 ++++++++
 builtin/clone.c                  | 19 +++++++++++++----
 builtin/fast-export.c            | 20 +++++++++++++-----
 builtin/init-db.c                | 36 +++++++++++++++++++++++++-------
 builtin/submodule--helper.c      | 10 +++++++--
 cache.h                          |  2 +-
 fmt-merge-msg.c                  |  6 ++++--
 refs.c                           | 34 ++++++++++++++++++++++++++++++
 refs.h                           | 15 +++++++++++++
 remote-testsvn.c                 | 12 ++++++++---
 remote.c                         | 15 ++++++++-----
 send-pack.c                      |  6 +++++-
 t/t0001-init.sh                  | 31 +++++++++++++++++++++++++++
 t/t3200-branch.sh                |  9 ++++++++
 t/t5528-push-default.sh          |  7 +++++++
 t/t5606-clone-options.sh         | 26 +++++++++++++++++++++++
 t/t6200-fmt-merge-msg.sh         |  7 +++++++
 t/t7406-submodule-update.sh      |  7 +++++++
 t/t9020-remote-svn.sh            |  6 ++++++
 t/t9351-fast-export-anonymize.sh | 15 +++++++++----
 transport-helper.c               |  6 +++++-
 24 files changed, 279 insertions(+), 35 deletions(-)


base-commit: 0313f36c6ebecb3bffe6f15cf25a4883100f0214
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-656%2Fdscho%2Fdefault-branch-name-option-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-656/dscho/default-branch-name-option-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/656

Range-diff vs v1:

  -:  ----------- >  1:  ebd10f73cd7 fast-export: do anonymize the primary branch name
  7:  e849def4a8c !  2:  f4d54739153 fmt-merge-msg: learn about the possibly-configured default branch name
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    fmt-merge-msg: learn about the possibly-configured default branch name
     +    fmt-merge-msg: introduce a way to override the main branch name
      
     -    When formatting the commit message for merge commits, Git appends "into
     -    <branch-name>" unless the current branch is the default branch.
     +    There is a growing number of projects and companies desiring to change
     +    the main branch name of their repositories (see e.g.
     +    https://twitter.com/mislav/status/1270388510684598272 for background on
     +    this).
      
     -    Now that we can configure what the default branch name should be, we
     -    will want to respect that setting in that scenario rather than using the
     -    compiled-in default branch name.
     +    However, there are a couple of hard-coded spots in Git's source code
     +    that make this endeavor harder than necessary. For example, when
     +    formatting the commit message for merge commits, Git appends "into
     +    <branch-name>" unless the current branch is the `master` branch.
     +
     +    Clearly, this is not what one wants when already having gone through all
     +    the steps to manually rename the main branch (and taking care of all the
     +    fall-out such as re-targeting existing Pull Requests).
     +
     +    Let's introduce a way to override Git's hard-coded default:
     +    `core.mainBranch`.
     +
     +    We will start supporting this config option in the `git fmt-merge-msg`
     +    command and successively adjust all other places where the main branch
     +    name is hard-coded.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     + ## Documentation/config/core.txt ##
     +@@ Documentation/config/core.txt: core.abbrev::
     + 	in your repository, which hopefully is enough for
     + 	abbreviated object names to stay unique for some time.
     + 	The minimum length is 4.
     ++
     ++core.mainBranch::
     ++	The name of the main (or: primary) branch in the current repository.
     ++	For historical reasons, `master` is used as the fall-back for this
     ++	setting.
     +
       ## fmt-merge-msg.c ##
      @@ fmt-merge-msg.c: static void fmt_merge_msg_title(struct strbuf *out,
       				const char *current_branch)
       {
       	int i = 0;
      -	char *sep = "";
     -+	char *sep = "", *default_branch_name;
     ++	char *sep = "", *main_branch;
       
       	strbuf_addstr(out, "Merge ");
       	for (i = 0; i < srcs.nr; i++) {
     @@ fmt-merge-msg.c: static void fmt_merge_msg_title(struct strbuf *out,
       	}
       
      -	if (!strcmp("master", current_branch))
     -+	default_branch_name = git_default_branch_name(1);
     -+	if (!strcmp(default_branch_name, current_branch))
     ++	main_branch = git_main_branch_name();
     ++	if (!strcmp(main_branch, current_branch))
       		strbuf_addch(out, '\n');
       	else
       		strbuf_addf(out, " into %s\n", current_branch);
     -+	free(default_branch_name);
     ++	free(main_branch);
       }
       
       static void fmt_tag_signature(struct strbuf *tagbuf,
      
     + ## refs.c ##
     +@@ refs.c: void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
     + 		argv_array_pushf(prefixes, *p, len, prefix);
     + }
     + 
     ++char *repo_main_branch_name(struct repository *r)
     ++{
     ++	const char *config_key = "core.mainbranch";
     ++	const char *config_display_key = "core.mainBranch";
     ++	const char *fall_back = "master";
     ++	char *name = NULL, *ret;
     ++
     ++	if (repo_config_get_string(r, config_key, &name) < 0)
     ++		die(_("could not retrieve `%s`"), config_display_key);
     ++
     ++	ret = name ? name : xstrdup(fall_back);
     ++
     ++	if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
     ++		die(_("invalid branch name: %s = %s"),
     ++		    config_display_key, name);
     ++
     ++	if (name != ret)
     ++		free(name);
     ++
     ++	return ret;
     ++}
     ++
     ++char *git_main_branch_name(void)
     ++{
     ++	return repo_main_branch_name(the_repository);
     ++}
     ++
     + /*
     +  * *string and *len will only be substituted, and *string returned (for
     +  * later free()ing) if the string passed in is a magic short-hand form
     +
     + ## refs.h ##
     +@@ refs.h: int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
     + int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
     + int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
     + 
     ++/*
     ++ * Retrieves the name of the main (or: primary) branch of the given
     ++ * repository.
     ++ */
     ++char *git_main_branch_name(void);
     ++char *repo_main_branch_name(struct repository *r);
     ++
     + /*
     +  * A ref_transaction represents a collection of reference updates that
     +  * should succeed or fail together.
     +
       ## t/t6200-fmt-merge-msg.sh ##
      @@ t/t6200-fmt-merge-msg.sh: test_expect_success 'setup FETCH_HEAD' '
       	git fetch . left
       '
       
      +test_expect_success 'with overridden default branch name' '
     -+	test_config core.defaultBranchName default &&
      +	test_when_finished "git switch master" &&
      +	git switch -c default &&
     -+	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
     ++	git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual &&
      +	! grep "into default" actual
      +'
      +
  3:  c9c9c81068e !  3:  bd8af3755ad send-pack/transport-helper: respect `core.defaultBranchName`
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    send-pack/transport-helper: respect `core.defaultBranchName`
     +    send-pack/transport-helper: respect `core.mainBranch`
      
     -    When mentioning the default branch name in an error message, we want to
     -    go with the preference specified by the user.
     +    When mentioning the main branch name in an error message, we want to go
     +    with the preference specified by the user, only falling back to Git's
     +    own, hard-coded default when none was configured explicitly.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     @@ send-pack.c: int send_pack(struct send_pack_args *args,
       	}
       
       	if (!remote_refs) {
     -+		char *branch_name = git_default_branch_name(1);
     ++		char *branch_name = git_main_branch_name();
      +
       		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
      -			"Perhaps you should specify a branch such as 'master'.\n");
     @@ send-pack.c: int send_pack(struct send_pack_args *args,
       	}
       	if (args->atomic && !atomic_supported)
      
     + ## t/t5528-push-default.sh ##
     +@@ t/t5528-push-default.sh: test_expect_success 'push from/to new branch with upstream, matching and simple'
     + 	test_push_failure upstream
     + '
     + 
     ++test_expect_success '"matching" fails if none match' '
     ++	git init --bare empty &&
     ++	test_must_fail git -c core.mainBranch=unmatch push empty : 2>actual &&
     ++	needle="Perhaps you should specify a branch such as '\''unmatch'\''" &&
     ++	test_i18ngrep "$needle" actual
     ++'
     ++
     + test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
     + 	git checkout -b ambiguous &&
     + 	test_config branch.ambiguous.remote parent1 &&
     +
       ## transport-helper.c ##
      @@ transport-helper.c: static int push_refs(struct transport *transport,
       	}
       
       	if (!remote_refs) {
     -+		char *branch_name = git_default_branch_name(1);
     ++		char *branch_name = git_main_branch_name();
      +
       		fprintf(stderr,
       			_("No refs in common and none specified; doing nothing.\n"
  -:  ----------- >  4:  ca1c63c3e01 git_main_branch_name(): optionally report the full ref name
  8:  1efe848f2b0 !  5:  a3be4f39aa2 fast-export: respect the possibly-overridden default branch name
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    fast-export: respect the possibly-overridden default branch name
     +    fast-export: handle overridden main branch names correctly
      
     -    When anonymizing commit history, we are careful to leave the branch name
     -    of the default branch alone.
     +    When anonymizing commit history, we are careful to translate the main
     +    branch name to `ref0`.
      
     -    When the default branch name is overridden via the config or via the
     -    environment variable, we will want `git fast-export` to use that
     -    overridden name instead.
     +    When the main branch name is overridden via the config, we will want
     +    `git fast-export` to use that overridden name instead.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     @@ builtin/fast-export.c: static const char *anonymize_refname(const char *refname)
       	};
       	static struct hashmap refs;
       	static struct strbuf anon = STRBUF_INIT;
     -+	static char *default_branch_name;
     ++	static char *main_branch;
       	int i;
       
       	/*
     --	 * We also leave "master" as a special case, since it does not reveal
     --	 * anything interesting.
     -+	 * We also leave the default branch name as a special case, since it
     -+	 * does not reveal anything interesting.
     + 	 * In certain circumstances, it might be interesting to be able to
     + 	 * identify the main branch. For that reason, let's force its name to
     + 	 * be anonymized to `ref0`.
     ++	 *
     ++	 * While the main branch name might often be `main` for new
     ++	 * repositories (and `master` for aged ones), and such well-known names
     ++	 * may not necessarily need anonymizing, it could be configured to use
     ++	 * a secret word that the user may not want to reveal.
       	 */
      -	if (!strcmp(refname, "refs/heads/master"))
     -+	if (!default_branch_name)
     -+		default_branch_name = git_default_branch_name(0);
     ++	if (!main_branch)
     ++		main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
      +
     -+	if (!strcmp(refname, default_branch_name))
     - 		return refname;
     ++	if (!strcmp(refname, main_branch))
     + 		return "refs/heads/ref0";
       
       	strbuf_reset(&anon);
     +
     + ## t/t9351-fast-export-anonymize.sh ##
     +@@ t/t9351-fast-export-anonymize.sh: test_expect_success 'stream translates master to ref0' '
     + 	! grep master stream
     + '
     + 
     ++test_expect_success 'respects configured main branch' '
     ++	git -c core.mainBranch=does-not-exist \
     ++		fast-export --anonymize --all >stream-without-ref0 &&
     ++	! grep ref0 stream-without-ref0
     ++'
     ++
     + test_expect_success 'stream omits other refnames' '
     + 	! grep other stream &&
     + 	! grep mytag stream
  -:  ----------- >  6:  933e314813d branch -m: adjust `core.mainBranch` if necessary
  1:  90912e32da1 !  7:  0ec04b2086e init: allow overriding the default branch name for new repositories
     @@
       ## Metadata ##
     -Author: Don Goodman-Wilson <don@goodman-wilson.com>
     +Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    init: allow overriding the default branch name for new repositories
     +    init: allow specifying the main branch name for the new repository
      
          There is a growing number of projects trying to avoid the non-inclusive
     -    name `master` in their repositories. For existing repositories, this
     -    requires manual work. For new repositories, the only way to do that
     -    automatically is by copying all of Git's template directory, then
     -    hard-coding the desired default branch name into the `.git/HEAD` file,
     -    and then configuring `init.templateDir` to point to those copied
     +    name `master` in their repositories: The `master`/`slave` terminology is
     +    insensitive and perpetuates injustice. This `master`/`slave` idea is
     +    actually where Git's naming comes from, as it was inherited from
     +    BitKeeper which uses the term in exactly this way, see
     +    https://mail.gnome.org/archives/desktop-devel-list/2019-May/msg00066.html
     +
     +    To change that branch name for new repositories, currently the only way
     +    to do that automatically is by copying all of Git's template directory,
     +    then hard-coding the desired default branch name into the `.git/HEAD`
     +    file, and then configuring `init.templateDir` to point to those copied
          template files.
      
     -    To make this process much less cumbersome, let's introduce support for
     -    `core.defaultBranchName`. That way, users won't need to keep their
     -    copied template files up to date, and won't interfere with default hooks
     -    installed by their administrators.
     +    To make this process much less cumbersome, let's introduce a new option:
     +    `--main-branch=<branch-name>`.
      
     -    While at it, also let users set the default branch name via the
     -    environment variable `GIT_TEST_DEFAULT_BRANCH_NAME`, in preparation for
     -    adjusting Git's test suite to a more inclusive default branch name. As
     -    is common in Git, the `GIT_TEST_*` variable takes precedence over the
     -    config setting.
     +    This will not only initialize the repository with the specified initial
     +    branch; It will also record that branch name in `core.mainBranch`.
      
     -    Note: we use the prefix `core.` instead of `init.` because we want to
     -    adjust also `git clone`, `git fmt-merge-msg` and other commands over the
     -    course of the next commits to respect this setting.
     +    Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     -    Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
     -    Helped-by: Derrick Stolee <dstolee@microsoft.com>
     -    Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
     + ## Documentation/git-init.txt ##
     +@@ Documentation/git-init.txt: SYNOPSIS
     + [verse]
     + 'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
     + 	  [--separate-git-dir <git dir>] [--object-format=<format]
     ++	  [-b <branch-name> | --main-branch=<branch-name>]
     + 	  [--shared[=<permissions>]] [directory]
     + 
     + 
     +@@ Documentation/git-init.txt: repository.
     + +
     + If this is reinitialization, the repository will be moved to the specified path.
     + 
     ++-b <branch-name::
     ++--main-branch=<branch-name>::
     ++
     ++Use the specified name for the main (or: initial) branch in the newly created
     ++repository. If not specified, fall back to the default name: `master`.
     ++
     + --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
     + 
     + Specify that the Git repository is to be shared amongst several users.  This
     +
     + ## builtin/clone.c ##
     +@@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
     + 		}
     + 	}
     + 
     +-	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
     ++	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
     ++		INIT_DB_QUIET);
     + 
     + 	if (real_git_dir)
     + 		git_dir = real_git_dir;
      
       ## builtin/init-db.c ##
     +@@ builtin/init-db.c: void initialize_repository_version(int hash_algo)
     + 
     + static int create_default_files(const char *template_path,
     + 				const char *original_git_dir,
     ++				const char *main_branch,
     + 				const struct repository_format *fmt)
     + {
     + 	struct stat st1;
      @@ builtin/init-db.c: static int create_default_files(const char *template_path,
       		die("failed to set up refs db: %s", err.buf);
       
     @@ builtin/init-db.c: static int create_default_files(const char *template_path,
       		  || readlink(path, junk, sizeof(junk)-1) != -1);
       	if (!reinit) {
      -		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
     -+		char *default_ref = git_default_branch_name(0);
     -+		if (create_symref("HEAD", default_ref, NULL) < 0)
     ++		char *ref;
     ++
     ++		if (!main_branch)
     ++			main_branch = "master";
     ++
     ++		ref = xstrfmt("refs/heads/%s", main_branch);
     ++		if (check_refname_format(ref, 0) < 0)
     ++			die(_("invalid main branch name: '%s'"), main_branch);
     ++
     ++		if (create_symref("HEAD", ref, NULL) < 0)
       			exit(1);
     -+		free(default_ref);
     - 	}
     +-	}
     ++		free(ref);
     ++
     ++		git_config_set("core.mainbranch", main_branch);
     ++	} else if (main_branch)
     ++		warning(_("re-init: ignoring --main-branch=%s"), main_branch);
       
       	initialize_repository_version(fmt->hash_algo);
     -
     - ## refs.c ##
     -@@ refs.c: void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
     - 		argv_array_pushf(prefixes, *p, len, prefix);
     + 
     +@@ builtin/init-db.c: static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
       }
       
     -+char *git_default_branch_name(int short_name)
     -+{
     -+	const char *branch_name = getenv("GIT_TEST_DEFAULT_BRANCH_NAME");
     -+	char *from_config = NULL, *prefixed;
     -+
     -+	/*
     -+	 * If the default branch name was not specified via the environment
     -+	 * variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config
     -+	 * setting core.defaultBranchName. If neither are set, fall back to the
     -+	 * hard-coded default.
     -+	 */
     -+	if (!branch_name || !*branch_name) {
     -+		if (git_config_get_string("core.defaultbranchname",
     -+					  &from_config) < 0)
     -+			die(_("Could not retrieve `core.defaultBranchName`"));
     -+
     -+		if (from_config)
     -+			branch_name = from_config;
     -+		else
     -+			branch_name = "master";
     -+	}
     -+
     -+	if (short_name)
     -+		return from_config ? from_config : xstrdup(branch_name);
     -+
     -+	/* prepend "refs/heads/" to the branch name */
     -+	prefixed = xstrfmt("refs/heads/%s", branch_name);
     -+	if (check_refname_format(prefixed, 0))
     -+		die(_("invalid default branch name: '%s'"), branch_name);
     -+
     -+	free(from_config);
     -+	return prefixed;
     -+}
     -+
     - /*
     -  * *string and *len will only be substituted, and *string returned (for
     -  * later free()ing) if the string passed in is a magic short-hand form
     + int init_db(const char *git_dir, const char *real_git_dir,
     +-	    const char *template_dir, int hash, unsigned int flags)
     ++	    const char *template_dir, int hash, const char *main_branch,
     ++	    unsigned int flags)
     + {
     + 	int reinit;
     + 	int exist_ok = flags & INIT_DB_EXIST_OK;
     +@@ builtin/init-db.c: int init_db(const char *git_dir, const char *real_git_dir,
     + 
     + 	validate_hash_algorithm(&repo_fmt, hash);
     + 
     +-	reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
     ++	reinit = create_default_files(template_dir, original_git_dir,
     ++				      main_branch, &repo_fmt);
     + 
     + 	create_object_directory();
     + 
     +@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *prefix)
     + 	const char *template_dir = NULL;
     + 	unsigned int flags = 0;
     + 	const char *object_format = NULL;
     ++	const char *main_branch = NULL;
     + 	int hash_algo = GIT_HASH_UNKNOWN;
     + 	const struct option init_db_options[] = {
     + 		OPT_STRING(0, "template", &template_dir, N_("template-directory"),
     +@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *prefix)
     + 		OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
     + 		OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
     + 			   N_("separate git dir from working tree")),
     ++		OPT_STRING('b', "main-branch", &main_branch, N_("name"),
     ++			   N_("override the name of the main branch")),
     + 		OPT_STRING(0, "object-format", &object_format, N_("hash"),
     + 			   N_("specify the hash algorithm to use")),
     + 		OPT_END()
     +@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *prefix)
     + 	UNLEAK(work_tree);
     + 
     + 	flags |= INIT_DB_EXIST_OK;
     +-	return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
     ++	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
     ++		       main_branch, flags);
     + }
      
     - ## refs.h ##
     -@@ refs.h: int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
     - int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
     - int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
     - 
     -+/*
     -+ * Retrieves the name of the default branch. If `short_name` is non-zero, the
     -+ * branch name will be prefixed with "refs/heads/".
     -+ */
     -+char *git_default_branch_name(int short_name);
     -+
     - /*
     -  * A ref_transaction represents a collection of reference updates that
     -  * should succeed or fail together.
     + ## cache.h ##
     +@@ cache.h: int path_inside_repo(const char *prefix, const char *path);
     + 
     + int init_db(const char *git_dir, const char *real_git_dir,
     + 	    const char *template_dir, int hash_algo,
     +-	    unsigned int flags);
     ++	    const char *main_branch, unsigned int flags);
     + void initialize_repository_version(int hash_algo);
     + 
     + void sanitize_stdfds(void);
      
       ## t/t0001-init.sh ##
      @@ t/t0001-init.sh: test_expect_success MINGW 'redirect std handles' '
       	grep "Needed a single revision" output.txt
       '
       
     -+test_expect_success 'custom default branch name from config' '
     -+	git config --global core.defaultbranchname nmb &&
     -+	GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config &&
     -+	git config --global --unset core.defaultbranchname &&
     -+	git -C custom-config symbolic-ref HEAD >actual &&
     -+	grep nmb actual
     -+'
     -+
     -+test_expect_success 'custom default branch name from env' '
     -+	GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env &&
     -+	git -C custom-env symbolic-ref HEAD >actual &&
     -+	grep nmb actual
     -+'
     ++test_expect_success '--main-branch' '
     ++	git init --main-branch=hello main-branch-option &&
     ++	git -C main-branch-option symbolic-ref HEAD >actual &&
     ++	echo refs/heads/hello >expect &&
     ++	test_cmp expect actual &&
      +
     -+test_expect_success 'invalid custom default branch name' '
     -+	test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \
     -+		git init custom-invalid 2>err &&
     -+	test_i18ngrep "invalid default branch name" err
     ++	: re-initializing should not change the main branch name &&
     ++	git init --main-branch=ignore main-branch-option 2>err &&
     ++	test_i18ngrep "ignoring --main-branch" err &&
     ++	git -C main-branch-option symbolic-ref HEAD >actual &&
     ++	grep hello actual &&
     ++	git -C main-branch-option config core.mainBranch >actual &&
     ++	grep hello actual
      +'
      +
       test_done
  -:  ----------- >  8:  c711eba7e76 init: allow overriding the default main branch name via the config
  6:  cce86c06bbf !  9:  0e59b618169 clone: learn about the possibly-configured default branch name
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    clone: learn about the possibly-configured default branch name
     +    clone: handle overridden main branch names
      
          When cloning a repository without any branches, Git chooses a default
          branch name for the as-yet unborn branch.
      
     -    Now that we can configure what the default branch name should be, we
     -    will want `git clone` to respect that setting.
     +    As part of the implicit initialization of the local repository, Git
     +    just learned to respect `init.defaultBranch` to choose a different main
     +    branch name. We now really want that branch name to be used as a
     +    fall-back.
     +
     +    At the same time, we also want to make sure that `core.mainBranch` is
     +    set correctly, reflecting the name of the main branch. In case we detect
     +    a main branch, we do have to do that explicitly, otherwise `init_db()`
     +    will already have done that for us.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     + ## Documentation/config/init.txt ##
     +@@ Documentation/config/init.txt: init.templateDir::
     + 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
     + 
     + init.defaultBranch::
     +-	Allows overriding the default branch name when initializing
     +-	a new repository.
     ++	Allows overriding the default branch name e.g. when initializing
     ++	a new repository or when cloning an empty repository.
     +
       ## builtin/clone.c ##
     +@@ builtin/clone.c: static void update_head(const struct ref *our, const struct ref *remote,
     + 		/* Local default branch link */
     + 		if (create_symref("HEAD", our->name, NULL) < 0)
     + 			die(_("unable to update HEAD"));
     ++		git_config_set("core.mainbranch", head);
     + 		if (!option_bare) {
     + 			update_ref(msg, "HEAD", &our->old_oid, NULL, 0,
     + 				   UPDATE_REFS_DIE_ON_ERR);
      @@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
       		remote_head_points_at = NULL;
       		remote_head = NULL;
     @@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
      -			install_branch_config(0, "master", option_origin,
      -					      "refs/heads/master");
      +		if (!option_bare) {
     -+			char *default_branch = git_default_branch_name(0);
     ++			char *main_branch =
     ++				git_main_branch_name(MAIN_BRANCH_FULL_NAME);
      +			const char *nick;
      +
     -+			if (!skip_prefix(default_branch, "refs/heads/", &nick))
     ++			if (!skip_prefix(main_branch, "refs/heads/", &nick))
      +				BUG("unexpected default branch '%s'",
     -+				    default_branch);
     ++				    main_branch);
      +			install_branch_config(0, nick, option_origin,
     -+					      default_branch);
     -+			free(default_branch);
     ++					      main_branch);
     ++			free(main_branch);
      +		}
       	}
       
       	write_refspec_config(src_ref_prefix, our_head_points_at,
      
     - ## t/t5609-clone-branch.sh ##
     -@@ t/t5609-clone-branch.sh: test_expect_success 'clone -b not allowed with empty repos' '
     - 	test_must_fail git clone -b branch empty clone-branch-empty
     + ## t/t5606-clone-options.sh ##
     +@@ t/t5606-clone-options.sh: test_expect_success 'redirected clone -v does show progress' '
     + 
       '
       
     -+test_expect_success 'chooses correct default branch name' '
     -+	GIT_TEST_DEFAULT_BRANCH_NAME= \
     -+		git -c core.defaultBranchName=up clone empty whats-up &&
     -+	test_write_lines refs/heads/up refs/heads/up >expect &&
     -+	git -C whats-up symbolic-ref HEAD >actual &&
     -+	git -C whats-up config branch.up.merge >>actual &&
     -+	test_cmp expect actual
     ++test_expect_success 'chooses correct default main branch name' '
     ++	git init --bare empty &&
     ++	git -c init.defaultBranch=up clone empty whats-up &&
     ++	test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) &&
     ++	test up = $(git -C whats-up config core.mainBranch) &&
     ++	test refs/heads/up = $(git -C whats-up config branch.up.merge)
     ++'
     ++
     ++test_expect_success 'guesses main branch name correctly' '
     ++	git init --main-branch=guess main-branch &&
     ++	test_commit -C main-branch no-spoilers &&
     ++	git -C main-branch branch abc guess &&
     ++	git clone main-branch is-it &&
     ++	test guess = $(git -C is-it config core.mainBranch) &&
     ++	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
      +'
      +
       test_done
  2:  06a2cea051c ! 10:  59b8f4cfbb2 remote: respect `core.defaultBranchName`
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    remote: respect `core.defaultBranchName`
     +    remote: learn about the possibly-overridden default main branch name
      
          When guessing the default branch name of a remote, and there are no refs
          to guess from, we want to go with the preference specified by the user
     -    for the fall-back.
     +    for the fall-back, i.e. the default name to be used for the main branch
     +    of new repositories (because as far as the user is concerned, a remote
     +    that has no branches yet is a new repository).
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     @@ remote.c: static void read_remotes_file(struct remote *remote)
       static void read_branches_file(struct remote *remote)
       {
      -	char *frag;
     -+	char *frag, *default_branch_name = NULL;
     ++	char *frag, *main_branch = NULL;
       	struct strbuf buf = STRBUF_INIT;
       	FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r");
       
     @@ remote.c: static void read_branches_file(struct remote *remote)
       	/*
       	 * The branches file would have URL and optionally
      -	 * #branch specified.  The "master" (or specified) branch is
     -+	 * #branch specified.  The default (or specified) branch is
     ++	 * #branch specified.  The main (or specified) branch is
       	 * fetched and stored in the local branch matching the
       	 * remote name.
       	 */
     @@ remote.c: static void read_branches_file(struct remote *remote)
       		*(frag++) = '\0';
       	else
      -		frag = "master";
     -+		frag = default_branch_name = git_default_branch_name(1);
     ++		frag = main_branch = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
       
       	add_url_alias(remote, strbuf_detach(&buf, NULL));
       	strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
     @@ remote.c: static void read_branches_file(struct remote *remote)
       	strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
       	refspec_append(&remote->push, buf.buf);
       	remote->fetch_tags = 1; /* always auto-follow */
     -+	free(default_branch_name);
     ++	free(main_branch);
       	strbuf_release(&buf);
       }
       
      @@ remote.c: struct ref *guess_remote_head(const struct ref *head,
     + 	if (head->symref)
     + 		return copy_ref(find_ref_by_name(refs, head->symref));
       
     - 	/* If refs/heads/master could be right, it is. */
     +-	/* If refs/heads/master could be right, it is. */
     ++	/* If a remote branch exists with the main branch name, let's use it. */
       	if (!all) {
      -		r = find_ref_by_name(refs, "refs/heads/master");
     -+		char *name = git_default_branch_name(0);
     ++		char *name = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
     ++						  MAIN_BRANCH_FOR_INIT);
      +
      +		r = find_ref_by_name(refs, name);
      +		free(name);
       		if (r && oideq(&r->old_oid, &head->old_oid))
       			return copy_ref(r);
       	}
     +
     + ## t/t5606-clone-options.sh ##
     +@@ t/t5606-clone-options.sh: test_expect_success 'guesses main branch name correctly' '
     + 	git -C main-branch branch abc guess &&
     + 	git clone main-branch is-it &&
     + 	test guess = $(git -C is-it config core.mainBranch) &&
     +-	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
     ++	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) &&
     ++
     ++	git -c init.defaultBranch=none init --bare no-head &&
     ++	git -C main-branch push ../no-head guess abc &&
     ++	git clone no-head is-it2 &&
     ++	test_must_fail git -C is-it2 symbolic-ref refs/remotes/origin/HEAD &&
     ++	git -C no-head update-ref --no-deref HEAD refs/heads/guess &&
     ++	git -c init.defaultBranch=guess clone no-head is-it3 &&
     ++	test refs/remotes/origin/guess = \
     ++		$(git -C is-it3 symbolic-ref refs/remotes/origin/HEAD)
     + '
     + 
     + test_done
  5:  06ef42052d5 ! 11:  59d6267f099 submodule: use the (possibly overridden) default branch name
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    submodule: use the (possibly overridden) default branch name
     +    submodule: use the correct default for the main branch name
      
          To allow for overriding the default branch name, we have introduced a
          config setting. With this patch, the `git submodule` command learns
     @@ builtin/submodule--helper.c: static const char *remote_submodule_branch(const ch
      -	if (!branch)
      -		return "master";
      +	if (!branch) {
     -+		static char *default_branch;
     ++		static char *fall_back;
      +
     -+		if (!default_branch)
     -+			default_branch = git_default_branch_name(1);
     ++		if (!fall_back)
     ++			fall_back = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
      +
     -+		return default_branch;
     ++		return fall_back;
      +	}
       
       	if (!strcmp(branch, ".")) {
       		const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
     +
     + ## t/t7406-submodule-update.sh ##
     +@@ t/t7406-submodule-update.sh: test_expect_success 'setup a submodule tree' '
     + 	)
     + '
     + 
     ++test_expect_success 'update --remote uses configured default main branch' '
     ++	git clone super main-branch &&
     ++	test_must_fail git -C main-branch -c init.defaultBranch=hello \
     ++		submodule update --init --remote submodule 2>err &&
     ++	test_i18ngrep origin/hello err
     ++'
     ++
     + test_expect_success 'submodule update detaching the HEAD ' '
     + 	(cd super/submodule &&
     + 	 git reset --hard HEAD~1
  4:  73cb567cd33 ! 12:  e09f857f068 testsvn: respect `core.defaultBranchName`
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    testsvn: respect `core.defaultBranchName`
     +    testsvn: respect `init.defaultBranch`
      
     -    Since the default branch name can now be configured, the `testsvn`
     -    remote helper needs to be told about it.
     +    The default name of the main branch in new repositories can now be
     +    configured. The `testsvn` remote helper translates the remote Subversion
     +    repository's branch name `trunk` to the hard-coded name `master`.
     +    Clearly, the intention was to make the name align with Git's detaults.
     +
     +    So while we are not talking about a newly-created repository in the
     +    `testsvn` context, it _still_ makes sense to use the overridden default
     +    name for the main branch whenever users configured it.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     @@ remote-testsvn.c: int cmd_main(int argc, const char **argv)
       			notes_ref_sb = STRBUF_INIT;
       	static struct remote *remote;
      -	const char *url_in;
     -+	const char *url_in, *default_branch;
     ++	const char *url_in, *remote_ref_short;
       
       	setup_git_directory();
       	if (argc < 2 || argc > 3) {
     @@ remote-testsvn.c: int cmd_main(int argc, const char **argv)
       		return 1;
       	}
       
     -+	remote_ref = git_default_branch_name(0);
     -+	if (!skip_prefix(remote_ref, "refs/heads/", &default_branch))
     ++	remote_ref = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
     ++					  MAIN_BRANCH_FOR_INIT);
     ++	if (!skip_prefix(remote_ref, "refs/heads/", &remote_ref_short))
      +		BUG("unexpected remote_ref '%s'", remote_ref);
      +
       	remote = remote_get(argv[1]);
     @@ remote-testsvn.c: int cmd_main(int argc, const char **argv)
       
      -	strbuf_addf(&private_ref_sb, "refs/svn/%s/master", remote->name);
      +	strbuf_addf(&private_ref_sb, "refs/svn/%s/%s",
     -+		    remote->name, default_branch);
     ++		    remote->name, remote_ref_short);
       	private_ref = private_ref_sb.buf;
       
       	strbuf_addf(&notes_ref_sb, "refs/notes/%s/revs", remote->name);
     +
     + ## t/t9020-remote-svn.sh ##
     +@@ t/t9020-remote-svn.sh: test_expect_success REMOTE_SVN 'incremental imports must lead to the same head'
     + 	test_cmp master.good .git/refs/remotes/svnsim/master
     + '
     + 
     ++test_expect_success REMOTE_SVN 'respects configured default main branch' '
     ++	git -c init.defaultBranch=trunk remote add -f trunk \
     ++		"testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" &&
     ++	git rev-parse --verify refs/remotes/trunk/trunk
     ++'
     ++
     + test_debug 'git branch -a'
     + 
     + test_done
  9:  f680e66dd6d <  -:  ----------- Document how the default branch name can be overridden

-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 01/12] fast-export: do anonymize the primary branch name
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Junio C Hamano via GitGitGadget
  2020-06-16 12:58     ` Jeff King
  2020-06-15 12:50   ` [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main " Johannes Schindelin via GitGitGadget
                     ` (11 subsequent siblings)
  12 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Junio C Hamano

From: Junio C Hamano <gitster@pobox.com>

In a fast-export stream with --anonymize option, all the end-user
data including refnames are munged to prevent exposure, but the
'master' branch is left intact.

There is a comment that explains why it is OK to leave 'master'
unanonymized (because everybody calls the primary branch 'master'
and it is no secret), but that does not justify why it is bad to
anonymize 'master' and make it indistinguishable from other
branches.  Assuming there _is_ a need to allow the readers of the
output to tell where the tip of the primary branch is, let's keep
the special casing of 'master', but still anonymize it to "ref0".
Because all other branches will be given ref+N where N is a positive
integer, this will keep the primary branch identifiable in the
output stream, without exposing what the name of the primary branch
is in the repository the export stream was taken from.

This is in preparation for introducing a mechanism to affect the
name of the primary branch used in the repository.  Once the
mechanism is in use, the name of the primary branch won't be
'master', and may not be allowed to be exposed.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/fast-export.c            | 9 +++++----
 t/t9351-fast-export-anonymize.sh | 9 +++++----
 2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 85868162eec..1072bbf041f 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len)
 {
 	static int counter;
 	struct strbuf out = STRBUF_INIT;
-	strbuf_addf(&out, "ref%d", counter++);
+	strbuf_addf(&out, "ref%d", ++counter);
 	return strbuf_detach(&out, len);
 }
 
@@ -518,11 +518,12 @@ static const char *anonymize_refname(const char *refname)
 	int i;
 
 	/*
-	 * We also leave "master" as a special case, since it does not reveal
-	 * anything interesting.
+	 * In certain circumstances, it might be interesting to be able to
+	 * identify the main branch. For that reason, let's force its name to
+	 * be anonymized to `ref0`.
 	 */
 	if (!strcmp(refname, "refs/heads/master"))
-		return refname;
+		return "refs/heads/ref0";
 
 	strbuf_reset(&anon);
 	for (i = 0; i < ARRAY_SIZE(prefixes); i++) {
diff --git a/t/t9351-fast-export-anonymize.sh b/t/t9351-fast-export-anonymize.sh
index 897dc509075..2415f0ec213 100755
--- a/t/t9351-fast-export-anonymize.sh
+++ b/t/t9351-fast-export-anonymize.sh
@@ -26,8 +26,9 @@ test_expect_success 'stream omits path names' '
 	! grep xyzzy stream
 '
 
-test_expect_success 'stream allows master as refname' '
-	grep master stream
+test_expect_success 'stream translates master to ref0' '
+	grep refs/heads/ref0 stream &&
+	! grep master stream
 '
 
 test_expect_success 'stream omits other refnames' '
@@ -57,7 +58,7 @@ test_expect_success 'import stream to new repository' '
 test_expect_success 'result has two branches' '
 	git for-each-ref --format="%(refname)" refs/heads >branches &&
 	test_line_count = 2 branches &&
-	other_branch=$(grep -v refs/heads/master branches)
+	other_branch=$(grep -v refs/heads/ref0 branches)
 '
 
 test_expect_success 'repo has original shape and timestamps' '
@@ -65,7 +66,7 @@ test_expect_success 'repo has original shape and timestamps' '
 		git log --format="%m %ct" --left-right --boundary "$@"
 	} &&
 	(cd .. && shape master...other) >expect &&
-	shape master...$other_branch >actual &&
+	shape ref0...$other_branch >actual &&
 	test_cmp expect actual
 '
 
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 01/12] fast-export: do anonymize the primary branch name Junio C Hamano via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-15 15:00     ` Phillip Wood
                       ` (4 more replies)
  2020-06-15 12:50   ` [PATCH v2 03/12] send-pack/transport-helper: respect `core.mainBranch` Johannes Schindelin via GitGitGadget
                     ` (10 subsequent siblings)
  12 siblings, 5 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

There is a growing number of projects and companies desiring to change
the main branch name of their repositories (see e.g.
https://twitter.com/mislav/status/1270388510684598272 for background on
this).

However, there are a couple of hard-coded spots in Git's source code
that make this endeavor harder than necessary. For example, when
formatting the commit message for merge commits, Git appends "into
<branch-name>" unless the current branch is the `master` branch.

Clearly, this is not what one wants when already having gone through all
the steps to manually rename the main branch (and taking care of all the
fall-out such as re-targeting existing Pull Requests).

Let's introduce a way to override Git's hard-coded default:
`core.mainBranch`.

We will start supporting this config option in the `git fmt-merge-msg`
command and successively adjust all other places where the main branch
name is hard-coded.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/config/core.txt |  5 +++++
 fmt-merge-msg.c               |  6 ++++--
 refs.c                        | 27 +++++++++++++++++++++++++++
 refs.h                        |  7 +++++++
 t/t6200-fmt-merge-msg.sh      |  7 +++++++
 5 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt
index 74619a9c03b..32bb5368ebb 100644
--- a/Documentation/config/core.txt
+++ b/Documentation/config/core.txt
@@ -626,3 +626,8 @@ core.abbrev::
 	in your repository, which hopefully is enough for
 	abbreviated object names to stay unique for some time.
 	The minimum length is 4.
+
+core.mainBranch::
+	The name of the main (or: primary) branch in the current repository.
+	For historical reasons, `master` is used as the fall-back for this
+	setting.
diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
index 72d32bd73b1..43f4f829242 100644
--- a/fmt-merge-msg.c
+++ b/fmt-merge-msg.c
@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
 				const char *current_branch)
 {
 	int i = 0;
-	char *sep = "";
+	char *sep = "", *main_branch;
 
 	strbuf_addstr(out, "Merge ");
 	for (i = 0; i < srcs.nr; i++) {
@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
 			strbuf_addf(out, " of %s", srcs.items[i].string);
 	}
 
-	if (!strcmp("master", current_branch))
+	main_branch = git_main_branch_name();
+	if (!strcmp(main_branch, current_branch))
 		strbuf_addch(out, '\n');
 	else
 		strbuf_addf(out, " into %s\n", current_branch);
+	free(main_branch);
 }
 
 static void fmt_tag_signature(struct strbuf *tagbuf,
diff --git a/refs.c b/refs.c
index 224ff66c7bb..f1854cffa2f 100644
--- a/refs.c
+++ b/refs.c
@@ -560,6 +560,33 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
 		argv_array_pushf(prefixes, *p, len, prefix);
 }
 
+char *repo_main_branch_name(struct repository *r)
+{
+	const char *config_key = "core.mainbranch";
+	const char *config_display_key = "core.mainBranch";
+	const char *fall_back = "master";
+	char *name = NULL, *ret;
+
+	if (repo_config_get_string(r, config_key, &name) < 0)
+		die(_("could not retrieve `%s`"), config_display_key);
+
+	ret = name ? name : xstrdup(fall_back);
+
+	if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
+		die(_("invalid branch name: %s = %s"),
+		    config_display_key, name);
+
+	if (name != ret)
+		free(name);
+
+	return ret;
+}
+
+char *git_main_branch_name(void)
+{
+	return repo_main_branch_name(the_repository);
+}
+
 /*
  * *string and *len will only be substituted, and *string returned (for
  * later free()ing) if the string passed in is a magic short-hand form
diff --git a/refs.h b/refs.h
index a92d2c74c83..a207ef01348 100644
--- a/refs.h
+++ b/refs.h
@@ -154,6 +154,13 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
 int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
 int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
 
+/*
+ * Retrieves the name of the main (or: primary) branch of the given
+ * repository.
+ */
+char *git_main_branch_name(void);
+char *repo_main_branch_name(struct repository *r);
+
 /*
  * A ref_transaction represents a collection of reference updates that
  * should succeed or fail together.
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index e4c2a6eca43..7a873f4a05c 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -158,6 +158,13 @@ test_expect_success 'setup FETCH_HEAD' '
 	git fetch . left
 '
 
+test_expect_success 'with overridden default branch name' '
+	test_when_finished "git switch master" &&
+	git switch -c default &&
+	git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual &&
+	! grep "into default" actual
+'
+
 test_expect_success 'merge.log=3 limits shortlog length' '
 	cat >expected <<-EOF &&
 	Merge branch ${apos}left${apos}
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 03/12] send-pack/transport-helper: respect `core.mainBranch`
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 01/12] fast-export: do anonymize the primary branch name Junio C Hamano via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main " Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 04/12] git_main_branch_name(): optionally report the full ref name Johannes Schindelin via GitGitGadget
                     ` (9 subsequent siblings)
  12 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When mentioning the main branch name in an error message, we want to go
with the preference specified by the user, only falling back to Git's
own, hard-coded default when none was configured explicitly.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 send-pack.c             | 6 +++++-
 t/t5528-push-default.sh | 7 +++++++
 transport-helper.c      | 6 +++++-
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/send-pack.c b/send-pack.c
index 0abee22283d..2532864c812 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -405,8 +405,12 @@ int send_pack(struct send_pack_args *args,
 	}
 
 	if (!remote_refs) {
+		char *branch_name = git_main_branch_name();
+
 		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
-			"Perhaps you should specify a branch such as 'master'.\n");
+			"Perhaps you should specify a branch such as '%s'.\n",
+			branch_name);
+		free(branch_name);
 		return 0;
 	}
 	if (args->atomic && !atomic_supported)
diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh
index 4d1e0c363ea..f7583b20f87 100755
--- a/t/t5528-push-default.sh
+++ b/t/t5528-push-default.sh
@@ -98,6 +98,13 @@ test_expect_success 'push from/to new branch with upstream, matching and simple'
 	test_push_failure upstream
 '
 
+test_expect_success '"matching" fails if none match' '
+	git init --bare empty &&
+	test_must_fail git -c core.mainBranch=unmatch push empty : 2>actual &&
+	needle="Perhaps you should specify a branch such as '\''unmatch'\''" &&
+	test_i18ngrep "$needle" actual
+'
+
 test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
 	git checkout -b ambiguous &&
 	test_config branch.ambiguous.remote parent1 &&
diff --git a/transport-helper.c b/transport-helper.c
index a46afcb69db..8c8f40e322d 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -1044,9 +1044,13 @@ static int push_refs(struct transport *transport,
 	}
 
 	if (!remote_refs) {
+		char *branch_name = git_main_branch_name();
+
 		fprintf(stderr,
 			_("No refs in common and none specified; doing nothing.\n"
-			  "Perhaps you should specify a branch such as 'master'.\n"));
+			  "Perhaps you should specify a branch such as '%s'.\n"),
+			branch_name);
+		free(branch_name);
 		return 0;
 	}
 
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 04/12] git_main_branch_name(): optionally report the full ref name
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (2 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 03/12] send-pack/transport-helper: respect `core.mainBranch` Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-15 15:04     ` Phillip Wood
  2020-06-15 12:50   ` [PATCH v2 05/12] fast-export: handle overridden main branch names correctly Johannes Schindelin via GitGitGadget
                     ` (8 subsequent siblings)
  12 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

We are about to introduce the first caller of that function (`git
fast-export`) that wants a full ref name instead of the short branch
name.

To make this change easier to review, let's refactor the function
accordingly without mixing in the actual first call using the new flag.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 fmt-merge-msg.c    |  2 +-
 refs.c             | 12 ++++++++----
 refs.h             |  8 ++++++--
 send-pack.c        |  2 +-
 transport-helper.c |  2 +-
 5 files changed, 17 insertions(+), 9 deletions(-)

diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
index 43f4f829242..03dba905643 100644
--- a/fmt-merge-msg.c
+++ b/fmt-merge-msg.c
@@ -451,7 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
 			strbuf_addf(out, " of %s", srcs.items[i].string);
 	}
 
-	main_branch = git_main_branch_name();
+	main_branch = git_main_branch_name(0);
 	if (!strcmp(main_branch, current_branch))
 		strbuf_addch(out, '\n');
 	else
diff --git a/refs.c b/refs.c
index f1854cffa2f..7da3ac178c4 100644
--- a/refs.c
+++ b/refs.c
@@ -560,8 +560,9 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
 		argv_array_pushf(prefixes, *p, len, prefix);
 }
 
-char *repo_main_branch_name(struct repository *r)
+char *repo_main_branch_name(struct repository *r, int flags)
 {
+	int full_name = flags & MAIN_BRANCH_FULL_NAME;
 	const char *config_key = "core.mainbranch";
 	const char *config_display_key = "core.mainBranch";
 	const char *fall_back = "master";
@@ -570,7 +571,10 @@ char *repo_main_branch_name(struct repository *r)
 	if (repo_config_get_string(r, config_key, &name) < 0)
 		die(_("could not retrieve `%s`"), config_display_key);
 
-	ret = name ? name : xstrdup(fall_back);
+	if (full_name)
+		ret = xstrfmt("refs/heads/%s", name ? name : fall_back);
+	else
+		ret = name ? name : xstrdup(fall_back);
 
 	if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
 		die(_("invalid branch name: %s = %s"),
@@ -582,9 +586,9 @@ char *repo_main_branch_name(struct repository *r)
 	return ret;
 }
 
-char *git_main_branch_name(void)
+char *git_main_branch_name(int flags)
 {
-	return repo_main_branch_name(the_repository);
+	return repo_main_branch_name(the_repository, flags);
 }
 
 /*
diff --git a/refs.h b/refs.h
index a207ef01348..96472f9a9f5 100644
--- a/refs.h
+++ b/refs.h
@@ -157,9 +157,13 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
 /*
  * Retrieves the name of the main (or: primary) branch of the given
  * repository.
+ *
+ * The result is an allocated string. Unless the flags ask for a short name, it
+ * will be prefixed with "refs/heads/".
  */
-char *git_main_branch_name(void);
-char *repo_main_branch_name(struct repository *r);
+#define MAIN_BRANCH_FULL_NAME (1<<0)
+char *git_main_branch_name(int flags);
+char *repo_main_branch_name(struct repository *r, int flags);
 
 /*
  * A ref_transaction represents a collection of reference updates that
diff --git a/send-pack.c b/send-pack.c
index 2532864c812..898720511d0 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -405,7 +405,7 @@ int send_pack(struct send_pack_args *args,
 	}
 
 	if (!remote_refs) {
-		char *branch_name = git_main_branch_name();
+		char *branch_name = git_main_branch_name(0);
 
 		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
 			"Perhaps you should specify a branch such as '%s'.\n",
diff --git a/transport-helper.c b/transport-helper.c
index 8c8f40e322d..7a54e5b2fb2 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -1044,7 +1044,7 @@ static int push_refs(struct transport *transport,
 	}
 
 	if (!remote_refs) {
-		char *branch_name = git_main_branch_name();
+		char *branch_name = git_main_branch_name(0);
 
 		fprintf(stderr,
 			_("No refs in common and none specified; doing nothing.\n"
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (3 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 04/12] git_main_branch_name(): optionally report the full ref name Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-15 15:05     ` Phillip Wood
  2020-06-15 17:09     ` Junio C Hamano
  2020-06-15 12:50   ` [PATCH v2 06/12] branch -m: adjust `core.mainBranch` if necessary Johannes Schindelin via GitGitGadget
                     ` (7 subsequent siblings)
  12 siblings, 2 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When anonymizing commit history, we are careful to translate the main
branch name to `ref0`.

When the main branch name is overridden via the config, we will want
`git fast-export` to use that overridden name instead.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/fast-export.c            | 11 ++++++++++-
 t/t9351-fast-export-anonymize.sh |  6 ++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 1072bbf041f..deeb01b6937 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname)
 	};
 	static struct hashmap refs;
 	static struct strbuf anon = STRBUF_INIT;
+	static char *main_branch;
 	int i;
 
 	/*
 	 * In certain circumstances, it might be interesting to be able to
 	 * identify the main branch. For that reason, let's force its name to
 	 * be anonymized to `ref0`.
+	 *
+	 * While the main branch name might often be `main` for new
+	 * repositories (and `master` for aged ones), and such well-known names
+	 * may not necessarily need anonymizing, it could be configured to use
+	 * a secret word that the user may not want to reveal.
 	 */
-	if (!strcmp(refname, "refs/heads/master"))
+	if (!main_branch)
+		main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
+
+	if (!strcmp(refname, main_branch))
 		return "refs/heads/ref0";
 
 	strbuf_reset(&anon);
diff --git a/t/t9351-fast-export-anonymize.sh b/t/t9351-fast-export-anonymize.sh
index 2415f0ec213..f42be635c2f 100755
--- a/t/t9351-fast-export-anonymize.sh
+++ b/t/t9351-fast-export-anonymize.sh
@@ -31,6 +31,12 @@ test_expect_success 'stream translates master to ref0' '
 	! grep master stream
 '
 
+test_expect_success 'respects configured main branch' '
+	git -c core.mainBranch=does-not-exist \
+		fast-export --anonymize --all >stream-without-ref0 &&
+	! grep ref0 stream-without-ref0
+'
+
 test_expect_success 'stream omits other refnames' '
 	! grep other stream &&
 	! grep mytag stream
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 06/12] branch -m: adjust `core.mainBranch` if necessary
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (4 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 05/12] fast-export: handle overridden main branch names correctly Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 07/12] init: allow specifying the main branch name for the new repository Johannes Schindelin via GitGitGadget
                     ` (6 subsequent siblings)
  12 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When renaming the main branch (as possibly identified by the
`core.mainBranch` setting), we will want to record that the main branch
now has a different name.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/branch.c  | 9 +++++++++
 t/t3200-branch.sh | 9 +++++++++
 2 files changed, 18 insertions(+)

diff --git a/builtin/branch.c b/builtin/branch.c
index accb61b1aae..62f8db5fb05 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -556,6 +556,15 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 	    replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch renamed to %s, but HEAD is not updated!"), newname);
 
+	if (!copy) {
+		char *main_branch = git_main_branch_name(0);
+
+		if (!strcmp(interpreted_oldname, main_branch))
+		    git_config_set("core.mainbranch", interpreted_newname);
+
+		free(main_branch);
+	}
+
 	strbuf_release(&logmsg);
 
 	strbuf_addf(&oldsection, "branch.%s", interpreted_oldname);
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index 411a70b0ce9..328544f2736 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -467,6 +467,15 @@ EOF
 	test_cmp expect actual
 '
 
+test_expect_success 'renaming the main branch modifies core.mainBranch' '
+	git init rename-main &&
+	test_commit -C rename-main initial &&
+	git -C rename-main branch -m trunk &&
+	git -C rename-main config core.mainBranch >actual &&
+	echo trunk >expect &&
+	test_cmp expect actual
+'
+
 test_expect_success 'git branch -c dumps usage' '
 	test_expect_code 128 git branch -c 2>err &&
 	test_i18ngrep "branch name required" err
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 07/12] init: allow specifying the main branch name for the new repository
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (5 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 06/12] branch -m: adjust `core.mainBranch` if necessary Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 08/12] init: allow overriding the default main branch name via the config Don Goodman-Wilson via GitGitGadget
                     ` (5 subsequent siblings)
  12 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

There is a growing number of projects trying to avoid the non-inclusive
name `master` in their repositories: The `master`/`slave` terminology is
insensitive and perpetuates injustice. This `master`/`slave` idea is
actually where Git's naming comes from, as it was inherited from
BitKeeper which uses the term in exactly this way, see
https://mail.gnome.org/archives/desktop-devel-list/2019-May/msg00066.html

To change that branch name for new repositories, currently the only way
to do that automatically is by copying all of Git's template directory,
then hard-coding the desired default branch name into the `.git/HEAD`
file, and then configuring `init.templateDir` to point to those copied
template files.

To make this process much less cumbersome, let's introduce a new option:
`--main-branch=<branch-name>`.

This will not only initialize the repository with the specified initial
branch; It will also record that branch name in `core.mainBranch`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-init.txt |  7 +++++++
 builtin/clone.c            |  3 ++-
 builtin/init-db.c          | 34 +++++++++++++++++++++++++++-------
 cache.h                    |  2 +-
 t/t0001-init.sh            | 15 +++++++++++++++
 5 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index adc6adfd380..011a7ff4d76 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 [verse]
 'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
 	  [--separate-git-dir <git dir>] [--object-format=<format]
+	  [-b <branch-name> | --main-branch=<branch-name>]
 	  [--shared[=<permissions>]] [directory]
 
 
@@ -67,6 +68,12 @@ repository.
 +
 If this is reinitialization, the repository will be moved to the specified path.
 
+-b <branch-name::
+--main-branch=<branch-name>::
+
+Use the specified name for the main (or: initial) branch in the newly created
+repository. If not specified, fall back to the default name: `master`.
+
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
 Specify that the Git repository is to be shared amongst several users.  This
diff --git a/builtin/clone.c b/builtin/clone.c
index cb48a291caf..487b0a42d75 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1108,7 +1108,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
+	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
+		INIT_DB_QUIET);
 
 	if (real_git_dir)
 		git_dir = real_git_dir;
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 0b7222e7188..287cdafaab1 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)
 
 static int create_default_files(const char *template_path,
 				const char *original_git_dir,
+				const char *main_branch,
 				const struct repository_format *fmt)
 {
 	struct stat st1;
@@ -258,16 +259,29 @@ static int create_default_files(const char *template_path,
 		die("failed to set up refs db: %s", err.buf);
 
 	/*
-	 * Create the default symlink from ".git/HEAD" to the "master"
-	 * branch, if it does not exist yet.
+	 * Create the default symlink from ".git/HEAD" to the default
+	 * branch name, if it does not exist yet.
 	 */
 	path = git_path_buf(&buf, "HEAD");
 	reinit = (!access(path, R_OK)
 		  || readlink(path, junk, sizeof(junk)-1) != -1);
 	if (!reinit) {
-		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
+		char *ref;
+
+		if (!main_branch)
+			main_branch = "master";
+
+		ref = xstrfmt("refs/heads/%s", main_branch);
+		if (check_refname_format(ref, 0) < 0)
+			die(_("invalid main branch name: '%s'"), main_branch);
+
+		if (create_symref("HEAD", ref, NULL) < 0)
 			exit(1);
-	}
+		free(ref);
+
+		git_config_set("core.mainbranch", main_branch);
+	} else if (main_branch)
+		warning(_("re-init: ignoring --main-branch=%s"), main_branch);
 
 	initialize_repository_version(fmt->hash_algo);
 
@@ -383,7 +397,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
 }
 
 int init_db(const char *git_dir, const char *real_git_dir,
-	    const char *template_dir, int hash, unsigned int flags)
+	    const char *template_dir, int hash, const char *main_branch,
+	    unsigned int flags)
 {
 	int reinit;
 	int exist_ok = flags & INIT_DB_EXIST_OK;
@@ -425,7 +440,8 @@ int init_db(const char *git_dir, const char *real_git_dir,
 
 	validate_hash_algorithm(&repo_fmt, hash);
 
-	reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
+	reinit = create_default_files(template_dir, original_git_dir,
+				      main_branch, &repo_fmt);
 
 	create_object_directory();
 
@@ -528,6 +544,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	const char *template_dir = NULL;
 	unsigned int flags = 0;
 	const char *object_format = NULL;
+	const char *main_branch = NULL;
 	int hash_algo = GIT_HASH_UNKNOWN;
 	const struct option init_db_options[] = {
 		OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ -541,6 +558,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 		OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
 		OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
 			   N_("separate git dir from working tree")),
+		OPT_STRING('b', "main-branch", &main_branch, N_("name"),
+			   N_("override the name of the main branch")),
 		OPT_STRING(0, "object-format", &object_format, N_("hash"),
 			   N_("specify the hash algorithm to use")),
 		OPT_END()
@@ -652,5 +671,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	UNLEAK(work_tree);
 
 	flags |= INIT_DB_EXIST_OK;
-	return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
+	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
+		       main_branch, flags);
 }
diff --git a/cache.h b/cache.h
index 0f0485ecfe2..afd5ad3121f 100644
--- a/cache.h
+++ b/cache.h
@@ -628,7 +628,7 @@ int path_inside_repo(const char *prefix, const char *path);
 
 int init_db(const char *git_dir, const char *real_git_dir,
 	    const char *template_dir, int hash_algo,
-	    unsigned int flags);
+	    const char *main_branch, unsigned int flags);
 void initialize_repository_version(int hash_algo);
 
 void sanitize_stdfds(void);
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 1edd5aeb8f0..5d8e321a703 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -464,4 +464,19 @@ test_expect_success MINGW 'redirect std handles' '
 	grep "Needed a single revision" output.txt
 '
 
+test_expect_success '--main-branch' '
+	git init --main-branch=hello main-branch-option &&
+	git -C main-branch-option symbolic-ref HEAD >actual &&
+	echo refs/heads/hello >expect &&
+	test_cmp expect actual &&
+
+	: re-initializing should not change the main branch name &&
+	git init --main-branch=ignore main-branch-option 2>err &&
+	test_i18ngrep "ignoring --main-branch" err &&
+	git -C main-branch-option symbolic-ref HEAD >actual &&
+	grep hello actual &&
+	git -C main-branch-option config core.mainBranch >actual &&
+	grep hello actual
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 08/12] init: allow overriding the default main branch name via the config
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (6 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 07/12] init: allow specifying the main branch name for the new repository Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Don Goodman-Wilson via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 09/12] clone: handle overridden main branch names Johannes Schindelin via GitGitGadget
                     ` (4 subsequent siblings)
  12 siblings, 0 replies; 178+ messages in thread
From: Don Goodman-Wilson via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Don Goodman-Wilson

From: Don Goodman-Wilson <don@goodman-wilson.com>

We just introduced the command-line option `--main-branch=<branch-name>`
to allow initializing a new repository with a different initial branch
than the hard-coded one.

To allow users to override the default main branch name more permanently
(i.e. without having to specify the name manually for each and every
`git init` invocation), let's introduce the `init.defaultBranch` config
setting.

Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
---
 Documentation/config/init.txt |  4 ++++
 builtin/init-db.c             |  6 ++++--
 refs.c                        |  7 +++++--
 refs.h                        |  4 ++++
 t/t0001-init.sh               | 16 ++++++++++++++++
 5 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt
index 46fa8c6a082..6ae4a38416e 100644
--- a/Documentation/config/init.txt
+++ b/Documentation/config/init.txt
@@ -1,3 +1,7 @@
 init.templateDir::
 	Specify the directory from which templates will be copied.
 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+
+init.defaultBranch::
+	Allows overriding the default branch name when initializing
+	a new repository.
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 287cdafaab1..d09c9dc7845 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -266,10 +266,11 @@ static int create_default_files(const char *template_path,
 	reinit = (!access(path, R_OK)
 		  || readlink(path, junk, sizeof(junk)-1) != -1);
 	if (!reinit) {
-		char *ref;
+		char *ref, *fall_back = NULL;
 
 		if (!main_branch)
-			main_branch = "master";
+			main_branch = fall_back =
+				git_main_branch_name(MAIN_BRANCH_FOR_INIT);
 
 		ref = xstrfmt("refs/heads/%s", main_branch);
 		if (check_refname_format(ref, 0) < 0)
@@ -280,6 +281,7 @@ static int create_default_files(const char *template_path,
 		free(ref);
 
 		git_config_set("core.mainbranch", main_branch);
+		free(fall_back);
 	} else if (main_branch)
 		warning(_("re-init: ignoring --main-branch=%s"), main_branch);
 
diff --git a/refs.c b/refs.c
index 7da3ac178c4..4b0e5b14062 100644
--- a/refs.c
+++ b/refs.c
@@ -563,8 +563,11 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
 char *repo_main_branch_name(struct repository *r, int flags)
 {
 	int full_name = flags & MAIN_BRANCH_FULL_NAME;
-	const char *config_key = "core.mainbranch";
-	const char *config_display_key = "core.mainBranch";
+	int for_init = flags & MAIN_BRANCH_FOR_INIT;
+	const char *config_key = for_init ?
+		 "init.defaultbranch" : "core.mainbranch";
+	const char *config_display_key = for_init ?
+		 "init.defaultBranch" : "core.mainBranch";
 	const char *fall_back = "master";
 	char *name = NULL, *ret;
 
diff --git a/refs.h b/refs.h
index 96472f9a9f5..c801d08490c 100644
--- a/refs.h
+++ b/refs.h
@@ -158,10 +158,14 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
  * Retrieves the name of the main (or: primary) branch of the given
  * repository.
  *
+ * To obtain the default for newly-initialized repositories, pass the flag
+ * `MAIN_BRANCH_FOR_INIT`.
+ *
  * The result is an allocated string. Unless the flags ask for a short name, it
  * will be prefixed with "refs/heads/".
  */
 #define MAIN_BRANCH_FULL_NAME (1<<0)
+#define MAIN_BRANCH_FOR_INIT   (1<<1)
 char *git_main_branch_name(int flags);
 char *repo_main_branch_name(struct repository *r, int flags);
 
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 5d8e321a703..fbf02066940 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -479,4 +479,20 @@ test_expect_success '--main-branch' '
 	grep hello actual
 '
 
+test_expect_success 'overridden default main branch name (config)' '
+	test_config_global init.defaultBranch nmb &&
+	git init main-branch-config &&
+	git -C main-branch-config symbolic-ref HEAD >actual &&
+	grep nmb actual &&
+	git -C main-branch-config config core.mainBranch >actual &&
+	echo nmb >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'invalid default branch name' '
+	test_config_global init.defaultBranch "with space" &&
+	test_must_fail git init main-branch-invalid 2>err &&
+	test_i18ngrep "invalid branch name" err
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 09/12] clone: handle overridden main branch names
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (7 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 08/12] init: allow overriding the default main branch name via the config Don Goodman-Wilson via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-16 13:22     ` Jeff King
  2020-06-15 12:50   ` [PATCH v2 10/12] remote: learn about the possibly-overridden default main branch name Johannes Schindelin via GitGitGadget
                     ` (3 subsequent siblings)
  12 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When cloning a repository without any branches, Git chooses a default
branch name for the as-yet unborn branch.

As part of the implicit initialization of the local repository, Git
just learned to respect `init.defaultBranch` to choose a different main
branch name. We now really want that branch name to be used as a
fall-back.

At the same time, we also want to make sure that `core.mainBranch` is
set correctly, reflecting the name of the main branch. In case we detect
a main branch, we do have to do that explicitly, otherwise `init_db()`
will already have done that for us.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/config/init.txt |  4 ++--
 builtin/clone.c               | 16 +++++++++++++---
 t/t5606-clone-options.sh      | 17 +++++++++++++++++
 3 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt
index 6ae4a38416e..dc77f8c8446 100644
--- a/Documentation/config/init.txt
+++ b/Documentation/config/init.txt
@@ -3,5 +3,5 @@ init.templateDir::
 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
 
 init.defaultBranch::
-	Allows overriding the default branch name when initializing
-	a new repository.
+	Allows overriding the default branch name e.g. when initializing
+	a new repository or when cloning an empty repository.
diff --git a/builtin/clone.c b/builtin/clone.c
index 487b0a42d75..755fcaeb0ba 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -718,6 +718,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
 		/* Local default branch link */
 		if (create_symref("HEAD", our->name, NULL) < 0)
 			die(_("unable to update HEAD"));
+		git_config_set("core.mainbranch", head);
 		if (!option_bare) {
 			update_ref(msg, "HEAD", &our->old_oid, NULL, 0,
 				   UPDATE_REFS_DIE_ON_ERR);
@@ -1264,9 +1265,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head_points_at = NULL;
 		remote_head = NULL;
 		option_no_checkout = 1;
-		if (!option_bare)
-			install_branch_config(0, "master", option_origin,
-					      "refs/heads/master");
+		if (!option_bare) {
+			char *main_branch =
+				git_main_branch_name(MAIN_BRANCH_FULL_NAME);
+			const char *nick;
+
+			if (!skip_prefix(main_branch, "refs/heads/", &nick))
+				BUG("unexpected default branch '%s'",
+				    main_branch);
+			install_branch_config(0, nick, option_origin,
+					      main_branch);
+			free(main_branch);
+		}
 	}
 
 	write_refspec_config(src_ref_prefix, our_head_points_at,
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 9e24ec88e67..98b2d8527f6 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -35,4 +35,21 @@ test_expect_success 'redirected clone -v does show progress' '
 
 '
 
+test_expect_success 'chooses correct default main branch name' '
+	git init --bare empty &&
+	git -c init.defaultBranch=up clone empty whats-up &&
+	test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) &&
+	test up = $(git -C whats-up config core.mainBranch) &&
+	test refs/heads/up = $(git -C whats-up config branch.up.merge)
+'
+
+test_expect_success 'guesses main branch name correctly' '
+	git init --main-branch=guess main-branch &&
+	test_commit -C main-branch no-spoilers &&
+	git -C main-branch branch abc guess &&
+	git clone main-branch is-it &&
+	test guess = $(git -C is-it config core.mainBranch) &&
+	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 10/12] remote: learn about the possibly-overridden default main branch name
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (8 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 09/12] clone: handle overridden main branch names Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-15 12:50   ` [PATCH v2 11/12] submodule: use the correct default for the " Johannes Schindelin via GitGitGadget
                     ` (2 subsequent siblings)
  12 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When guessing the default branch name of a remote, and there are no refs
to guess from, we want to go with the preference specified by the user
for the fall-back, i.e. the default name to be used for the main branch
of new repositories (because as far as the user is concerned, a remote
that has no branches yet is a new repository).

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 remote.c                 | 15 ++++++++++-----
 t/t5606-clone-options.sh | 11 ++++++++++-
 2 files changed, 20 insertions(+), 6 deletions(-)

diff --git a/remote.c b/remote.c
index 534c6426f1e..2dcf4ac6d15 100644
--- a/remote.c
+++ b/remote.c
@@ -256,7 +256,7 @@ static void read_remotes_file(struct remote *remote)
 
 static void read_branches_file(struct remote *remote)
 {
-	char *frag;
+	char *frag, *main_branch = NULL;
 	struct strbuf buf = STRBUF_INIT;
 	FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r");
 
@@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)
 
 	/*
 	 * The branches file would have URL and optionally
-	 * #branch specified.  The "master" (or specified) branch is
+	 * #branch specified.  The main (or specified) branch is
 	 * fetched and stored in the local branch matching the
 	 * remote name.
 	 */
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
 	if (frag)
 		*(frag++) = '\0';
 	else
-		frag = "master";
+		frag = main_branch = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
 	strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ -299,6 +299,7 @@ static void read_branches_file(struct remote *remote)
 	strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
 	refspec_append(&remote->push, buf.buf);
 	remote->fetch_tags = 1; /* always auto-follow */
+	free(main_branch);
 	strbuf_release(&buf);
 }
 
@@ -2097,9 +2098,13 @@ struct ref *guess_remote_head(const struct ref *head,
 	if (head->symref)
 		return copy_ref(find_ref_by_name(refs, head->symref));
 
-	/* If refs/heads/master could be right, it is. */
+	/* If a remote branch exists with the main branch name, let's use it. */
 	if (!all) {
-		r = find_ref_by_name(refs, "refs/heads/master");
+		char *name = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
+						  MAIN_BRANCH_FOR_INIT);
+
+		r = find_ref_by_name(refs, name);
+		free(name);
 		if (r && oideq(&r->old_oid, &head->old_oid))
 			return copy_ref(r);
 	}
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 98b2d8527f6..61ce9c09920 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -49,7 +49,16 @@ test_expect_success 'guesses main branch name correctly' '
 	git -C main-branch branch abc guess &&
 	git clone main-branch is-it &&
 	test guess = $(git -C is-it config core.mainBranch) &&
-	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
+	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) &&
+
+	git -c init.defaultBranch=none init --bare no-head &&
+	git -C main-branch push ../no-head guess abc &&
+	git clone no-head is-it2 &&
+	test_must_fail git -C is-it2 symbolic-ref refs/remotes/origin/HEAD &&
+	git -C no-head update-ref --no-deref HEAD refs/heads/guess &&
+	git -c init.defaultBranch=guess clone no-head is-it3 &&
+	test refs/remotes/origin/guess = \
+		$(git -C is-it3 symbolic-ref refs/remotes/origin/HEAD)
 '
 
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 11/12] submodule: use the correct default for the main branch name
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (9 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 10/12] remote: learn about the possibly-overridden default main branch name Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-16 13:46     ` Jeff King
  2020-06-15 12:50   ` [PATCH v2 12/12] testsvn: respect `init.defaultBranch` Johannes Schindelin via GitGitGadget
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  12 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

To allow for overriding the default branch name, we have introduced a
config setting. With this patch, the `git submodule` command learns
about this, too.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/submodule--helper.c | 10 ++++++++--
 t/t7406-submodule-update.sh |  7 +++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 46c03d2a126..48d73e8d9cb 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1980,8 +1980,14 @@ static const char *remote_submodule_branch(const char *path)
 		branch = sub->branch;
 	free(key);
 
-	if (!branch)
-		return "master";
+	if (!branch) {
+		static char *fall_back;
+
+		if (!fall_back)
+			fall_back = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
+
+		return fall_back;
+	}
 
 	if (!strcmp(branch, ".")) {
 		const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 4fb447a143e..641113afef4 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -70,6 +70,13 @@ test_expect_success 'setup a submodule tree' '
 	)
 '
 
+test_expect_success 'update --remote uses configured default main branch' '
+	git clone super main-branch &&
+	test_must_fail git -C main-branch -c init.defaultBranch=hello \
+		submodule update --init --remote submodule 2>err &&
+	test_i18ngrep origin/hello err
+'
+
 test_expect_success 'submodule update detaching the HEAD ' '
 	(cd super/submodule &&
 	 git reset --hard HEAD~1
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v2 12/12] testsvn: respect `init.defaultBranch`
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (10 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 11/12] submodule: use the correct default for the " Johannes Schindelin via GitGitGadget
@ 2020-06-15 12:50   ` Johannes Schindelin via GitGitGadget
  2020-06-16 13:51     ` Jeff King
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  12 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-15 12:50 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

The default name of the main branch in new repositories can now be
configured. The `testsvn` remote helper translates the remote Subversion
repository's branch name `trunk` to the hard-coded name `master`.
Clearly, the intention was to make the name align with Git's detaults.

So while we are not talking about a newly-created repository in the
`testsvn` context, it _still_ makes sense to use the overridden default
name for the main branch whenever users configured it.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 remote-testsvn.c      | 12 +++++++++---
 t/t9020-remote-svn.sh |  6 ++++++
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/remote-testsvn.c b/remote-testsvn.c
index 3af708c5b67..6ec300bf6c3 100644
--- a/remote-testsvn.c
+++ b/remote-testsvn.c
@@ -13,7 +13,7 @@
 static const char *url;
 static int dump_from_file;
 static const char *private_ref;
-static const char *remote_ref = "refs/heads/master";
+static char *remote_ref;
 static const char *marksfilename, *notes_ref;
 struct rev_note { unsigned int rev_nr; };
 
@@ -286,7 +286,7 @@ int cmd_main(int argc, const char **argv)
 			private_ref_sb = STRBUF_INIT, marksfilename_sb = STRBUF_INIT,
 			notes_ref_sb = STRBUF_INIT;
 	static struct remote *remote;
-	const char *url_in;
+	const char *url_in, *remote_ref_short;
 
 	setup_git_directory();
 	if (argc < 2 || argc > 3) {
@@ -294,6 +294,11 @@ int cmd_main(int argc, const char **argv)
 		return 1;
 	}
 
+	remote_ref = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
+					  MAIN_BRANCH_FOR_INIT);
+	if (!skip_prefix(remote_ref, "refs/heads/", &remote_ref_short))
+		BUG("unexpected remote_ref '%s'", remote_ref);
+
 	remote = remote_get(argv[1]);
 	url_in = (argc == 3) ? argv[2] : remote->url[0];
 
@@ -306,7 +311,8 @@ int cmd_main(int argc, const char **argv)
 		url = url_sb.buf;
 	}
 
-	strbuf_addf(&private_ref_sb, "refs/svn/%s/master", remote->name);
+	strbuf_addf(&private_ref_sb, "refs/svn/%s/%s",
+		    remote->name, remote_ref_short);
 	private_ref = private_ref_sb.buf;
 
 	strbuf_addf(&notes_ref_sb, "refs/notes/%s/revs", remote->name);
diff --git a/t/t9020-remote-svn.sh b/t/t9020-remote-svn.sh
index 6fca08e5e35..c931193f013 100755
--- a/t/t9020-remote-svn.sh
+++ b/t/t9020-remote-svn.sh
@@ -84,6 +84,12 @@ test_expect_success REMOTE_SVN 'incremental imports must lead to the same head'
 	test_cmp master.good .git/refs/remotes/svnsim/master
 '
 
+test_expect_success REMOTE_SVN 'respects configured default main branch' '
+	git -c init.defaultBranch=trunk remote add -f trunk \
+		"testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" &&
+	git rev-parse --verify refs/remotes/trunk/trunk
+'
+
 test_debug 'git branch -a'
 
 test_done
-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-15 12:50   ` [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main " Johannes Schindelin via GitGitGadget
@ 2020-06-15 15:00     ` Phillip Wood
  2020-06-23 12:31       ` Johannes Schindelin
  2020-06-15 17:05     ` Junio C Hamano
                       ` (3 subsequent siblings)
  4 siblings, 1 reply; 178+ messages in thread
From: Phillip Wood @ 2020-06-15 15:00 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget, git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Alban Gruin, Johannes Sixt, Johannes Schindelin

Hi dscho

On 15/06/2020 13:50, Johannes Schindelin via GitGitGadget wrote:
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> There is a growing number of projects and companies desiring to change
> the main branch name of their repositories (see e.g.
> https://twitter.com/mislav/status/1270388510684598272 for background on
> this).

I think this is a good way of phrasing the rationale for the change

> However, there are a couple of hard-coded spots in Git's source code
> that make this endeavor harder than necessary. For example, when
> formatting the commit message for merge commits, Git appends "into
> <branch-name>" unless the current branch is the `master` branch.
> 
> Clearly, this is not what one wants when already having gone through all
> the steps to manually rename the main branch

This didn't quite scan for me maybe s/already having/one has already/ ?

> (and taking care of all the
> fall-out such as re-targeting existing Pull Requests).
> 
> Let's introduce a way to override Git's hard-coded default:
> `core.mainBranch`.
> 
> We will start supporting this config option in the `git fmt-merge-msg`
> command and successively adjust all other places where the main branch
> name is hard-coded.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>   Documentation/config/core.txt |  5 +++++
>   fmt-merge-msg.c               |  6 ++++--
>   refs.c                        | 27 +++++++++++++++++++++++++++
>   refs.h                        |  7 +++++++
>   t/t6200-fmt-merge-msg.sh      |  7 +++++++
>   5 files changed, 50 insertions(+), 2 deletions(-)
> 
> diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt
> index 74619a9c03b..32bb5368ebb 100644
> --- a/Documentation/config/core.txt
> +++ b/Documentation/config/core.txt
> @@ -626,3 +626,8 @@ core.abbrev::
>   	in your repository, which hopefully is enough for
>   	abbreviated object names to stay unique for some time.
>   	The minimum length is 4.
> +
> +core.mainBranch::
> +	The name of the main (or: primary) branch in the current repository.
> +	For historical reasons, `master` is used as the fall-back for this
> +	setting.
> diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
> index 72d32bd73b1..43f4f829242 100644
> --- a/fmt-merge-msg.c
> +++ b/fmt-merge-msg.c
> @@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
>   				const char *current_branch)
>   {
>   	int i = 0;
> -	char *sep = "";
> +	char *sep = "", *main_branch;
>   
>   	strbuf_addstr(out, "Merge ");
>   	for (i = 0; i < srcs.nr; i++) {
> @@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
>   			strbuf_addf(out, " of %s", srcs.items[i].string);
>   	}
>   
> -	if (!strcmp("master", current_branch))
> +	main_branch = git_main_branch_name();
> +	if (!strcmp(main_branch, current_branch))
>   		strbuf_addch(out, '\n');
>   	else
>   		strbuf_addf(out, " into %s\n", current_branch);
> +	free(main_branch);
>   }
>   
>   static void fmt_tag_signature(struct strbuf *tagbuf,
> diff --git a/refs.c b/refs.c
> index 224ff66c7bb..f1854cffa2f 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -560,6 +560,33 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
>   		argv_array_pushf(prefixes, *p, len, prefix);
>   }
>   
> +char *repo_main_branch_name(struct repository *r)
> +{
> +	const char *config_key = "core.mainbranch";
> +	const char *config_display_key = "core.mainBranch";
> +	const char *fall_back = "master";
> +	char *name = NULL, *ret;
> +
> +	if (repo_config_get_string(r, config_key, &name) < 0)
> +		die(_("could not retrieve `%s`"), config_display_key);
> +
> +	ret = name ? name : xstrdup(fall_back);
> +
> +	if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
> +		die(_("invalid branch name: %s = %s"),
> +		    config_display_key, name);
> +
> +	if (name != ret)
> +		free(name);

I'm struggling to come up with a scenario where name != NULL && name != 
ret here, however once we get to patch 4 that scenario definitely does 
exist.

> +
> +	return ret;
> +}
> +
> +char *git_main_branch_name(void)
> +{
> +	return repo_main_branch_name(the_repository);
> +}
> +
>   /*
>    * *string and *len will only be substituted, and *string returned (for
>    * later free()ing) if the string passed in is a magic short-hand form
> diff --git a/refs.h b/refs.h
> index a92d2c74c83..a207ef01348 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -154,6 +154,13 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
>   int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
>   int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
>   
> +/*
> + * Retrieves the name of the main (or: primary) branch of the given

nit pick, I'm confused by the ':'

Best Wishes

Phillip

> + * repository.
> + */
> +char *git_main_branch_name(void);
> +char *repo_main_branch_name(struct repository *r);
> +
>   /*
>    * A ref_transaction represents a collection of reference updates that
>    * should succeed or fail together.
> diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
> index e4c2a6eca43..7a873f4a05c 100755
> --- a/t/t6200-fmt-merge-msg.sh
> +++ b/t/t6200-fmt-merge-msg.sh
> @@ -158,6 +158,13 @@ test_expect_success 'setup FETCH_HEAD' '
>   	git fetch . left
>   '
>   
> +test_expect_success 'with overridden default branch name' '
> +	test_when_finished "git switch master" &&
> +	git switch -c default &&
> +	git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual &&
> +	! grep "into default" actual
> +'
> +
>   test_expect_success 'merge.log=3 limits shortlog length' '
>   	cat >expected <<-EOF &&
>   	Merge branch ${apos}left${apos}
> 

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 04/12] git_main_branch_name(): optionally report the full ref name
  2020-06-15 12:50   ` [PATCH v2 04/12] git_main_branch_name(): optionally report the full ref name Johannes Schindelin via GitGitGadget
@ 2020-06-15 15:04     ` Phillip Wood
  2020-06-23 19:17       ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Phillip Wood @ 2020-06-15 15:04 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget, git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Alban Gruin, Johannes Sixt, Johannes Schindelin

Hi dscho

On 15/06/2020 13:50, Johannes Schindelin via GitGitGadget wrote:
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> We are about to introduce the first caller of that function (`git
> fast-export`) that wants a full ref name instead of the short branch
> name.
> 
> To make this change easier to review, let's refactor the function
> accordingly without mixing in the actual first call using the new flag.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>   fmt-merge-msg.c    |  2 +-
>   refs.c             | 12 ++++++++----
>   refs.h             |  8 ++++++--
>   send-pack.c        |  2 +-
>   transport-helper.c |  2 +-
>   5 files changed, 17 insertions(+), 9 deletions(-)
> 
> diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
> index 43f4f829242..03dba905643 100644
> --- a/fmt-merge-msg.c
> +++ b/fmt-merge-msg.c
> @@ -451,7 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
>   			strbuf_addf(out, " of %s", srcs.items[i].string);
>   	}
>   
> -	main_branch = git_main_branch_name();
> +	main_branch = git_main_branch_name(0);
>   	if (!strcmp(main_branch, current_branch))
>   		strbuf_addch(out, '\n');
>   	else
> diff --git a/refs.c b/refs.c
> index f1854cffa2f..7da3ac178c4 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -560,8 +560,9 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
>   		argv_array_pushf(prefixes, *p, len, prefix);
>   }
>   
> -char *repo_main_branch_name(struct repository *r)
> +char *repo_main_branch_name(struct repository *r, int flags)
>   {
> +	int full_name = flags & MAIN_BRANCH_FULL_NAME;
>   	const char *config_key = "core.mainbranch";
>   	const char *config_display_key = "core.mainBranch";
>   	const char *fall_back = "master";
> @@ -570,7 +571,10 @@ char *repo_main_branch_name(struct repository *r)
>   	if (repo_config_get_string(r, config_key, &name) < 0)
>   		die(_("could not retrieve `%s`"), config_display_key);
>   
> -	ret = name ? name : xstrdup(fall_back);
> +	if (full_name)
> +		ret = xstrfmt("refs/heads/%s", name ? name : fall_back);
> +	else
> +		ret = name ? name : xstrdup(fall_back);

This looks good, we always check the name before returning it and free 
name if we're returning refs/heads/<name>

>   	if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
>   		die(_("invalid branch name: %s = %s"),
> @@ -582,9 +586,9 @@ char *repo_main_branch_name(struct repository *r)
>   	return ret;
>   }
>   
> -char *git_main_branch_name(void)
> +char *git_main_branch_name(int flags)
>   {
> -	return repo_main_branch_name(the_repository);
> +	return repo_main_branch_name(the_repository, flags);
>   }
>   
>   /*
> diff --git a/refs.h b/refs.h
> index a207ef01348..96472f9a9f5 100644
> --- a/refs.h
> +++ b/refs.h
> @@ -157,9 +157,13 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
>   /*
>    * Retrieves the name of the main (or: primary) branch of the given
>    * repository.
> + *
> + * The result is an allocated string. Unless the flags ask for a short name, it
> + * will be prefixed with "refs/heads/".
>    */

nit pick: the flag is defined to give the fullname, to get the short 
name you just pass 0.

Best Wishes

Phillip

> -char *git_main_branch_name(void);
> -char *repo_main_branch_name(struct repository *r);
> +#define MAIN_BRANCH_FULL_NAME (1<<0)
> +char *git_main_branch_name(int flags);
> +char *repo_main_branch_name(struct repository *r, int flags);
>   
>   /*
>    * A ref_transaction represents a collection of reference updates that
> diff --git a/send-pack.c b/send-pack.c
> index 2532864c812..898720511d0 100644
> --- a/send-pack.c
> +++ b/send-pack.c
> @@ -405,7 +405,7 @@ int send_pack(struct send_pack_args *args,
>   	}
>   
>   	if (!remote_refs) {
> -		char *branch_name = git_main_branch_name();
> +		char *branch_name = git_main_branch_name(0);
>   
>   		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
>   			"Perhaps you should specify a branch such as '%s'.\n",
> diff --git a/transport-helper.c b/transport-helper.c
> index 8c8f40e322d..7a54e5b2fb2 100644
> --- a/transport-helper.c
> +++ b/transport-helper.c
> @@ -1044,7 +1044,7 @@ static int push_refs(struct transport *transport,
>   	}
>   
>   	if (!remote_refs) {
> -		char *branch_name = git_main_branch_name();
> +		char *branch_name = git_main_branch_name(0);
>   
>   		fprintf(stderr,
>   			_("No refs in common and none specified; doing nothing.\n"
> 

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
  2020-06-15 12:50   ` [PATCH v2 05/12] fast-export: handle overridden main branch names correctly Johannes Schindelin via GitGitGadget
@ 2020-06-15 15:05     ` Phillip Wood
  2020-06-16 13:10       ` Jeff King
  2020-06-15 17:09     ` Junio C Hamano
  1 sibling, 1 reply; 178+ messages in thread
From: Phillip Wood @ 2020-06-15 15:05 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget, git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Alban Gruin, Johannes Sixt, Johannes Schindelin

Hi dscho

On 15/06/2020 13:50, Johannes Schindelin via GitGitGadget wrote:
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> When anonymizing commit history, we are careful to translate the main
> branch name to `ref0`.
> 
> When the main branch name is overridden via the config, we will want
> `git fast-export` to use that overridden name instead.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>   builtin/fast-export.c            | 11 ++++++++++-
>   t/t9351-fast-export-anonymize.sh |  6 ++++++
>   2 files changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/builtin/fast-export.c b/builtin/fast-export.c
> index 1072bbf041f..deeb01b6937 100644
> --- a/builtin/fast-export.c
> +++ b/builtin/fast-export.c
> @@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname)
>   	};
>   	static struct hashmap refs;
>   	static struct strbuf anon = STRBUF_INIT;
> +	static char *main_branch;
>   	int i;
>   
>   	/*
>   	 * In certain circumstances, it might be interesting to be able to
>   	 * identify the main branch. For that reason, let's force its name to
>   	 * be anonymized to `ref0`.
> +	 *
> +	 * While the main branch name might often be `main` for new
> +	 * repositories (and `master` for aged ones), and such well-known names
> +	 * may not necessarily need anonymizing, it could be configured to use
> +	 * a secret word that the user may not want to reveal.
>   	 */
> -	if (!strcmp(refname, "refs/heads/master"))
> +	if (!main_branch)
> +		main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
> +
> +	if (!strcmp(refname, main_branch))
>   		return "refs/heads/ref0";

This leaks main_branch if it came from git_main_branch_name()

Best Wishes

Phillip

>   	strbuf_reset(&anon);
> diff --git a/t/t9351-fast-export-anonymize.sh b/t/t9351-fast-export-anonymize.sh
> index 2415f0ec213..f42be635c2f 100755
> --- a/t/t9351-fast-export-anonymize.sh
> +++ b/t/t9351-fast-export-anonymize.sh
> @@ -31,6 +31,12 @@ test_expect_success 'stream translates master to ref0' '
>   	! grep master stream
>   '
>   
> +test_expect_success 'respects configured main branch' '
> +	git -c core.mainBranch=does-not-exist \
> +		fast-export --anonymize --all >stream-without-ref0 &&
> +	! grep ref0 stream-without-ref0
> +'
> +
>   test_expect_success 'stream omits other refnames' '
>   	! grep other stream &&
>   	! grep mytag stream
> 

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-15 12:50   ` [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main " Johannes Schindelin via GitGitGadget
  2020-06-15 15:00     ` Phillip Wood
@ 2020-06-15 17:05     ` Junio C Hamano
  2020-06-23 19:19       ` Johannes Schindelin
  2020-06-16  8:46     ` Ævar Arnfjörð Bjarmason
                       ` (2 subsequent siblings)
  4 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-15 17:05 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
> index 72d32bd73b1..43f4f829242 100644
> --- a/fmt-merge-msg.c
> +++ b/fmt-merge-msg.c
> @@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
>  				const char *current_branch)
>  {
>  	int i = 0;
> -	char *sep = "";
> +	char *sep = "", *main_branch;
>  
>  	strbuf_addstr(out, "Merge ");
>  	for (i = 0; i < srcs.nr; i++) {
> @@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
>  			strbuf_addf(out, " of %s", srcs.items[i].string);
>  	}
>  
> -	if (!strcmp("master", current_branch))
> +	main_branch = git_main_branch_name();
> +	if (!strcmp(main_branch, current_branch))
>  		strbuf_addch(out, '\n');
>  	else
>  		strbuf_addf(out, " into %s\n", current_branch);
> +	free(main_branch);

While you are at it, taking

https://lore.kernel.org/git/20200614211500.GA22505@dcvr/

and the response to it into consideration, I'd suggest we should
support the case where the user says "no single branch is special
here" by configuring it to an empty string.

> +core.mainBranch::
> +	The name of the main (or: primary) branch in the current repository.
> +	For historical reasons, `master` is used as the fall-back for this
> +	setting.

As to the naming of the configuration variable and the actual
fall-back value, I would strongly suggest making them DIFFERNT
(i.e. separate the concept from an actual value).

An instruction

    ... oh, if you want to do so, you can set the core.mainBranch
    configuration variable to 'main'

sounds strange than

    ... oh, if you want to do so, you can set the core.primaryBranch
    configuration variable to 'main'

at least to me, and since I am OK with your choice of 'main' as the
replacement for 'master', a separate word would be more appropriate
for the variable name.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
  2020-06-15 12:50   ` [PATCH v2 05/12] fast-export: handle overridden main branch names correctly Johannes Schindelin via GitGitGadget
  2020-06-15 15:05     ` Phillip Wood
@ 2020-06-15 17:09     ` Junio C Hamano
  2020-06-23 19:22       ` Johannes Schindelin
  1 sibling, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-15 17:09 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> +	 * While the main branch name might often be `main` for new
> +	 * repositories (and `master` for aged ones), and such well-known names

As I said, if you used a different word for the first 'main' in the
sentence, it reads much better.

> +	 * may not necessarily need anonymizing, it could be configured to use
> +	 * a secret word that the user may not want to reveal.
>  	 */
> -	if (!strcmp(refname, "refs/heads/master"))
> +	if (!main_branch)
> +		main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
> +
> +	if (!strcmp(refname, main_branch))
>  		return "refs/heads/ref0";

The same comment as 02/12 applies here.  If the helper function
returns "" when the user says that no branch is more special than
others in the repository, the code would automatically do the right
thing.

In any case, thanks for working on it.  I am on "vacation" so will
be commenting on the rest of the series later in the week.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-15 10:03 ` Pratyush Yadav
  2020-06-14 22:26   ` Johannes Schindelin
@ 2020-06-15 23:10   ` brian m. carlson
  1 sibling, 0 replies; 178+ messages in thread
From: brian m. carlson @ 2020-06-15 23:10 UTC (permalink / raw)
  To: Pratyush Yadav
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	Johannes Schindelin

[-- Attachment #1: Type: text/plain, Size: 1596 bytes --]

On 2020-06-15 at 10:03:27, Pratyush Yadav wrote:
> For example, my vim plugins are submodules in the '~/.vim/bundle'
> directory. When I want to update them, I run:
> 
>   git submodule foreach 'git remote update && git reset --hard origin/master'
> 
> With this change hitting a Git release, more and more people would call
> their main branch different names they like. So what is the recommended
> way to do something like this now? How do I checkout the tip of the main
> branch? How do I push to the main branch? How do I pull from the main
> branch? And so on...

This is a common issue that's long existed but may become more common as
people change their branches.  I believe when you clone that it by
default pulls down a HEAD reference for the remote.  So you can use
origin/HEAD (a symref) in this case to use the correct default branch,
whatever it may be called.  Then your code doesn't have to care about
the actual name, which is probably better anyway.

If you want to know the actual name, you can use this: git rev-parse
--abbrev-ref origin/HEAD.

If the owner of the repository chooses to change that name or if you
lack the HEAD reference for a remote, you can fix it with "git remote
set-head origin -a".

I'll see if I can find time this week to work up a FAQ entry about how
to do this, since it seems to be a common question folks have.  I myself
wasn't aware of "git remote set-head" until the other day, so I don't
expect others to be familiar with it, either.
-- 
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-14 22:26   ` Johannes Schindelin
@ 2020-06-16  0:19     ` Denton Liu
  2020-06-23 20:10       ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Denton Liu @ 2020-06-16  0:19 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Pratyush Yadav, Johannes Schindelin via GitGitGadget, git, don,
	stolee, peff, sandals

Hi Dscho,

On Mon, Jun 15, 2020 at 12:26:03AM +0200, Johannes Schindelin wrote:
> > For example, my vim plugins are submodules in the '~/.vim/bundle'
> > directory. When I want to update them, I run:
> >
> >   git submodule foreach 'git remote update && git reset --hard origin/master'
> >
> > With this change hitting a Git release, more and more people would call
> > their main branch different names they like. So what is the recommended
> > way to do something like this now? How do I checkout the tip of the main
> > branch? How do I push to the main branch? How do I pull from the main
> > branch? And so on...
> 
> ... has less to do with a new Git release, but more with the decision of
> an existing project to change their main branch name.
> 
> That's something users already had to deal with, of course. For example,
> projects switching to the Git Flow model will start to use the main branch
> name `development`.

I brought this concern up in a parallel thread but I'll bring it up here
too since it's relevant. Currently, in the .gitmodules file, if the
branch is not specified, it defaults to 'master'.

When I want to update my vim plugins, I run
`git submodule update --remote` which pulls in all of my submodules'
'master' branches. By convention, a lack of `branch` key in .gitmodules
conventionally means 'master'.

With your change, it becomes the value of git_main_branch_name(), which
is fine for now. However, if this value changes to something else, then
when I update my Git, suddenly `git submodule update --remote` will be
broken for me as all of the new repositories that I pull will be for an
incorrect (and possibly missing) branch.

This leaves us in a scenario where one developer running an older
version of Git would have submodule updates work perfectly fine while a
developer with a newer version would have it suddenly broken. This might
be hard to debug, especially for someone who doesn't follow the release
notes around Git and doesn't realise why the default has suddenly
changed.

This problem gets much worse if we allow the main branch name to be
configurable as then the *private* configurations that a developer has
may have an effect on the *publicly visible* behaviour of a repository.

I think I see three possible solutions to this:

	1. Special case 'master' in submodules to retain backwards
	compatibility.

	I don't think this is very appealing as if the change is made to
	use another default branch name, then the "default" branch for
	submodules would be "master" even though the new default
	everywhere else would be different. And in the future, someone
	who doesn't know the context behind all of this would be very
	confused where there are two different default branch names.

	2. Disable 'update --remote' support for submodules that don't
	specify a branch.

	If Git detects that a branch key is missing when trying to do an
	'update --remote', it should just quit out and refuse to do
	anything. Of course, this a very backwards incompatible change
	and it would require several release cycles to implement where
	we warn users about this impending change before we actually
	make it happen.

	3. Make 'update --remote' get HEAD.

	I argue that this is how it always should've been implemented
	but, alas, I can't go back in time and fix it. Regardless, it
	might be good to flip this to be the default if we're going to
	be making the change anyway.

	Unfortunately, this suffers from both the problems of 1 and 2.
	As with 1, we'll end up in a situation where users with
	different versions of Git may experience different behaviours
	given the same public repository and I think this is definitely
	undesirable. With 2, this change will also require a long
	deprecation period which I don't think it compatible with how
	people seem to want the default branch switch to happen this
	release.

So I dunno. I think my opinion leans on not changing the default branch
at all. Since it seems like the consensus is generally that it _will_
change, I think I would prefer options 3, 2 and 1 in that order.

Thoughts?

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-15 12:50   ` [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main " Johannes Schindelin via GitGitGadget
  2020-06-15 15:00     ` Phillip Wood
  2020-06-15 17:05     ` Junio C Hamano
@ 2020-06-16  8:46     ` Ævar Arnfjörð Bjarmason
  2020-06-17 18:21       ` Junio C Hamano
  2020-06-16 13:04     ` Jeff King
  2020-06-17 20:56     ` Johannes Sixt
  4 siblings, 1 reply; 178+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-06-16  8:46 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin


On Mon, Jun 15 2020, Johannes Schindelin via GitGitGadget wrote:

> From: Johannes Schindelin <johannes.schindelin@gmx.de>

> +core.mainBranch::
> +	The name of the main (or: primary) branch in the current repository.
> +	For historical reasons, `master` is used as the fall-back for this
> +	setting.

Everywhere else in git-config(1) we just say something to the effect of
the more brief:

    The name of the main (or: primary) branch in the current repository
    (`master` by default).

I think we should do the same here for consistency & ease of reading.

As you note at the start of this series we're not changing the default
yet, so referring to the current default as historical is putting the
cart before the horse as far as producing self-contained patch serieses
goes.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-10 21:19 [PATCH 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                   ` (13 preceding siblings ...)
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
@ 2020-06-16  9:47 ` Ævar Arnfjörð Bjarmason
  2020-06-16 14:09   ` Jeff King
  2020-06-17 20:28   ` Junio C Hamano
  14 siblings, 2 replies; 178+ messages in thread
From: Ævar Arnfjörð Bjarmason @ 2020-06-16  9:47 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Johannes Schindelin


On Wed, Jun 10 2020, Johannes Schindelin via GitGitGadget wrote:

> This series DOES NOT change the default automatically, but only provides an
> opt-in mechanism for interested users. It also presents a way forward for
> such a transition, if and when we decide to do so. Specifically, the new
> GIT_TEST_DEFAULT_BRANCH_NAME environment variable could be used to update
> test scripts on an individual basis instead of all-at-once.

I don't have much time for review today, but hopefully these comments
are useful. These comments are on the series as a whole[1] mainly to
save myself time in chasing down individual patches, and I think it's
more useful as one E-Mail, hopefully.

I think this change is going in a good technical direction. I'm just
commenting on the "how it would be done" aspect, I'm not going to add
another voice to the larger "is this a useful endeavor?" discussion
vis-a-vis what the larger goal is.

But I do have purely technical concerns about where this is going.

The part where we just make it easier to do what you could do all along
with sed(1) or whatever to rename the branch after "git init" is
obviously correct (or close enough). That part's easy enough.

The parts I'm concerned about is the behavior of how we make the branch
name persistent, which is new "while we're at it" behavior in git
unrelated to the convenience of allowing a configuration of the main
branch name without "git init --template" or after the fact sed(1)
munging.

Specifically:

 1. The special case in fmt-merge-msg we always had for "master" sucked
    in terms of producing more verbose merge messages for those of us
    who had repos where the main branch wasn't "master", but at least it
    was consistent.

    Now we've created a situation where a user's local config impacts
    what we put in the machine-generated commit messages.

    Now, these messages were never "plumbing", and other users could use
    different git frontends than "core git" etc, but it's a really
    useful property we've tried to maintain that a user's local
    configuration doesn't change what we put in these messages. It's why
    we've left them out of the i18n mechanism.

 2. The whole core.mainBranch thing rubs me the wrong way. So now if we
    rename a branch we munge it, but if you've got an older git version
    or whatever you get different results and the config isn't carried
    forward.

    I'd *really* like to avoid having what's essentially a refstore
    side-value if we can.

 3. Whatever we do with the submodule guess-a-name functionality, I
    think it's the wrong path to make it proceed in lockstep with
    MAIN_BRANCH_FOR_INIT.

    When you decide to change your branch names != when the rest of the
    world does it.

    Also, whatever the suckyness of the current hardcoded "master"
    behavior I think it sucks more than different users on the same
    version can fail or succeed to clone a repository depending on a
    config they set for "what branch names do I want on new repos?".

    This is simlar to #1, in that I'd much rather have behavior that
    consistently sucks than one that interacts with the wider world
    (writing commits, cloning random other repos) that differs because
    of my *local* config preferences.

 4. For fast-export I think we should just drop this entire "master"
    special case instead of making it read the config. That's also in
    line with its documentation. Let's just call it ref0.

    Either that or just hardcode whatever passes for the "main" branch
    name, but anything but making the to-be-shared anonymized output
    continue to leak local config, similar to #1 and #3 above.

In summary, I'd like this series much better if we split off the
convenience change for "init" from the improved heuristics/guesses for
remote "master". Just my 0.02.

1. git diff --stat -p @{u}...pr-656/dscho/default-branch-name-option-v2

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-14  8:57         ` Johannes Schindelin
@ 2020-06-16 12:25           ` Jeff King
  2020-06-18 10:17             ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 12:25 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Alban Gruin, Junio C Hamano, Don Goodman-Wilson via GitGitGadget,
	git, don, stolee, sandals

On Sun, Jun 14, 2020 at 10:57:41AM +0200, Johannes Schindelin wrote:

> > >> Why adding yet another environment variable instead of relying only on a
> > >> config option?  I understand it's for the tests, but can't we add a
> > >> shell function in test-lib.sh (and friends) that tries to read
> > >> `GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets
> > >> `core.defaultBranchName'?
> > >
> > > Can you produce such a patch that does it cleanly?  My knee jerk
> > > reaction is that I would suspect that you end up having to touch
> > > many places in the t/ scripts, but if you prove otherwise, that
> > > would certainly be appreciated.
> > >
> > > And no,
> > >
> > >     git () { command git -c core.defaultBranchName=master "$@" }
> > >
> > > is not an acceptable solution.
> > >
> >
> > I wanted to to do something like this:
> >
> >   if test -n "$GIT_TEST_DEFAULT_BRANCH_NAME";
> >   then
> >       git config core.defaultBranchName "$GIT_TEST_DEFAULT_BRANCH_NAME"
> >   fi
> >
> > But since we do not have a repository to store the config, it won't
> > work.  Sorry for the noise.
> 
> We actually would have `~/.gitconfig` because `HOME` is set to `t/trash
> directory.<test-name>/`.
> 
> However, that would cause all kinds of issues when test scripts expect the
> directory to be pristine, containing only `.git/` but not `.gitconfig`.

Putting:

  GIT_CONFIG_PARAMETERS="'core.defaultBranchName=...'"

into the environment would work (and yes, you need the single quotes
embedded in the variable), and solves all of the complaints above.
Further "git -c" invocations properly append to it. But:

  - there are a few tests which explicitly tweak that variable

  - it technically changes any tests of "-c" because now we'd never
    cover the case where we start without the variable defined

I think baking in a special environment variable like you have is not so
bad. If this did become too common a pattern, though (special test-only
environment variables that do have a separate config option), I wouldn't
be opposed to a GIT_TEST_CONFIG_PARAMETERS which takes precedence over
other config, and comes with a big warning label that it shouldn't be
relied upon outside the test suite. That's equally ugly to
GIT_TEST_DEFAULT_BRANCH_NAME, but at least solves the problem once for
all of them. I'm just not sure we have enough "all of them" to make it
worth doing.

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 2/9] remote: respect `core.defaultBranchName`
  2020-06-10 21:19 ` [PATCH 2/9] remote: respect `core.defaultBranchName` Johannes Schindelin via GitGitGadget
@ 2020-06-16 12:35   ` Jeff King
  2020-06-18 10:21     ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 12:35 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, sandals, Johannes Schindelin

On Wed, Jun 10, 2020 at 09:19:23PM +0000, Johannes Schindelin via GitGitGadget wrote:

> @@ -2099,7 +2100,10 @@ struct ref *guess_remote_head(const struct ref *head,
>  
>  	/* If refs/heads/master could be right, it is. */
>  	if (!all) {
> -		r = find_ref_by_name(refs, "refs/heads/master");
> +		char *name = git_default_branch_name(0);
> +
> +		r = find_ref_by_name(refs, name);
> +		free(name);
>  		if (r && oideq(&r->old_oid, &head->old_oid))
>  			return copy_ref(r);
>  	}

You'd perhaps want to update the comment above, too.

However, I think we should be a bit more lenient on the "reading" side
default names. Just because "foo" is _my_ default branch name, does not
mean it is the default on the remote side. We cannot know what the other
side's default preference is, but in a world where we have 15 years of
repos that may have been created with "master", it is probably still a
good guess.

I.e., I think this probably ought to check the preferred name, and then
fall back to the existing behavior, like:

  if (!all) {
	  char *name;

          /* try the user's preferred default branch name */
	  name = git_default_branch_name(0);
	  r = find_ref_by_name(refs, name);
	  free(name);
	  if (r && oideq(&r->old_oid, &head->old_oid))
	          return copy_ref(r);

	  /* otherwise, try "master", which is the historical default */
	  r = find_ref_by_name(refs, "refs/heads/master");
	  if (r && oideq(&r->old_oid, &head->old_oid))
	          return copy_ref(r);
  }

That will help minimize fallout when git_default_branch_name() changes,
either by user config or if we switch the baked-in default. In the
latter case, we might also consider hard-coding that as a guess between
the user's preferred name and the historical "master".

Hopefully this would not matter _too_ much either way, as most servers
would support the symref extension these days. But I still think we
should do our best to minimize spots where the user may see a
regression.

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-11  0:16   ` Eric Sunshine
  2020-06-11 14:09     ` Johannes Schindelin
@ 2020-06-16 12:45     ` Jeff King
  2020-06-16 12:47       ` Jeff King
  2020-06-23 20:32       ` Johannes Schindelin
  1 sibling, 2 replies; 178+ messages in thread
From: Jeff King @ 2020-06-16 12:45 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Don Goodman-Wilson via GitGitGadget, Git List, Derrick Stolee,
	brian m. carlson, Johannes Schindelin, Don Goodman-Wilson

On Wed, Jun 10, 2020 at 08:16:38PM -0400, Eric Sunshine wrote:

> > +/*
> > + * Retrieves the name of the default branch. If `short_name` is non-zero, the
> > + * branch name will be prefixed with "refs/heads/".
> > + */
> > +char *git_default_branch_name(int short_name);
> 
> Overall, the internal logic regarding duplicating/freeing strings
> would probably be easier to grok if there were two separate functions:
> 
>     char *git_default_branch_name(void);
>     char *git_default_ref_name(void);
> 
> but that's subjective.

Having seen one of the callers, might it be worth avoiding handing off
ownership of the string entirely?

I.e., this comes from a string that's already owned for the lifetime of
the process (either the environment, or a string stored by the config
machinery). Could we just pass that back (or if we want to be more
careful about getenv() lifetimes, we can copy it into a static owned by
this function)?

Then all of the callers can stop dealing with the extra free(), and you
can do:

  const char *git_default_branch_name(void)
  {
	return skip_prefix("refs/heads/", git_default_ref_name());
  }

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-16 12:45     ` Jeff King
@ 2020-06-16 12:47       ` Jeff King
  2020-06-18 13:08         ` Johannes Schindelin
  2020-06-23 20:32       ` Johannes Schindelin
  1 sibling, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 12:47 UTC (permalink / raw)
  To: Eric Sunshine
  Cc: Don Goodman-Wilson via GitGitGadget, Git List, Derrick Stolee,
	brian m. carlson, Johannes Schindelin, Don Goodman-Wilson

On Tue, Jun 16, 2020 at 08:45:02AM -0400, Jeff King wrote:

> On Wed, Jun 10, 2020 at 08:16:38PM -0400, Eric Sunshine wrote:
> 
> > > +/*
> > > + * Retrieves the name of the default branch. If `short_name` is non-zero, the
> > > + * branch name will be prefixed with "refs/heads/".
> > > + */
> > > +char *git_default_branch_name(int short_name);
> > 
> > Overall, the internal logic regarding duplicating/freeing strings
> > would probably be easier to grok if there were two separate functions:
> > 
> >     char *git_default_branch_name(void);
> >     char *git_default_ref_name(void);
> > 
> > but that's subjective.
> 
> Having seen one of the callers, might it be worth avoiding handing off
> ownership of the string entirely?
> 
> I.e., this comes from a string that's already owned for the lifetime of
> the process (either the environment, or a string stored by the config
> machinery). Could we just pass that back (or if we want to be more
> careful about getenv() lifetimes, we can copy it into a static owned by
> this function)?
> 
> Then all of the callers can stop dealing with the extra free(), and you
> can do:
> 
>   const char *git_default_branch_name(void)
>   {
> 	return skip_prefix("refs/heads/", git_default_ref_name());
>   }

Actually, one small hiccup is that the config option specifies the
branch name, not the ref name. So you really would have to prepare a
static-owned copy of it to turn "foo" into "refs/heads/foo" to get the
refname.

On the other hand, that would also be a good time to run
check_ref_format(). In the patch as-is, the "short" return does not
check that the branch is a valid name.

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
  2020-06-15 12:50   ` [PATCH v2 01/12] fast-export: do anonymize the primary branch name Junio C Hamano via GitGitGadget
@ 2020-06-16 12:58     ` Jeff King
  2020-06-17 18:16       ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 12:58 UTC (permalink / raw)
  To: Junio C Hamano via GitGitGadget
  Cc: git, don, stolee, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin, Junio C Hamano

On Mon, Jun 15, 2020 at 12:50:05PM +0000, Junio C Hamano via GitGitGadget wrote:

> There is a comment that explains why it is OK to leave 'master'
> unanonymized (because everybody calls the primary branch 'master'
> and it is no secret), but that does not justify why it is bad to
> anonymize 'master' and make it indistinguishable from other
> branches.  Assuming there _is_ a need to allow the readers of the
> output to tell where the tip of the primary branch is, let's keep
> the special casing of 'master', but still anonymize it to "ref0".
> Because all other branches will be given ref+N where N is a positive
> integer, this will keep the primary branch identifiable in the
> output stream, without exposing what the name of the primary branch
> is in the repository the export stream was taken from.

I think this is fine. The reason I left "master" as-is in the original
is that it is potentially helpful to have an idea of its specialness
when reproducing a traversal in the anonymized. I.e., if you know that a
bug is shown by "git rev-list master~17..master~3", then you can
reproduce it with the same command in the anonymized repo. Losing any
idea of where the primary branch is would make that impossible. But with
this patch, you can swap it out for "ref0~17", etc, which is OK.

Of course that only helps you for _one_ branch. A more generally useful
mechanism would be to teach fast-export to write the ref mapping (and
perhaps file mappings, etc) to a separate file. Then you could convert
any reproduction recipe to use the anonymized names, and share only that
recipe along with the anonymized dump. But that's _way_ outside the
scope of your series. This seems like a good interim step to retain the
status quo.

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-15 12:50   ` [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main " Johannes Schindelin via GitGitGadget
                       ` (2 preceding siblings ...)
  2020-06-16  8:46     ` Ævar Arnfjörð Bjarmason
@ 2020-06-16 13:04     ` Jeff King
  2020-06-17 18:23       ` Junio C Hamano
  2020-06-17 20:56     ` Johannes Sixt
  4 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 13:04 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin

On Mon, Jun 15, 2020 at 12:50:06PM +0000, Johannes Schindelin via GitGitGadget wrote:

> +char *repo_main_branch_name(struct repository *r)
> +{
> +	const char *config_key = "core.mainbranch";
> +	const char *config_display_key = "core.mainBranch";
> +	const char *fall_back = "master";
> +	char *name = NULL, *ret;
> +
> +	if (repo_config_get_string(r, config_key, &name) < 0)
> +		die(_("could not retrieve `%s`"), config_display_key);
> +
> +	ret = name ? name : xstrdup(fall_back);
> +
> +	if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
> +		die(_("invalid branch name: %s = %s"),
> +		    config_display_key, name);

Ah, this fixes the "we do not check the format of the short name" issue
I pointed out in v1 (sorry, I just realized that v2 existed so I'll
resume reviewing from there; I do still think this might make life
easier for callers by returning a const pointer).

I'm not sure if this check_refname_format() is valid, though. IIRC we've
had issues where "ONELEVEL" was used to check a branch name, but misses
some cases. The more full check done by strbuf_check_branch_ref()
actually creates the full refname and checks that. It also catches stuff
like refs/heads/HEAD.

I doubt that it matters too much for us to be completely thorough here
(unlike some other spots, we are not enforcing rules against potentially
malicious names, but rather just helping the user realize early that
their config is bogus). So I'm not sure how careful we want to be.

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
  2020-06-15 15:05     ` Phillip Wood
@ 2020-06-16 13:10       ` Jeff King
  2020-06-16 15:49         ` Phillip Wood
  2020-06-18 10:08         ` Johannes Schindelin
  0 siblings, 2 replies; 178+ messages in thread
From: Jeff King @ 2020-06-16 13:10 UTC (permalink / raw)
  To: phillip.wood
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals,
	Matt Rogers, Eric Sunshine, Taylor Blau, Alban Gruin,
	Johannes Sixt, Johannes Schindelin

On Mon, Jun 15, 2020 at 04:05:52PM +0100, Phillip Wood wrote:

> > @@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname)
> >   	};
> >   	static struct hashmap refs;
> >   	static struct strbuf anon = STRBUF_INIT;
> > +	static char *main_branch;
> [...]
> > -	if (!strcmp(refname, "refs/heads/master"))
> > +	if (!main_branch)
> > +		main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
> > +
> > +	if (!strcmp(refname, main_branch))
> >   		return "refs/heads/ref0";
> 
> This leaks main_branch if it came from git_main_branch_name()

It's a static that's used over and over, so I think it's intentional to
essentially memoize it for the life of the program (at which point we
could free it, but don't bother to do so, letting the process exit take
care of it, and trusting in leak detectors to be aware that it's still
reachable, as we do for lots of other process-lifetime allocations).

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 09/12] clone: handle overridden main branch names
  2020-06-15 12:50   ` [PATCH v2 09/12] clone: handle overridden main branch names Johannes Schindelin via GitGitGadget
@ 2020-06-16 13:22     ` Jeff King
  2020-06-23 20:58       ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 13:22 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin

On Mon, Jun 15, 2020 at 12:50:13PM +0000, Johannes Schindelin via GitGitGadget wrote:

> diff --git a/builtin/clone.c b/builtin/clone.c
> index 487b0a42d75..755fcaeb0ba 100644
> --- a/builtin/clone.c
> +++ b/builtin/clone.c
> @@ -718,6 +718,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
>  		/* Local default branch link */
>  		if (create_symref("HEAD", our->name, NULL) < 0)
>  			die(_("unable to update HEAD"));
> +		git_config_set("core.mainbranch", head);
>  		if (!option_bare) {
>  			update_ref(msg, "HEAD", &our->old_oid, NULL, 0,
>  				   UPDATE_REFS_DIE_ON_ERR);

Just making sure I understand what's going on here...

This covers the case that we've run "clone -b foo" or similar, but there
are two other case arms when "foo" is a tag, or the remote HEAD is
unreachable. And there we don't set core.mainbranch at all.

But we would not want it to be missing, because that will likely need to
stay a default for "master" indefinitely (to keep behavior for existing
repositories). However, it won't be missing. We'll always have set it
during the init_db() call, and this is just overriding that. So we'd end
update_head() with either:

  - core.mainbranch set to the same branch we point HEAD to, whether we
    got it from the remote side or from "-b foo"

  - if we write a detached HEAD, then core.mainbranch remains at
    init.mainbranch (or defaulting to "master" now, and probably "main"
    later). We have no better option.

If so, then that makes sense to me.

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 11/12] submodule: use the correct default for the main branch name
  2020-06-15 12:50   ` [PATCH v2 11/12] submodule: use the correct default for the " Johannes Schindelin via GitGitGadget
@ 2020-06-16 13:46     ` Jeff King
  2020-06-23 21:03       ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 13:46 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Johannes Schindelin

On Mon, Jun 15, 2020 at 12:50:15PM +0000, Johannes Schindelin via GitGitGadget wrote:

> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> To allow for overriding the default branch name, we have introduced a
> config setting. With this patch, the `git submodule` command learns
> about this, too.

This was the other reading case (besides guess_remote_head()) that I'm
most concerned with causing regressions in a world where some repos are
on "master" and some are on "main".

This value ends up as the output of "submodule--helper remote-branch".

I was initially worried that we used this branch name for the fallback
when the server doesn't allow us to fetch the sha1 directly, but it
doesn't look like it. That's good, because handling fallbacks there
would be tricky.

Instead, we seem to use this only after fetching all of the refs for a
submodule:

  $ git grep -h -B2 -A11 remote-branch git-submodule.sh
  		if test -n "$remote"
  		then
  			branch=$(git submodule--helper remote-branch "$sm_path")
  			if test -z "$nofetch"
  			then
  				# Fetch remote before determining tracking $sha1
  				fetch_in_submodule "$sm_path" $depth ||
  				die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
  			fi
  			remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote)
  			sha1=$(sanitize_submodule_env; cd "$sm_path" &&
  				git rev-parse --verify "${remote_name}/${branch}") ||
  			die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
  		fi

and then we just use that branch name to resolve a sha1. So this will
break cases where you've set init.mainBranch, the submodule repo is
still on "master", and you haven't configured a branch in .gitmodules.

It seems like, independent of any change in the default branch names, we
ought to be using $remote_name/HEAD for this case anyway. I suspect that
would be a behavior improvement by itself, as it means more cases could
avoid having to specify the branch name in .gitmodules manually.
Probably nobody noticed so far because "HEAD" is almost always "master"
in the current world. It technically breaks the case that you truly did
want to use "master" in the submodule, but they set HEAD to something
else, and you couldn't be bothered to put it into your .gitmodules file.
That seems rather unlikely to me.

And then everything would Just Work without having to worry about the
local mainbranch value at all.

Alternatively, submodule--helper could pass back the empty string for
"no, we don't have a configured branch name" and this shell code could
actually try a sequence of reasonable guesses: init.mainbranch, then
"master" (and between the two, "main" if that later becomes the
default).

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 12/12] testsvn: respect `init.defaultBranch`
  2020-06-15 12:50   ` [PATCH v2 12/12] testsvn: respect `init.defaultBranch` Johannes Schindelin via GitGitGadget
@ 2020-06-16 13:51     ` Jeff King
  2020-06-23 21:07       ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 13:51 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: Jonathan Nieder, git, don, stolee, sandals, Matt Rogers,
	Eric Sunshine, Taylor Blau, Phillip Wood, Alban Gruin,
	Johannes Sixt, Johannes Schindelin

On Mon, Jun 15, 2020 at 12:50:16PM +0000, Johannes Schindelin via GitGitGadget wrote:

> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> The default name of the main branch in new repositories can now be
> configured. The `testsvn` remote helper translates the remote Subversion
> repository's branch name `trunk` to the hard-coded name `master`.
> Clearly, the intention was to make the name align with Git's detaults.

s/detaults/defaults/ :)

I'd agree that moving this to Git's default name makes sense.

Though my overall preference is still to delete this whole testsvn thing
entirely (I have some other pending tree-wide changes that are being
held up by it, too). After getting "would you mind holding off until..."
from Jonathan in [1], I've been waiting almost 2 years. Maybe now is the
time?

-Peff

[1] https://lore.kernel.org/git/20180818052605.GA241538@aiede.svl.corp.google.com/

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-16  9:47 ` [PATCH " Ævar Arnfjörð Bjarmason
@ 2020-06-16 14:09   ` Jeff King
  2020-06-16 14:24     ` Jeff King
  2020-06-17 20:28   ` Junio C Hamano
  1 sibling, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 14:09 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals,
	Johannes Schindelin

On Tue, Jun 16, 2020 at 11:47:10AM +0200, Ævar Arnfjörð Bjarmason wrote:

> But I do have purely technical concerns about where this is going.
> 
> The part where we just make it easier to do what you could do all along
> with sed(1) or whatever to rename the branch after "git init" is
> obviously correct (or close enough). That part's easy enough.
> 
> The parts I'm concerned about is the behavior of how we make the branch
> name persistent, which is new "while we're at it" behavior in git
> unrelated to the convenience of allowing a configuration of the main
> branch name without "git init --template" or after the fact sed(1)
> munging.

I've read the whole thing and left some specific comments, but your
thinking more or less matches mine, with a few notes below.

> Specifically:
> 
>  1. The special case in fmt-merge-msg we always had for "master" sucked
>     in terms of producing more verbose merge messages for those of us
>     who had repos where the main branch wasn't "master", but at least it
>     was consistent.
> 
>     Now we've created a situation where a user's local config impacts
>     what we put in the machine-generated commit messages.
> 
>     Now, these messages were never "plumbing", and other users could use
>     different git frontends than "core git" etc, but it's a really
>     useful property we've tried to maintain that a user's local
>     configuration doesn't change what we put in these messages. It's why
>     we've left them out of the i18n mechanism.

I'm actually tempted to say that "master" should stop being special.
It's a little nice, I guess, if merges back to the main branch are a
little more terse in their message. But I actually think consistently
saying:

  Merge branch 'jk/foo' into main

_even if it's the main branch_ is actually pretty sane. It conveys more
information about what happened that could be useful later, and I don't
think it makes the result less readable.

>  2. The whole core.mainBranch thing rubs me the wrong way. So now if we
>     rename a branch we munge it, but if you've got an older git version
>     or whatever you get different results and the config isn't carried
>     forward.
> 
>     I'd *really* like to avoid having what's essentially a refstore
>     side-value if we can.

I think it's necessary if we're going to have parts of the code that say
"this is the special branch in this repo". Because we must leave the
unconfigured state as "master is the special branch" in order to avoid
regressing existing repositories. It _could_ be a flag that says "I was
configured using init.mainBranch, so use that value". But I don't think
that solves your fundamental concerns.

However, I wonder if we can get away with saying "there is no special
branch" entirely. The things that care about the special branch are:

 - guessing HEAD; but this is guessing what the _remote_ side wants
   anyway, so it really has nothing to do with your local
   core.mainBranch (plus that guess shouldn't even be used much with
   modern git anyway).

 - the default branch for submodules; this is basically the same boat,
   and really ought to just be using the remote HEAD anyway.

 - slightly shorter merge messages. See above.

 - various "perhaps you should specify a branch such as master"
   messages. These could be reworded to avoid mentioning a specific
   branch, or could pick a real branch name.

 - fast-export anonymization. We could probably use HEAD as "ref0"
   instead (or do the output-map thing I mentioned, which is a much
   better solution anyway).

I think with that, we could ditch core.mainBranch entirely, with no
notion at all of "this branch is special in this repo". We use HEAD
where appropriate, and otherwise avoid any specialness.

>  3. Whatever we do with the submodule guess-a-name functionality, I
>     think it's the wrong path to make it proceed in lockstep with
>     MAIN_BRANCH_FOR_INIT.
> 
>     When you decide to change your branch names != when the rest of the
>     world does it.

Yeah, this was my main concern for the whole series: what will break in
a world of mixed main-branch names. Thankfully very little, it seems.
But as much as possible we should be not just choosing our preferred
value, but trying to match possible states. I think teaching the
HEAD-guessing to try a few names, plus using HEAD for submodules, will
pretty much do it (see my replies to individual patches for more
details).

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-16 14:09   ` Jeff King
@ 2020-06-16 14:24     ` Jeff King
  2020-06-23 20:28       ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-16 14:24 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals,
	Johannes Schindelin

On Tue, Jun 16, 2020 at 10:09:32AM -0400, Jeff King wrote:

> I think with that, we could ditch core.mainBranch entirely, with no
> notion at all of "this branch is special in this repo". We use HEAD
> where appropriate, and otherwise avoid any specialness.

One obvious exception is that third-party tools may want to know the
"special" branch for some reason. But I'm inclined to say that they
should (in this order):

  - consider whether they really need a special branch at all, or if the
    mechanism can be made more generic

  - consider whether HEAD is the best value for a special branch (e.g.,
    GitHub pull requests default to targeting HEAD)

  - rely on per-tool config for what's special (because it really may
    vary between tools, and that's more flexible anyway)

But I'm open to hearing about cases where some tool really wants to know
"what did the user consider the special branch at the time of creation".

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
  2020-06-16 13:10       ` Jeff King
@ 2020-06-16 15:49         ` Phillip Wood
  2020-06-18 10:08         ` Johannes Schindelin
  1 sibling, 0 replies; 178+ messages in thread
From: Phillip Wood @ 2020-06-16 15:49 UTC (permalink / raw)
  To: Jeff King, phillip.wood
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals,
	Matt Rogers, Eric Sunshine, Taylor Blau, Alban Gruin,
	Johannes Sixt, Johannes Schindelin

Hi Peff

On 16/06/2020 14:10, Jeff King wrote:
> On Mon, Jun 15, 2020 at 04:05:52PM +0100, Phillip Wood wrote:
> 
>>> @@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname)
>>>    	};
>>>    	static struct hashmap refs;
>>>    	static struct strbuf anon = STRBUF_INIT;
>>> +	static char *main_branch;
>> [...]
>>> -	if (!strcmp(refname, "refs/heads/master"))
>>> +	if (!main_branch)
>>> +		main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
>>> +
>>> +	if (!strcmp(refname, main_branch))
>>>    		return "refs/heads/ref0";
>>
>> This leaks main_branch if it came from git_main_branch_name()
> 
> It's a static that's used over and over, so I think it's intentional to
> essentially memoize it for the life of the program 

Oh you're right, I completely misread the patch

Thanks

Phillip

> (at which point we
> could free it, but don't bother to do so, letting the process exit take
> care of it, and trusting in leak detectors to be aware that it's still
> reachable, as we do for lots of other process-lifetime allocations).
> 
> -Peff
> 

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
  2020-06-16 12:58     ` Jeff King
@ 2020-06-17 18:16       ` Junio C Hamano
  2020-06-17 21:23         ` Jeff King
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-17 18:16 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano via GitGitGadget, git, don, stolee, sandals,
	Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Johannes Schindelin

Jeff King <peff@peff.net> writes:

> Of course that only helps you for _one_ branch. A more generally useful
> mechanism would be to teach fast-export to write the ref mapping (and
> perhaps file mappings, etc) to a separate file. Then you could convert
> any reproduction recipe to use the anonymized names, and share only that
> recipe along with the anonymized dump. But that's _way_ outside the
> scope of your series. This seems like a good interim step to retain the
> status quo.

Actually, dropping this special case, and dropping the other special
case with fmt-merge-msg, we can do without the notion of the
"primary" branch.

We still need to have the default name, when user does not specify
one, given to the first branch "git init" creates and "git clone"
that cannot figure out what the HEAD at the origin points at uses,
but one less thing to worry about is always better ;-)

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-16  8:46     ` Ævar Arnfjörð Bjarmason
@ 2020-06-17 18:21       ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-17 18:21 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Johannes Schindelin

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

> On Mon, Jun 15 2020, Johannes Schindelin via GitGitGadget wrote:
>
>> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
>> +core.mainBranch::
>> +	The name of the main (or: primary) branch in the current repository.
>> +	For historical reasons, `master` is used as the fall-back for this
>> +	setting.
>
> Everywhere else in git-config(1) we just say something to the effect of
> the more brief:
>
>     The name of the main (or: primary) branch in the current repository
>     (`master` by default).
>
> I think we should do the same here for consistency & ease of reading.
>
> As you note at the start of this series we're not changing the default
> yet, so referring to the current default as historical is putting the
> cart before the horse as far as producing self-contained patch serieses
> goes.

Very good point.  

In [*1*], I gave a potential outline of how a transition plan might
look like (if we were to transition, that is), but what is written
as step 1. in there should be split into two: step 0, in which the
mechanisms (1) to change the default name used for the first branch
and (2) to specify the primary branch that is special-cased by a few
commands are introduced, without any future plan, and step 1, in
which warning and/or advice messages knudge the users and hint the
future direction.

Thanks.


[Reference]

*1* https://lore.kernel.org/git/xmqqeeqiztpq.fsf@gitster.c.googlers.com

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-16 13:04     ` Jeff King
@ 2020-06-17 18:23       ` Junio C Hamano
  2020-06-18 13:15         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-17 18:23 UTC (permalink / raw)
  To: Jeff King
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals,
	Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Johannes Schindelin

Jeff King <peff@peff.net> writes:

> I'm not sure if this check_refname_format() is valid, though. IIRC we've
> had issues where "ONELEVEL" was used to check a branch name, but misses
> some cases. The more full check done by strbuf_check_branch_ref()
> actually creates the full refname and checks that. It also catches stuff
> like refs/heads/HEAD.

Yup.

I actually am in favor of removing special casing of a single branch
done by fmt-merge-msg and fast-export --anonymize, so this may not
matter.

We still need a mechanism to allow users specify the default name to
be given to the first branch "git init" creates and used by "git clone"
as a fallback name when it cannot infer what the other side uses, though.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-14  8:55                           ` Johannes Schindelin
@ 2020-06-17 20:06                             ` Junio C Hamano
  2020-06-23 21:11                               ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-17 20:06 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Johannes Sixt, Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> Yes, the trouble with `maint` did cross my mind, but I try not to
> "overfit" to git/git. :-)

I do not think it is overfitting; if the solution cannot even
support the originating project well, there is something wrong.

Most likely, I'd be tempted to rename it myself away from any name
that is too similar to 'maint'; perhaps to 'stable' (or 'devo', h/t
tla ;-).


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-16  9:47 ` [PATCH " Ævar Arnfjörð Bjarmason
  2020-06-16 14:09   ` Jeff King
@ 2020-06-17 20:28   ` Junio C Hamano
  1 sibling, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-17 20:28 UTC (permalink / raw)
  To: Ævar Arnfjörð Bjarmason
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Johannes Schindelin

Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

>  1. The special case in fmt-merge-msg we always had for "master" sucked
>     in terms of producing more verbose merge messages for those of us
>     who had repos where the main branch wasn't "master", but at least it
>     was consistent.
>
>     Now we've created a situation where a user's local config impacts
>     what we put in the machine-generated commit messages.
>
>     Now, these messages were never "plumbing", and other users could use
>     different git frontends than "core git" etc, but it's a really
>     useful property we've tried to maintain that a user's local
>     configuration doesn't change what we put in these messages. It's why
>     we've left them out of the i18n mechanism.

I doubt the last sentence reflects the reality.  As the person who
invented the fmt-merge-msg's mechanism (including it special casing
of 'master'), I know that it was the sentence lego that made it
impossible to localize and left the code pretty much intact since
the days it was introduced.

Having said that, I am personally inclined to vote for getting rid
of the special casing of any branch by "git fmt-merge-msg" and "git
fast-export --anonymize".  We still need a mechanism to let users
configure the word used by "git init" to give the first branch it
creates as its name, but that is merely the first branch created in
the repository and does not have to be the primary.

>  2. The whole core.mainBranch thing rubs me the wrong way. So now if we
>     rename a branch we munge it, but if you've got an older git version
>     or whatever you get different results and the config isn't carried
>     forward.

And we can get rid of this worry at the same time by doing so.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-15 12:50   ` [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main " Johannes Schindelin via GitGitGadget
                       ` (3 preceding siblings ...)
  2020-06-16 13:04     ` Jeff King
@ 2020-06-17 20:56     ` Johannes Sixt
  2020-06-17 21:16       ` Junio C Hamano
  4 siblings, 1 reply; 178+ messages in thread
From: Johannes Sixt @ 2020-06-17 20:56 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Schindelin

Am 15.06.20 um 14:50 schrieb Johannes Schindelin via GitGitGadget:
> @@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
>  			strbuf_addf(out, " of %s", srcs.items[i].string);
>  	}
>  
> -	if (!strcmp("master", current_branch))
> +	main_branch = git_main_branch_name();
> +	if (!strcmp(main_branch, current_branch))
>  		strbuf_addch(out, '\n');
>  	else
>  		strbuf_addf(out, " into %s\n", current_branch);
> +	free(main_branch);
>  }

Now that the removal of this special case is on the plate, I would
prefer that the phrase "into foo" is never appended instead of always
appended.

For me, it was a always more of a hindrance than a help. The story goes
like this: A branch that I'm working on was named "edit-box-fix"
yesterday, but today it was renamed to "layout-fix" because the scope
changed. I had merged a topic "rename-buttons" yesterday, and now I have
to go back and rename that "into edit-box-fix" thing! Argh! And tomorrow
I'm going to branch off yet another feature "optional-reset" from
today's state that will be merged into upstream soon; "Merge branch
'rename-buttons' into layout-fix" will read strange in a history that
ends in "Merge branch 'optional-reset'".

And I haven't even mentioned this horrid "into HEAD", which you get
during a rebase operation.

To be clear, the branch name in "Merge branch 'option-reset'" is very
important and invaluable. But the "into foo" part is mostly noise.

-- Hannes

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-17 20:56     ` Johannes Sixt
@ 2020-06-17 21:16       ` Junio C Hamano
  2020-06-23 21:12         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-17 21:16 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Schindelin

Johannes Sixt <j6t@kdbg.org> writes:

> Am 15.06.20 um 14:50 schrieb Johannes Schindelin via GitGitGadget:
>> @@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
>>  			strbuf_addf(out, " of %s", srcs.items[i].string);
>>  	}
>>  
>> -	if (!strcmp("master", current_branch))
>> +	main_branch = git_main_branch_name();
>> +	if (!strcmp(main_branch, current_branch))
>>  		strbuf_addch(out, '\n');
>>  	else
>>  		strbuf_addf(out, " into %s\n", current_branch);
>> +	free(main_branch);
>>  }
>
> Now that the removal of this special case is on the plate, I would
> prefer that the phrase "into foo" is never appended instead of always
> appended.

I do not mind such an optional feature.  I always find it useful
whenever I read "git log --oneline --first-parent master..pu" (of
course I have an alias for that) to see which topics are already in
my private "to be used in real life" edition, so I would oppose to
an unconditional removal, though.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
  2020-06-17 18:16       ` Junio C Hamano
@ 2020-06-17 21:23         ` Jeff King
  2020-06-18  2:06           ` Elijah Newren
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-17 21:23 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Junio C Hamano via GitGitGadget, git, don, stolee, sandals,
	Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Johannes Schindelin

On Wed, Jun 17, 2020 at 11:16:05AM -0700, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > Of course that only helps you for _one_ branch. A more generally useful
> > mechanism would be to teach fast-export to write the ref mapping (and
> > perhaps file mappings, etc) to a separate file. Then you could convert
> > any reproduction recipe to use the anonymized names, and share only that
> > recipe along with the anonymized dump. But that's _way_ outside the
> > scope of your series. This seems like a good interim step to retain the
> > status quo.
> 
> Actually, dropping this special case, and dropping the other special
> case with fmt-merge-msg, we can do without the notion of the
> "primary" branch.

That leaves us in the interim with a "fast-export --anonymize" that is a
little harder to use (you have no way to know which branch was which).

But I don't mind at all implementing the map-dumping feature to help
move this along. As long as both make it into the same release, then
fast-export only gets better, and never regresses. :)

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
  2020-06-17 21:23         ` Jeff King
@ 2020-06-18  2:06           ` Elijah Newren
  2020-06-18  6:30             ` Junio C Hamano
  2020-06-18 11:45             ` Jeff King
  0 siblings, 2 replies; 178+ messages in thread
From: Elijah Newren @ 2020-06-18  2:06 UTC (permalink / raw)
  To: Jeff King
  Cc: Junio C Hamano, Junio C Hamano via GitGitGadget,
	Git Mailing List, Don Goodman-Wilson, Derrick Stolee,
	brian m. carlson, Matt Rogers, Eric Sunshine, Taylor Blau,
	Phillip Wood, Alban Gruin, Johannes Sixt, Johannes Schindelin

On Wed, Jun 17, 2020 at 2:25 PM Jeff King <peff@peff.net> wrote:
>
> On Wed, Jun 17, 2020 at 11:16:05AM -0700, Junio C Hamano wrote:
>
> > Jeff King <peff@peff.net> writes:
> >
> > > Of course that only helps you for _one_ branch. A more generally useful
> > > mechanism would be to teach fast-export to write the ref mapping (and
> > > perhaps file mappings, etc) to a separate file. Then you could convert
> > > any reproduction recipe to use the anonymized names, and share only that
> > > recipe along with the anonymized dump. But that's _way_ outside the
> > > scope of your series. This seems like a good interim step to retain the
> > > status quo.
> >
> > Actually, dropping this special case, and dropping the other special
> > case with fmt-merge-msg, we can do without the notion of the
> > "primary" branch.
>
> That leaves us in the interim with a "fast-export --anonymize" that is a
> little harder to use (you have no way to know which branch was which).

Why does fast-export special case on "master" rather than on HEAD?
Isn't it more relevant to know the active branch than what _might_
have been the initial branch?  It kind of feels like a bug to me that
HEAD isn't the special case construct.

(Speaking as someone whose company a number of years ago had most
their big repos and lots of little repos switch their main branch to
be named "develop", and in some of those repos deleted "master" but
didn't in others.  If I had needed some steps to reproduce a problem,
and hadn't been on the inside, any special casing from fast-export
would make more sense to me to apply to "develop" than to "master".)

> But I don't mind at all implementing the map-dumping feature to help
> move this along. As long as both make it into the same release, then
> fast-export only gets better, and never regresses. :)

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
  2020-06-18  2:06           ` Elijah Newren
@ 2020-06-18  6:30             ` Junio C Hamano
  2020-06-18  7:13               ` Elijah Newren
  2020-06-18 11:45             ` Jeff King
  1 sibling, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-18  6:30 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Jeff King, Junio C Hamano via GitGitGadget, Git Mailing List,
	Don Goodman-Wilson, Derrick Stolee, brian m. carlson,
	Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Johannes Schindelin

Elijah Newren <newren@gmail.com> writes:

>> That leaves us in the interim with a "fast-export --anonymize" that is a
>> little harder to use (you have no way to know which branch was which).
>
> Why does fast-export special case on "master" rather than on HEAD?
> Isn't it more relevant to know the active branch than what _might_
> have been the initial branch?  It kind of feels like a bug to me that
> HEAD isn't the special case construct.

I am torn on that one.  Surely HEAD is often the branch that has our
current attention.  It may well be what we are exporting and we may
want to see the topology formed by other refs relative to it.

On the other hand, the current branch may not necessarily be what we
are exporting.  Historically a project has a single branch that is
the focus of most users' attention when they talk about the general
state of the project's progress, so it is understandable to expect
that the topology may want to be seen relative to that one central
line of development.

> (Speaking as someone whose company a number of years ago had most
> their big repos and lots of little repos switch their main branch to
> be named "develop", and in some of those repos deleted "master" but
> didn't in others.  If I had needed some steps to reproduce a problem,
> and hadn't been on the inside, any special casing from fast-export
> would make more sense to me to apply to "develop" than to "master".)

Yes, absolutely.  You either check "develop" out temporarily just to
take anonymized export to make "develop" discoverable in the output,
or you would have set core.primaryBranch to "develop" once sometime
in the past to tell Git that "develop" is that special one, not
"master", so you can take such an export from any branch.  As the
anonymized export is primarily/solely a debugging aid, convenience
would not be of much value, but the latter feels more convenient to
me.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
  2020-06-18  6:30             ` Junio C Hamano
@ 2020-06-18  7:13               ` Elijah Newren
  0 siblings, 0 replies; 178+ messages in thread
From: Elijah Newren @ 2020-06-18  7:13 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Junio C Hamano via GitGitGadget, Git Mailing List,
	Don Goodman-Wilson, Derrick Stolee, brian m. carlson,
	Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Johannes Schindelin

Hi Junio,

On Wed, Jun 17, 2020 at 11:30 PM Junio C Hamano <gitster@pobox.com> wrote:
>
> Elijah Newren <newren@gmail.com> writes:
>
> >> That leaves us in the interim with a "fast-export --anonymize" that is a
> >> little harder to use (you have no way to know which branch was which).
> >
> > Why does fast-export special case on "master" rather than on HEAD?
> > Isn't it more relevant to know the active branch than what _might_
> > have been the initial branch?  It kind of feels like a bug to me that
> > HEAD isn't the special case construct.
>
> I am torn on that one.  Surely HEAD is often the branch that has our
> current attention.  It may well be what we are exporting and we may
> want to see the topology formed by other refs relative to it.
>
> On the other hand, the current branch may not necessarily be what we
> are exporting.  Historically a project has a single branch that is
> the focus of most users' attention when they talk about the general
> state of the project's progress, so it is understandable to expect
> that the topology may want to be seen relative to that one central
> line of development.

I'm trying to understand here, but I feel like I'm missing something.
Let me try to explain what I understand and hopefully you can figure
out what I'm not seeing...


Regardless of what is mainline and whether or not it is important,
users probably trigger their bug when a certain branch is checked out.
Their bug may also trigger on other branches, but it at least triggers
on one, and some bugs will only trigger on one branch.  It seems
logical to me that we would want to have the same branch checked out
(it's the one most likely to trigger the same issue), and thus
identifying the HEAD branch is generally important.  (Mainline may be
too, I'm merely asserting that HEAD is important at this point.)

If users trigger their bug by providing various revision
specifications on the command line that compare multiple branches or
something, then we're already in the situation of needing to know how
to map more than one reference to anonymized ones in order to be able
to replicate their issue.  However, knowing the mainline might not
even help in this case; we instead need to know the anonymized form of
the references they are using, whatever those are, and mainline is
only useful if it happens to be one of them.

So, I think HEAD is always useful.  Additional references would
sometimes be useful, but it's not clear to me that mainline is one of
those additional references.  Maybe I'm just being dense, and I
apologize if so, but under what circumstances does knowing the
mainline help with debugging a user issue where an anonymized
fast-export is provided?

> > (Speaking as someone whose company a number of years ago had most
> > their big repos and lots of little repos switch their main branch to
> > be named "develop", and in some of those repos deleted "master" but
> > didn't in others.  If I had needed some steps to reproduce a problem,
> > and hadn't been on the inside, any special casing from fast-export
> > would make more sense to me to apply to "develop" than to "master".)
>
> Yes, absolutely.  You either check "develop" out temporarily just to
> take anonymized export to make "develop" discoverable in the output,

That makes sense; if the bug triggers while they are on develop then
I'd expect them to be on develop when they export.  If it triggers on
some other branch, I'd expect them to stay on that other branch when
they export even if "develop" is the mainline.

> or you would have set core.primaryBranch to "develop" once sometime
> in the past to tell Git that "develop" is that special one, not
> "master", so you can take such an export from any branch.

This doesn't make sense to me.  The person who changed the primary
branch to "develop" for some repository did so years ago.  That
individual might not even still be at the company, and even if they
are, may well be working on a totally different project (and
repository) today.  Perhaps that individual set core.primaryBranch at
the time, but git-config settings aren't copied by fetch/clone/push,
so I don't see how this one helps at all.  We could tell all future
developers who clone any of these repositories that they also need to
set core.primaryBranch when they clone the repo, but that seems super
lame to me especially since the odds that any one of them will ever
need or benefit from it are approximately 0.  And yet, it'll be one of
these developers who joined the project long after the switchover who
runs into problems and provides fast-export dumps.


It feels like I'm probably just missing something obvious, but I
really don't see how the mainline is special here.  Please do point
out what I'm missing.

Thanks,
Elijah

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
  2020-06-16 13:10       ` Jeff King
  2020-06-16 15:49         ` Phillip Wood
@ 2020-06-18 10:08         ` Johannes Schindelin
  1 sibling, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-18 10:08 UTC (permalink / raw)
  To: Jeff King
  Cc: phillip.wood, Johannes Schindelin via GitGitGadget, git, don,
	stolee, sandals, Matt Rogers, Eric Sunshine, Taylor Blau,
	Alban Gruin, Johannes Sixt

Hi Peff,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Mon, Jun 15, 2020 at 04:05:52PM +0100, Phillip Wood wrote:
>
> > > @@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname)
> > >   	};
> > >   	static struct hashmap refs;
> > >   	static struct strbuf anon = STRBUF_INIT;
> > > +	static char *main_branch;
> > [...]
> > > -	if (!strcmp(refname, "refs/heads/master"))
> > > +	if (!main_branch)
> > > +		main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
> > > +
> > > +	if (!strcmp(refname, main_branch))
> > >   		return "refs/heads/ref0";
> >
> > This leaks main_branch if it came from git_main_branch_name()
>
> It's a static that's used over and over, so I think it's intentional to
> essentially memoize it for the life of the program (at which point we
> could free it, but don't bother to do so, letting the process exit take
> care of it, and trusting in leak detectors to be aware that it's still
> reachable, as we do for lots of other process-lifetime allocations).

That is indeed the intention, and I will edit the commit message
accordingly.

Thanks,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-16 12:25           ` Jeff King
@ 2020-06-18 10:17             ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-18 10:17 UTC (permalink / raw)
  To: Jeff King
  Cc: Alban Gruin, Junio C Hamano, Don Goodman-Wilson via GitGitGadget,
	git, don, stolee, sandals

Hi Peff,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Sun, Jun 14, 2020 at 10:57:41AM +0200, Johannes Schindelin wrote:
>
> > > >> Why adding yet another environment variable instead of relying only on a
> > > >> config option?  I understand it's for the tests, but can't we add a
> > > >> shell function in test-lib.sh (and friends) that tries to read
> > > >> `GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets
> > > >> `core.defaultBranchName'?
> > > >
> > > > Can you produce such a patch that does it cleanly?  My knee jerk
> > > > reaction is that I would suspect that you end up having to touch
> > > > many places in the t/ scripts, but if you prove otherwise, that
> > > > would certainly be appreciated.
> > > >
> > > > And no,
> > > >
> > > >     git () { command git -c core.defaultBranchName=master "$@" }
> > > >
> > > > is not an acceptable solution.
> > > >
> > >
> > > I wanted to to do something like this:
> > >
> > >   if test -n "$GIT_TEST_DEFAULT_BRANCH_NAME";
> > >   then
> > >       git config core.defaultBranchName "$GIT_TEST_DEFAULT_BRANCH_NAME"
> > >   fi
> > >
> > > But since we do not have a repository to store the config, it won't
> > > work.  Sorry for the noise.
> >
> > We actually would have `~/.gitconfig` because `HOME` is set to `t/trash
> > directory.<test-name>/`.
> >
> > However, that would cause all kinds of issues when test scripts expect the
> > directory to be pristine, containing only `.git/` but not `.gitconfig`.
>
> Putting:
>
>   GIT_CONFIG_PARAMETERS="'core.defaultBranchName=...'"
>
> into the environment would work (and yes, you need the single quotes
> embedded in the variable), and solves all of the complaints above.
> Further "git -c" invocations properly append to it. But:
>
>   - there are a few tests which explicitly tweak that variable
>
>   - it technically changes any tests of "-c" because now we'd never
>     cover the case where we start without the variable defined

Indeed.

> I think baking in a special environment variable like you have is not so
> bad. If this did become too common a pattern, though (special test-only
> environment variables that do have a separate config option), I wouldn't
> be opposed to a GIT_TEST_CONFIG_PARAMETERS which takes precedence over
> other config, and comes with a big warning label that it shouldn't be
> relied upon outside the test suite. That's equally ugly to
> GIT_TEST_DEFAULT_BRANCH_NAME, but at least solves the problem once for
> all of them. I'm just not sure we have enough "all of them" to make it
> worth doing.

FWIW I do not plan on using that variable for a long time. And it is not
in this here patch series any longer, so let's discuss it in the future
patch contribution of mine.

Thanks,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 2/9] remote: respect `core.defaultBranchName`
  2020-06-16 12:35   ` Jeff King
@ 2020-06-18 10:21     ` Johannes Schindelin
  2020-06-18 11:50       ` Jeff King
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-18 10:21 UTC (permalink / raw)
  To: Jeff King; +Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals

Hi Peff,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Wed, Jun 10, 2020 at 09:19:23PM +0000, Johannes Schindelin via GitGitGadget wrote:
>
> > @@ -2099,7 +2100,10 @@ struct ref *guess_remote_head(const struct ref *head,
> >
> >  	/* If refs/heads/master could be right, it is. */
> >  	if (!all) {
> > -		r = find_ref_by_name(refs, "refs/heads/master");
> > +		char *name = git_default_branch_name(0);
> > +
> > +		r = find_ref_by_name(refs, name);
> > +		free(name);
> >  		if (r && oideq(&r->old_oid, &head->old_oid))
> >  			return copy_ref(r);
> >  	}
>
> You'd perhaps want to update the comment above, too.
>
> However, I think we should be a bit more lenient on the "reading" side
> default names. Just because "foo" is _my_ default branch name, does not
> mean it is the default on the remote side. We cannot know what the other
> side's default preference is, but in a world where we have 15 years of
> repos that may have been created with "master", it is probably still a
> good guess.
>
> I.e., I think this probably ought to check the preferred name, and then
> fall back to the existing behavior, like:
>
>   if (!all) {
> 	  char *name;
>
>           /* try the user's preferred default branch name */
> 	  name = git_default_branch_name(0);
> 	  r = find_ref_by_name(refs, name);
> 	  free(name);
> 	  if (r && oideq(&r->old_oid, &head->old_oid))
> 	          return copy_ref(r);
>
> 	  /* otherwise, try "master", which is the historical default */
> 	  r = find_ref_by_name(refs, "refs/heads/master");
> 	  if (r && oideq(&r->old_oid, &head->old_oid))
> 	          return copy_ref(r);
>   }
>
> That will help minimize fallout when git_default_branch_name() changes,
> either by user config or if we switch the baked-in default. In the
> latter case, we might also consider hard-coding that as a guess between
> the user's preferred name and the historical "master".
>
> Hopefully this would not matter _too_ much either way, as most servers
> would support the symref extension these days. But I still think we
> should do our best to minimize spots where the user may see a
> regression.

Sure, we could just leave this alone, or we can just ditch the
special-casing of `master` here.

As you say, this does not affect any modern Git version, and IIRC the code
after that special-casing tries to find any remote ref that matches the
remote `HEAD`.

So it's not like we _need_ this special-casing, anyway.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
  2020-06-18  2:06           ` Elijah Newren
  2020-06-18  6:30             ` Junio C Hamano
@ 2020-06-18 11:45             ` Jeff King
  1 sibling, 0 replies; 178+ messages in thread
From: Jeff King @ 2020-06-18 11:45 UTC (permalink / raw)
  To: Elijah Newren
  Cc: Junio C Hamano, Junio C Hamano via GitGitGadget,
	Git Mailing List, Don Goodman-Wilson, Derrick Stolee,
	brian m. carlson, Matt Rogers, Eric Sunshine, Taylor Blau,
	Phillip Wood, Alban Gruin, Johannes Sixt, Johannes Schindelin

On Wed, Jun 17, 2020 at 07:06:26PM -0700, Elijah Newren wrote:

> > That leaves us in the interim with a "fast-export --anonymize" that is a
> > little harder to use (you have no way to know which branch was which).
> 
> Why does fast-export special case on "master" rather than on HEAD?
> Isn't it more relevant to know the active branch than what _might_
> have been the initial branch?  It kind of feels like a bug to me that
> HEAD isn't the special case construct.

I don't really remember my exact thought at the time, but it was
probably along the lines of: "master" is special not because it's
inherently special, but because revealing it doesn't compromise the
anonymity, since it's not a user-selected name.

That's not true of other names we might see in HEAD. But if we're
turning it into "ref0" or some other special name anyway, then we
haven't revealed anything.

That said, I still lean towards just being able to dump the whole
mapping by request. That solves this problem and many more.

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 2/9] remote: respect `core.defaultBranchName`
  2020-06-18 10:21     ` Johannes Schindelin
@ 2020-06-18 11:50       ` Jeff King
  2020-06-23 21:15         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Jeff King @ 2020-06-18 11:50 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals

On Thu, Jun 18, 2020 at 12:21:30PM +0200, Johannes Schindelin wrote:

> > Hopefully this would not matter _too_ much either way, as most servers
> > would support the symref extension these days. But I still think we
> > should do our best to minimize spots where the user may see a
> > regression.
> 
> Sure, we could just leave this alone, or we can just ditch the
> special-casing of `master` here.
> 
> As you say, this does not affect any modern Git version, and IIRC the code
> after that special-casing tries to find any remote ref that matches the
> remote `HEAD`.

I think we need to be a little careful with "any modern Git", because a
modern client against an old (or perhaps an alternative implementation)
server might still use it. I have to imagine it's pretty rare, but I
think it's still useful to return _some_ value.

But as you note, even without a symref extension, we already try to
guess based on a unique branch. Probably even choosing the first one
alphabetically would be reasonable. But I'd rather err on the side of
historical compatibility if we can do so easily. Looking for
init.mainBranch, followed by master, accomplishes that and isn't many
lines of code.

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-16 12:47       ` Jeff King
@ 2020-06-18 13:08         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-18 13:08 UTC (permalink / raw)
  To: Jeff King
  Cc: Eric Sunshine, Don Goodman-Wilson via GitGitGadget, Git List,
	Derrick Stolee, brian m. carlson, Don Goodman-Wilson

Hi Peff,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Tue, Jun 16, 2020 at 08:45:02AM -0400, Jeff King wrote:
>
> > On Wed, Jun 10, 2020 at 08:16:38PM -0400, Eric Sunshine wrote:
> >
> > > > +/*
> > > > + * Retrieves the name of the default branch. If `short_name` is non-zero, the
> > > > + * branch name will be prefixed with "refs/heads/".
> > > > + */
> > > > +char *git_default_branch_name(int short_name);
> > >
> > > Overall, the internal logic regarding duplicating/freeing strings
> > > would probably be easier to grok if there were two separate functions:
> > >
> > >     char *git_default_branch_name(void);
> > >     char *git_default_ref_name(void);
> > >
> > > but that's subjective.
> >
> > Having seen one of the callers, might it be worth avoiding handing off
> > ownership of the string entirely?
> >
> > I.e., this comes from a string that's already owned for the lifetime of
> > the process (either the environment, or a string stored by the config
> > machinery). Could we just pass that back (or if we want to be more
> > careful about getenv() lifetimes, we can copy it into a static owned by
> > this function)?
> >
> > Then all of the callers can stop dealing with the extra free(), and you
> > can do:
> >
> >   const char *git_default_branch_name(void)
> >   {
> > 	return skip_prefix("refs/heads/", git_default_ref_name());
> >   }
>
> Actually, one small hiccup is that the config option specifies the
> branch name, not the ref name. So you really would have to prepare a
> static-owned copy of it to turn "foo" into "refs/heads/foo" to get the
> refname.
>
> On the other hand, that would also be a good time to run
> check_ref_format(). In the patch as-is, the "short" return does not
> check that the branch is a valid name.

Legit.

I will work on this.

Thanks,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-17 18:23       ` Junio C Hamano
@ 2020-06-18 13:15         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-18 13:15 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Jeff King, Johannes Schindelin via GitGitGadget, git, don,
	stolee, sandals, Matt Rogers, Eric Sunshine, Taylor Blau,
	Phillip Wood, Alban Gruin, Johannes Sixt

Hi,

On Wed, 17 Jun 2020, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
>
> > I'm not sure if this check_refname_format() is valid, though. IIRC we've
> > had issues where "ONELEVEL" was used to check a branch name, but misses
> > some cases. The more full check done by strbuf_check_branch_ref()
> > actually creates the full refname and checks that. It also catches stuff
> > like refs/heads/HEAD.
>
> Yup.
>
> I actually am in favor of removing special casing of a single branch
> done by fmt-merge-msg and fast-export --anonymize, so this may not
> matter.
>
> We still need a mechanism to allow users specify the default name to
> be given to the first branch "git init" creates and used by "git clone"
> as a fallback name when it cannot infer what the other side uses, though.

All right, `core.mainBranch` will go, then, and `init.defaultBranch` will
stay and I will check the full ref.

Thank you for your help improving the patch series,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-15 15:00     ` Phillip Wood
@ 2020-06-23 12:31       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 12:31 UTC (permalink / raw)
  To: phillip.wood
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Alban Gruin,
	Johannes Sixt

Hi Phillip,

On Mon, 15 Jun 2020, Phillip Wood wrote:

> On 15/06/2020 13:50, Johannes Schindelin via GitGitGadget wrote:
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > There is a growing number of projects and companies desiring to change
> > the main branch name of their repositories (see e.g.
> > https://twitter.com/mislav/status/1270388510684598272 for background on
> > this).
>
> I think this is a good way of phrasing the rationale for the change

As I am replacing this patch in v3 with a version that simply drops the
special handling of the `master` branch, I moved that rationale into the
patch introducing support for `git init --initial-branch=<name>`.

> > However, there are a couple of hard-coded spots in Git's source code
> > that make this endeavor harder than necessary. For example, when
> > formatting the commit message for merge commits, Git appends "into
> > <branch-name>" unless the current branch is the `master` branch.
> >
> > Clearly, this is not what one wants when already having gone through all
> > the steps to manually rename the main branch
>
> This didn't quite scan for me maybe s/already having/one has already/ ?

Thank you! If I had not dropped that part of the commit message, I would
have taken your suggested fix.

> > (and taking care of all the
> > fall-out such as re-targeting existing Pull Requests).
> >
> > Let's introduce a way to override Git's hard-coded default:
> > `core.mainBranch`.
> >
> > We will start supporting this config option in the `git fmt-merge-msg`
> > command and successively adjust all other places where the main branch
> > name is hard-coded.
> >
> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> > ---
> >   Documentation/config/core.txt |  5 +++++
> >   fmt-merge-msg.c               |  6 ++++--
> >   refs.c                        | 27 +++++++++++++++++++++++++++
> >   refs.h                        |  7 +++++++
> >   t/t6200-fmt-merge-msg.sh      |  7 +++++++
> >   5 files changed, 50 insertions(+), 2 deletions(-)
> >
> > diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt
> > index 74619a9c03b..32bb5368ebb 100644
> > --- a/Documentation/config/core.txt
> > +++ b/Documentation/config/core.txt
> > @@ -626,3 +626,8 @@ core.abbrev::
> >    in your repository, which hopefully is enough for
> >    abbreviated object names to stay unique for some time.
> >    The minimum length is 4.
> > +
> > +core.mainBranch::
> > +	The name of the main (or: primary) branch in the current repository.
> > +	For historical reasons, `master` is used as the fall-back for this
> > +	setting.
> > diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
> > index 72d32bd73b1..43f4f829242 100644
> > --- a/fmt-merge-msg.c
> > +++ b/fmt-merge-msg.c
> > @@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
> >   				const char *current_branch)
> >   {
> >   	int i = 0;
> > -	char *sep = "";
> > +	char *sep = "", *main_branch;
> >
> >    strbuf_addstr(out, "Merge ");
> >    for (i = 0; i < srcs.nr; i++) {
> > @@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
> >    		strbuf_addf(out, " of %s", srcs.items[i].string);
> >    }
> >   -	if (!strcmp("master", current_branch))
> > +	main_branch = git_main_branch_name();
> > +	if (!strcmp(main_branch, current_branch))
> >    	strbuf_addch(out, '\n');
> >    else
> >   		strbuf_addf(out, " into %s\n", current_branch);
> > +	free(main_branch);
> >   }
> >
> >   static void fmt_tag_signature(struct strbuf *tagbuf,
> > diff --git a/refs.c b/refs.c
> > index 224ff66c7bb..f1854cffa2f 100644
> > --- a/refs.c
> > +++ b/refs.c
> > @@ -560,6 +560,33 @@ void expand_ref_prefix(struct argv_array *prefixes,
> > const char *prefix)
> >   		argv_array_pushf(prefixes, *p, len, prefix);
> >   }
> >
> > +char *repo_main_branch_name(struct repository *r)
> > +{
> > +	const char *config_key = "core.mainbranch";
> > +	const char *config_display_key = "core.mainBranch";
> > +	const char *fall_back = "master";
> > +	char *name = NULL, *ret;
> > +
> > +	if (repo_config_get_string(r, config_key, &name) < 0)
> > +		die(_("could not retrieve `%s`"), config_display_key);
> > +
> > +	ret = name ? name : xstrdup(fall_back);
> > +
> > +	if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
> > +		die(_("invalid branch name: %s = %s"),
> > +		    config_display_key, name);
> > +
> > +	if (name != ret)
> > +		free(name);
>
> I'm struggling to come up with a scenario where name != NULL && name != ret
> here, however once we get to patch 4 that scenario definitely does exist.

Right.

But as I am dropping the concept of `core.mainBranch` from v3, this won't
apply anymore.

>
> > +
> > +	return ret;
> > +}
> > +
> > +char *git_main_branch_name(void)
> > +{
> > +	return repo_main_branch_name(the_repository);
> > +}
> > +
> >   /*
> >    * *string and *len will only be substituted, and *string returned (for
> >    * later free()ing) if the string passed in is a magic short-hand form
> > diff --git a/refs.h b/refs.h
> > index a92d2c74c83..a207ef01348 100644
> > --- a/refs.h
> > +++ b/refs.h
> > @@ -154,6 +154,13 @@ int repo_dwim_log(struct repository *r, const char
> > *str, int len, struct object_
> >   int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
> >   int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
> >
> > +/*
> > + * Retrieves the name of the main (or: primary) branch of the given
>
> nit pick, I'm confused by the ':'

Right, v3 won't have that peculiar construct.

Thank you for your review!
Dscho

>
> Best Wishes
>
> Phillip
>
> > + * repository.
> > + */
> > +char *git_main_branch_name(void);
> > +char *repo_main_branch_name(struct repository *r);
> > +
> >   /*
> >    * A ref_transaction represents a collection of reference updates that
> >    * should succeed or fail together.
> > diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
> > index e4c2a6eca43..7a873f4a05c 100755
> > --- a/t/t6200-fmt-merge-msg.sh
> > +++ b/t/t6200-fmt-merge-msg.sh
> > @@ -158,6 +158,13 @@ test_expect_success 'setup FETCH_HEAD' '
> >   	git fetch . left
> >   '
> >
> > +test_expect_success 'with overridden default branch name' '
> > +	test_when_finished "git switch master" &&
> > +	git switch -c default &&
> > +	git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual
> > &&
> > +	! grep "into default" actual
> > +'
> > +
> >   test_expect_success 'merge.log=3 limits shortlog length' '
> >    cat >expected <<-EOF &&
> >    Merge branch ${apos}left${apos}
> >
>
>

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 04/12] git_main_branch_name(): optionally report the full ref name
  2020-06-15 15:04     ` Phillip Wood
@ 2020-06-23 19:17       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 19:17 UTC (permalink / raw)
  To: phillip.wood
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Alban Gruin,
	Johannes Sixt

Hi Phillip,

On Mon, 15 Jun 2020, Phillip Wood wrote:

> On 15/06/2020 13:50, Johannes Schindelin via GitGitGadget wrote:
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > We are about to introduce the first caller of that function (`git
> > fast-export`) that wants a full ref name instead of the short branch
> > name.
> >
> > To make this change easier to review, let's refactor the function
> > accordingly without mixing in the actual first call using the new flag.
> >
> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> > ---
> >   fmt-merge-msg.c    |  2 +-
> >   refs.c             | 12 ++++++++----
> >   refs.h             |  8 ++++++--
> >   send-pack.c        |  2 +-
> >   transport-helper.c |  2 +-
> >   5 files changed, 17 insertions(+), 9 deletions(-)
> >
> > diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
> > index 43f4f829242..03dba905643 100644
> > --- a/fmt-merge-msg.c
> > +++ b/fmt-merge-msg.c
> > @@ -451,7 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
> >    		strbuf_addf(out, " of %s", srcs.items[i].string);
> >    }
> >   -	main_branch = git_main_branch_name();
> > +	main_branch = git_main_branch_name(0);
> >    if (!strcmp(main_branch, current_branch))
> >    	strbuf_addch(out, '\n');
> >   	else
> > diff --git a/refs.c b/refs.c
> > index f1854cffa2f..7da3ac178c4 100644
> > --- a/refs.c
> > +++ b/refs.c
> > @@ -560,8 +560,9 @@ void expand_ref_prefix(struct argv_array *prefixes,
> > const char *prefix)
> >   		argv_array_pushf(prefixes, *p, len, prefix);
> >   }
> >
> > -char *repo_main_branch_name(struct repository *r)
> > +char *repo_main_branch_name(struct repository *r, int flags)
> >   {
> > +	int full_name = flags & MAIN_BRANCH_FULL_NAME;
> >    const char *config_key = "core.mainbranch";
> >    const char *config_display_key = "core.mainBranch";
> >    const char *fall_back = "master";
> > @@ -570,7 +571,10 @@ char *repo_main_branch_name(struct repository *r)
> >    if (repo_config_get_string(r, config_key, &name) < 0)
> >     die(_("could not retrieve `%s`"), config_display_key);
> >   -	ret = name ? name : xstrdup(fall_back);
> > +	if (full_name)
> > +		ret = xstrfmt("refs/heads/%s", name ? name : fall_back);
> > +	else
> > +		ret = name ? name : xstrdup(fall_back);
>
> This looks good, we always check the name before returning it and free name if
> we're returning refs/heads/<name>
>
> >    if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
> >   		die(_("invalid branch name: %s = %s"),
> > @@ -582,9 +586,9 @@ char *repo_main_branch_name(struct repository *r)
> >   	return ret;
> >   }
> >
> > -char *git_main_branch_name(void)
> > +char *git_main_branch_name(int flags)
> >   {
> > -	return repo_main_branch_name(the_repository);
> > +	return repo_main_branch_name(the_repository, flags);
> >   }
> >
> >   /*
> > diff --git a/refs.h b/refs.h
> > index a207ef01348..96472f9a9f5 100644
> > --- a/refs.h
> > +++ b/refs.h
> > @@ -157,9 +157,13 @@ int dwim_log(const char *str, int len, struct object_id
> > *oid, char **ref);
> >   /*
> >    * Retrieves the name of the main (or: primary) branch of the given
> >    * repository.
> > + *
> > + * The result is an allocated string. Unless the flags ask for a short
> > name, it
> > + * will be prefixed with "refs/heads/".
> >    */
>
> nit pick: the flag is defined to give the fullname, to get the short name you
> just pass 0.

I decided to drop the flag and always return the name, not the full ref.
It makes the code _slightly_ less efficient, but easier to follow.

Ciao,
Dscho

>
> Best Wishes
>
> Phillip
>
> > -char *git_main_branch_name(void);
> > -char *repo_main_branch_name(struct repository *r);
> > +#define MAIN_BRANCH_FULL_NAME (1<<0)
> > +char *git_main_branch_name(int flags);
> > +char *repo_main_branch_name(struct repository *r, int flags);
> >
> >   /*
> >    * A ref_transaction represents a collection of reference updates that
> > diff --git a/send-pack.c b/send-pack.c
> > index 2532864c812..898720511d0 100644
> > --- a/send-pack.c
> > +++ b/send-pack.c
> > @@ -405,7 +405,7 @@ int send_pack(struct send_pack_args *args,
> >    }
> >
> >   	if (!remote_refs) {
> > -		char *branch_name = git_main_branch_name();
> > +		char *branch_name = git_main_branch_name(0);
> >
> >     fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
> >   			"Perhaps you should specify a branch such as '%s'.\n",
> > diff --git a/transport-helper.c b/transport-helper.c
> > index 8c8f40e322d..7a54e5b2fb2 100644
> > --- a/transport-helper.c
> > +++ b/transport-helper.c
> > @@ -1044,7 +1044,7 @@ static int push_refs(struct transport *transport,
> >    }
> >
> >   	if (!remote_refs) {
> > -		char *branch_name = git_main_branch_name();
> > +		char *branch_name = git_main_branch_name(0);
> >
> >     fprintf(stderr,
> >      _("No refs in common and none specified; doing nothing.\n"
> >
>

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-15 17:05     ` Junio C Hamano
@ 2020-06-23 19:19       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 19:19 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt

Hi Junio,

On Mon, 15 Jun 2020, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
> > index 72d32bd73b1..43f4f829242 100644
> > --- a/fmt-merge-msg.c
> > +++ b/fmt-merge-msg.c
> > @@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
> >  				const char *current_branch)
> >  {
> >  	int i = 0;
> > -	char *sep = "";
> > +	char *sep = "", *main_branch;
> >
> >  	strbuf_addstr(out, "Merge ");
> >  	for (i = 0; i < srcs.nr; i++) {
> > @@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
> >  			strbuf_addf(out, " of %s", srcs.items[i].string);
> >  	}
> >
> > -	if (!strcmp("master", current_branch))
> > +	main_branch = git_main_branch_name();
> > +	if (!strcmp(main_branch, current_branch))
> >  		strbuf_addch(out, '\n');
> >  	else
> >  		strbuf_addf(out, " into %s\n", current_branch);
> > +	free(main_branch);
>
> While you are at it, taking
>
> https://lore.kernel.org/git/20200614211500.GA22505@dcvr/
>
> and the response to it into consideration, I'd suggest we should
> support the case where the user says "no single branch is special
> here" by configuring it to an empty string.

Together with Peff's comments, I think we're even further than that: v3 of
this patch series will completely drop `core.mainBranch` and not
special-case *any* branch in `fmt-merge-msg`.

There is still merit in Hannes Sixt's wish to be able to turn off the
`into <branch>` suffix, but that is orthogonal to the purpose of this here
patch series.

Ciao,
Dscho

>
> > +core.mainBranch::
> > +	The name of the main (or: primary) branch in the current repository.
> > +	For historical reasons, `master` is used as the fall-back for this
> > +	setting.
>
> As to the naming of the configuration variable and the actual
> fall-back value, I would strongly suggest making them DIFFERNT
> (i.e. separate the concept from an actual value).
>
> An instruction
>
>     ... oh, if you want to do so, you can set the core.mainBranch
>     configuration variable to 'main'
>
> sounds strange than
>
>     ... oh, if you want to do so, you can set the core.primaryBranch
>     configuration variable to 'main'
>
> at least to me, and since I am OK with your choice of 'main' as the
> replacement for 'master', a separate word would be more appropriate
> for the variable name.
>
>

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
  2020-06-15 17:09     ` Junio C Hamano
@ 2020-06-23 19:22       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 19:22 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt

Hi Junio,

On Mon, 15 Jun 2020, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > +	 * While the main branch name might often be `main` for new
> > +	 * repositories (and `master` for aged ones), and such well-known names
>
> As I said, if you used a different word for the first 'main' in the
> sentence, it reads much better.
>
> > +	 * may not necessarily need anonymizing, it could be configured to use
> > +	 * a secret word that the user may not want to reveal.
> >  	 */
> > -	if (!strcmp(refname, "refs/heads/master"))
> > +	if (!main_branch)
> > +		main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
> > +
> > +	if (!strcmp(refname, main_branch))
> >  		return "refs/heads/ref0";
>
> The same comment as 02/12 applies here.  If the helper function
> returns "" when the user says that no branch is more special than
> others in the repository, the code would automatically do the right
> thing.

Seeing as the `fast-export` patches in this here patch series will be
dropped from v3, in favor of Peff's patches, this does no longer need to
be addressed.

> In any case, thanks for working on it.  I am on "vacation" so will
> be commenting on the rest of the series later in the week.

Welcome back! I hope you were able to rest.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-16  0:19     ` Denton Liu
@ 2020-06-23 20:10       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 20:10 UTC (permalink / raw)
  To: Denton Liu
  Cc: Pratyush Yadav, Johannes Schindelin via GitGitGadget, git, don,
	stolee, peff, sandals

Hi Denton,

On Mon, 15 Jun 2020, Denton Liu wrote:

> On Mon, Jun 15, 2020 at 12:26:03AM +0200, Johannes Schindelin wrote:
> > > For example, my vim plugins are submodules in the '~/.vim/bundle'
> > > directory. When I want to update them, I run:
> > >
> > >   git submodule foreach 'git remote update && git reset --hard origin/master'
> > >
> > > With this change hitting a Git release, more and more people would call
> > > their main branch different names they like. So what is the recommended
> > > way to do something like this now? How do I checkout the tip of the main
> > > branch? How do I push to the main branch? How do I pull from the main
> > > branch? And so on...
> >
> > ... has less to do with a new Git release, but more with the decision of
> > an existing project to change their main branch name.
> >
> > That's something users already had to deal with, of course. For example,
> > projects switching to the Git Flow model will start to use the main branch
> > name `development`.
>
> I brought this concern up in a parallel thread but I'll bring it up here
> too since it's relevant. Currently, in the .gitmodules file, if the
> branch is not specified, it defaults to 'master'.
>
> When I want to update my vim plugins, I run
> `git submodule update --remote` which pulls in all of my submodules'
> 'master' branches. By convention, a lack of `branch` key in .gitmodules
> conventionally means 'master'.
>
> With your change, it becomes the value of git_main_branch_name(), which
> is fine for now. However, if this value changes to something else, then
> when I update my Git, suddenly `git submodule update --remote` will be
> broken for me as all of the new repositories that I pull will be for an
> incorrect (and possibly missing) branch.
>
> This leaves us in a scenario where one developer running an older
> version of Git would have submodule updates work perfectly fine while a
> developer with a newer version would have it suddenly broken. This might
> be hard to debug, especially for someone who doesn't follow the release
> notes around Git and doesn't realise why the default has suddenly
> changed.
>
> This problem gets much worse if we allow the main branch name to be
> configurable as then the *private* configurations that a developer has
> may have an effect on the *publicly visible* behaviour of a repository.
>
> I think I see three possible solutions to this:
>
> 	1. Special case 'master' in submodules to retain backwards
> 	compatibility.
>
> 	I don't think this is very appealing as if the change is made to
> 	use another default branch name, then the "default" branch for
> 	submodules would be "master" even though the new default
> 	everywhere else would be different. And in the future, someone
> 	who doesn't know the context behind all of this would be very
> 	confused where there are two different default branch names.
>
> 	2. Disable 'update --remote' support for submodules that don't
> 	specify a branch.
>
> 	If Git detects that a branch key is missing when trying to do an
> 	'update --remote', it should just quit out and refuse to do
> 	anything. Of course, this a very backwards incompatible change
> 	and it would require several release cycles to implement where
> 	we warn users about this impending change before we actually
> 	make it happen.
>
> 	3. Make 'update --remote' get HEAD.
>
> 	I argue that this is how it always should've been implemented
> 	but, alas, I can't go back in time and fix it. Regardless, it
> 	might be good to flip this to be the default if we're going to
> 	be making the change anyway.
>
> 	Unfortunately, this suffers from both the problems of 1 and 2.
> 	As with 1, we'll end up in a situation where users with
> 	different versions of Git may experience different behaviours
> 	given the same public repository and I think this is definitely
> 	undesirable. With 2, this change will also require a long
> 	deprecation period which I don't think it compatible with how
> 	people seem to want the default branch switch to happen this
> 	release.
>
> So I dunno. I think my opinion leans on not changing the default branch
> at all. Since it seems like the consensus is generally that it _will_
> change, I think I would prefer options 3, 2 and 1 in that order.
>
> Thoughts?

My intuition matches your preference, and I have a strong preference for
3.

It took some banging my head (not my HEAD...) against the code to convince
myself that the patch I prepared for v3 is good: I managed to confuse
myself what with all those submodules and clones in t7406.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 0/9] Allow overriding the default name of the default branch
  2020-06-16 14:24     ` Jeff King
@ 2020-06-23 20:28       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 20:28 UTC (permalink / raw)
  To: Jeff King
  Cc: Ævar Arnfjörð Bjarmason,
	Johannes Schindelin via GitGitGadget, git, don, stolee, sandals

[-- Attachment #1: Type: text/plain, Size: 1665 bytes --]

Hi Peff & Ævar,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Tue, Jun 16, 2020 at 10:09:32AM -0400, Jeff King wrote:
>
> > I think with that, we could ditch core.mainBranch entirely, with no
> > notion at all of "this branch is special in this repo". We use HEAD
> > where appropriate, and otherwise avoid any specialness.
>
> One obvious exception is that third-party tools may want to know the
> "special" branch for some reason. But I'm inclined to say that they
> should (in this order):
>
>   - consider whether they really need a special branch at all, or if the
>     mechanism can be made more generic
>
>   - consider whether HEAD is the best value for a special branch (e.g.,
>     GitHub pull requests default to targeting HEAD)

Indeed, this is applicable in many circumstances. For example, instead of
https://github.com/git/git/blob/master/README.md it is just as easy (and
more robust) to write https://github.com/git/git/blob/HEAD/README.md.

The same goes for `git ls-remote origin HEAD` and as a consequence, `git
fetch origin HEAD`: it fetches the default branch of the remote
repository.

And with that, I could imagine that this is not actually necessary:

>   - rely on per-tool config for what's special (because it really may
>     vary between tools, and that's more flexible anyway)
>
> But I'm open to hearing about cases where some tool really wants to know
> "what did the user consider the special branch at the time of creation".

I cannot think of any use cases, apart from essentially creating a new
repository, where a tool or a user would want to know of such a
preference.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
  2020-06-16 12:45     ` Jeff King
  2020-06-16 12:47       ` Jeff King
@ 2020-06-23 20:32       ` Johannes Schindelin
  1 sibling, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 20:32 UTC (permalink / raw)
  To: Jeff King
  Cc: Eric Sunshine, Don Goodman-Wilson via GitGitGadget, Git List,
	Derrick Stolee, brian m. carlson, Don Goodman-Wilson

Hi Peff,


On Tue, 16 Jun 2020, Jeff King wrote:

> On Wed, Jun 10, 2020 at 08:16:38PM -0400, Eric Sunshine wrote:
>
> > > +/*
> > > + * Retrieves the name of the default branch. If `short_name` is non-zero, the
> > > + * branch name will be prefixed with "refs/heads/".
> > > + */
> > > +char *git_default_branch_name(int short_name);
> >
> > Overall, the internal logic regarding duplicating/freeing strings
> > would probably be easier to grok if there were two separate functions:
> >
> >     char *git_default_branch_name(void);
> >     char *git_default_ref_name(void);
> >
> > but that's subjective.
>
> Having seen one of the callers, might it be worth avoiding handing off
> ownership of the string entirely?

For `git_default_branch_name()`: yes. For `repo_default_branch_name()`,
not really, as that is potentially repository-specific.

(Side note: while I cannot really think of a use case where you would want
to set `init.defaultBranch` in a repository-local config, there _might_ be
use cases for that out there, and it _is_ how our config machinery works.)

> I.e., this comes from a string that's already owned for the lifetime of
> the process (either the environment, or a string stored by the config
> machinery). Could we just pass that back (or if we want to be more
> careful about getenv() lifetimes, we can copy it into a static owned by
> this function)?
>
> Then all of the callers can stop dealing with the extra free(), and you
> can do:
>
>   const char *git_default_branch_name(void)
>   {
> 	return skip_prefix("refs/heads/", git_default_ref_name());
>   }

For ease of use, I decided to only ever return the branch name (but check
the full ref).

Those callers that actually need the full ref usually also need the branch
name, and it is easy enough to call `xstrfmt("refs/heads/%s", ...)`.

It might make the code a bit less efficient (but who cares, it's not like
we're setting up a gazillion repositories per second all the time), but
quite a bit easier to reason about.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 09/12] clone: handle overridden main branch names
  2020-06-16 13:22     ` Jeff King
@ 2020-06-23 20:58       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 20:58 UTC (permalink / raw)
  To: Jeff King
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals,
	Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt

Hi Peff,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Mon, Jun 15, 2020 at 12:50:13PM +0000, Johannes Schindelin via GitGitGadget wrote:
>
> > diff --git a/builtin/clone.c b/builtin/clone.c
> > index 487b0a42d75..755fcaeb0ba 100644
> > --- a/builtin/clone.c
> > +++ b/builtin/clone.c
> > @@ -718,6 +718,7 @@ static void update_head(const struct ref *our, const struct ref *remote,
> >  		/* Local default branch link */
> >  		if (create_symref("HEAD", our->name, NULL) < 0)
> >  			die(_("unable to update HEAD"));
> > +		git_config_set("core.mainbranch", head);
> >  		if (!option_bare) {
> >  			update_ref(msg, "HEAD", &our->old_oid, NULL, 0,
> >  				   UPDATE_REFS_DIE_ON_ERR);
>
> Just making sure I understand what's going on here...
>
> This covers the case that we've run "clone -b foo" or similar, but there
> are two other case arms when "foo" is a tag, or the remote HEAD is
> unreachable. And there we don't set core.mainbranch at all.

It was actually meant to catch the case where the remote repository has a
default branch other than `master`.

> But we would not want it to be missing, because that will likely need to
> stay a default for "master" indefinitely (to keep behavior for existing
> repositories). However, it won't be missing. We'll always have set it
> during the init_db() call, and this is just overriding that. So we'd end
> update_head() with either:
>
>   - core.mainbranch set to the same branch we point HEAD to, whether we
>     got it from the remote side or from "-b foo"
>
>   - if we write a detached HEAD, then core.mainbranch remains at
>     init.mainbranch (or defaulting to "master" now, and probably "main"
>     later). We have no better option.
>
> If so, then that makes sense to me.

In any case, this does not matter anymore, as I am dropping
`core.mainBranch` from v3, as you had suggested elsewhere in this thread.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 11/12] submodule: use the correct default for the main branch name
  2020-06-16 13:46     ` Jeff King
@ 2020-06-23 21:03       ` Johannes Schindelin
  2020-06-23 21:14         ` Jeff King
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 21:03 UTC (permalink / raw)
  To: Jeff King
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals,
	Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt

Hi Peff,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Mon, Jun 15, 2020 at 12:50:15PM +0000, Johannes Schindelin via GitGitGadget wrote:
>
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > To allow for overriding the default branch name, we have introduced a
> > config setting. With this patch, the `git submodule` command learns
> > about this, too.
>
> This was the other reading case (besides guess_remote_head()) that I'm
> most concerned with causing regressions in a world where some repos are
> on "master" and some are on "main".
>
> This value ends up as the output of "submodule--helper remote-branch".
>
> I was initially worried that we used this branch name for the fallback
> when the server doesn't allow us to fetch the sha1 directly, but it
> doesn't look like it. That's good, because handling fallbacks there
> would be tricky.
>
> Instead, we seem to use this only after fetching all of the refs for a
> submodule:
>
>   $ git grep -h -B2 -A11 remote-branch git-submodule.sh
>   		if test -n "$remote"
>   		then
>   			branch=$(git submodule--helper remote-branch "$sm_path")
>   			if test -z "$nofetch"
>   			then
>   				# Fetch remote before determining tracking $sha1
>   				fetch_in_submodule "$sm_path" $depth ||
>   				die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
>   			fi
>   			remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote)
>   			sha1=$(sanitize_submodule_env; cd "$sm_path" &&
>   				git rev-parse --verify "${remote_name}/${branch}") ||
>   			die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
>   		fi
>
> and then we just use that branch name to resolve a sha1. So this will
> break cases where you've set init.mainBranch, the submodule repo is
> still on "master", and you haven't configured a branch in .gitmodules.
>
> It seems like, independent of any change in the default branch names, we
> ought to be using $remote_name/HEAD for this case anyway. I suspect that
> would be a behavior improvement by itself, as it means more cases could
> avoid having to specify the branch name in .gitmodules manually.
> Probably nobody noticed so far because "HEAD" is almost always "master"
> in the current world. It technically breaks the case that you truly did
> want to use "master" in the submodule, but they set HEAD to something
> else, and you couldn't be bothered to put it into your .gitmodules file.
> That seems rather unlikely to me.
>
> And then everything would Just Work without having to worry about the
> local mainbranch value at all.

This is the route that I am taking.

Please note that t7519 contains a few test cases that rely on the current
confusing behavior where `git submodule update --remote` fetches the
remote `master` even if that is not the remote repository's current
branch!

I did adjust t7519 to stop verifying this confusing behavior, and to
verify the saner behavior instead.

This is of course a bit worrisome, as there might actually be users out
there relying on the confusing behavior.

However, I think it is okay to fix this:

- The `git submodule update --remote` command does not strike me as
  awfully common. In fact, I had never heard of it before I worked on this
  here patch.

- Current Git's behavior when running this command is outright confusing,
  unless the remote repository's current branch _is_ `master` (in which
  case the proposed behavior matches the old behavior).

- It is actually easily fixed by setting `submodule.<name>.branch` to
  `master` _iff_ users want to reinstate the old behavior.

> Alternatively, submodule--helper could pass back the empty string for
> "no, we don't have a configured branch name" and this shell code could
> actually try a sequence of reasonable guesses: init.mainbranch, then
> "master" (and between the two, "main" if that later becomes the
> default).

Quite honestly: I'd rather not.

Thank you,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 12/12] testsvn: respect `init.defaultBranch`
  2020-06-16 13:51     ` Jeff King
@ 2020-06-23 21:07       ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 21:07 UTC (permalink / raw)
  To: Jeff King
  Cc: Johannes Schindelin via GitGitGadget, Jonathan Nieder, git, don,
	stolee, sandals, Matt Rogers, Eric Sunshine, Taylor Blau,
	Phillip Wood, Alban Gruin, Johannes Sixt

Hi Peff,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Mon, Jun 15, 2020 at 12:50:16PM +0000, Johannes Schindelin via GitGitGadget wrote:
>
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > The default name of the main branch in new repositories can now be
> > configured. The `testsvn` remote helper translates the remote Subversion
> > repository's branch name `trunk` to the hard-coded name `master`.
> > Clearly, the intention was to make the name align with Git's detaults.
>
> s/detaults/defaults/ :)

:-)

Will fix.

> I'd agree that moving this to Git's default name makes sense.

Okay.

> Though my overall preference is still to delete this whole testsvn thing
> entirely (I have some other pending tree-wide changes that are being
> held up by it, too). After getting "would you mind holding off until..."
> from Jonathan in [1], I've been waiting almost 2 years. Maybe now is the
> time?

I wouldn't mind dropping `testsvn`, seeing as there are fewer and fewer
users of `git svn` (and even those are unlikely to switch to `testsvn`,
should that ever become production-ready).

Having said that, this is an orthogonal issue to the purpose of this patch
series. And I would really like to get this patch series into a shape that
can be merged down to `next` soon.

Thank you,
Dscho

>
> -Peff
>
> [1] https://lore.kernel.org/git/20180818052605.GA241538@aiede.svl.corp.google.com/
>

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-17 20:06                             ` Junio C Hamano
@ 2020-06-23 21:11                               ` Johannes Schindelin
  2020-06-23 21:32                                 ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 21:11 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Sixt, Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Hi Junio,

On Wed, 17 Jun 2020, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > Yes, the trouble with `maint` did cross my mind, but I try not to
> > "overfit" to git/git. :-)
>
> I do not think it is overfitting; if the solution cannot even
> support the originating project well, there is something wrong.
>
> Most likely, I'd be tempted to rename it myself away from any name
> that is too similar to 'maint'; perhaps to 'stable' (or 'devo', h/t
> tla ;-).

You could also use `next` instead of `master`, which would make intuitive
sense because the commits that make it into that branch are slated to be
part of the next major Git version.

And a relatively obvious name for the current `next` might be `cooking`.

I refrained from proposing this earlier, thinking that this would be too
disruptive, but since `pu` was renamed to `seen`...

:-)

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
  2020-06-17 21:16       ` Junio C Hamano
@ 2020-06-23 21:12         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 21:12 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Sixt, Johannes Schindelin via GitGitGadget, git, don,
	stolee, peff, sandals, Matt Rogers, Eric Sunshine, Taylor Blau,
	Phillip Wood, Alban Gruin

Hi Junio & Hannes,


On Wed, 17 Jun 2020, Junio C Hamano wrote:

> Johannes Sixt <j6t@kdbg.org> writes:
>
> > Am 15.06.20 um 14:50 schrieb Johannes Schindelin via GitGitGadget:
> >> @@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
> >>  			strbuf_addf(out, " of %s", srcs.items[i].string);
> >>  	}
> >>
> >> -	if (!strcmp("master", current_branch))
> >> +	main_branch = git_main_branch_name();
> >> +	if (!strcmp(main_branch, current_branch))
> >>  		strbuf_addch(out, '\n');
> >>  	else
> >>  		strbuf_addf(out, " into %s\n", current_branch);
> >> +	free(main_branch);
> >>  }
> >
> > Now that the removal of this special case is on the plate, I would
> > prefer that the phrase "into foo" is never appended instead of always
> > appended.
>
> I do not mind such an optional feature.  I always find it useful
> whenever I read "git log --oneline --first-parent master..pu" (of
> course I have an alias for that) to see which topics are already in
> my private "to be used in real life" edition, so I would oppose to
> an unconditional removal, though.

I concur that this would make for a fine optional feature. Of course, that
is an issue that is separate from the goal to make the default branch name
used by `git init` configurable, so I will leave that feature to be
implemented later (and by somebody else).

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v2 11/12] submodule: use the correct default for the main branch name
  2020-06-23 21:03       ` Johannes Schindelin
@ 2020-06-23 21:14         ` Jeff King
  0 siblings, 0 replies; 178+ messages in thread
From: Jeff King @ 2020-06-23 21:14 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals,
	Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt

On Tue, Jun 23, 2020 at 11:03:57PM +0200, Johannes Schindelin wrote:

> > [use HEAD instead of master]
> This is the route that I am taking.
> [...]
> This is of course a bit worrisome, as there might actually be users out
> there relying on the confusing behavior.
> 
> However, I think it is okay to fix this:
> 
> - The `git submodule update --remote` command does not strike me as
>   awfully common. In fact, I had never heard of it before I worked on this
>   here patch.
> 
> - Current Git's behavior when running this command is outright confusing,
>   unless the remote repository's current branch _is_ `master` (in which
>   case the proposed behavior matches the old behavior).
> 
> - It is actually easily fixed by setting `submodule.<name>.branch` to
>   `master` _iff_ users want to reinstate the old behavior.

Thanks, I agree that this is the best way forward, and that the current
confusing behavior is as likely to be doing the wrong thing as the right
(when it even differs).

-Peff

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH 2/9] remote: respect `core.defaultBranchName`
  2020-06-18 11:50       ` Jeff King
@ 2020-06-23 21:15         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-23 21:15 UTC (permalink / raw)
  To: Jeff King; +Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, sandals

Hi Peff,

On Thu, 18 Jun 2020, Jeff King wrote:

> On Thu, Jun 18, 2020 at 12:21:30PM +0200, Johannes Schindelin wrote:
>
> > > Hopefully this would not matter _too_ much either way, as most servers
> > > would support the symref extension these days. But I still think we
> > > should do our best to minimize spots where the user may see a
> > > regression.
> >
> > Sure, we could just leave this alone, or we can just ditch the
> > special-casing of `master` here.
> >
> > As you say, this does not affect any modern Git version, and IIRC the code
> > after that special-casing tries to find any remote ref that matches the
> > remote `HEAD`.
>
> I think we need to be a little careful with "any modern Git", because a
> modern client against an old (or perhaps an alternative implementation)
> server might still use it. I have to imagine it's pretty rare, but I
> think it's still useful to return _some_ value.
>
> But as you note, even without a symref extension, we already try to
> guess based on a unique branch. Probably even choosing the first one
> alphabetically would be reasonable. But I'd rather err on the side of
> historical compatibility if we can do so easily. Looking for
> init.mainBranch, followed by master, accomplishes that and isn't many
> lines of code.

I ended up using `init.defaultBranch` as preference, falling back to
`master`, and then falling back to the first ref matching the given commit
hash.

That should be safe enough.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
  2020-06-23 21:11                               ` Johannes Schindelin
@ 2020-06-23 21:32                                 ` Junio C Hamano
  0 siblings, 0 replies; 178+ messages in thread
From: Junio C Hamano @ 2020-06-23 21:32 UTC (permalink / raw)
  To: Johannes Schindelin
  Cc: Johannes Sixt, Matt Rogers, brian m. carlson,
	Johannes Schindelin via GitGitGadget, Git Mailing List, don,
	stolee, Jeff King

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> You could also use `next` instead of `master`, which would make intuitive
> sense because the commits that make it into that branch are slated to be
> part of the next major Git version.
>
> And a relatively obvious name for the current `next` might be `cooking`.
>
> I refrained from proposing this earlier, thinking that this would be too
> disruptive, but since `pu` was renamed to `seen`...

Renaming 'pu' away from two-letter has a positive technical and
social effect.  Using 'next' for anything but what it currently
means does not have any such upside and only the downside of
confusing people.

As to 'cooking', I am not sure.  Personally I consider that the
topics that are in 'next' plus those that are soon to be in 'next'
are all 'cooking'.  But I do not think anybody's dying to rename
'next', so...



^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 0/8] Allow overriding the default name of the default branch
  2020-06-15 12:50 ` [PATCH v2 00/12] " Johannes Schindelin via GitGitGadget
                     ` (11 preceding siblings ...)
  2020-06-15 12:50   ` [PATCH v2 12/12] testsvn: respect `init.defaultBranch` Johannes Schindelin via GitGitGadget
@ 2020-06-23 22:33   ` Johannes Schindelin via GitGitGadget
  2020-06-23 22:33     ` [PATCH v3 1/8] fmt-merge-msg: stop treating `master` specially Johannes Schindelin via GitGitGadget
                       ` (8 more replies)
  12 siblings, 9 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin

A growing number of open source projects aims to avoid the branch name 
master due to its negative connotation. See [1] for an existing discussion
on this. The links [2], [3], and [4] describe community-driven ways for
users to rename their default branches or use template edits to set a new
default branch name.

[1] 
https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/

[2] https://twitter.com/mislav/status/1270388510684598272

[3] 
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx

[4] https://github.com/ethomson/retarget_prs

By necessity, existing repositories require a lot of manual work to move
away from that branch name, but it should be much easier for new
repositories.

This patch series allows overriding the branch name being used for new
repositories' main branch. This can be configured via init.defaultBranch.

The initial patch was started by newcomer Don Goodman-Wilson, as well as the
bigger change that morphed into #655, where we demonstrate how to change
Git's hard-coded default branch name for new repositories to main based on
this here patch series, verifying the approach. Thanks for the contribution!

This series DOES NOT change the default automatically, but only provides an
opt-in mechanism for interested users. The plan for that is to convert the
test scripts incrementally (by introducing GIT_TEST_DEFAULT_MAIN_BRANCH_NAME
, which overrides init.defaultBranch, and then converting the tricky test
scripts first, one by one, using that environment variable).

Changes since v2:

 * Dropped the fast-export patches, as they have been superseded by Peff's 
   jk/fast-export-anonym
   [https://github.com/gitgitgadget/git/commits/jk/fast-export-anonym].
   
   
 * Adjusted the fmt-merge-msg patch so as to not special-case master anymore
   (instead of special-casing a specific "main" branch).
   
   
 * Modified the git submodule patch so that it uses origin/HEAD instead of
   trying to look for a remote branch with the name indicated by 
   init.defaultBranch.
   
   

Changes since v1:

 * The modifications to respect GIT_TEST_DEFAULT_BRANCH_NAME have been
   backed out from this patch series, as they are only relevant once we
   start converting the test suite to accommodate for a new default main
   branch name.
   
   
 * An error message that started with an upper-case letter was downcased.
   
   
 * git_default_branch_name()'s logic was simplified by replacing an if ...
   else ... by a ternary assignment.
   
   
 * The git_default_branch_name() function was renamed to 
   git_main_branch_name() and a corresponding repo_main_branch_name() was
   introduced.
   
   
 * The "init" commit message's first paragraph now elaborates a little bit
   on the reasoning why projects want to move away from the current default
   branch name.
   
   
 * The "init" commit was split into two.
   
   
 * There are now two config settings: init.defaultBranch (defining the
   branch name to use when initializing new repositories) and 
   core.mainBranch (which is now configured by init_db(), declaring what the
   name of the main branch is in this repository).
   
   
 * The commits were re-ordered to introduce the concept of core.mainBranch 
   first because technically, this is something that we could do even
   without changing git init at all.
   
   
 * git fast-export --anonymize now always uses the ref name ref0 for the
   main branch, no matter whether it was overridden or whether the fall-back
   is in effect.
   
   
 * The code comment regarding anonymizing the main branch to ref0 in git
   fast-export --anonymize was enhanced.
   
   
 * A new patch was added to rename core.mainBranch if the main branch is
   renamed via git branch -m.
   
   
 * Added a patch that introduces support for git init
   --main-branch=<branch-name>.
   
   
 * Where possible, I added tests (although I did not try to extend test
   coverage to all changes: the send-pack.c/transport-helper.c patch only
   adds a test for the send-pack.c adjustment, for example).

Don Goodman-Wilson (1):
  init: allow setting the default for the initial branch name via the
    config

Johannes Schindelin (7):
  fmt-merge-msg: stop treating `master` specially
  send-pack/transport-helper: avoid mentioning a particular branch
  submodule: use a better fall-back for missing remote.<name>.branch
  init: allow specifying the initial branch name for the new repository
  clone: use configured default branch name when appropriate
  remote: use the configured default branch name when appropriate
  testsvn: respect `init.defaultBranch`

 Documentation/config/init.txt                 |  4 ++
 Documentation/git-init.txt                    |  7 ++
 Documentation/git-submodule.txt               |  4 +-
 builtin/clone.c                               | 13 ++--
 builtin/init-db.c                             | 34 +++++++--
 builtin/submodule--helper.c                   |  2 +-
 cache.h                                       |  2 +-
 fmt-merge-msg.c                               |  5 +-
 refs.c                                        | 30 ++++++++
 refs.h                                        |  9 +++
 remote-testsvn.c                              | 10 ++-
 remote.c                                      | 14 +++-
 send-pack.c                                   |  2 +-
 t/t0001-init.sh                               | 26 +++++++
 t/t1507-rev-parse-upstream.sh                 |  2 +-
 t/t4013-diff-various.sh                       |  4 +-
 t/t4013/diff.log_--decorate=full_--all        |  2 +-
 t/t4013/diff.log_--decorate_--all             |  2 +-
 ...--patch-with-stat_--summary_master_--_dir_ |  2 +-
 t/t4013/diff.log_--patch-with-stat_master     |  2 +-
 .../diff.log_--patch-with-stat_master_--_dir_ |  2 +-
 ...ot_--cc_--patch-with-stat_--summary_master |  2 +-
 ..._--root_--patch-with-stat_--summary_master |  2 +-
 .../diff.log_--root_--patch-with-stat_master  |  2 +-
 ...root_-c_--patch-with-stat_--summary_master |  2 +-
 t/t4013/diff.log_--root_-p_master             |  2 +-
 t/t4013/diff.log_--root_master                |  2 +-
 t/t4013/diff.log_-m_-p_--first-parent_master  |  2 +-
 t/t4013/diff.log_-m_-p_master                 |  4 +-
 t/t4013/diff.log_-p_--first-parent_master     |  2 +-
 t/t4013/diff.log_-p_master                    |  2 +-
 t/t4013/diff.log_master                       |  2 +-
 t/t4013/diff.show_--first-parent_master       |  2 +-
 t/t4013/diff.show_-c_master                   |  2 +-
 t/t4013/diff.show_-m_master                   |  4 +-
 t/t4013/diff.show_master                      |  2 +-
 ...ot_--cc_--patch-with-stat_--summary_master |  2 +-
 ...root_-c_--patch-with-stat_--summary_master |  2 +-
 t/t4202-log.sh                                | 72 +++++++++----------
 t/t5528-push-default.sh                       |  6 ++
 t/t5606-clone-options.sh                      | 24 +++++++
 t/t6200-fmt-merge-msg.sh                      | 36 +++++-----
 t/t7406-submodule-update.sh                   | 16 +++++
 t/t7419-submodule-set-branch.sh               |  7 +-
 t/t7600-merge.sh                              | 14 ++--
 t/t7608-merge-messages.sh                     | 10 +--
 t/t9020-remote-svn.sh                         |  6 ++
 transport-helper.c                            |  2 +-
 48 files changed, 287 insertions(+), 122 deletions(-)


base-commit: c9c318d6bf26bcecdca5b6f31683b9d5887a83ee
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-656%2Fdscho%2Fdefault-branch-name-option-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-656/dscho/default-branch-name-option-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/656

Range-diff vs v2:

  1:  ebd10f73cd <  -:  ---------- fast-export: do anonymize the primary branch name
  -:  ---------- >  1:  fffdb9944f fmt-merge-msg: stop treating `master` specially
  3:  bd8af3755a !  2:  a29943d7bb send-pack/transport-helper: respect `core.mainBranch`
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    send-pack/transport-helper: respect `core.mainBranch`
     +    send-pack/transport-helper: avoid mentioning a particular branch
      
     -    When mentioning the main branch name in an error message, we want to go
     -    with the preference specified by the user, only falling back to Git's
     -    own, hard-coded default when none was configured explicitly.
     +    When trying to push all matching branches, but none match, we offer a
     +    message suggesting to push the `master` branch.
     +
     +    However, we want to step away from making that branch any more special
     +    than any other branch, so let's reword that message to mention no branch
     +    in particular.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
       ## send-pack.c ##
      @@ send-pack.c: int send_pack(struct send_pack_args *args,
     - 	}
       
       	if (!remote_refs) {
     -+		char *branch_name = git_main_branch_name();
     -+
       		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
      -			"Perhaps you should specify a branch such as 'master'.\n");
     -+			"Perhaps you should specify a branch such as '%s'.\n",
     -+			branch_name);
     -+		free(branch_name);
     ++			"Perhaps you should specify a specific branch.\n");
       		return 0;
       	}
       	if (args->atomic && !atomic_supported)
     @@ t/t5528-push-default.sh: test_expect_success 'push from/to new branch with upstr
       
      +test_expect_success '"matching" fails if none match' '
      +	git init --bare empty &&
     -+	test_must_fail git -c core.mainBranch=unmatch push empty : 2>actual &&
     -+	needle="Perhaps you should specify a branch such as '\''unmatch'\''" &&
     -+	test_i18ngrep "$needle" actual
     ++	test_must_fail git push empty : 2>actual &&
     ++	test_i18ngrep "Perhaps you should specify a specific branch" actual
      +'
      +
       test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
     @@ t/t5528-push-default.sh: test_expect_success 'push from/to new branch with upstr
      
       ## transport-helper.c ##
      @@ transport-helper.c: static int push_refs(struct transport *transport,
     - 	}
     - 
       	if (!remote_refs) {
     -+		char *branch_name = git_main_branch_name();
     -+
       		fprintf(stderr,
       			_("No refs in common and none specified; doing nothing.\n"
      -			  "Perhaps you should specify a branch such as 'master'.\n"));
     -+			  "Perhaps you should specify a branch such as '%s'.\n"),
     -+			branch_name);
     -+		free(branch_name);
     ++			  "Perhaps you should specify a specific branch.\n"));
       		return 0;
       	}
       
 11:  59d6267f09 !  3:  6bda69541b submodule: use the correct default for the main branch name
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    submodule: use the correct default for the main branch name
     +    submodule: use a better fall-back for missing remote.<name>.branch
      
     -    To allow for overriding the default branch name, we have introduced a
     -    config setting. With this patch, the `git submodule` command learns
     -    about this, too.
     +    When `remote.<name>.branch` is not configured, `git submodule update`
     +    currently falls back to using the branch name `master`. A much better
     +    idea, however, is to use `HEAD`: on all Git servers running reasonably
     +    recent Git versions, the symref `HEAD` points to the main branch.
     +
     +    Note: t7419 demonstrates that there _might_ be use cases out there that
     +    _expect_ `git submodule update --remote` to update submodules to the
     +    remote `master` branch even if the remote `HEAD` points to another
     +    branch. Arguably, this patch makes the behavior more intuitive, but
     +    there is a slight possibility that this might cause regressions in
     +    obscure setups.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     + ## Documentation/git-submodule.txt ##
     +@@ Documentation/git-submodule.txt: OPTIONS
     + 	`.gitmodules` for `update --remote`.  A special value of `.` is used to
     + 	indicate that the name of the branch in the submodule should be the
     + 	same name as the current branch in the current repository.  If the
     +-	option is not specified, it defaults to 'master'.
     ++	option is not specified, it defaults to 'HEAD'.
     + 
     + -f::
     + --force::
     +@@ Documentation/git-submodule.txt: OPTIONS
     + 	the superproject's recorded SHA-1 to update the submodule, use the
     + 	status of the submodule's remote-tracking branch.  The remote used
     + 	is branch's remote (`branch.<name>.remote`), defaulting to `origin`.
     +-	The remote branch used defaults to `master`, but the branch name may
     ++	The remote branch used defaults to `HEAD`, but the branch name may
     + 	be overridden by setting the `submodule.<name>.branch` option in
     + 	either `.gitmodules` or `.git/config` (with `.git/config` taking
     + 	precedence).
     +
       ## builtin/submodule--helper.c ##
      @@ builtin/submodule--helper.c: static const char *remote_submodule_branch(const char *path)
     - 		branch = sub->branch;
       	free(key);
       
     --	if (!branch)
     + 	if (!branch)
      -		return "master";
     -+	if (!branch) {
     -+		static char *fall_back;
     -+
     -+		if (!fall_back)
     -+			fall_back = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
     -+
     -+		return fall_back;
     -+	}
     ++		return "HEAD";
       
       	if (!strcmp(branch, ".")) {
       		const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
     @@ t/t7406-submodule-update.sh: test_expect_success 'setup a submodule tree' '
       	)
       '
       
     -+test_expect_success 'update --remote uses configured default main branch' '
     -+	git clone super main-branch &&
     -+	test_must_fail git -C main-branch -c init.defaultBranch=hello \
     -+		submodule update --init --remote submodule 2>err &&
     -+	test_i18ngrep origin/hello err
     ++test_expect_success 'update --remote falls back to using HEAD' '
     ++	test_create_repo main-branch-submodule &&
     ++	test_commit -C main-branch-submodule initial &&
     ++
     ++	test_create_repo main-branch &&
     ++	git -C main-branch submodule add ../main-branch-submodule &&
     ++	git -C main-branch commit -m add-submodule &&
     ++
     ++	git -C main-branch-submodule switch -c hello &&
     ++	test_commit -C main-branch-submodule world &&
     ++
     ++	git clone --recursive main-branch main-branch-clone &&
     ++	git -C main-branch-clone submodule update --remote main-branch-submodule &&
     ++	test_path_exists main-branch-clone/main-branch-submodule/world.t
      +'
      +
       test_expect_success 'submodule update detaching the HEAD ' '
       	(cd super/submodule &&
       	 git reset --hard HEAD~1
     +
     + ## t/t7419-submodule-set-branch.sh ##
     +@@ t/t7419-submodule-set-branch.sh: test_expect_success 'test submodule set-branch --branch' '
     + '
     + 
     + test_expect_success 'test submodule set-branch --default' '
     ++	test_commit -C submodule c &&
     + 	(cd super &&
     + 		git submodule set-branch --default submodule &&
     + 		! grep branch .gitmodules &&
     + 		git submodule update --remote &&
     + 		cat <<-\EOF >expect &&
     +-		a
     ++		c
     + 		EOF
     + 		git -C submodule show -s --pretty=%s >actual &&
     + 		test_cmp expect actual
     +@@ t/t7419-submodule-set-branch.sh: test_expect_success 'test submodule set-branch --default' '
     + '
     + 
     + test_expect_success 'test submodule set-branch -b' '
     ++	test_commit -C submodule b &&
     + 	(cd super &&
     + 		git submodule set-branch -b topic submodule &&
     + 		grep "branch = topic" .gitmodules &&
     +@@ t/t7419-submodule-set-branch.sh: test_expect_success 'test submodule set-branch -b' '
     + '
     + 
     + test_expect_success 'test submodule set-branch -d' '
     ++	test_commit -C submodule d &&
     + 	(cd super &&
     + 		git submodule set-branch -d submodule &&
     + 		! grep branch .gitmodules &&
     + 		git submodule update --remote &&
     + 		cat <<-\EOF >expect &&
     +-		a
     ++		d
     + 		EOF
     + 		git -C submodule show -s --pretty=%s >actual &&
     + 		test_cmp expect actual
  7:  0ec04b2086 !  4:  e8a6587c1a init: allow specifying the main branch name for the new repository
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    init: allow specifying the main branch name for the new repository
     +    init: allow specifying the initial branch name for the new repository
      
     -    There is a growing number of projects trying to avoid the non-inclusive
     -    name `master` in their repositories: The `master`/`slave` terminology is
     -    insensitive and perpetuates injustice. This `master`/`slave` idea is
     -    actually where Git's naming comes from, as it was inherited from
     -    BitKeeper which uses the term in exactly this way, see
     -    https://mail.gnome.org/archives/desktop-devel-list/2019-May/msg00066.html
     +    There is a growing number of projects and companies desiring to change
     +    the main branch name of their repositories (see e.g.
     +    https://twitter.com/mislav/status/1270388510684598272 for background on
     +    this).
      
          To change that branch name for new repositories, currently the only way
          to do that automatically is by copying all of Git's template directory,
     @@ Commit message
          template files.
      
          To make this process much less cumbersome, let's introduce a new option:
     -    `--main-branch=<branch-name>`.
     -
     -    This will not only initialize the repository with the specified initial
     -    branch; It will also record that branch name in `core.mainBranch`.
     +    `--initial-branch=<branch-name>`.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     @@ Documentation/git-init.txt: SYNOPSIS
       [verse]
       'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
       	  [--separate-git-dir <git dir>] [--object-format=<format]
     -+	  [-b <branch-name> | --main-branch=<branch-name>]
     ++	  [-b <branch-name> | --initial-branch=<branch-name>]
       	  [--shared[=<permissions>]] [directory]
       
       
     @@ Documentation/git-init.txt: repository.
       If this is reinitialization, the repository will be moved to the specified path.
       
      +-b <branch-name::
     -+--main-branch=<branch-name>::
     ++--initial-branch=<branch-name>::
      +
     -+Use the specified name for the main (or: initial) branch in the newly created
     -+repository. If not specified, fall back to the default name: `master`.
     ++Use the specified name for the initial branch in the newly created repository.
     ++If not specified, fall back to the default name: `master`.
      +
       --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
       
     @@ builtin/init-db.c: void initialize_repository_version(int hash_algo)
       
       static int create_default_files(const char *template_path,
       				const char *original_git_dir,
     -+				const char *main_branch,
     ++				const char *initial_branch,
       				const struct repository_format *fmt)
       {
       	struct stat st1;
     @@ builtin/init-db.c: static int create_default_files(const char *template_path,
      -		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
      +		char *ref;
      +
     -+		if (!main_branch)
     -+			main_branch = "master";
     ++		if (!initial_branch)
     ++			initial_branch = "master";
      +
     -+		ref = xstrfmt("refs/heads/%s", main_branch);
     ++		ref = xstrfmt("refs/heads/%s", initial_branch);
      +		if (check_refname_format(ref, 0) < 0)
     -+			die(_("invalid main branch name: '%s'"), main_branch);
     ++			die(_("invalid initial branch name: '%s'"),
     ++			    initial_branch);
      +
      +		if (create_symref("HEAD", ref, NULL) < 0)
       			exit(1);
      -	}
      +		free(ref);
     -+
     -+		git_config_set("core.mainbranch", main_branch);
     -+	} else if (main_branch)
     -+		warning(_("re-init: ignoring --main-branch=%s"), main_branch);
     ++	} else if (initial_branch)
     ++		warning(_("re-init: ignoring --initial-branch=%s"),
     ++			initial_branch);
       
       	initialize_repository_version(fmt->hash_algo);
       
     @@ builtin/init-db.c: static void validate_hash_algorithm(struct repository_format
       
       int init_db(const char *git_dir, const char *real_git_dir,
      -	    const char *template_dir, int hash, unsigned int flags)
     -+	    const char *template_dir, int hash, const char *main_branch,
     ++	    const char *template_dir, int hash, const char *initial_branch,
      +	    unsigned int flags)
       {
       	int reinit;
     @@ builtin/init-db.c: int init_db(const char *git_dir, const char *real_git_dir,
       
      -	reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
      +	reinit = create_default_files(template_dir, original_git_dir,
     -+				      main_branch, &repo_fmt);
     ++				      initial_branch, &repo_fmt);
       
       	create_object_directory();
       
     @@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
       	const char *template_dir = NULL;
       	unsigned int flags = 0;
       	const char *object_format = NULL;
     -+	const char *main_branch = NULL;
     ++	const char *initial_branch = NULL;
       	int hash_algo = GIT_HASH_UNKNOWN;
       	const struct option init_db_options[] = {
       		OPT_STRING(0, "template", &template_dir, N_("template-directory"),
     @@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
       		OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
       		OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
       			   N_("separate git dir from working tree")),
     -+		OPT_STRING('b', "main-branch", &main_branch, N_("name"),
     -+			   N_("override the name of the main branch")),
     ++		OPT_STRING('b', "initial-branch", &initial_branch, N_("name"),
     ++			   N_("override the name of the initial branch")),
       		OPT_STRING(0, "object-format", &object_format, N_("hash"),
       			   N_("specify the hash algorithm to use")),
       		OPT_END()
     @@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
       	flags |= INIT_DB_EXIST_OK;
      -	return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
      +	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
     -+		       main_branch, flags);
     ++		       initial_branch, flags);
       }
      
       ## cache.h ##
     @@ cache.h: int path_inside_repo(const char *prefix, const char *path);
       int init_db(const char *git_dir, const char *real_git_dir,
       	    const char *template_dir, int hash_algo,
      -	    unsigned int flags);
     -+	    const char *main_branch, unsigned int flags);
     ++	    const char *initial_branch, unsigned int flags);
       void initialize_repository_version(int hash_algo);
       
       void sanitize_stdfds(void);
     @@ t/t0001-init.sh: test_expect_success MINGW 'redirect std handles' '
       	grep "Needed a single revision" output.txt
       '
       
     -+test_expect_success '--main-branch' '
     -+	git init --main-branch=hello main-branch-option &&
     -+	git -C main-branch-option symbolic-ref HEAD >actual &&
     ++test_expect_success '--initial-branch' '
     ++	git init --initial-branch=hello initial-branch-option &&
     ++	git -C initial-branch-option symbolic-ref HEAD >actual &&
      +	echo refs/heads/hello >expect &&
      +	test_cmp expect actual &&
      +
     -+	: re-initializing should not change the main branch name &&
     -+	git init --main-branch=ignore main-branch-option 2>err &&
     -+	test_i18ngrep "ignoring --main-branch" err &&
     -+	git -C main-branch-option symbolic-ref HEAD >actual &&
     -+	grep hello actual &&
     -+	git -C main-branch-option config core.mainBranch >actual &&
     ++	: re-initializing should not change the branch name &&
     ++	git init --initial-branch=ignore initial-branch-option 2>err &&
     ++	test_i18ngrep "ignoring --initial-branch" err &&
     ++	git -C initial-branch-option symbolic-ref HEAD >actual &&
      +	grep hello actual
      +'
      +
  2:  f4d5473915 !  5:  a500e0f214 fmt-merge-msg: introduce a way to override the main branch name
     @@
       ## Metadata ##
     -Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
     +Author: Don Goodman-Wilson <don@goodman-wilson.com>
      
       ## Commit message ##
     -    fmt-merge-msg: introduce a way to override the main branch name
     +    init: allow setting the default for the initial branch name via the config
      
     -    There is a growing number of projects and companies desiring to change
     -    the main branch name of their repositories (see e.g.
     -    https://twitter.com/mislav/status/1270388510684598272 for background on
     -    this).
     +    We just introduced the command-line option
     +    `--initial-branch=<branch-name>` to allow initializing a new repository
     +    with a different initial branch than the hard-coded one.
      
     -    However, there are a couple of hard-coded spots in Git's source code
     -    that make this endeavor harder than necessary. For example, when
     -    formatting the commit message for merge commits, Git appends "into
     -    <branch-name>" unless the current branch is the `master` branch.
     +    To allow users to override the initial branch name more permanently
     +    (i.e. without having to specify the name manually for each and every
     +    `git init` invocation), let's introduce the `init.defaultBranch` config
     +    setting.
      
     -    Clearly, this is not what one wants when already having gone through all
     -    the steps to manually rename the main branch (and taking care of all the
     -    fall-out such as re-targeting existing Pull Requests).
     +    Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
     +    Helped-by: Derrick Stolee <dstolee@microsoft.com>
     +    Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
      
     -    Let's introduce a way to override Git's hard-coded default:
     -    `core.mainBranch`.
     -
     -    We will start supporting this config option in the `git fmt-merge-msg`
     -    command and successively adjust all other places where the main branch
     -    name is hard-coded.
     -
     -    Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
     -
     - ## Documentation/config/core.txt ##
     -@@ Documentation/config/core.txt: core.abbrev::
     - 	in your repository, which hopefully is enough for
     - 	abbreviated object names to stay unique for some time.
     - 	The minimum length is 4.
     + ## Documentation/config/init.txt ##
     +@@
     + init.templateDir::
     + 	Specify the directory from which templates will be copied.
     + 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
      +
     -+core.mainBranch::
     -+	The name of the main (or: primary) branch in the current repository.
     -+	For historical reasons, `master` is used as the fall-back for this
     -+	setting.
     ++init.defaultBranch::
     ++	Allows overriding the default branch name when initializing
     ++	a new repository.
      
     - ## fmt-merge-msg.c ##
     -@@ fmt-merge-msg.c: static void fmt_merge_msg_title(struct strbuf *out,
     - 				const char *current_branch)
     - {
     - 	int i = 0;
     --	char *sep = "";
     -+	char *sep = "", *main_branch;
     + ## builtin/init-db.c ##
     +@@ builtin/init-db.c: static int create_default_files(const char *template_path,
     + 		char *ref;
       
     - 	strbuf_addstr(out, "Merge ");
     - 	for (i = 0; i < srcs.nr; i++) {
     -@@ fmt-merge-msg.c: static void fmt_merge_msg_title(struct strbuf *out,
     - 			strbuf_addf(out, " of %s", srcs.items[i].string);
     - 	}
     + 		if (!initial_branch)
     +-			initial_branch = "master";
     ++			initial_branch = git_default_branch_name();
       
     --	if (!strcmp("master", current_branch))
     -+	main_branch = git_main_branch_name();
     -+	if (!strcmp(main_branch, current_branch))
     - 		strbuf_addch(out, '\n');
     - 	else
     - 		strbuf_addf(out, " into %s\n", current_branch);
     -+	free(main_branch);
     - }
     - 
     - static void fmt_tag_signature(struct strbuf *tagbuf,
     + 		ref = xstrfmt("refs/heads/%s", initial_branch);
     + 		if (check_refname_format(ref, 0) < 0)
      
       ## refs.c ##
      @@ refs.c: void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
       		argv_array_pushf(prefixes, *p, len, prefix);
       }
       
     -+char *repo_main_branch_name(struct repository *r)
     ++char *repo_default_branch_name(struct repository *r)
      +{
     -+	const char *config_key = "core.mainbranch";
     -+	const char *config_display_key = "core.mainBranch";
     -+	const char *fall_back = "master";
     -+	char *name = NULL, *ret;
     ++	const char *config_key = "init.defaultbranch";
     ++	const char *config_display_key = "init.defaultBranch";
     ++	char *ret = NULL, *full_ref;
      +
     -+	if (repo_config_get_string(r, config_key, &name) < 0)
     ++	if (repo_config_get_string(r, config_key, &ret) < 0)
      +		die(_("could not retrieve `%s`"), config_display_key);
      +
     -+	ret = name ? name : xstrdup(fall_back);
     -+
     -+	if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
     -+		die(_("invalid branch name: %s = %s"),
     -+		    config_display_key, name);
     ++	if (!ret)
     ++		ret = xstrdup("master");
      +
     -+	if (name != ret)
     -+		free(name);
     ++	full_ref = xstrfmt("refs/heads/%s", ret);
     ++	if (check_refname_format(full_ref, 0))
     ++		die(_("invalid branch name: %s = %s"), config_display_key, ret);
     ++	free(full_ref);
      +
      +	return ret;
      +}
      +
     -+char *git_main_branch_name(void)
     ++const char *git_default_branch_name(void)
      +{
     -+	return repo_main_branch_name(the_repository);
     ++	static char *ret;
     ++
     ++	if (!ret)
     ++		ret = repo_default_branch_name(the_repository);
     ++
     ++	return ret;
      +}
      +
       /*
     @@ refs.h: int repo_dwim_log(struct repository *r, const char *str, int len, struct
       int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
       
      +/*
     -+ * Retrieves the name of the main (or: primary) branch of the given
     -+ * repository.
     ++ * Retrieves the default branch name for newly-initialized repositories.
     ++ *
     ++ * The return value of `repo_default_branch_name()` is an allocated string. The
     ++ * return value of `git_default_branch_name()` is a singleton.
      + */
     -+char *git_main_branch_name(void);
     -+char *repo_main_branch_name(struct repository *r);
     ++const char *git_default_branch_name(void);
     ++char *repo_default_branch_name(struct repository *r);
      +
       /*
        * A ref_transaction represents a collection of reference updates that
        * should succeed or fail together.
      
     - ## t/t6200-fmt-merge-msg.sh ##
     -@@ t/t6200-fmt-merge-msg.sh: test_expect_success 'setup FETCH_HEAD' '
     - 	git fetch . left
     + ## t/t0001-init.sh ##
     +@@ t/t0001-init.sh: test_expect_success '--initial-branch' '
     + 	grep hello actual
       '
       
     -+test_expect_success 'with overridden default branch name' '
     -+	test_when_finished "git switch master" &&
     -+	git switch -c default &&
     -+	git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual &&
     -+	! grep "into default" actual
     ++test_expect_success 'overridden default initial branch name (config)' '
     ++	test_config_global init.defaultBranch nmb &&
     ++	git init initial-branch-config &&
     ++	git -C initial-branch-config symbolic-ref HEAD >actual &&
     ++	grep nmb actual
     ++'
     ++
     ++test_expect_success 'invalid default branch name' '
     ++	test_config_global init.defaultBranch "with space" &&
     ++	test_must_fail git init initial-branch-invalid 2>err &&
     ++	test_i18ngrep "invalid branch name" err
      +'
      +
     - test_expect_success 'merge.log=3 limits shortlog length' '
     - 	cat >expected <<-EOF &&
     - 	Merge branch ${apos}left${apos}
     + test_done
  4:  ca1c63c3e0 <  -:  ---------- git_main_branch_name(): optionally report the full ref name
  5:  a3be4f39aa <  -:  ---------- fast-export: handle overridden main branch names correctly
  6:  933e314813 <  -:  ---------- branch -m: adjust `core.mainBranch` if necessary
  8:  c711eba7e7 <  -:  ---------- init: allow overriding the default main branch name via the config
  9:  0e59b61816 !  6:  c0d74cedd1 clone: handle overridden main branch names
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    clone: handle overridden main branch names
     +    clone: use configured default branch name when appropriate
      
          When cloning a repository without any branches, Git chooses a default
          branch name for the as-yet unborn branch.
      
     -    As part of the implicit initialization of the local repository, Git
     -    just learned to respect `init.defaultBranch` to choose a different main
     +    As part of the implicit initialization of the local repository, Git just
     +    learned to respect `init.defaultBranch` to choose a different initial
          branch name. We now really want that branch name to be used as a
          fall-back.
      
     -    At the same time, we also want to make sure that `core.mainBranch` is
     -    set correctly, reflecting the name of the main branch. In case we detect
     -    a main branch, we do have to do that explicitly, otherwise `init_db()`
     -    will already have done that for us.
     -
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
       ## Documentation/config/init.txt ##
     @@ Documentation/config/init.txt: init.templateDir::
      +	a new repository or when cloning an empty repository.
      
       ## builtin/clone.c ##
     -@@ builtin/clone.c: static void update_head(const struct ref *our, const struct ref *remote,
     - 		/* Local default branch link */
     - 		if (create_symref("HEAD", our->name, NULL) < 0)
     - 			die(_("unable to update HEAD"));
     -+		git_config_set("core.mainbranch", head);
     - 		if (!option_bare) {
     - 			update_ref(msg, "HEAD", &our->old_oid, NULL, 0,
     - 				   UPDATE_REFS_DIE_ON_ERR);
      @@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
       		remote_head_points_at = NULL;
       		remote_head = NULL;
     @@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
      -			install_branch_config(0, "master", option_origin,
      -					      "refs/heads/master");
      +		if (!option_bare) {
     -+			char *main_branch =
     -+				git_main_branch_name(MAIN_BRANCH_FULL_NAME);
     -+			const char *nick;
     ++			const char *branch = git_default_branch_name();
     ++			char *ref = xstrfmt("refs/heads/%s", branch);
      +
     -+			if (!skip_prefix(main_branch, "refs/heads/", &nick))
     -+				BUG("unexpected default branch '%s'",
     -+				    main_branch);
     -+			install_branch_config(0, nick, option_origin,
     -+					      main_branch);
     -+			free(main_branch);
     ++			install_branch_config(0, branch, option_origin, ref);
     ++			free(ref);
      +		}
       	}
       
     @@ t/t5606-clone-options.sh: test_expect_success 'redirected clone -v does show pro
       
       '
       
     -+test_expect_success 'chooses correct default main branch name' '
     ++test_expect_success 'chooses correct default initial branch name' '
      +	git init --bare empty &&
      +	git -c init.defaultBranch=up clone empty whats-up &&
      +	test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) &&
     -+	test up = $(git -C whats-up config core.mainBranch) &&
      +	test refs/heads/up = $(git -C whats-up config branch.up.merge)
      +'
      +
     -+test_expect_success 'guesses main branch name correctly' '
     -+	git init --main-branch=guess main-branch &&
     -+	test_commit -C main-branch no-spoilers &&
     -+	git -C main-branch branch abc guess &&
     -+	git clone main-branch is-it &&
     -+	test guess = $(git -C is-it config core.mainBranch) &&
     ++test_expect_success 'guesses initial branch name correctly' '
     ++	git init --initial-branch=guess initial-branch &&
     ++	test_commit -C initial-branch no-spoilers &&
     ++	git -C initial-branch branch abc guess &&
     ++	git clone initial-branch is-it &&
      +	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
      +'
      +
 10:  59b8f4cfbb !  7:  00a1b281e5 remote: learn about the possibly-overridden default main branch name
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    remote: learn about the possibly-overridden default main branch name
     +    remote: use the configured default branch name when appropriate
      
          When guessing the default branch name of a remote, and there are no refs
          to guess from, we want to go with the preference specified by the user
     -    for the fall-back, i.e. the default name to be used for the main branch
     -    of new repositories (because as far as the user is concerned, a remote
     -    that has no branches yet is a new repository).
     +    for the fall-back, i.e. the default name to be used for the initial
     +    branch of new repositories (because as far as the user is concerned, a
     +    remote that has no branches yet is a new repository).
     +
     +    At the same time, when talking to an older Git server that does not
     +    report a symref for `HEAD` (but instead reports a commit hash), let's
     +    try to guess the configured default branch name first. If it does not
     +    match the reported commit hash, let's fall back to `master` as before.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
       ## remote.c ##
     -@@ remote.c: static void read_remotes_file(struct remote *remote)
     - 
     - static void read_branches_file(struct remote *remote)
     - {
     --	char *frag;
     -+	char *frag, *main_branch = NULL;
     - 	struct strbuf buf = STRBUF_INIT;
     - 	FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r");
     - 
      @@ remote.c: static void read_branches_file(struct remote *remote)
       
       	/*
     @@ remote.c: static void read_branches_file(struct remote *remote)
       		*(frag++) = '\0';
       	else
      -		frag = "master";
     -+		frag = main_branch = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
     ++		frag = (char *)git_default_branch_name();
       
       	add_url_alias(remote, strbuf_detach(&buf, NULL));
       	strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
     -@@ remote.c: static void read_branches_file(struct remote *remote)
     - 	strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
     - 	refspec_append(&remote->push, buf.buf);
     - 	remote->fetch_tags = 1; /* always auto-follow */
     -+	free(main_branch);
     - 	strbuf_release(&buf);
     - }
     - 
      @@ remote.c: struct ref *guess_remote_head(const struct ref *head,
       	if (head->symref)
       		return copy_ref(find_ref_by_name(refs, head->symref));
       
      -	/* If refs/heads/master could be right, it is. */
     -+	/* If a remote branch exists with the main branch name, let's use it. */
     ++	/* If a remote branch exists with the default branch name, let's use it. */
       	if (!all) {
     --		r = find_ref_by_name(refs, "refs/heads/master");
     -+		char *name = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
     -+						  MAIN_BRANCH_FOR_INIT);
     ++		char *ref = xstrfmt("refs/heads/%s", git_default_branch_name());
     ++
     ++		r = find_ref_by_name(refs, ref);
     ++		free(ref);
     ++		if (r && oideq(&r->old_oid, &head->old_oid))
     ++			return copy_ref(r);
      +
     -+		r = find_ref_by_name(refs, name);
     -+		free(name);
     ++		/* Fall back to the hard-coded historical default */
     + 		r = find_ref_by_name(refs, "refs/heads/master");
       		if (r && oideq(&r->old_oid, &head->old_oid))
       			return copy_ref(r);
     - 	}
      
       ## t/t5606-clone-options.sh ##
     -@@ t/t5606-clone-options.sh: test_expect_success 'guesses main branch name correctly' '
     - 	git -C main-branch branch abc guess &&
     - 	git clone main-branch is-it &&
     - 	test guess = $(git -C is-it config core.mainBranch) &&
     +@@ t/t5606-clone-options.sh: test_expect_success 'guesses initial branch name correctly' '
     + 	test_commit -C initial-branch no-spoilers &&
     + 	git -C initial-branch branch abc guess &&
     + 	git clone initial-branch is-it &&
      -	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
      +	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) &&
      +
      +	git -c init.defaultBranch=none init --bare no-head &&
     -+	git -C main-branch push ../no-head guess abc &&
     ++	git -C initial-branch push ../no-head guess abc &&
      +	git clone no-head is-it2 &&
      +	test_must_fail git -C is-it2 symbolic-ref refs/remotes/origin/HEAD &&
      +	git -C no-head update-ref --no-deref HEAD refs/heads/guess &&
 12:  e09f857f06 !  8:  1aa0e63785 testsvn: respect `init.defaultBranch`
     @@ Metadata
       ## Commit message ##
          testsvn: respect `init.defaultBranch`
      
     -    The default name of the main branch in new repositories can now be
     +    The default name of the initial branch in new repositories can now be
          configured. The `testsvn` remote helper translates the remote Subversion
          repository's branch name `trunk` to the hard-coded name `master`.
     -    Clearly, the intention was to make the name align with Git's detaults.
     +    Clearly, the intention was to make the name align with Git's defaults.
      
          So while we are not talking about a newly-created repository in the
     -    `testsvn` context, it _still_ makes sense to use the overridden default
     -    name for the main branch whenever users configured it.
     +    `testsvn` context, it is a newly-created _Git_ repository, si it _still_
     +    makes sense to use the overridden default name for the initial branch
     +    whenever users configured it.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     @@ remote-testsvn.c: int cmd_main(int argc, const char **argv)
       		return 1;
       	}
       
     -+	remote_ref = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
     -+					  MAIN_BRANCH_FOR_INIT);
     -+	if (!skip_prefix(remote_ref, "refs/heads/", &remote_ref_short))
     -+		BUG("unexpected remote_ref '%s'", remote_ref);
     ++	remote_ref_short = git_default_branch_name();
     ++	remote_ref = xstrfmt("refs/heads/%s", remote_ref_short);
      +
       	remote = remote_get(argv[1]);
       	url_in = (argc == 3) ? argv[2] : remote->url[0];
     @@ t/t9020-remote-svn.sh: test_expect_success REMOTE_SVN 'incremental imports must
       	test_cmp master.good .git/refs/remotes/svnsim/master
       '
       
     -+test_expect_success REMOTE_SVN 'respects configured default main branch' '
     ++test_expect_success REMOTE_SVN 'respects configured default initial branch' '
      +	git -c init.defaultBranch=trunk remote add -f trunk \
      +		"testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" &&
      +	git rev-parse --verify refs/remotes/trunk/trunk

-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 1/8] fmt-merge-msg: stop treating `master` specially
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
@ 2020-06-23 22:33     ` Johannes Schindelin via GitGitGadget
  2020-06-24 16:16       ` Junio C Hamano
  2020-06-23 22:33     ` [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch Johannes Schindelin via GitGitGadget
                       ` (7 subsequent siblings)
  8 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

In the context of many projects renaming their primary branch names away
from `master`, Git wants to stop treating the `master` branch specially.

Let's start with `git fmt-merge-msg`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 fmt-merge-msg.c                               |  5 +-
 t/t1507-rev-parse-upstream.sh                 |  2 +-
 t/t4013-diff-various.sh                       |  4 +-
 t/t4013/diff.log_--decorate=full_--all        |  2 +-
 t/t4013/diff.log_--decorate_--all             |  2 +-
 ...--patch-with-stat_--summary_master_--_dir_ |  2 +-
 t/t4013/diff.log_--patch-with-stat_master     |  2 +-
 .../diff.log_--patch-with-stat_master_--_dir_ |  2 +-
 ...ot_--cc_--patch-with-stat_--summary_master |  2 +-
 ..._--root_--patch-with-stat_--summary_master |  2 +-
 .../diff.log_--root_--patch-with-stat_master  |  2 +-
 ...root_-c_--patch-with-stat_--summary_master |  2 +-
 t/t4013/diff.log_--root_-p_master             |  2 +-
 t/t4013/diff.log_--root_master                |  2 +-
 t/t4013/diff.log_-m_-p_--first-parent_master  |  2 +-
 t/t4013/diff.log_-m_-p_master                 |  4 +-
 t/t4013/diff.log_-p_--first-parent_master     |  2 +-
 t/t4013/diff.log_-p_master                    |  2 +-
 t/t4013/diff.log_master                       |  2 +-
 t/t4013/diff.show_--first-parent_master       |  2 +-
 t/t4013/diff.show_-c_master                   |  2 +-
 t/t4013/diff.show_-m_master                   |  4 +-
 t/t4013/diff.show_master                      |  2 +-
 ...ot_--cc_--patch-with-stat_--summary_master |  2 +-
 ...root_-c_--patch-with-stat_--summary_master |  2 +-
 t/t4202-log.sh                                | 72 +++++++++----------
 t/t6200-fmt-merge-msg.sh                      | 36 +++++-----
 t/t7600-merge.sh                              | 14 ++--
 t/t7608-merge-messages.sh                     | 10 +--
 29 files changed, 94 insertions(+), 97 deletions(-)

diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
index 72d32bd73b..cfb8ff2f33 100644
--- a/fmt-merge-msg.c
+++ b/fmt-merge-msg.c
@@ -451,10 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
 			strbuf_addf(out, " of %s", srcs.items[i].string);
 	}
 
-	if (!strcmp("master", current_branch))
-		strbuf_addch(out, '\n');
-	else
-		strbuf_addf(out, " into %s\n", current_branch);
+	strbuf_addf(out, " into %s\n", current_branch);
 }
 
 static void fmt_tag_signature(struct strbuf *tagbuf,
diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh
index dfc0d96d8a..f213aa8053 100755
--- a/t/t1507-rev-parse-upstream.sh
+++ b/t/t1507-rev-parse-upstream.sh
@@ -137,7 +137,7 @@ test_expect_success 'merge my-side@{u} records the correct name' '
 	git branch -t new my-side@{u} &&
 	git merge -s ours new@{u} &&
 	git show -s --pretty=tformat:%s >actual &&
-	echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect &&
+	echo "Merge remote-tracking branch ${SQ}origin/side${SQ} into master" >expect &&
 	test_cmp expect actual
 )
 '
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 3f60f7d96c..43267d6024 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -117,12 +117,12 @@ test_expect_success setup '
 
 : <<\EOF
 ! [initial] Initial
- * [master] Merge branch 'side'
+ * [master] Merge branch 'side' into master
   ! [rearrange] Rearranged lines in dir/sub
    ! [side] Side
 ----
   +  [rearrange] Rearranged lines in dir/sub
- -   [master] Merge branch 'side'
+ -   [master] Merge branch 'side' into master
  * + [side] Side
  *   [master^] Third
  *   [master~2] Second
diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all
index 3f9b872ece..c56783b985 100644
--- a/t/t4013/diff.log_--decorate=full_--all
+++ b/t/t4013/diff.log_--decorate=full_--all
@@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (refs/heads/side)
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--decorate_--all b/t/t4013/diff.log_--decorate_--all
index f5e20e1e14..1cbdc038f4 100644
--- a/t/t4013/diff.log_--decorate_--all
+++ b/t/t4013/diff.log_--decorate_--all
@@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (side)
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
index a18f1472a9..f5b1b6516b 100644
--- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master
index ae425c4672..af23803cdc 100644
--- a/t/t4013/diff.log_--patch-with-stat_master
+++ b/t/t4013/diff.log_--patch-with-stat_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
index d5207cadf4..814098fbf8 100644
--- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
index 0fc1e8cd71..b927fe4a98 100644
--- a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
  dir/sub | 2 ++
  file0   | 3 +++
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
index dffc09dde9..6db3cea329 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master
index 55aa98012d..98e9c320c3 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
index 019d85f7de..b61b1117ae 100644
--- a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
  dir/sub | 2 ++
  file0   | 3 +++
diff --git a/t/t4013/diff.log_--root_-p_master b/t/t4013/diff.log_--root_-p_master
index b42c334439..345bd9e8a9 100644
--- a/t/t4013/diff.log_--root_-p_master
+++ b/t/t4013/diff.log_--root_-p_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--root_master b/t/t4013/diff.log_--root_master
index e8f46159da..db56b1fe6b 100644
--- a/t/t4013/diff.log_--root_master
+++ b/t/t4013/diff.log_--root_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_-m_-p_--first-parent_master b/t/t4013/diff.log_-m_-p_--first-parent_master
index 7a0073f529..bcadb50e26 100644
--- a/t/t4013/diff.log_-m_-p_--first-parent_master
+++ b/t/t4013/diff.log_-m_-p_--first-parent_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index cead32e..992913c 100644
diff --git a/t/t4013/diff.log_-m_-p_master b/t/t4013/diff.log_-m_-p_master
index 9ca62a01ed..2acf43a9fb 100644
--- a/t/t4013/diff.log_-m_-p_master
+++ b/t/t4013/diff.log_-m_-p_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index cead32e..992913c 100644
@@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index 7289e35..992913c 100644
diff --git a/t/t4013/diff.log_-p_--first-parent_master b/t/t4013/diff.log_-p_--first-parent_master
index 3fc896d424..c6a5876d80 100644
--- a/t/t4013/diff.log_-p_--first-parent_master
+++ b/t/t4013/diff.log_-p_--first-parent_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_-p_master b/t/t4013/diff.log_-p_master
index bf1326dc36..1841cded94 100644
--- a/t/t4013/diff.log_-p_master
+++ b/t/t4013/diff.log_-p_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_master b/t/t4013/diff.log_master
index a8f6ce5abd..f8ec445eb3 100644
--- a/t/t4013/diff.log_master
+++ b/t/t4013/diff.log_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.show_--first-parent_master b/t/t4013/diff.show_--first-parent_master
index 3dcbe473a0..94548f4598 100644
--- a/t/t4013/diff.show_--first-parent_master
+++ b/t/t4013/diff.show_--first-parent_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index cead32e..992913c 100644
diff --git a/t/t4013/diff.show_-c_master b/t/t4013/diff.show_-c_master
index 81aba8da96..1c46ed64fd 100644
--- a/t/t4013/diff.show_-c_master
+++ b/t/t4013/diff.show_-c_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --combined dir/sub
 index cead32e,7289e35..992913c
diff --git a/t/t4013/diff.show_-m_master b/t/t4013/diff.show_-m_master
index 4ea2ee453d..7559fc22f8 100644
--- a/t/t4013/diff.show_-m_master
+++ b/t/t4013/diff.show_-m_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index cead32e..992913c 100644
@@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index 7289e35..992913c 100644
diff --git a/t/t4013/diff.show_master b/t/t4013/diff.show_master
index fb08ce0e46..57091c5d90 100644
--- a/t/t4013/diff.show_master
+++ b/t/t4013/diff.show_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --cc dir/sub
 index cead32e,7289e35..992913c
diff --git a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
index 30aae7817b..5f13a71bb5 100644
--- a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
  dir/sub | 2 ++
  file0   | 3 +++
diff --git a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
index d1d32bd34c..8acb88267b 100644
--- a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
  dir/sub | 2 ++
  file0   | 3 +++
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index a0930599aa..fd9af658af 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -483,7 +483,7 @@ test_expect_success 'set up merge history' '
 '
 
 cat > expect <<\EOF
-*   Merge branch 'side'
+*   Merge branch 'side' into master
 |\
 | * side-2
 | * side-1
@@ -502,7 +502,7 @@ test_expect_success 'log --graph with merge' '
 '
 
 cat > expect <<\EOF
-| | | *   Merge branch 'side'
+| | | *   Merge branch 'side' into master
 | | | |\
 | | | | * side-2
 | | | | * side-1
@@ -521,7 +521,7 @@ test_expect_success 'log --graph --line-prefix="| | | " with merge' '
 '
 
 cat > expect.colors <<\EOF
-*   Merge branch 'side'
+*   Merge branch 'side' into master
 <BLUE>|<RESET><CYAN>\<RESET>
 <BLUE>|<RESET> * side-2
 <BLUE>|<RESET> * side-1
@@ -555,7 +555,7 @@ cat > expect <<\EOF
 |\  Merge: A B
 | | Author: A U Thor <author@example.com>
 | |
-| |     Merge branch 'side'
+| |     Merge branch 'side' into master
 | |
 | * commit tags/side-2
 | | Author: A U Thor <author@example.com>
@@ -632,11 +632,11 @@ test_expect_success 'set up more tangled history' '
 '
 
 cat > expect <<\EOF
-*   Merge tag 'reach'
+*   Merge tag 'reach' into master
 |\
 | \
 |  \
-*-. \   Merge tags 'octopus-a' and 'octopus-b'
+*-. \   Merge tags 'octopus-a' and 'octopus-b' into master
 |\ \ \
 * | | | seventh
 | | * | octopus-b
@@ -646,14 +646,14 @@ cat > expect <<\EOF
 |/ /
 | * reach
 |/
-*   Merge branch 'tangle'
+*   Merge branch 'tangle' into master
 |\
 | *   Merge branch 'side' (early part) into tangle
 | |\
 | * \   Merge branch 'master' (early part) into tangle
 | |\ \
 | * | | tangle-a
-* | | |   Merge branch 'side'
+* | | |   Merge branch 'side' into master
 |\ \ \ \
 | * | | | side-2
 | | |_|/
@@ -735,16 +735,16 @@ test_expect_success 'log.decorate configuration' '
 
 test_expect_success 'decorate-refs with glob' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b (octopus-b)
 	octopus-a (octopus-a)
 	reach
 	EOF
 	cat >expect.no-decorate <<-\EOF &&
-	Merge-tag-reach
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b
 	octopus-a
@@ -765,8 +765,8 @@ test_expect_success 'decorate-refs with glob' '
 
 test_expect_success 'decorate-refs without globs' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b
 	octopus-a
@@ -779,8 +779,8 @@ test_expect_success 'decorate-refs without globs' '
 
 test_expect_success 'multiple decorate-refs' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b (octopus-b)
 	octopus-a (octopus-a)
@@ -794,8 +794,8 @@ test_expect_success 'multiple decorate-refs' '
 
 test_expect_success 'decorate-refs-exclude with glob' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (HEAD -> master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (HEAD -> master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh (tag: seventh)
 	octopus-b (tag: octopus-b)
 	octopus-a (tag: octopus-a)
@@ -811,8 +811,8 @@ test_expect_success 'decorate-refs-exclude with glob' '
 
 test_expect_success 'decorate-refs-exclude without globs' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (HEAD -> master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (HEAD -> master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh (tag: seventh)
 	octopus-b (tag: octopus-b, octopus-b)
 	octopus-a (tag: octopus-a, octopus-a)
@@ -828,8 +828,8 @@ test_expect_success 'decorate-refs-exclude without globs' '
 
 test_expect_success 'multiple decorate-refs-exclude' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (HEAD -> master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (HEAD -> master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh (tag: seventh)
 	octopus-b (tag: octopus-b)
 	octopus-a (tag: octopus-a)
@@ -851,8 +851,8 @@ test_expect_success 'multiple decorate-refs-exclude' '
 
 test_expect_success 'decorate-refs and decorate-refs-exclude' '
 	cat >expect.no-decorate <<-\EOF &&
-	Merge-tag-reach (master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b
 	octopus-a
@@ -866,8 +866,8 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' '
 
 test_expect_success 'deocrate-refs and log.excludeDecoration' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b (octopus-b)
 	octopus-a (octopus-a)
@@ -881,10 +881,10 @@ test_expect_success 'deocrate-refs and log.excludeDecoration' '
 
 test_expect_success 'decorate-refs-exclude and simplify-by-decoration' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (HEAD -> master)
+	Merge-tag-reach-into-master (HEAD -> master)
 	reach (tag: reach, reach)
 	seventh (tag: seventh)
-	Merge-branch-tangle
+	Merge-branch-tangle-into-master
 	Merge-branch-side-early-part-into-tangle (tangle)
 	tangle-a (tag: tangle-a)
 	EOF
@@ -1068,7 +1068,7 @@ cat >expect <<\EOF
 |\  Merge: MERGE_PARENTS
 | | Author: A U Thor <author@example.com>
 | |
-| |     Merge branch 'tangle'
+| |     Merge branch 'tangle' into master
 | |
 | *   commit COMMIT_OBJECT_NAME
 | |\  Merge: MERGE_PARENTS
@@ -1102,7 +1102,7 @@ cat >expect <<\EOF
 |\ \ \ \  Merge: MERGE_PARENTS
 | | | | | Author: A U Thor <author@example.com>
 | | | | |
-| | | | |     Merge branch 'side'
+| | | | |     Merge branch 'side' into master
 | | | | |
 | * | | | commit COMMIT_OBJECT_NAME
 | | |_|/  Author: A U Thor <author@example.com>
@@ -1343,7 +1343,7 @@ cat >expect <<\EOF
 *** |\  Merge: MERGE_PARENTS
 *** | | Author: A U Thor <author@example.com>
 *** | |
-*** | |     Merge branch 'tangle'
+*** | |     Merge branch 'tangle' into master
 *** | |
 *** | *   commit COMMIT_OBJECT_NAME
 *** | |\  Merge: MERGE_PARENTS
@@ -1377,7 +1377,7 @@ cat >expect <<\EOF
 *** |\ \ \ \  Merge: MERGE_PARENTS
 *** | | | | | Author: A U Thor <author@example.com>
 *** | | | | |
-*** | | | | |     Merge branch 'side'
+*** | | | | |     Merge branch 'side' into master
 *** | | | | |
 *** | * | | | commit COMMIT_OBJECT_NAME
 *** | | |_|/  Author: A U Thor <author@example.com>
@@ -1540,8 +1540,8 @@ cat >expect <<-\EOF
 * reach
 |
 | A	reach.t
-* Merge branch 'tangle'
-*   Merge branch 'side'
+* Merge branch 'tangle' into master
+*   Merge branch 'side' into master
 |\
 | * side-2
 |
@@ -1562,8 +1562,8 @@ cat >expect <<-\EOF
 * reach
 |
 | reach.t
-* Merge branch 'tangle'
-*   Merge branch 'side'
+* Merge branch 'tangle' into master
+*   Merge branch 'side' into master
 |\
 | * side-2
 |
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index e4c2a6eca4..2b3fd498d0 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -79,7 +79,7 @@ test_expect_success GPG 'set up a signed tag' '
 '
 
 test_expect_success 'message for merging local branch' '
-	echo "Merge branch ${apos}left${apos}" >expected &&
+	echo "Merge branch ${apos}left${apos} into master" >expected &&
 
 	git checkout master &&
 	git fetch . left &&
@@ -107,7 +107,7 @@ test_expect_success GPG 'message for merging local tag signed by unknown key' '
 '
 
 test_expect_success 'message for merging external branch' '
-	echo "Merge branch ${apos}left${apos} of $(pwd)" >expected &&
+	echo "Merge branch ${apos}left${apos} of $(pwd) into master" >expected &&
 
 	git checkout master &&
 	git fetch "$(pwd)" left &&
@@ -118,7 +118,7 @@ test_expect_success 'message for merging external branch' '
 
 test_expect_success '[merge] summary/log configuration' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -160,7 +160,7 @@ test_expect_success 'setup FETCH_HEAD' '
 
 test_expect_success 'merge.log=3 limits shortlog length' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -177,7 +177,7 @@ test_expect_success 'merge.log=3 limits shortlog length' '
 
 test_expect_success 'merge.log=5 shows all 5 commits' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -195,7 +195,7 @@ test_expect_success 'merge.log=5 shows all 5 commits' '
 
 test_expect_success '--log=5 with custom comment character' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	x By Another Author (3) and A U Thor (2)
 	x Via Another Committer
@@ -212,14 +212,14 @@ test_expect_success '--log=5 with custom comment character' '
 '
 
 test_expect_success 'merge.log=0 disables shortlog' '
-	echo "Merge branch ${apos}left${apos}" >expected &&
+	echo "Merge branch ${apos}left${apos} into master" >expected &&
 	git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual &&
 	test_cmp expected actual
 '
 
 test_expect_success '--log=3 limits shortlog length' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -236,7 +236,7 @@ test_expect_success '--log=3 limits shortlog length' '
 
 test_expect_success '--log=5 shows all 5 commits' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -253,13 +253,13 @@ test_expect_success '--log=5 shows all 5 commits' '
 '
 
 test_expect_success '--no-log disables shortlog' '
-	echo "Merge branch ${apos}left${apos}" >expected &&
+	echo "Merge branch ${apos}left${apos} into master" >expected &&
 	git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual &&
 	test_cmp expected actual
 '
 
 test_expect_success '--log=0 disables shortlog' '
-	echo "Merge branch ${apos}left${apos}" >expected &&
+	echo "Merge branch ${apos}left${apos} into master" >expected &&
 	git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual &&
 	test_cmp expected actual
 '
@@ -300,7 +300,7 @@ test_expect_success 'fmt-merge-msg -m' '
 
 test_expect_success 'setup: expected shortlog for two branches' '
 	cat >expected <<-EOF
-	Merge branches ${apos}left${apos} and ${apos}right${apos}
+	Merge branches ${apos}left${apos} and ${apos}right${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -397,7 +397,7 @@ test_expect_success 'merge-msg with nothing to merge' '
 
 test_expect_success 'merge-msg tag' '
 	cat >expected <<-EOF &&
-	Merge tag ${apos}tag-r3${apos}
+	Merge tag ${apos}tag-r3${apos} into master
 
 	* tag ${apos}tag-r3${apos}:
 	  Right #3
@@ -418,7 +418,7 @@ test_expect_success 'merge-msg tag' '
 
 test_expect_success 'merge-msg two tags' '
 	cat >expected <<-EOF &&
-	Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos}
+	Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} into master
 
 	* tag ${apos}tag-r3${apos}:
 	  Right #3
@@ -448,7 +448,7 @@ test_expect_success 'merge-msg two tags' '
 
 test_expect_success 'merge-msg tag and branch' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos}
+	Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} into master
 
 	* tag ${apos}tag-r3${apos}:
 	  Right #3
@@ -479,7 +479,7 @@ test_expect_success 'merge-msg tag and branch' '
 test_expect_success 'merge-msg lots of commits' '
 	{
 		cat <<-EOF &&
-		Merge branch ${apos}long${apos}
+		Merge branch ${apos}long${apos} into master
 
 		* long: (35 commits)
 		EOF
@@ -516,7 +516,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' '
 	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
 	{
 		cat <<-\EOF
-		Merge tag '\''annote'\''
+		Merge tag '\''annote'\'' into master
 
 		An annotated one
 
@@ -531,7 +531,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' '
 	git merge --no-commit --no-ff $annote &&
 	{
 		cat <<-EOF
-		Merge tag '\''$annote'\''
+		Merge tag '\''$annote'\'' into master
 
 		An annotated one
 
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 5883a6adc3..1d45f9a4ed 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -14,9 +14,9 @@ Testing basic merge operations/option parsing.
     ! [c4] c4
      ! [c5] c5
       ! [c6] c6
-       * [master] Merge commit 'c1'
+       * [master] Merge commit 'c1' into master
 --------
-       - [master] Merge commit 'c1'
+       - [master] Merge commit 'c1' into master
  +     * [c1] commit 1
       +  [c6] c6
      +   [c5] c5
@@ -44,8 +44,8 @@ test_write_lines '1 X' 2 '3 X' 4 '5 X' 6 7 8 '9 X' >result.1-3-5-9
 test_write_lines 1 2 3 4 5 6 7 8 '9 Z' >result.9z
 
 create_merge_msgs () {
-	echo "Merge tag 'c2'" >msg.1-5 &&
-	echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 &&
+	echo "Merge tag 'c2' into master" >msg.1-5 &&
+	echo "Merge tags 'c2' and 'c3' into master" >msg.1-5-9 &&
 	{
 		echo "Squashed commit of the following:" &&
 		echo &&
@@ -258,7 +258,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '
 	git commit --no-edit -a &&
 
 	cat >expect <<-\EOF &&
-	Merge tag '"'"'c7'"'"'
+	Merge tag '"'"'c7'"'"' into master
 
 	# ------------------------ >8 ------------------------
 	# Do not modify or remove the line above.
@@ -808,10 +808,10 @@ test_expect_success 'merge with conflicted --autostash changes' '
 '
 
 cat >expected.branch <<\EOF
-Merge branch 'c5-branch' (early part)
+Merge branch 'c5-branch' (early part) into master
 EOF
 cat >expected.tag <<\EOF
-Merge commit 'c5~1'
+Merge commit 'c5~1' into master
 EOF
 
 test_expect_success 'merge early part of c2' '
diff --git a/t/t7608-merge-messages.sh b/t/t7608-merge-messages.sh
index 8e7e0a5865..2af33f195b 100755
--- a/t/t7608-merge-messages.sh
+++ b/t/t7608-merge-messages.sh
@@ -16,7 +16,7 @@ test_expect_success 'merge local branch' '
 	git checkout master &&
 	test_commit master-2 &&
 	git merge local-branch &&
-	check_oneline "Merge branch Qlocal-branchQ"
+	check_oneline "Merge branch Qlocal-branchQ into master"
 '
 
 test_expect_success 'merge octopus branches' '
@@ -26,7 +26,7 @@ test_expect_success 'merge octopus branches' '
 	test_commit octopus-2 &&
 	git checkout master &&
 	git merge octopus-a octopus-b &&
-	check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ"
+	check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ into master"
 '
 
 test_expect_success 'merge tag' '
@@ -35,7 +35,7 @@ test_expect_success 'merge tag' '
 	git checkout master &&
 	test_commit master-3 &&
 	git merge tag-1 &&
-	check_oneline "Merge tag Qtag-1Q"
+	check_oneline "Merge tag Qtag-1Q into master"
 '
 
 test_expect_success 'ambiguous tag' '
@@ -44,7 +44,7 @@ test_expect_success 'ambiguous tag' '
 	git checkout master &&
 	test_commit master-4 &&
 	git merge ambiguous &&
-	check_oneline "Merge tag QambiguousQ"
+	check_oneline "Merge tag QambiguousQ into master"
 '
 
 test_expect_success 'remote-tracking branch' '
@@ -54,7 +54,7 @@ test_expect_success 'remote-tracking branch' '
 	git checkout master &&
 	test_commit master-5 &&
 	git merge origin/master &&
-	check_oneline "Merge remote-tracking branch Qorigin/masterQ"
+	check_oneline "Merge remote-tracking branch Qorigin/masterQ into master"
 '
 
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  2020-06-23 22:33     ` [PATCH v3 1/8] fmt-merge-msg: stop treating `master` specially Johannes Schindelin via GitGitGadget
@ 2020-06-23 22:33     ` Johannes Schindelin via GitGitGadget
  2020-06-24  0:36       ` Junio C Hamano
  2020-06-23 22:33     ` [PATCH v3 3/8] submodule: use a better fall-back for missing remote.<name>.branch Johannes Schindelin via GitGitGadget
                       ` (6 subsequent siblings)
  8 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When trying to push all matching branches, but none match, we offer a
message suggesting to push the `master` branch.

However, we want to step away from making that branch any more special
than any other branch, so let's reword that message to mention no branch
in particular.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 send-pack.c             | 2 +-
 t/t5528-push-default.sh | 6 ++++++
 transport-helper.c      | 2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/send-pack.c b/send-pack.c
index 0abee22283..db79cdac77 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -406,7 +406,7 @@ int send_pack(struct send_pack_args *args,
 
 	if (!remote_refs) {
 		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
-			"Perhaps you should specify a branch such as 'master'.\n");
+			"Perhaps you should specify a specific branch.\n");
 		return 0;
 	}
 	if (args->atomic && !atomic_supported)
diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh
index 4d1e0c363e..68b84c4add 100755
--- a/t/t5528-push-default.sh
+++ b/t/t5528-push-default.sh
@@ -98,6 +98,12 @@ test_expect_success 'push from/to new branch with upstream, matching and simple'
 	test_push_failure upstream
 '
 
+test_expect_success '"matching" fails if none match' '
+	git init --bare empty &&
+	test_must_fail git push empty : 2>actual &&
+	test_i18ngrep "Perhaps you should specify a specific branch" actual
+'
+
 test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
 	git checkout -b ambiguous &&
 	test_config branch.ambiguous.remote parent1 &&
diff --git a/transport-helper.c b/transport-helper.c
index a46afcb69d..b81a3486bd 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -1046,7 +1046,7 @@ static int push_refs(struct transport *transport,
 	if (!remote_refs) {
 		fprintf(stderr,
 			_("No refs in common and none specified; doing nothing.\n"
-			  "Perhaps you should specify a branch such as 'master'.\n"));
+			  "Perhaps you should specify a specific branch.\n"));
 		return 0;
 	}
 
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 3/8] submodule: use a better fall-back for missing remote.<name>.branch
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  2020-06-23 22:33     ` [PATCH v3 1/8] fmt-merge-msg: stop treating `master` specially Johannes Schindelin via GitGitGadget
  2020-06-23 22:33     ` [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch Johannes Schindelin via GitGitGadget
@ 2020-06-23 22:33     ` Johannes Schindelin via GitGitGadget
  2020-06-24  2:18       ` Philippe Blain
  2020-06-23 22:33     ` [PATCH v3 4/8] init: allow specifying the initial branch name for the new repository Johannes Schindelin via GitGitGadget
                       ` (5 subsequent siblings)
  8 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When `remote.<name>.branch` is not configured, `git submodule update`
currently falls back to using the branch name `master`. A much better
idea, however, is to use `HEAD`: on all Git servers running reasonably
recent Git versions, the symref `HEAD` points to the main branch.

Note: t7419 demonstrates that there _might_ be use cases out there that
_expect_ `git submodule update --remote` to update submodules to the
remote `master` branch even if the remote `HEAD` points to another
branch. Arguably, this patch makes the behavior more intuitive, but
there is a slight possibility that this might cause regressions in
obscure setups.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-submodule.txt |  4 ++--
 builtin/submodule--helper.c     |  2 +-
 t/t7406-submodule-update.sh     | 16 ++++++++++++++++
 t/t7419-submodule-set-branch.sh |  7 +++++--
 4 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index c9ed2bf3d5..b20f85e622 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -284,7 +284,7 @@ OPTIONS
 	`.gitmodules` for `update --remote`.  A special value of `.` is used to
 	indicate that the name of the branch in the submodule should be the
 	same name as the current branch in the current repository.  If the
-	option is not specified, it defaults to 'master'.
+	option is not specified, it defaults to 'HEAD'.
 
 -f::
 --force::
@@ -322,7 +322,7 @@ OPTIONS
 	the superproject's recorded SHA-1 to update the submodule, use the
 	status of the submodule's remote-tracking branch.  The remote used
 	is branch's remote (`branch.<name>.remote`), defaulting to `origin`.
-	The remote branch used defaults to `master`, but the branch name may
+	The remote branch used defaults to `HEAD`, but the branch name may
 	be overridden by setting the `submodule.<name>.branch` option in
 	either `.gitmodules` or `.git/config` (with `.git/config` taking
 	precedence).
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 46c03d2a12..f55f7b7704 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1981,7 +1981,7 @@ static const char *remote_submodule_branch(const char *path)
 	free(key);
 
 	if (!branch)
-		return "master";
+		return "HEAD";
 
 	if (!strcmp(branch, ".")) {
 		const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 4fb447a143..aa19ff3a2e 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -70,6 +70,22 @@ test_expect_success 'setup a submodule tree' '
 	)
 '
 
+test_expect_success 'update --remote falls back to using HEAD' '
+	test_create_repo main-branch-submodule &&
+	test_commit -C main-branch-submodule initial &&
+
+	test_create_repo main-branch &&
+	git -C main-branch submodule add ../main-branch-submodule &&
+	git -C main-branch commit -m add-submodule &&
+
+	git -C main-branch-submodule switch -c hello &&
+	test_commit -C main-branch-submodule world &&
+
+	git clone --recursive main-branch main-branch-clone &&
+	git -C main-branch-clone submodule update --remote main-branch-submodule &&
+	test_path_exists main-branch-clone/main-branch-submodule/world.t
+'
+
 test_expect_success 'submodule update detaching the HEAD ' '
 	(cd super/submodule &&
 	 git reset --hard HEAD~1
diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh
index fd25f786a3..3b925c302f 100755
--- a/t/t7419-submodule-set-branch.sh
+++ b/t/t7419-submodule-set-branch.sh
@@ -52,12 +52,13 @@ test_expect_success 'test submodule set-branch --branch' '
 '
 
 test_expect_success 'test submodule set-branch --default' '
+	test_commit -C submodule c &&
 	(cd super &&
 		git submodule set-branch --default submodule &&
 		! grep branch .gitmodules &&
 		git submodule update --remote &&
 		cat <<-\EOF >expect &&
-		a
+		c
 		EOF
 		git -C submodule show -s --pretty=%s >actual &&
 		test_cmp expect actual
@@ -65,6 +66,7 @@ test_expect_success 'test submodule set-branch --default' '
 '
 
 test_expect_success 'test submodule set-branch -b' '
+	test_commit -C submodule b &&
 	(cd super &&
 		git submodule set-branch -b topic submodule &&
 		grep "branch = topic" .gitmodules &&
@@ -78,12 +80,13 @@ test_expect_success 'test submodule set-branch -b' '
 '
 
 test_expect_success 'test submodule set-branch -d' '
+	test_commit -C submodule d &&
 	(cd super &&
 		git submodule set-branch -d submodule &&
 		! grep branch .gitmodules &&
 		git submodule update --remote &&
 		cat <<-\EOF >expect &&
-		a
+		d
 		EOF
 		git -C submodule show -s --pretty=%s >actual &&
 		test_cmp expect actual
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 4/8] init: allow specifying the initial branch name for the new repository
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                       ` (2 preceding siblings ...)
  2020-06-23 22:33     ` [PATCH v3 3/8] submodule: use a better fall-back for missing remote.<name>.branch Johannes Schindelin via GitGitGadget
@ 2020-06-23 22:33     ` Johannes Schindelin via GitGitGadget
  2020-06-24  0:58       ` Junio C Hamano
  2020-06-23 22:33     ` [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config Don Goodman-Wilson via GitGitGadget
                       ` (4 subsequent siblings)
  8 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

There is a growing number of projects and companies desiring to change
the main branch name of their repositories (see e.g.
https://twitter.com/mislav/status/1270388510684598272 for background on
this).

To change that branch name for new repositories, currently the only way
to do that automatically is by copying all of Git's template directory,
then hard-coding the desired default branch name into the `.git/HEAD`
file, and then configuring `init.templateDir` to point to those copied
template files.

To make this process much less cumbersome, let's introduce a new option:
`--initial-branch=<branch-name>`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-init.txt |  7 +++++++
 builtin/clone.c            |  3 ++-
 builtin/init-db.c          | 34 +++++++++++++++++++++++++++-------
 cache.h                    |  2 +-
 t/t0001-init.sh            | 13 +++++++++++++
 5 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index adc6adfd38..36dccc6e52 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 [verse]
 'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
 	  [--separate-git-dir <git dir>] [--object-format=<format]
+	  [-b <branch-name> | --initial-branch=<branch-name>]
 	  [--shared[=<permissions>]] [directory]
 
 
@@ -67,6 +68,12 @@ repository.
 +
 If this is reinitialization, the repository will be moved to the specified path.
 
+-b <branch-name::
+--initial-branch=<branch-name>::
+
+Use the specified name for the initial branch in the newly created repository.
+If not specified, fall back to the default name: `master`.
+
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
 Specify that the Git repository is to be shared amongst several users.  This
diff --git a/builtin/clone.c b/builtin/clone.c
index 2a8e3aaaed..b751bdf13e 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1111,7 +1111,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
+	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
+		INIT_DB_QUIET);
 
 	if (real_git_dir)
 		git_dir = real_git_dir;
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 0b7222e718..a898153901 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)
 
 static int create_default_files(const char *template_path,
 				const char *original_git_dir,
+				const char *initial_branch,
 				const struct repository_format *fmt)
 {
 	struct stat st1;
@@ -258,16 +259,29 @@ static int create_default_files(const char *template_path,
 		die("failed to set up refs db: %s", err.buf);
 
 	/*
-	 * Create the default symlink from ".git/HEAD" to the "master"
-	 * branch, if it does not exist yet.
+	 * Create the default symlink from ".git/HEAD" to the default
+	 * branch name, if it does not exist yet.
 	 */
 	path = git_path_buf(&buf, "HEAD");
 	reinit = (!access(path, R_OK)
 		  || readlink(path, junk, sizeof(junk)-1) != -1);
 	if (!reinit) {
-		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
+		char *ref;
+
+		if (!initial_branch)
+			initial_branch = "master";
+
+		ref = xstrfmt("refs/heads/%s", initial_branch);
+		if (check_refname_format(ref, 0) < 0)
+			die(_("invalid initial branch name: '%s'"),
+			    initial_branch);
+
+		if (create_symref("HEAD", ref, NULL) < 0)
 			exit(1);
-	}
+		free(ref);
+	} else if (initial_branch)
+		warning(_("re-init: ignoring --initial-branch=%s"),
+			initial_branch);
 
 	initialize_repository_version(fmt->hash_algo);
 
@@ -383,7 +397,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
 }
 
 int init_db(const char *git_dir, const char *real_git_dir,
-	    const char *template_dir, int hash, unsigned int flags)
+	    const char *template_dir, int hash, const char *initial_branch,
+	    unsigned int flags)
 {
 	int reinit;
 	int exist_ok = flags & INIT_DB_EXIST_OK;
@@ -425,7 +440,8 @@ int init_db(const char *git_dir, const char *real_git_dir,
 
 	validate_hash_algorithm(&repo_fmt, hash);
 
-	reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
+	reinit = create_default_files(template_dir, original_git_dir,
+				      initial_branch, &repo_fmt);
 
 	create_object_directory();
 
@@ -528,6 +544,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	const char *template_dir = NULL;
 	unsigned int flags = 0;
 	const char *object_format = NULL;
+	const char *initial_branch = NULL;
 	int hash_algo = GIT_HASH_UNKNOWN;
 	const struct option init_db_options[] = {
 		OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ -541,6 +558,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 		OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
 		OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
 			   N_("separate git dir from working tree")),
+		OPT_STRING('b', "initial-branch", &initial_branch, N_("name"),
+			   N_("override the name of the initial branch")),
 		OPT_STRING(0, "object-format", &object_format, N_("hash"),
 			   N_("specify the hash algorithm to use")),
 		OPT_END()
@@ -652,5 +671,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	UNLEAK(work_tree);
 
 	flags |= INIT_DB_EXIST_OK;
-	return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
+	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
+		       initial_branch, flags);
 }
diff --git a/cache.h b/cache.h
index 0f0485ecfe..654426460c 100644
--- a/cache.h
+++ b/cache.h
@@ -628,7 +628,7 @@ int path_inside_repo(const char *prefix, const char *path);
 
 int init_db(const char *git_dir, const char *real_git_dir,
 	    const char *template_dir, int hash_algo,
-	    unsigned int flags);
+	    const char *initial_branch, unsigned int flags);
 void initialize_repository_version(int hash_algo);
 
 void sanitize_stdfds(void);
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 1edd5aeb8f..61837ca25f 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -464,4 +464,17 @@ test_expect_success MINGW 'redirect std handles' '
 	grep "Needed a single revision" output.txt
 '
 
+test_expect_success '--initial-branch' '
+	git init --initial-branch=hello initial-branch-option &&
+	git -C initial-branch-option symbolic-ref HEAD >actual &&
+	echo refs/heads/hello >expect &&
+	test_cmp expect actual &&
+
+	: re-initializing should not change the branch name &&
+	git init --initial-branch=ignore initial-branch-option 2>err &&
+	test_i18ngrep "ignoring --initial-branch" err &&
+	git -C initial-branch-option symbolic-ref HEAD >actual &&
+	grep hello actual
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                       ` (3 preceding siblings ...)
  2020-06-23 22:33     ` [PATCH v3 4/8] init: allow specifying the initial branch name for the new repository Johannes Schindelin via GitGitGadget
@ 2020-06-23 22:33     ` Don Goodman-Wilson via GitGitGadget
  2020-06-24  1:05       ` Junio C Hamano
  2020-06-23 22:33     ` [PATCH v3 6/8] clone: use configured default branch name when appropriate Johannes Schindelin via GitGitGadget
                       ` (3 subsequent siblings)
  8 siblings, 1 reply; 178+ messages in thread
From: Don Goodman-Wilson via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin, Don Goodman-Wilson

From: Don Goodman-Wilson <don@goodman-wilson.com>

We just introduced the command-line option
`--initial-branch=<branch-name>` to allow initializing a new repository
with a different initial branch than the hard-coded one.

To allow users to override the initial branch name more permanently
(i.e. without having to specify the name manually for each and every
`git init` invocation), let's introduce the `init.defaultBranch` config
setting.

Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
---
 Documentation/config/init.txt |  4 ++++
 builtin/init-db.c             |  2 +-
 refs.c                        | 30 ++++++++++++++++++++++++++++++
 refs.h                        |  9 +++++++++
 t/t0001-init.sh               | 13 +++++++++++++
 5 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt
index 46fa8c6a08..6ae4a38416 100644
--- a/Documentation/config/init.txt
+++ b/Documentation/config/init.txt
@@ -1,3 +1,7 @@
 init.templateDir::
 	Specify the directory from which templates will be copied.
 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+
+init.defaultBranch::
+	Allows overriding the default branch name when initializing
+	a new repository.
diff --git a/builtin/init-db.c b/builtin/init-db.c
index a898153901..b8634b5f35 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -269,7 +269,7 @@ static int create_default_files(const char *template_path,
 		char *ref;
 
 		if (!initial_branch)
-			initial_branch = "master";
+			initial_branch = git_default_branch_name();
 
 		ref = xstrfmt("refs/heads/%s", initial_branch);
 		if (check_refname_format(ref, 0) < 0)
diff --git a/refs.c b/refs.c
index 224ff66c7b..b98dea5217 100644
--- a/refs.c
+++ b/refs.c
@@ -560,6 +560,36 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
 		argv_array_pushf(prefixes, *p, len, prefix);
 }
 
+char *repo_default_branch_name(struct repository *r)
+{
+	const char *config_key = "init.defaultbranch";
+	const char *config_display_key = "init.defaultBranch";
+	char *ret = NULL, *full_ref;
+
+	if (repo_config_get_string(r, config_key, &ret) < 0)
+		die(_("could not retrieve `%s`"), config_display_key);
+
+	if (!ret)
+		ret = xstrdup("master");
+
+	full_ref = xstrfmt("refs/heads/%s", ret);
+	if (check_refname_format(full_ref, 0))
+		die(_("invalid branch name: %s = %s"), config_display_key, ret);
+	free(full_ref);
+
+	return ret;
+}
+
+const char *git_default_branch_name(void)
+{
+	static char *ret;
+
+	if (!ret)
+		ret = repo_default_branch_name(the_repository);
+
+	return ret;
+}
+
 /*
  * *string and *len will only be substituted, and *string returned (for
  * later free()ing) if the string passed in is a magic short-hand form
diff --git a/refs.h b/refs.h
index e010f8aec2..f212f8945e 100644
--- a/refs.h
+++ b/refs.h
@@ -154,6 +154,15 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
 int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
 int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
 
+/*
+ * Retrieves the default branch name for newly-initialized repositories.
+ *
+ * The return value of `repo_default_branch_name()` is an allocated string. The
+ * return value of `git_default_branch_name()` is a singleton.
+ */
+const char *git_default_branch_name(void);
+char *repo_default_branch_name(struct repository *r);
+
 /*
  * A ref_transaction represents a collection of reference updates that
  * should succeed or fail together.
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 61837ca25f..047197d08f 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -477,4 +477,17 @@ test_expect_success '--initial-branch' '
 	grep hello actual
 '
 
+test_expect_success 'overridden default initial branch name (config)' '
+	test_config_global init.defaultBranch nmb &&
+	git init initial-branch-config &&
+	git -C initial-branch-config symbolic-ref HEAD >actual &&
+	grep nmb actual
+'
+
+test_expect_success 'invalid default branch name' '
+	test_config_global init.defaultBranch "with space" &&
+	test_must_fail git init initial-branch-invalid 2>err &&
+	test_i18ngrep "invalid branch name" err
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 6/8] clone: use configured default branch name when appropriate
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                       ` (4 preceding siblings ...)
  2020-06-23 22:33     ` [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config Don Goodman-Wilson via GitGitGadget
@ 2020-06-23 22:33     ` Johannes Schindelin via GitGitGadget
  2020-06-23 22:33     ` [PATCH v3 7/8] remote: use the " Johannes Schindelin via GitGitGadget
                       ` (2 subsequent siblings)
  8 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When cloning a repository without any branches, Git chooses a default
branch name for the as-yet unborn branch.

As part of the implicit initialization of the local repository, Git just
learned to respect `init.defaultBranch` to choose a different initial
branch name. We now really want that branch name to be used as a
fall-back.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/config/init.txt |  4 ++--
 builtin/clone.c               | 10 +++++++---
 t/t5606-clone-options.sh      | 15 +++++++++++++++
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt
index 6ae4a38416..dc77f8c844 100644
--- a/Documentation/config/init.txt
+++ b/Documentation/config/init.txt
@@ -3,5 +3,5 @@ init.templateDir::
 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
 
 init.defaultBranch::
-	Allows overriding the default branch name when initializing
-	a new repository.
+	Allows overriding the default branch name e.g. when initializing
+	a new repository or when cloning an empty repository.
diff --git a/builtin/clone.c b/builtin/clone.c
index b751bdf13e..9a3f91b268 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1267,9 +1267,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head_points_at = NULL;
 		remote_head = NULL;
 		option_no_checkout = 1;
-		if (!option_bare)
-			install_branch_config(0, "master", option_origin,
-					      "refs/heads/master");
+		if (!option_bare) {
+			const char *branch = git_default_branch_name();
+			char *ref = xstrfmt("refs/heads/%s", branch);
+
+			install_branch_config(0, branch, option_origin, ref);
+			free(ref);
+		}
 	}
 
 	write_refspec_config(src_ref_prefix, our_head_points_at,
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 9e24ec88e6..286bfd93ac 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -35,4 +35,19 @@ test_expect_success 'redirected clone -v does show progress' '
 
 '
 
+test_expect_success 'chooses correct default initial branch name' '
+	git init --bare empty &&
+	git -c init.defaultBranch=up clone empty whats-up &&
+	test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) &&
+	test refs/heads/up = $(git -C whats-up config branch.up.merge)
+'
+
+test_expect_success 'guesses initial branch name correctly' '
+	git init --initial-branch=guess initial-branch &&
+	test_commit -C initial-branch no-spoilers &&
+	git -C initial-branch branch abc guess &&
+	git clone initial-branch is-it &&
+	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 7/8] remote: use the configured default branch name when appropriate
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                       ` (5 preceding siblings ...)
  2020-06-23 22:33     ` [PATCH v3 6/8] clone: use configured default branch name when appropriate Johannes Schindelin via GitGitGadget
@ 2020-06-23 22:33     ` Johannes Schindelin via GitGitGadget
  2020-06-24  1:10       ` Junio C Hamano
  2020-06-23 22:33     ` [PATCH v3 8/8] testsvn: respect `init.defaultBranch` Johannes Schindelin via GitGitGadget
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  8 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When guessing the default branch name of a remote, and there are no refs
to guess from, we want to go with the preference specified by the user
for the fall-back, i.e. the default name to be used for the initial
branch of new repositories (because as far as the user is concerned, a
remote that has no branches yet is a new repository).

At the same time, when talking to an older Git server that does not
report a symref for `HEAD` (but instead reports a commit hash), let's
try to guess the configured default branch name first. If it does not
match the reported commit hash, let's fall back to `master` as before.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 remote.c                 | 14 +++++++++++---
 t/t5606-clone-options.sh | 11 ++++++++++-
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/remote.c b/remote.c
index 534c6426f1..965129adc3 100644
--- a/remote.c
+++ b/remote.c
@@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)
 
 	/*
 	 * The branches file would have URL and optionally
-	 * #branch specified.  The "master" (or specified) branch is
+	 * #branch specified.  The main (or specified) branch is
 	 * fetched and stored in the local branch matching the
 	 * remote name.
 	 */
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
 	if (frag)
 		*(frag++) = '\0';
 	else
-		frag = "master";
+		frag = (char *)git_default_branch_name();
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
 	strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ -2097,8 +2097,16 @@ struct ref *guess_remote_head(const struct ref *head,
 	if (head->symref)
 		return copy_ref(find_ref_by_name(refs, head->symref));
 
-	/* If refs/heads/master could be right, it is. */
+	/* If a remote branch exists with the default branch name, let's use it. */
 	if (!all) {
+		char *ref = xstrfmt("refs/heads/%s", git_default_branch_name());
+
+		r = find_ref_by_name(refs, ref);
+		free(ref);
+		if (r && oideq(&r->old_oid, &head->old_oid))
+			return copy_ref(r);
+
+		/* Fall back to the hard-coded historical default */
 		r = find_ref_by_name(refs, "refs/heads/master");
 		if (r && oideq(&r->old_oid, &head->old_oid))
 			return copy_ref(r);
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 286bfd93ac..e69427f881 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -47,7 +47,16 @@ test_expect_success 'guesses initial branch name correctly' '
 	test_commit -C initial-branch no-spoilers &&
 	git -C initial-branch branch abc guess &&
 	git clone initial-branch is-it &&
-	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
+	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) &&
+
+	git -c init.defaultBranch=none init --bare no-head &&
+	git -C initial-branch push ../no-head guess abc &&
+	git clone no-head is-it2 &&
+	test_must_fail git -C is-it2 symbolic-ref refs/remotes/origin/HEAD &&
+	git -C no-head update-ref --no-deref HEAD refs/heads/guess &&
+	git -c init.defaultBranch=guess clone no-head is-it3 &&
+	test refs/remotes/origin/guess = \
+		$(git -C is-it3 symbolic-ref refs/remotes/origin/HEAD)
 '
 
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v3 8/8] testsvn: respect `init.defaultBranch`
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                       ` (6 preceding siblings ...)
  2020-06-23 22:33     ` [PATCH v3 7/8] remote: use the " Johannes Schindelin via GitGitGadget
@ 2020-06-23 22:33     ` Johannes Schindelin via GitGitGadget
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  8 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-23 22:33 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

The default name of the initial branch in new repositories can now be
configured. The `testsvn` remote helper translates the remote Subversion
repository's branch name `trunk` to the hard-coded name `master`.
Clearly, the intention was to make the name align with Git's defaults.

So while we are not talking about a newly-created repository in the
`testsvn` context, it is a newly-created _Git_ repository, si it _still_
makes sense to use the overridden default name for the initial branch
whenever users configured it.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 remote-testsvn.c      | 10 +++++++---
 t/t9020-remote-svn.sh |  6 ++++++
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/remote-testsvn.c b/remote-testsvn.c
index 3af708c5b6..cde39b94fb 100644
--- a/remote-testsvn.c
+++ b/remote-testsvn.c
@@ -13,7 +13,7 @@
 static const char *url;
 static int dump_from_file;
 static const char *private_ref;
-static const char *remote_ref = "refs/heads/master";
+static char *remote_ref;
 static const char *marksfilename, *notes_ref;
 struct rev_note { unsigned int rev_nr; };
 
@@ -286,7 +286,7 @@ int cmd_main(int argc, const char **argv)
 			private_ref_sb = STRBUF_INIT, marksfilename_sb = STRBUF_INIT,
 			notes_ref_sb = STRBUF_INIT;
 	static struct remote *remote;
-	const char *url_in;
+	const char *url_in, *remote_ref_short;
 
 	setup_git_directory();
 	if (argc < 2 || argc > 3) {
@@ -294,6 +294,9 @@ int cmd_main(int argc, const char **argv)
 		return 1;
 	}
 
+	remote_ref_short = git_default_branch_name();
+	remote_ref = xstrfmt("refs/heads/%s", remote_ref_short);
+
 	remote = remote_get(argv[1]);
 	url_in = (argc == 3) ? argv[2] : remote->url[0];
 
@@ -306,7 +309,8 @@ int cmd_main(int argc, const char **argv)
 		url = url_sb.buf;
 	}
 
-	strbuf_addf(&private_ref_sb, "refs/svn/%s/master", remote->name);
+	strbuf_addf(&private_ref_sb, "refs/svn/%s/%s",
+		    remote->name, remote_ref_short);
 	private_ref = private_ref_sb.buf;
 
 	strbuf_addf(&notes_ref_sb, "refs/notes/%s/revs", remote->name);
diff --git a/t/t9020-remote-svn.sh b/t/t9020-remote-svn.sh
index 9fcfa969a9..754c4a3284 100755
--- a/t/t9020-remote-svn.sh
+++ b/t/t9020-remote-svn.sh
@@ -84,6 +84,12 @@ test_expect_success REMOTE_SVN 'incremental imports must lead to the same head'
 	test_cmp master.good .git/refs/remotes/svnsim/master
 '
 
+test_expect_success REMOTE_SVN 'respects configured default initial branch' '
+	git -c init.defaultBranch=trunk remote add -f trunk \
+		"testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" &&
+	git rev-parse --verify refs/remotes/trunk/trunk
+'
+
 test_debug 'git branch -a'
 
 test_done
-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch
  2020-06-23 22:33     ` [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch Johannes Schindelin via GitGitGadget
@ 2020-06-24  0:36       ` Junio C Hamano
  2020-06-24 12:44         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-24  0:36 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> @@ -1046,7 +1046,7 @@ static int push_refs(struct transport *transport,
>  	if (!remote_refs) {
>  		fprintf(stderr,
>  			_("No refs in common and none specified; doing nothing.\n"
> -			  "Perhaps you should specify a branch such as 'master'.\n"));
> +			  "Perhaps you should specify a specific branch.\n"));

Hmph, not just "specify a branch."?  Maybe it is just me, but
"specify a specific branch" did not roll well on my tongue.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 4/8] init: allow specifying the initial branch name for the new repository
  2020-06-23 22:33     ` [PATCH v3 4/8] init: allow specifying the initial branch name for the new repository Johannes Schindelin via GitGitGadget
@ 2020-06-24  0:58       ` Junio C Hamano
  2020-06-24 12:55         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-24  0:58 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

>  [verse]
>  'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
>  	  [--separate-git-dir <git dir>] [--object-format=<format]

Completely offtopic.  We lack the closing ket> here.

> +	  [-b <branch-name> | --initial-branch=<branch-name>]
>  	  [--shared[=<permissions>]] [directory]
>  
>  
> @@ -67,6 +68,12 @@ repository.
>  +
>  If this is reinitialization, the repository will be moved to the specified path.
>  
> +-b <branch-name::
> +--initial-branch=<branch-name>::
> +
> +Use the specified name for the initial branch in the newly created repository.
> +If not specified, fall back to the default name: `master`.

OK.

> diff --git a/builtin/clone.c b/builtin/clone.c
> index 2a8e3aaaed..b751bdf13e 100644
> --- a/builtin/clone.c
> +++ b/builtin/clone.c
> @@ -1111,7 +1111,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
>  		}
>  	}
>  
> -	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
> +	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
> +		INIT_DB_QUIET);
>  
>  	if (real_git_dir)
>  		git_dir = real_git_dir;
> diff --git a/builtin/init-db.c b/builtin/init-db.c
> index 0b7222e718..a898153901 100644
> --- a/builtin/init-db.c
> +++ b/builtin/init-db.c
> @@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)
>  
>  static int create_default_files(const char *template_path,
>  				const char *original_git_dir,
> +				const char *initial_branch,
>  				const struct repository_format *fmt)
>  {
>  	struct stat st1;
> @@ -258,16 +259,29 @@ static int create_default_files(const char *template_path,
>  		die("failed to set up refs db: %s", err.buf);
>  
>  	/*
> -	 * Create the default symlink from ".git/HEAD" to the "master"
> -	 * branch, if it does not exist yet.
> +	 * Create the default symlink from ".git/HEAD" to the default
> +	 * branch name, if it does not exist yet.
>  	 */

To the caller of this helper, it may be "the default", but as far as
this helper is concerned, it is not "default" but the initial branch
that was given by the caller.  How about...

	/*
	 * Point the initial branch with HEAD symref, if HEAD does
	 * not exist yet.
	 */

... to modernize the reference to symlink and replace it with
symref?

> +		if (!initial_branch)
> +			initial_branch = "master";
> +
> +		ref = xstrfmt("refs/heads/%s", initial_branch);
> +		if (check_refname_format(ref, 0) < 0)
> +			die(_("invalid initial branch name: '%s'"),
> +			    initial_branch);

Good.  We make sure to prefix with "refs/heads/" so the callers
cannot abuse us to point HEAD outside the local branches.

> +		if (create_symref("HEAD", ref, NULL) < 0)
>  			exit(1);
> -	}
> +		free(ref);
> +	} else if (initial_branch)
> +		warning(_("re-init: ignoring --initial-branch=%s"),
> +			initial_branch);

Somehow the error checking convention feels uneven in this API.  It
is a warning-worthy offense for the caller to give initial_branch
when we are re-initializing, but it is not an error for the caller
not to supply the initial branch name on the other side of if/else.
Worse yet, this helper function even knows the command line option
name that resulted in the parameter coming to it.

That unevenness ultimately comes from the fact that the caller does
not know if we are dealing with a repository that already has HEAD
before calling, but at least we should be able to tell the caller
if we initialized or not with our return value and allow the caller
to issue this warning---that way we can lose the warning from here
and get rid of the uneven feeling.  Oh, and ...

> @@ -383,7 +397,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
>  }
>  
>  int init_db(const char *git_dir, const char *real_git_dir,
> -	    const char *template_dir, int hash, unsigned int flags)
> +	    const char *template_dir, int hash, const char *initial_branch,
> +	    unsigned int flags)
>  {
>  	int reinit;
>  	int exist_ok = flags & INIT_DB_EXIST_OK;
> @@ -425,7 +440,8 @@ int init_db(const char *git_dir, const char *real_git_dir,
>  
>  	validate_hash_algorithm(&repo_fmt, hash);
>  
> -	reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
> +	reinit = create_default_files(template_dir, original_git_dir,
> +				      initial_branch, &repo_fmt);

... we are telling the caller if we are in reinit situation, so we
can afford to do exactly that.  

	reinit = create_default_files...
 	if (reinit && initial_branch)
		warning(_("re-init: ignored --initial-branch"));

That's much better ;-)

Other than that, looks good to me.

Thanks.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config
  2020-06-23 22:33     ` [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config Don Goodman-Wilson via GitGitGadget
@ 2020-06-24  1:05       ` Junio C Hamano
  2020-06-24 12:56         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-24  1:05 UTC (permalink / raw)
  To: Don Goodman-Wilson via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin

"Don Goodman-Wilson via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> diff --git a/builtin/init-db.c b/builtin/init-db.c
> index a898153901..b8634b5f35 100644
> --- a/builtin/init-db.c
> +++ b/builtin/init-db.c
> @@ -269,7 +269,7 @@ static int create_default_files(const char *template_path,
>  		char *ref;
>  
>  		if (!initial_branch)
> -			initial_branch = "master";
> +			initial_branch = git_default_branch_name();
>  
>  		ref = xstrfmt("refs/heads/%s", initial_branch);
>  		if (check_refname_format(ref, 0) < 0)

Continuing with the division of labor between this helper and its
caller, I had this funny dislike of falling back here and not in the
caller.  But with the same idea of using "reinit", we could get rid
of this "if the caller didn't give us initial_branch, fall back
to..." logic from the function.  The caller may do

	reinit = create_default_files(...
			initial_branch ? initial_branch : "master",
			...);
	if (reinit || initial_branch)
		warning(_(...));
	
in the previous step and then we can teach the caller to use the
configured value instead of the hardcoded "master".

That's much better ;-)

Other than that, looks good to me.

Thanks.

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 7/8] remote: use the configured default branch name when appropriate
  2020-06-23 22:33     ` [PATCH v3 7/8] remote: use the " Johannes Schindelin via GitGitGadget
@ 2020-06-24  1:10       ` Junio C Hamano
  2020-06-24 13:00         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Junio C Hamano @ 2020-06-24  1:10 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin

"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> diff --git a/remote.c b/remote.c
> index 534c6426f1..965129adc3 100644
> --- a/remote.c
> +++ b/remote.c
> @@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)
>  
>  	/*
>  	 * The branches file would have URL and optionally
> -	 * #branch specified.  The "master" (or specified) branch is
> +	 * #branch specified.  The main (or specified) branch is
>  	 * fetched and stored in the local branch matching the
>  	 * remote name.
>  	 */

Isn't this a bit premature here?


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 3/8] submodule: use a better fall-back for missing remote.<name>.branch
  2020-06-23 22:33     ` [PATCH v3 3/8] submodule: use a better fall-back for missing remote.<name>.branch Johannes Schindelin via GitGitGadget
@ 2020-06-24  2:18       ` Philippe Blain
  2020-06-24 12:51         ` Johannes Schindelin
  0 siblings, 1 reply; 178+ messages in thread
From: Philippe Blain @ 2020-06-24  2:18 UTC (permalink / raw)
  To: Johannes Schindelin via GitGitGadget
  Cc: git, don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Johannes Schindelin

Hi Dscho,

> Le 23 juin 2020 à 18:33, Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> a écrit :
> 
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> When `remote.<name>.branch` is not configured, `git submodule update`
> currently falls back to using the branch name `master`. A much better
> idea, however, is to use `HEAD`: on all Git servers running reasonably
> recent Git versions, the symref `HEAD` points to the main branch.

To be pedantic, it is up to the maintainer/developers to make sure that 
HEAD on the canonic repository indeed points to the branch that is considered
the 'main' branch of the project; the Git version does not really matter IMO...
I've seen plenty of repos at work that have HEAD pointing to `master` but `master` 
is not used, or not anymore...

> Note: t7419 demonstrates that there _might_ be use cases out there that
> _expect_ `git submodule update --remote` to update submodules to the
> remote `master` branch even if the remote `HEAD` points to another
> branch. Arguably, this patch makes the behavior more intuitive, but
> there is a slight possibility that this might cause regressions in
> obscure setups.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>

I think that's an excellent idea. However I'd be more explicit in the commit message title:
submodule: fall back to remote's HEAD for missing remote.<name>.branch

meta comment: I never know where is the best place to make suggestions
about changing the commit message title, since I can't quote it in my replies!

> ---
> Documentation/git-submodule.txt |  4 ++--
> builtin/submodule--helper.c     |  2 +-
> t/t7406-submodule-update.sh     | 16 ++++++++++++++++
> t/t7419-submodule-set-branch.sh |  7 +++++--
> 4 files changed, 24 insertions(+), 5 deletions(-)

I think Documentation/gitmodules.txt (`submodule.<name>.branch` header)
 should also be changed to reflect the behaviour change: 

diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
index 67275fd187..539b4e1997 100644
--- a/Documentation/gitmodules.txt
+++ b/Documentation/gitmodules.txt
@@ -49,9 +49,9 @@ submodule.<name>.update::
 
 submodule.<name>.branch::
 	A remote branch name for tracking updates in the upstream submodule.
-	If the option is not specified, it defaults to 'master'.  A special
-	value of `.` is used to indicate that the name of the branch in the
-	submodule should be the same name as the current branch in the
+	If the option is not specified, it defaults to the remote 'HEAD'.
+	A special value of `.` is used to indicate that the name of the branch
+	in the submodule should be the same name as the current branch in the
 	current repository.  See the `--remote` documentation in
 	linkgit:git-submodule[1] for details.

> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> index c9ed2bf3d5..b20f85e622 100644
> --- a/Documentation/git-submodule.txt
> +++ b/Documentation/git-submodule.txt
> @@ -284,7 +284,7 @@ OPTIONS
> 	`.gitmodules` for `update --remote`.  A special value of `.` is used to
> 	indicate that the name of the branch in the submodule should be the
> 	same name as the current branch in the current repository.  If the
> -	option is not specified, it defaults to 'master'.
> +	option is not specified, it defaults to 'HEAD'.

Just to be extra clear (it's easy to get confused with submodules!) I'd say explicitly:

If the option is not specified, it defaults to the remote 'HEAD'.

> 
> -f::
> --force::
> @@ -322,7 +322,7 @@ OPTIONS
> 	the superproject's recorded SHA-1 to update the submodule, use the
> 	status of the submodule's remote-tracking branch.  The remote used
> 	is branch's remote (`branch.<name>.remote`), defaulting to `origin`.
> -	The remote branch used defaults to `master`, but the branch name may
> +	The remote branch used defaults to `HEAD`, but the branch name may

Same thing here:

The remote branch used defaults to the remote `HEAD`.

> 	be overridden by setting the `submodule.<name>.branch` option in
> 	either `.gitmodules` or `.git/config` (with `.git/config` taking
> 	precedence).

Also, you seem to have missed the `master` reference in the description of 
the 'set-branch' subcommand. Something like this would do, I think:

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index c9ed2bf3d5..8cf5831a72 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -183,7 +183,7 @@ set-branch (-d|--default) [--] <path>::
 	Sets the default remote tracking branch for the submodule. The
 	`--branch` option allows the remote branch to be specified. The
 	`--default` option removes the submodule.<name>.branch configuration
-	key, which causes the tracking branch to default to 'master'.
+	key, which causes the tracking branch to default to the remote 'HEAD'.
 
 set-url [--] <path> <newurl>::
 	Sets the URL of the specified submodule to <newurl>. Then, it will


The rest of the patch looks good.

Cheers,
Philippe.


^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch
  2020-06-24  0:36       ` Junio C Hamano
@ 2020-06-24 12:44         ` Johannes Schindelin
  2020-06-24 15:44           ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-24 12:44 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Denton Liu,
	Ævar Arnfjörð Bjarmason

Hi Junio,

On Tue, 23 Jun 2020, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > @@ -1046,7 +1046,7 @@ static int push_refs(struct transport *transport,
> >  	if (!remote_refs) {
> >  		fprintf(stderr,
> >  			_("No refs in common and none specified; doing nothing.\n"
> > -			  "Perhaps you should specify a branch such as 'master'.\n"));
> > +			  "Perhaps you should specify a specific branch.\n"));
>
> Hmph, not just "specify a branch."?  Maybe it is just me, but
> "specify a specific branch" did not roll well on my tongue.

Oh well. "Perhaps you should specify a branch" sounded too judgmental to
me, but I'm not a native speaker, so I simply removed the word "specific".

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 3/8] submodule: use a better fall-back for missing remote.<name>.branch
  2020-06-24  2:18       ` Philippe Blain
@ 2020-06-24 12:51         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-24 12:51 UTC (permalink / raw)
  To: Philippe Blain
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Denton Liu,
	Ævar Arnfjörð Bjarmason

[-- Attachment #1: Type: text/plain, Size: 5891 bytes --]

Hi Philippe,

On Tue, 23 Jun 2020, Philippe Blain wrote:

> > Le 23 juin 2020 à 18:33, Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> a écrit :
> >
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > When `remote.<name>.branch` is not configured, `git submodule update`
> > currently falls back to using the branch name `master`. A much better
> > idea, however, is to use `HEAD`: on all Git servers running reasonably
> > recent Git versions, the symref `HEAD` points to the main branch.
>
> To be pedantic, it is up to the maintainer/developers to make sure that
> HEAD on the canonic repository indeed points to the branch that is
> considered the 'main' branch of the project; the Git version does not
> really matter IMO... I've seen plenty of repos at work that have HEAD
> pointing to `master` but `master` is not used, or not anymore...

Oh, but in this case, my main concern was servers that are so old that
`HEAD` is not a symref, in which case it can be a bit tricky to figure out
the default branch.

In any case, I feel this is such a minor point that I don't really want to
spend a lot of time on this paragraph.

> > Note: t7419 demonstrates that there _might_ be use cases out there that
> > _expect_ `git submodule update --remote` to update submodules to the
> > remote `master` branch even if the remote `HEAD` points to another
> > branch. Arguably, this patch makes the behavior more intuitive, but
> > there is a slight possibility that this might cause regressions in
> > obscure setups.
> >
> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> I think that's an excellent idea. However I'd be more explicit in the
> commit message title:
>
> submodule: fall back to remote's HEAD for missing remote.<name>.branch

Great!

> meta comment: I never know where is the best place to make suggestions
> about changing the commit message title, since I can't quote it in my
> replies!

True. You could copy it, but that's not the same.

> > ---
> > Documentation/git-submodule.txt |  4 ++--
> > builtin/submodule--helper.c     |  2 +-
> > t/t7406-submodule-update.sh     | 16 ++++++++++++++++
> > t/t7419-submodule-set-branch.sh |  7 +++++--
> > 4 files changed, 24 insertions(+), 5 deletions(-)
>
> I think Documentation/gitmodules.txt (`submodule.<name>.branch` header)
>  should also be changed to reflect the behaviour change:
>
> diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
> index 67275fd187..539b4e1997 100644
> --- a/Documentation/gitmodules.txt
> +++ b/Documentation/gitmodules.txt
> @@ -49,9 +49,9 @@ submodule.<name>.update::
>
>  submodule.<name>.branch::
>  	A remote branch name for tracking updates in the upstream submodule.
> -	If the option is not specified, it defaults to 'master'.  A special
> -	value of `.` is used to indicate that the name of the branch in the
> -	submodule should be the same name as the current branch in the
> +	If the option is not specified, it defaults to the remote 'HEAD'.
> +	A special value of `.` is used to indicate that the name of the branch
> +	in the submodule should be the same name as the current branch in the
>  	current repository.  See the `--remote` documentation in
>  	linkgit:git-submodule[1] for details.

Excellent, I used that verbatim. Thank you!

> > diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> > index c9ed2bf3d5..b20f85e622 100644
> > --- a/Documentation/git-submodule.txt
> > +++ b/Documentation/git-submodule.txt
> > @@ -284,7 +284,7 @@ OPTIONS
> > 	`.gitmodules` for `update --remote`.  A special value of `.` is used to
> > 	indicate that the name of the branch in the submodule should be the
> > 	same name as the current branch in the current repository.  If the
> > -	option is not specified, it defaults to 'master'.
> > +	option is not specified, it defaults to 'HEAD'.
>
> Just to be extra clear (it's easy to get confused with submodules!) I'd
> say explicitly:
>
> If the option is not specified, it defaults to the remote 'HEAD'.

Good idea. I incorporated that, too.

> > -f::
> > --force::
> > @@ -322,7 +322,7 @@ OPTIONS
> > 	the superproject's recorded SHA-1 to update the submodule, use the
> > 	status of the submodule's remote-tracking branch.  The remote used
> > 	is branch's remote (`branch.<name>.remote`), defaulting to `origin`.
> > -	The remote branch used defaults to `master`, but the branch name may
> > +	The remote branch used defaults to `HEAD`, but the branch name may
>
> Same thing here:
>
> The remote branch used defaults to the remote `HEAD`.

And that.

> > 	be overridden by setting the `submodule.<name>.branch` option in
> > 	either `.gitmodules` or `.git/config` (with `.git/config` taking
> > 	precedence).
>
> Also, you seem to have missed the `master` reference in the description of
> the 'set-branch' subcommand. Something like this would do, I think:
>
> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> index c9ed2bf3d5..8cf5831a72 100644
> --- a/Documentation/git-submodule.txt
> +++ b/Documentation/git-submodule.txt
> @@ -183,7 +183,7 @@ set-branch (-d|--default) [--] <path>::
>  	Sets the default remote tracking branch for the submodule. The
>  	`--branch` option allows the remote branch to be specified. The
>  	`--default` option removes the submodule.<name>.branch configuration
> -	key, which causes the tracking branch to default to 'master'.
> +	key, which causes the tracking branch to default to the remote 'HEAD'.
>
>  set-url [--] <path> <newurl>::
>  	Sets the URL of the specified submodule to <newurl>. Then, it will

And that.

> The rest of the patch looks good.

Awesome. Thank you for helping me improve this patch series!

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 4/8] init: allow specifying the initial branch name for the new repository
  2020-06-24  0:58       ` Junio C Hamano
@ 2020-06-24 12:55         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-24 12:55 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Denton Liu,
	Ævar Arnfjörð Bjarmason

Hi Junio,

On Tue, 23 Jun 2020, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> >  [verse]
> >  'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
> >  	  [--separate-git-dir <git dir>] [--object-format=<format]
>
> Completely offtopic.  We lack the closing ket> here.

Not so off-topic: the fix for this would cause conflicts. In the interest
of avoiding merge conflicts, I incorporated a patch to fix that (`git
grep` found two more instances, which I fixed "while at it").

> > +	  [-b <branch-name> | --initial-branch=<branch-name>]
> >  	  [--shared[=<permissions>]] [directory]
> >
> >
> > @@ -67,6 +68,12 @@ repository.
> >  +
> >  If this is reinitialization, the repository will be moved to the specified path.
> >
> > +-b <branch-name::
> > +--initial-branch=<branch-name>::
> > +
> > +Use the specified name for the initial branch in the newly created repository.
> > +If not specified, fall back to the default name: `master`.
>
> OK.
>
> > diff --git a/builtin/clone.c b/builtin/clone.c
> > index 2a8e3aaaed..b751bdf13e 100644
> > --- a/builtin/clone.c
> > +++ b/builtin/clone.c
> > @@ -1111,7 +1111,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
> >  		}
> >  	}
> >
> > -	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
> > +	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
> > +		INIT_DB_QUIET);
> >
> >  	if (real_git_dir)
> >  		git_dir = real_git_dir;
> > diff --git a/builtin/init-db.c b/builtin/init-db.c
> > index 0b7222e718..a898153901 100644
> > --- a/builtin/init-db.c
> > +++ b/builtin/init-db.c
> > @@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)
> >
> >  static int create_default_files(const char *template_path,
> >  				const char *original_git_dir,
> > +				const char *initial_branch,
> >  				const struct repository_format *fmt)
> >  {
> >  	struct stat st1;
> > @@ -258,16 +259,29 @@ static int create_default_files(const char *template_path,
> >  		die("failed to set up refs db: %s", err.buf);
> >
> >  	/*
> > -	 * Create the default symlink from ".git/HEAD" to the "master"
> > -	 * branch, if it does not exist yet.
> > +	 * Create the default symlink from ".git/HEAD" to the default
> > +	 * branch name, if it does not exist yet.
> >  	 */
>
> To the caller of this helper, it may be "the default", but as far as
> this helper is concerned, it is not "default" but the initial branch
> that was given by the caller.  How about...
>
> 	/*
> 	 * Point the initial branch with HEAD symref, if HEAD does
> 	 * not exist yet.
> 	 */
>
> ... to modernize the reference to symlink and replace it with
> symref?

Good point. I massaged your proposed comment and replaced the old one with
it.

> > +		if (!initial_branch)
> > +			initial_branch = "master";
> > +
> > +		ref = xstrfmt("refs/heads/%s", initial_branch);
> > +		if (check_refname_format(ref, 0) < 0)
> > +			die(_("invalid initial branch name: '%s'"),
> > +			    initial_branch);
>
> Good.  We make sure to prefix with "refs/heads/" so the callers
> cannot abuse us to point HEAD outside the local branches.

Yes, Peff offered that concern, and I agree.

> > +		if (create_symref("HEAD", ref, NULL) < 0)
> >  			exit(1);
> > -	}
> > +		free(ref);
> > +	} else if (initial_branch)
> > +		warning(_("re-init: ignoring --initial-branch=%s"),
> > +			initial_branch);
>
> Somehow the error checking convention feels uneven in this API.  It
> is a warning-worthy offense for the caller to give initial_branch
> when we are re-initializing, but it is not an error for the caller
> not to supply the initial branch name on the other side of if/else.
> Worse yet, this helper function even knows the command line option
> name that resulted in the parameter coming to it.
>
> That unevenness ultimately comes from the fact that the caller does
> not know if we are dealing with a repository that already has HEAD
> before calling, but at least we should be able to tell the caller
> if we initialized or not with our return value and allow the caller
> to issue this warning---that way we can lose the warning from here
> and get rid of the uneven feeling.  Oh, and ...
>
> > @@ -383,7 +397,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
> >  }
> >
> >  int init_db(const char *git_dir, const char *real_git_dir,
> > -	    const char *template_dir, int hash, unsigned int flags)
> > +	    const char *template_dir, int hash, const char *initial_branch,
> > +	    unsigned int flags)
> >  {
> >  	int reinit;
> >  	int exist_ok = flags & INIT_DB_EXIST_OK;
> > @@ -425,7 +440,8 @@ int init_db(const char *git_dir, const char *real_git_dir,
> >
> >  	validate_hash_algorithm(&repo_fmt, hash);
> >
> > -	reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
> > +	reinit = create_default_files(template_dir, original_git_dir,
> > +				      initial_branch, &repo_fmt);
>
> ... we are telling the caller if we are in reinit situation, so we
> can afford to do exactly that.
>
> 	reinit = create_default_files...
>  	if (reinit && initial_branch)
> 		warning(_("re-init: ignored --initial-branch"));

I changed it accordingly.

Thanks,
Dscho

>
> That's much better ;-)
>
> Other than that, looks good to me.
>
> Thanks.
>
>

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config
  2020-06-24  1:05       ` Junio C Hamano
@ 2020-06-24 12:56         ` Johannes Schindelin
  2020-06-24 16:25           ` Junio C Hamano
  0 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-24 12:56 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Don Goodman-Wilson via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Denton Liu,
	Ævar Arnfjörð Bjarmason

Hi Junio,

On Tue, 23 Jun 2020, Junio C Hamano wrote:

> "Don Goodman-Wilson via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > diff --git a/builtin/init-db.c b/builtin/init-db.c
> > index a898153901..b8634b5f35 100644
> > --- a/builtin/init-db.c
> > +++ b/builtin/init-db.c
> > @@ -269,7 +269,7 @@ static int create_default_files(const char *template_path,
> >  		char *ref;
> >
> >  		if (!initial_branch)
> > -			initial_branch = "master";
> > +			initial_branch = git_default_branch_name();
> >
> >  		ref = xstrfmt("refs/heads/%s", initial_branch);
> >  		if (check_refname_format(ref, 0) < 0)
>
> Continuing with the division of labor between this helper and its
> caller, I had this funny dislike of falling back here and not in the
> caller.  But with the same idea of using "reinit", we could get rid
> of this "if the caller didn't give us initial_branch, fall back
> to..." logic from the function.  The caller may do
>
> 	reinit = create_default_files(...
> 			initial_branch ? initial_branch : "master",
> 			...);
> 	if (reinit || initial_branch)
> 		warning(_(...));
>
> in the previous step and then we can teach the caller to use the
> configured value instead of the hardcoded "master".

While that is really tempting, there is another called of `init_db()`
(which calls `create_default_files()`): `builtin/clone.c`. And I do not
wish to duplicate the logic there.

So I left this as-is.

Ciao,
Dscho

>
> That's much better ;-)
>
> Other than that, looks good to me.
>
> Thanks.
>

^ permalink raw reply	[flat|nested] 178+ messages in thread

* Re: [PATCH v3 7/8] remote: use the configured default branch name when appropriate
  2020-06-24  1:10       ` Junio C Hamano
@ 2020-06-24 13:00         ` Johannes Schindelin
  0 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin @ 2020-06-24 13:00 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Schindelin via GitGitGadget, git, don, stolee, peff,
	sandals, Matt Rogers, Eric Sunshine, Taylor Blau, Phillip Wood,
	Alban Gruin, Johannes Sixt, Denton Liu,
	Ævar Arnfjörð Bjarmason

Hi Junio,

On Tue, 23 Jun 2020, Junio C Hamano wrote:

> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > diff --git a/remote.c b/remote.c
> > index 534c6426f1..965129adc3 100644
> > --- a/remote.c
> > +++ b/remote.c
> > @@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)
> >
> >  	/*
> >  	 * The branches file would have URL and optionally
> > -	 * #branch specified.  The "master" (or specified) branch is
> > +	 * #branch specified.  The main (or specified) branch is
> >  	 * fetched and stored in the local branch matching the
> >  	 * remote name.
> >  	 */
>
> Isn't this a bit premature here?

Actually, it is just wrong. It should talk about the default branch
instead.

Ciao,
Dscho

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v4 0/9] Allow overriding the default name of the default branch
  2020-06-23 22:33   ` [PATCH v3 0/8] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                       ` (7 preceding siblings ...)
  2020-06-23 22:33     ` [PATCH v3 8/8] testsvn: respect `init.defaultBranch` Johannes Schindelin via GitGitGadget
@ 2020-06-24 14:46     ` Johannes Schindelin via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially Johannes Schindelin via GitGitGadget
                         ` (10 more replies)
  8 siblings, 11 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-24 14:46 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Philippe Blain, Johannes Schindelin

A growing number of open source projects aims to avoid the branch name 
master due to its negative connotation. See [1] for an existing discussion
on this. The links [2], [3], and [4] describe community-driven ways for
users to rename their default branches or use template edits to set a new
default branch name.

[1] 
https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/

[2] https://twitter.com/mislav/status/1270388510684598272

[3] 
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx

[4] https://github.com/ethomson/retarget_prs

By necessity, existing repositories require a lot of manual work to move
away from that branch name, but it should be much easier for new
repositories.

This patch series allows overriding the branch name being used for new
repositories' main branch. This can be configured via init.defaultBranch.

The initial patch was started by newcomer Don Goodman-Wilson, as well as the
bigger change that morphed into #655, where we demonstrate how to change
Git's hard-coded default branch name for new repositories to main based on
this here patch series, verifying the approach. Thanks for the contribution!

This series DOES NOT change the default automatically, but only provides an
opt-in mechanism for interested users. The plan for that is to convert the
test scripts incrementally (by introducing GIT_TEST_DEFAULT_MAIN_BRANCH_NAME
, which overrides init.defaultBranch, and then converting the tricky test
scripts first, one by one, using that environment variable).

Changes since v3:

 * We now avoid the phrasing "specify a specific" in the messages.
   
   
 * The git submodule patch has a better commit title now, and it also
   adjusts the documentation more completely now (thanks, Philippe!).
   
   
 * A code comment in builtin/init-db.c was updated to no longer talk about a 
   symlink when it comes to HEAD.
   
   
 * Made it the responsibility of the caller to warn about reinit &&
   initial_branch.
   
   

Changes since v2:

 * Dropped the fast-export patches, as they have been superseded by Peff's 
   jk/fast-export-anonym
   [https://github.com/gitgitgadget/git/commits/jk/fast-export-anonym].
   
   
 * Adjusted the fmt-merge-msg patch so as to not special-case master anymore
   (instead of special-casing a specific "main" branch).
   
   
 * Modified the git submodule patch so that it uses origin/HEAD instead of
   trying to look for a remote branch with the name indicated by 
   init.defaultBranch.
   
   

Changes since v1:

 * The modifications to respect GIT_TEST_DEFAULT_BRANCH_NAME have been
   backed out from this patch series, as they are only relevant once we
   start converting the test suite to accommodate for a new default main
   branch name.
   
   
 * An error message that started with an upper-case letter was downcased.
   
   
 * git_default_branch_name()'s logic was simplified by replacing an if ...
   else ... by a ternary assignment.
   
   
 * The git_default_branch_name() function was renamed to 
   git_main_branch_name() and a corresponding repo_main_branch_name() was
   introduced.
   
   
 * The "init" commit message's first paragraph now elaborates a little bit
   on the reasoning why projects want to move away from the current default
   branch name.
   
   
 * The "init" commit was split into two.
   
   
 * There are now two config settings: init.defaultBranch (defining the
   branch name to use when initializing new repositories) and 
   core.mainBranch (which is now configured by init_db(), declaring what the
   name of the main branch is in this repository).
   
   
 * The commits were re-ordered to introduce the concept of core.mainBranch 
   first because technically, this is something that we could do even
   without changing git init at all.
   
   
 * git fast-export --anonymize now always uses the ref name ref0 for the
   main branch, no matter whether it was overridden or whether the fall-back
   is in effect.
   
   
 * The code comment regarding anonymizing the main branch to ref0 in git
   fast-export --anonymize was enhanced.
   
   
 * A new patch was added to rename core.mainBranch if the main branch is
   renamed via git branch -m.
   
   
 * Added a patch that introduces support for git init
   --main-branch=<branch-name>.
   
   
 * Where possible, I added tests (although I did not try to extend test
   coverage to all changes: the send-pack.c/transport-helper.c patch only
   adds a test for the send-pack.c adjustment, for example).

Don Goodman-Wilson (1):
  init: allow setting the default for the initial branch name via the
    config

Johannes Schindelin (8):
  fmt-merge-msg: stop treating `master` specially
  send-pack/transport-helper: avoid mentioning a particular branch
  submodule: fall back to remote's HEAD for missing remote.<name>.branch
  docs: add missing diamond brackets
  init: allow specifying the initial branch name for the new repository
  clone: use configured default branch name when appropriate
  remote: use the configured default branch name when appropriate
  testsvn: respect `init.defaultBranch`

 Documentation/config/init.txt                 |  4 ++
 Documentation/git-branch.txt                  |  2 +-
 Documentation/git-clone.txt                   |  2 +-
 Documentation/git-init.txt                    |  9 ++-
 Documentation/git-submodule.txt               | 12 ++--
 Documentation/gitmodules.txt                  |  6 +-
 builtin/clone.c                               | 13 ++--
 builtin/init-db.c                             | 33 +++++++--
 builtin/submodule--helper.c                   |  2 +-
 cache.h                                       |  2 +-
 fmt-merge-msg.c                               |  5 +-
 refs.c                                        | 30 ++++++++
 refs.h                                        |  9 +++
 remote-testsvn.c                              | 10 ++-
 remote.c                                      | 14 +++-
 send-pack.c                                   |  2 +-
 t/t0001-init.sh                               | 26 +++++++
 t/t1507-rev-parse-upstream.sh                 |  2 +-
 t/t4013-diff-various.sh                       |  4 +-
 t/t4013/diff.log_--decorate=full_--all        |  2 +-
 t/t4013/diff.log_--decorate_--all             |  2 +-
 ...--patch-with-stat_--summary_master_--_dir_ |  2 +-
 t/t4013/diff.log_--patch-with-stat_master     |  2 +-
 .../diff.log_--patch-with-stat_master_--_dir_ |  2 +-
 ...ot_--cc_--patch-with-stat_--summary_master |  2 +-
 ..._--root_--patch-with-stat_--summary_master |  2 +-
 .../diff.log_--root_--patch-with-stat_master  |  2 +-
 ...root_-c_--patch-with-stat_--summary_master |  2 +-
 t/t4013/diff.log_--root_-p_master             |  2 +-
 t/t4013/diff.log_--root_master                |  2 +-
 t/t4013/diff.log_-m_-p_--first-parent_master  |  2 +-
 t/t4013/diff.log_-m_-p_master                 |  4 +-
 t/t4013/diff.log_-p_--first-parent_master     |  2 +-
 t/t4013/diff.log_-p_master                    |  2 +-
 t/t4013/diff.log_master                       |  2 +-
 t/t4013/diff.show_--first-parent_master       |  2 +-
 t/t4013/diff.show_-c_master                   |  2 +-
 t/t4013/diff.show_-m_master                   |  4 +-
 t/t4013/diff.show_master                      |  2 +-
 ...ot_--cc_--patch-with-stat_--summary_master |  2 +-
 ...root_-c_--patch-with-stat_--summary_master |  2 +-
 t/t4202-log.sh                                | 72 +++++++++----------
 t/t5528-push-default.sh                       |  6 ++
 t/t5606-clone-options.sh                      | 24 +++++++
 t/t6200-fmt-merge-msg.sh                      | 36 +++++-----
 t/t7406-submodule-update.sh                   | 16 +++++
 t/t7419-submodule-set-branch.sh               |  7 +-
 t/t7600-merge.sh                              | 14 ++--
 t/t7608-merge-messages.sh                     | 10 +--
 t/t9020-remote-svn.sh                         |  6 ++
 transport-helper.c                            |  2 +-
 51 files changed, 297 insertions(+), 131 deletions(-)


base-commit: c9c318d6bf26bcecdca5b6f31683b9d5887a83ee
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-656%2Fdscho%2Fdefault-branch-name-option-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-656/dscho/default-branch-name-option-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/656

Range-diff vs v3:

  1:  fffdb9944f =  1:  fffdb9944f fmt-merge-msg: stop treating `master` specially
  2:  a29943d7bb !  2:  1216de51ab send-pack/transport-helper: avoid mentioning a particular branch
     @@ send-pack.c: int send_pack(struct send_pack_args *args,
       	if (!remote_refs) {
       		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
      -			"Perhaps you should specify a branch such as 'master'.\n");
     -+			"Perhaps you should specify a specific branch.\n");
     ++			"Perhaps you should specify a branch.\n");
       		return 0;
       	}
       	if (args->atomic && !atomic_supported)
     @@ t/t5528-push-default.sh: test_expect_success 'push from/to new branch with upstr
      +test_expect_success '"matching" fails if none match' '
      +	git init --bare empty &&
      +	test_must_fail git push empty : 2>actual &&
     -+	test_i18ngrep "Perhaps you should specify a specific branch" actual
     ++	test_i18ngrep "Perhaps you should specify a branch" actual
      +'
      +
       test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
     @@ transport-helper.c: static int push_refs(struct transport *transport,
       		fprintf(stderr,
       			_("No refs in common and none specified; doing nothing.\n"
      -			  "Perhaps you should specify a branch such as 'master'.\n"));
     -+			  "Perhaps you should specify a specific branch.\n"));
     ++			  "Perhaps you should specify a branch.\n"));
       		return 0;
       	}
       
  3:  6bda69541b !  3:  54563642db submodule: use a better fall-back for missing remote.<name>.branch
     @@ Metadata
      Author: Johannes Schindelin <Johannes.Schindelin@gmx.de>
      
       ## Commit message ##
     -    submodule: use a better fall-back for missing remote.<name>.branch
     +    submodule: fall back to remote's HEAD for missing remote.<name>.branch
      
          When `remote.<name>.branch` is not configured, `git submodule update`
          currently falls back to using the branch name `master`. A much better
     -    idea, however, is to use `HEAD`: on all Git servers running reasonably
     -    recent Git versions, the symref `HEAD` points to the main branch.
     +    idea, however, is to use the remote `HEAD`: on all Git servers running
     +    reasonably recent Git versions, the symref `HEAD` points to the main
     +    branch.
      
          Note: t7419 demonstrates that there _might_ be use cases out there that
          _expect_ `git submodule update --remote` to update submodules to the
     @@ Commit message
          there is a slight possibility that this might cause regressions in
          obscure setups.
      
     +    Even so, it should be okay to fix this behavior without anything like a
     +    longer transition period:
     +
     +    - The `git submodule update --remote` command is not really common.
     +
     +    - Current Git's behavior when running this command is outright
     +      confusing, unless the remote repository's current branch _is_ `master`
     +      (in which case the proposed behavior matches the old behavior).
     +
     +    - If a user encounters a regression due to the changed behavior, the fix
     +      is actually trivial: setting `submodule.<name>.branch` to `master`
     +      will reinstate the old behavior.
     +
     +    Helped-by: Philippe Blain <levraiphilippeblain@gmail.com>
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
       ## Documentation/git-submodule.txt ##
     +@@ Documentation/git-submodule.txt: set-branch (-d|--default) [--] <path>::
     + 	Sets the default remote tracking branch for the submodule. The
     + 	`--branch` option allows the remote branch to be specified. The
     + 	`--default` option removes the submodule.<name>.branch configuration
     +-	key, which causes the tracking branch to default to 'master'.
     ++	key, which causes the tracking branch to default to the remote 'HEAD'.
     + 
     + set-url [--] <path> <newurl>::
     + 	Sets the URL of the specified submodule to <newurl>. Then, it will
      @@ Documentation/git-submodule.txt: OPTIONS
       	`.gitmodules` for `update --remote`.  A special value of `.` is used to
       	indicate that the name of the branch in the submodule should be the
       	same name as the current branch in the current repository.  If the
      -	option is not specified, it defaults to 'master'.
     -+	option is not specified, it defaults to 'HEAD'.
     ++	option is not specified, it defaults to the remote 'HEAD'.
       
       -f::
       --force::
     @@ Documentation/git-submodule.txt: OPTIONS
       	status of the submodule's remote-tracking branch.  The remote used
       	is branch's remote (`branch.<name>.remote`), defaulting to `origin`.
      -	The remote branch used defaults to `master`, but the branch name may
     -+	The remote branch used defaults to `HEAD`, but the branch name may
     - 	be overridden by setting the `submodule.<name>.branch` option in
     - 	either `.gitmodules` or `.git/config` (with `.git/config` taking
     - 	precedence).
     +-	be overridden by setting the `submodule.<name>.branch` option in
     +-	either `.gitmodules` or `.git/config` (with `.git/config` taking
     +-	precedence).
     ++	The remote branch used defaults to the remote `HEAD`, but the branch
     ++	name may be overridden by setting the `submodule.<name>.branch`
     ++	option in either `.gitmodules` or `.git/config` (with `.git/config`
     ++	taking precedence).
     + +
     + This works for any of the supported update procedures (`--checkout`,
     + `--rebase`, etc.).  The only change is the source of the target SHA-1.
     +
     + ## Documentation/gitmodules.txt ##
     +@@ Documentation/gitmodules.txt: submodule.<name>.update::
     + 
     + submodule.<name>.branch::
     + 	A remote branch name for tracking updates in the upstream submodule.
     +-	If the option is not specified, it defaults to 'master'.  A special
     +-	value of `.` is used to indicate that the name of the branch in the
     +-	submodule should be the same name as the current branch in the
     ++	If the option is not specified, it defaults to the remote 'HEAD'.
     ++	A special value of `.` is used to indicate that the name of the branch
     ++	in the submodule should be the same name as the current branch in the
     + 	current repository.  See the `--remote` documentation in
     + 	linkgit:git-submodule[1] for details.
     + 
      
       ## builtin/submodule--helper.c ##
      @@ builtin/submodule--helper.c: static const char *remote_submodule_branch(const char *path)
  -:  ---------- >  4:  1d723d35ed docs: add missing diamond brackets
  4:  e8a6587c1a !  5:  9edd4fd3b2 init: allow specifying the initial branch name for the new repository
     @@ Documentation/git-init.txt
      @@ Documentation/git-init.txt: SYNOPSIS
       [verse]
       'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
     - 	  [--separate-git-dir <git dir>] [--object-format=<format]
     + 	  [--separate-git-dir <git dir>] [--object-format=<format>]
      +	  [-b <branch-name> | --initial-branch=<branch-name>]
       	  [--shared[=<permissions>]] [directory]
       
     @@ builtin/init-db.c: static int create_default_files(const char *template_path,
       	/*
      -	 * Create the default symlink from ".git/HEAD" to the "master"
      -	 * branch, if it does not exist yet.
     -+	 * Create the default symlink from ".git/HEAD" to the default
     -+	 * branch name, if it does not exist yet.
     ++	 * Point the HEAD symref to the initial branch with if HEAD does
     ++	 * not yet exist.
       	 */
       	path = git_path_buf(&buf, "HEAD");
       	reinit = (!access(path, R_OK)
     @@ builtin/init-db.c: static int create_default_files(const char *template_path,
      +
      +		if (create_symref("HEAD", ref, NULL) < 0)
       			exit(1);
     --	}
      +		free(ref);
     -+	} else if (initial_branch)
     -+		warning(_("re-init: ignoring --initial-branch=%s"),
     -+			initial_branch);
     + 	}
       
       	initialize_repository_version(fmt->hash_algo);
     - 
      @@ builtin/init-db.c: static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
       }
       
     @@ builtin/init-db.c: int init_db(const char *git_dir, const char *real_git_dir,
      -	reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
      +	reinit = create_default_files(template_dir, original_git_dir,
      +				      initial_branch, &repo_fmt);
     ++	if (reinit && initial_branch)
     ++		warning(_("re-init: ignored --initial-branch=%s"),
     ++			initial_branch);
       
       	create_object_directory();
       
     @@ t/t0001-init.sh: test_expect_success MINGW 'redirect std handles' '
      +
      +	: re-initializing should not change the branch name &&
      +	git init --initial-branch=ignore initial-branch-option 2>err &&
     -+	test_i18ngrep "ignoring --initial-branch" err &&
     ++	test_i18ngrep "ignored --initial-branch" err &&
      +	git -C initial-branch-option symbolic-ref HEAD >actual &&
      +	grep hello actual
      +'
  5:  a500e0f214 =  6:  7747eaa57d init: allow setting the default for the initial branch name via the config
  6:  c0d74cedd1 =  7:  1cff7705e4 clone: use configured default branch name when appropriate
  7:  00a1b281e5 !  8:  0a7c0bdfda remote: use the configured default branch name when appropriate
     @@ remote.c: static void read_branches_file(struct remote *remote)
       	/*
       	 * The branches file would have URL and optionally
      -	 * #branch specified.  The "master" (or specified) branch is
     -+	 * #branch specified.  The main (or specified) branch is
     ++	 * #branch specified.  The default (or specified) branch is
       	 * fetched and stored in the local branch matching the
       	 * remote name.
       	 */
  8:  1aa0e63785 =  9:  6c72abf677 testsvn: respect `init.defaultBranch`

-- 
gitgitgadget

^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
@ 2020-06-24 14:46       ` Johannes Schindelin via GitGitGadget
  2020-06-29 16:20         ` Đoàn Trần Công Danh
  2020-06-24 14:46       ` [PATCH v4 2/9] send-pack/transport-helper: avoid mentioning a particular branch Johannes Schindelin via GitGitGadget
                         ` (9 subsequent siblings)
  10 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-24 14:46 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Philippe Blain, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

In the context of many projects renaming their primary branch names away
from `master`, Git wants to stop treating the `master` branch specially.

Let's start with `git fmt-merge-msg`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 fmt-merge-msg.c                               |  5 +-
 t/t1507-rev-parse-upstream.sh                 |  2 +-
 t/t4013-diff-various.sh                       |  4 +-
 t/t4013/diff.log_--decorate=full_--all        |  2 +-
 t/t4013/diff.log_--decorate_--all             |  2 +-
 ...--patch-with-stat_--summary_master_--_dir_ |  2 +-
 t/t4013/diff.log_--patch-with-stat_master     |  2 +-
 .../diff.log_--patch-with-stat_master_--_dir_ |  2 +-
 ...ot_--cc_--patch-with-stat_--summary_master |  2 +-
 ..._--root_--patch-with-stat_--summary_master |  2 +-
 .../diff.log_--root_--patch-with-stat_master  |  2 +-
 ...root_-c_--patch-with-stat_--summary_master |  2 +-
 t/t4013/diff.log_--root_-p_master             |  2 +-
 t/t4013/diff.log_--root_master                |  2 +-
 t/t4013/diff.log_-m_-p_--first-parent_master  |  2 +-
 t/t4013/diff.log_-m_-p_master                 |  4 +-
 t/t4013/diff.log_-p_--first-parent_master     |  2 +-
 t/t4013/diff.log_-p_master                    |  2 +-
 t/t4013/diff.log_master                       |  2 +-
 t/t4013/diff.show_--first-parent_master       |  2 +-
 t/t4013/diff.show_-c_master                   |  2 +-
 t/t4013/diff.show_-m_master                   |  4 +-
 t/t4013/diff.show_master                      |  2 +-
 ...ot_--cc_--patch-with-stat_--summary_master |  2 +-
 ...root_-c_--patch-with-stat_--summary_master |  2 +-
 t/t4202-log.sh                                | 72 +++++++++----------
 t/t6200-fmt-merge-msg.sh                      | 36 +++++-----
 t/t7600-merge.sh                              | 14 ++--
 t/t7608-merge-messages.sh                     | 10 +--
 29 files changed, 94 insertions(+), 97 deletions(-)

diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c
index 72d32bd73b..cfb8ff2f33 100644
--- a/fmt-merge-msg.c
+++ b/fmt-merge-msg.c
@@ -451,10 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
 			strbuf_addf(out, " of %s", srcs.items[i].string);
 	}
 
-	if (!strcmp("master", current_branch))
-		strbuf_addch(out, '\n');
-	else
-		strbuf_addf(out, " into %s\n", current_branch);
+	strbuf_addf(out, " into %s\n", current_branch);
 }
 
 static void fmt_tag_signature(struct strbuf *tagbuf,
diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh
index dfc0d96d8a..f213aa8053 100755
--- a/t/t1507-rev-parse-upstream.sh
+++ b/t/t1507-rev-parse-upstream.sh
@@ -137,7 +137,7 @@ test_expect_success 'merge my-side@{u} records the correct name' '
 	git branch -t new my-side@{u} &&
 	git merge -s ours new@{u} &&
 	git show -s --pretty=tformat:%s >actual &&
-	echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect &&
+	echo "Merge remote-tracking branch ${SQ}origin/side${SQ} into master" >expect &&
 	test_cmp expect actual
 )
 '
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 3f60f7d96c..43267d6024 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -117,12 +117,12 @@ test_expect_success setup '
 
 : <<\EOF
 ! [initial] Initial
- * [master] Merge branch 'side'
+ * [master] Merge branch 'side' into master
   ! [rearrange] Rearranged lines in dir/sub
    ! [side] Side
 ----
   +  [rearrange] Rearranged lines in dir/sub
- -   [master] Merge branch 'side'
+ -   [master] Merge branch 'side' into master
  * + [side] Side
  *   [master^] Third
  *   [master~2] Second
diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all
index 3f9b872ece..c56783b985 100644
--- a/t/t4013/diff.log_--decorate=full_--all
+++ b/t/t4013/diff.log_--decorate=full_--all
@@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (refs/heads/side)
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--decorate_--all b/t/t4013/diff.log_--decorate_--all
index f5e20e1e14..1cbdc038f4 100644
--- a/t/t4013/diff.log_--decorate_--all
+++ b/t/t4013/diff.log_--decorate_--all
@@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (side)
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
index a18f1472a9..f5b1b6516b 100644
--- a/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--patch-with-stat_master b/t/t4013/diff.log_--patch-with-stat_master
index ae425c4672..af23803cdc 100644
--- a/t/t4013/diff.log_--patch-with-stat_master
+++ b/t/t4013/diff.log_--patch-with-stat_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--patch-with-stat_master_--_dir_ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
index d5207cadf4..814098fbf8 100644
--- a/t/t4013/diff.log_--patch-with-stat_master_--_dir_
+++ b/t/t4013/diff.log_--patch-with-stat_master_--_dir_
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
index 0fc1e8cd71..b927fe4a98 100644
--- a/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
  dir/sub | 2 ++
  file0   | 3 +++
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
index dffc09dde9..6db3cea329 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--root_--patch-with-stat_master b/t/t4013/diff.log_--root_--patch-with-stat_master
index 55aa98012d..98e9c320c3 100644
--- a/t/t4013/diff.log_--root_--patch-with-stat_master
+++ b/t/t4013/diff.log_--root_--patch-with-stat_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
index 019d85f7de..b61b1117ae 100644
--- a/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
  dir/sub | 2 ++
  file0   | 3 +++
diff --git a/t/t4013/diff.log_--root_-p_master b/t/t4013/diff.log_--root_-p_master
index b42c334439..345bd9e8a9 100644
--- a/t/t4013/diff.log_--root_-p_master
+++ b/t/t4013/diff.log_--root_-p_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--root_master b/t/t4013/diff.log_--root_master
index e8f46159da..db56b1fe6b 100644
--- a/t/t4013/diff.log_--root_master
+++ b/t/t4013/diff.log_--root_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_-m_-p_--first-parent_master b/t/t4013/diff.log_-m_-p_--first-parent_master
index 7a0073f529..bcadb50e26 100644
--- a/t/t4013/diff.log_-m_-p_--first-parent_master
+++ b/t/t4013/diff.log_-m_-p_--first-parent_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index cead32e..992913c 100644
diff --git a/t/t4013/diff.log_-m_-p_master b/t/t4013/diff.log_-m_-p_master
index 9ca62a01ed..2acf43a9fb 100644
--- a/t/t4013/diff.log_-m_-p_master
+++ b/t/t4013/diff.log_-m_-p_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index cead32e..992913c 100644
@@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index 7289e35..992913c 100644
diff --git a/t/t4013/diff.log_-p_--first-parent_master b/t/t4013/diff.log_-p_--first-parent_master
index 3fc896d424..c6a5876d80 100644
--- a/t/t4013/diff.log_-p_--first-parent_master
+++ b/t/t4013/diff.log_-p_--first-parent_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_-p_master b/t/t4013/diff.log_-p_master
index bf1326dc36..1841cded94 100644
--- a/t/t4013/diff.log_-p_master
+++ b/t/t4013/diff.log_-p_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_master b/t/t4013/diff.log_master
index a8f6ce5abd..f8ec445eb3 100644
--- a/t/t4013/diff.log_master
+++ b/t/t4013/diff.log_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a
 Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.show_--first-parent_master b/t/t4013/diff.show_--first-parent_master
index 3dcbe473a0..94548f4598 100644
--- a/t/t4013/diff.show_--first-parent_master
+++ b/t/t4013/diff.show_--first-parent_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index cead32e..992913c 100644
diff --git a/t/t4013/diff.show_-c_master b/t/t4013/diff.show_-c_master
index 81aba8da96..1c46ed64fd 100644
--- a/t/t4013/diff.show_-c_master
+++ b/t/t4013/diff.show_-c_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --combined dir/sub
 index cead32e,7289e35..992913c
diff --git a/t/t4013/diff.show_-m_master b/t/t4013/diff.show_-m_master
index 4ea2ee453d..7559fc22f8 100644
--- a/t/t4013/diff.show_-m_master
+++ b/t/t4013/diff.show_-m_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index cead32e..992913c 100644
@@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --git a/dir/sub b/dir/sub
 index 7289e35..992913c 100644
diff --git a/t/t4013/diff.show_master b/t/t4013/diff.show_master
index fb08ce0e46..57091c5d90 100644
--- a/t/t4013/diff.show_master
+++ b/t/t4013/diff.show_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
 diff --cc dir/sub
 index cead32e,7289e35..992913c
diff --git a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
index 30aae7817b..5f13a71bb5 100644
--- a/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
  dir/sub | 2 ++
  file0   | 3 +++
diff --git a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
index d1d32bd34c..8acb88267b 100644
--- a/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
+++ b/t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9
 Author: A U Thor <author@example.com>
 Date:   Mon Jun 26 00:04:00 2006 +0000
 
-    Merge branch 'side'
+    Merge branch 'side' into master
 
  dir/sub | 2 ++
  file0   | 3 +++
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index a0930599aa..fd9af658af 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -483,7 +483,7 @@ test_expect_success 'set up merge history' '
 '
 
 cat > expect <<\EOF
-*   Merge branch 'side'
+*   Merge branch 'side' into master
 |\
 | * side-2
 | * side-1
@@ -502,7 +502,7 @@ test_expect_success 'log --graph with merge' '
 '
 
 cat > expect <<\EOF
-| | | *   Merge branch 'side'
+| | | *   Merge branch 'side' into master
 | | | |\
 | | | | * side-2
 | | | | * side-1
@@ -521,7 +521,7 @@ test_expect_success 'log --graph --line-prefix="| | | " with merge' '
 '
 
 cat > expect.colors <<\EOF
-*   Merge branch 'side'
+*   Merge branch 'side' into master
 <BLUE>|<RESET><CYAN>\<RESET>
 <BLUE>|<RESET> * side-2
 <BLUE>|<RESET> * side-1
@@ -555,7 +555,7 @@ cat > expect <<\EOF
 |\  Merge: A B
 | | Author: A U Thor <author@example.com>
 | |
-| |     Merge branch 'side'
+| |     Merge branch 'side' into master
 | |
 | * commit tags/side-2
 | | Author: A U Thor <author@example.com>
@@ -632,11 +632,11 @@ test_expect_success 'set up more tangled history' '
 '
 
 cat > expect <<\EOF
-*   Merge tag 'reach'
+*   Merge tag 'reach' into master
 |\
 | \
 |  \
-*-. \   Merge tags 'octopus-a' and 'octopus-b'
+*-. \   Merge tags 'octopus-a' and 'octopus-b' into master
 |\ \ \
 * | | | seventh
 | | * | octopus-b
@@ -646,14 +646,14 @@ cat > expect <<\EOF
 |/ /
 | * reach
 |/
-*   Merge branch 'tangle'
+*   Merge branch 'tangle' into master
 |\
 | *   Merge branch 'side' (early part) into tangle
 | |\
 | * \   Merge branch 'master' (early part) into tangle
 | |\ \
 | * | | tangle-a
-* | | |   Merge branch 'side'
+* | | |   Merge branch 'side' into master
 |\ \ \ \
 | * | | | side-2
 | | |_|/
@@ -735,16 +735,16 @@ test_expect_success 'log.decorate configuration' '
 
 test_expect_success 'decorate-refs with glob' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b (octopus-b)
 	octopus-a (octopus-a)
 	reach
 	EOF
 	cat >expect.no-decorate <<-\EOF &&
-	Merge-tag-reach
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b
 	octopus-a
@@ -765,8 +765,8 @@ test_expect_success 'decorate-refs with glob' '
 
 test_expect_success 'decorate-refs without globs' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b
 	octopus-a
@@ -779,8 +779,8 @@ test_expect_success 'decorate-refs without globs' '
 
 test_expect_success 'multiple decorate-refs' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b (octopus-b)
 	octopus-a (octopus-a)
@@ -794,8 +794,8 @@ test_expect_success 'multiple decorate-refs' '
 
 test_expect_success 'decorate-refs-exclude with glob' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (HEAD -> master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (HEAD -> master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh (tag: seventh)
 	octopus-b (tag: octopus-b)
 	octopus-a (tag: octopus-a)
@@ -811,8 +811,8 @@ test_expect_success 'decorate-refs-exclude with glob' '
 
 test_expect_success 'decorate-refs-exclude without globs' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (HEAD -> master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (HEAD -> master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh (tag: seventh)
 	octopus-b (tag: octopus-b, octopus-b)
 	octopus-a (tag: octopus-a, octopus-a)
@@ -828,8 +828,8 @@ test_expect_success 'decorate-refs-exclude without globs' '
 
 test_expect_success 'multiple decorate-refs-exclude' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (HEAD -> master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (HEAD -> master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh (tag: seventh)
 	octopus-b (tag: octopus-b)
 	octopus-a (tag: octopus-a)
@@ -851,8 +851,8 @@ test_expect_success 'multiple decorate-refs-exclude' '
 
 test_expect_success 'decorate-refs and decorate-refs-exclude' '
 	cat >expect.no-decorate <<-\EOF &&
-	Merge-tag-reach (master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b
 	octopus-a
@@ -866,8 +866,8 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' '
 
 test_expect_success 'deocrate-refs and log.excludeDecoration' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (master)
-	Merge-tags-octopus-a-and-octopus-b
+	Merge-tag-reach-into-master (master)
+	Merge-tags-octopus-a-and-octopus-b-into-master
 	seventh
 	octopus-b (octopus-b)
 	octopus-a (octopus-a)
@@ -881,10 +881,10 @@ test_expect_success 'deocrate-refs and log.excludeDecoration' '
 
 test_expect_success 'decorate-refs-exclude and simplify-by-decoration' '
 	cat >expect.decorate <<-\EOF &&
-	Merge-tag-reach (HEAD -> master)
+	Merge-tag-reach-into-master (HEAD -> master)
 	reach (tag: reach, reach)
 	seventh (tag: seventh)
-	Merge-branch-tangle
+	Merge-branch-tangle-into-master
 	Merge-branch-side-early-part-into-tangle (tangle)
 	tangle-a (tag: tangle-a)
 	EOF
@@ -1068,7 +1068,7 @@ cat >expect <<\EOF
 |\  Merge: MERGE_PARENTS
 | | Author: A U Thor <author@example.com>
 | |
-| |     Merge branch 'tangle'
+| |     Merge branch 'tangle' into master
 | |
 | *   commit COMMIT_OBJECT_NAME
 | |\  Merge: MERGE_PARENTS
@@ -1102,7 +1102,7 @@ cat >expect <<\EOF
 |\ \ \ \  Merge: MERGE_PARENTS
 | | | | | Author: A U Thor <author@example.com>
 | | | | |
-| | | | |     Merge branch 'side'
+| | | | |     Merge branch 'side' into master
 | | | | |
 | * | | | commit COMMIT_OBJECT_NAME
 | | |_|/  Author: A U Thor <author@example.com>
@@ -1343,7 +1343,7 @@ cat >expect <<\EOF
 *** |\  Merge: MERGE_PARENTS
 *** | | Author: A U Thor <author@example.com>
 *** | |
-*** | |     Merge branch 'tangle'
+*** | |     Merge branch 'tangle' into master
 *** | |
 *** | *   commit COMMIT_OBJECT_NAME
 *** | |\  Merge: MERGE_PARENTS
@@ -1377,7 +1377,7 @@ cat >expect <<\EOF
 *** |\ \ \ \  Merge: MERGE_PARENTS
 *** | | | | | Author: A U Thor <author@example.com>
 *** | | | | |
-*** | | | | |     Merge branch 'side'
+*** | | | | |     Merge branch 'side' into master
 *** | | | | |
 *** | * | | | commit COMMIT_OBJECT_NAME
 *** | | |_|/  Author: A U Thor <author@example.com>
@@ -1540,8 +1540,8 @@ cat >expect <<-\EOF
 * reach
 |
 | A	reach.t
-* Merge branch 'tangle'
-*   Merge branch 'side'
+* Merge branch 'tangle' into master
+*   Merge branch 'side' into master
 |\
 | * side-2
 |
@@ -1562,8 +1562,8 @@ cat >expect <<-\EOF
 * reach
 |
 | reach.t
-* Merge branch 'tangle'
-*   Merge branch 'side'
+* Merge branch 'tangle' into master
+*   Merge branch 'side' into master
 |\
 | * side-2
 |
diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh
index e4c2a6eca4..2b3fd498d0 100755
--- a/t/t6200-fmt-merge-msg.sh
+++ b/t/t6200-fmt-merge-msg.sh
@@ -79,7 +79,7 @@ test_expect_success GPG 'set up a signed tag' '
 '
 
 test_expect_success 'message for merging local branch' '
-	echo "Merge branch ${apos}left${apos}" >expected &&
+	echo "Merge branch ${apos}left${apos} into master" >expected &&
 
 	git checkout master &&
 	git fetch . left &&
@@ -107,7 +107,7 @@ test_expect_success GPG 'message for merging local tag signed by unknown key' '
 '
 
 test_expect_success 'message for merging external branch' '
-	echo "Merge branch ${apos}left${apos} of $(pwd)" >expected &&
+	echo "Merge branch ${apos}left${apos} of $(pwd) into master" >expected &&
 
 	git checkout master &&
 	git fetch "$(pwd)" left &&
@@ -118,7 +118,7 @@ test_expect_success 'message for merging external branch' '
 
 test_expect_success '[merge] summary/log configuration' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -160,7 +160,7 @@ test_expect_success 'setup FETCH_HEAD' '
 
 test_expect_success 'merge.log=3 limits shortlog length' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -177,7 +177,7 @@ test_expect_success 'merge.log=3 limits shortlog length' '
 
 test_expect_success 'merge.log=5 shows all 5 commits' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -195,7 +195,7 @@ test_expect_success 'merge.log=5 shows all 5 commits' '
 
 test_expect_success '--log=5 with custom comment character' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	x By Another Author (3) and A U Thor (2)
 	x Via Another Committer
@@ -212,14 +212,14 @@ test_expect_success '--log=5 with custom comment character' '
 '
 
 test_expect_success 'merge.log=0 disables shortlog' '
-	echo "Merge branch ${apos}left${apos}" >expected &&
+	echo "Merge branch ${apos}left${apos} into master" >expected &&
 	git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual &&
 	test_cmp expected actual
 '
 
 test_expect_success '--log=3 limits shortlog length' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -236,7 +236,7 @@ test_expect_success '--log=3 limits shortlog length' '
 
 test_expect_success '--log=5 shows all 5 commits' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}
+	Merge branch ${apos}left${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -253,13 +253,13 @@ test_expect_success '--log=5 shows all 5 commits' '
 '
 
 test_expect_success '--no-log disables shortlog' '
-	echo "Merge branch ${apos}left${apos}" >expected &&
+	echo "Merge branch ${apos}left${apos} into master" >expected &&
 	git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual &&
 	test_cmp expected actual
 '
 
 test_expect_success '--log=0 disables shortlog' '
-	echo "Merge branch ${apos}left${apos}" >expected &&
+	echo "Merge branch ${apos}left${apos} into master" >expected &&
 	git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual &&
 	test_cmp expected actual
 '
@@ -300,7 +300,7 @@ test_expect_success 'fmt-merge-msg -m' '
 
 test_expect_success 'setup: expected shortlog for two branches' '
 	cat >expected <<-EOF
-	Merge branches ${apos}left${apos} and ${apos}right${apos}
+	Merge branches ${apos}left${apos} and ${apos}right${apos} into master
 
 	# By Another Author (3) and A U Thor (2)
 	# Via Another Committer
@@ -397,7 +397,7 @@ test_expect_success 'merge-msg with nothing to merge' '
 
 test_expect_success 'merge-msg tag' '
 	cat >expected <<-EOF &&
-	Merge tag ${apos}tag-r3${apos}
+	Merge tag ${apos}tag-r3${apos} into master
 
 	* tag ${apos}tag-r3${apos}:
 	  Right #3
@@ -418,7 +418,7 @@ test_expect_success 'merge-msg tag' '
 
 test_expect_success 'merge-msg two tags' '
 	cat >expected <<-EOF &&
-	Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos}
+	Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} into master
 
 	* tag ${apos}tag-r3${apos}:
 	  Right #3
@@ -448,7 +448,7 @@ test_expect_success 'merge-msg two tags' '
 
 test_expect_success 'merge-msg tag and branch' '
 	cat >expected <<-EOF &&
-	Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos}
+	Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} into master
 
 	* tag ${apos}tag-r3${apos}:
 	  Right #3
@@ -479,7 +479,7 @@ test_expect_success 'merge-msg tag and branch' '
 test_expect_success 'merge-msg lots of commits' '
 	{
 		cat <<-EOF &&
-		Merge branch ${apos}long${apos}
+		Merge branch ${apos}long${apos} into master
 
 		* long: (35 commits)
 		EOF
@@ -516,7 +516,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' '
 	git fmt-merge-msg <.git/FETCH_HEAD >actual &&
 	{
 		cat <<-\EOF
-		Merge tag '\''annote'\''
+		Merge tag '\''annote'\'' into master
 
 		An annotated one
 
@@ -531,7 +531,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' '
 	git merge --no-commit --no-ff $annote &&
 	{
 		cat <<-EOF
-		Merge tag '\''$annote'\''
+		Merge tag '\''$annote'\'' into master
 
 		An annotated one
 
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 5883a6adc3..1d45f9a4ed 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -14,9 +14,9 @@ Testing basic merge operations/option parsing.
     ! [c4] c4
      ! [c5] c5
       ! [c6] c6
-       * [master] Merge commit 'c1'
+       * [master] Merge commit 'c1' into master
 --------
-       - [master] Merge commit 'c1'
+       - [master] Merge commit 'c1' into master
  +     * [c1] commit 1
       +  [c6] c6
      +   [c5] c5
@@ -44,8 +44,8 @@ test_write_lines '1 X' 2 '3 X' 4 '5 X' 6 7 8 '9 X' >result.1-3-5-9
 test_write_lines 1 2 3 4 5 6 7 8 '9 Z' >result.9z
 
 create_merge_msgs () {
-	echo "Merge tag 'c2'" >msg.1-5 &&
-	echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 &&
+	echo "Merge tag 'c2' into master" >msg.1-5 &&
+	echo "Merge tags 'c2' and 'c3' into master" >msg.1-5-9 &&
 	{
 		echo "Squashed commit of the following:" &&
 		echo &&
@@ -258,7 +258,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '
 	git commit --no-edit -a &&
 
 	cat >expect <<-\EOF &&
-	Merge tag '"'"'c7'"'"'
+	Merge tag '"'"'c7'"'"' into master
 
 	# ------------------------ >8 ------------------------
 	# Do not modify or remove the line above.
@@ -808,10 +808,10 @@ test_expect_success 'merge with conflicted --autostash changes' '
 '
 
 cat >expected.branch <<\EOF
-Merge branch 'c5-branch' (early part)
+Merge branch 'c5-branch' (early part) into master
 EOF
 cat >expected.tag <<\EOF
-Merge commit 'c5~1'
+Merge commit 'c5~1' into master
 EOF
 
 test_expect_success 'merge early part of c2' '
diff --git a/t/t7608-merge-messages.sh b/t/t7608-merge-messages.sh
index 8e7e0a5865..2af33f195b 100755
--- a/t/t7608-merge-messages.sh
+++ b/t/t7608-merge-messages.sh
@@ -16,7 +16,7 @@ test_expect_success 'merge local branch' '
 	git checkout master &&
 	test_commit master-2 &&
 	git merge local-branch &&
-	check_oneline "Merge branch Qlocal-branchQ"
+	check_oneline "Merge branch Qlocal-branchQ into master"
 '
 
 test_expect_success 'merge octopus branches' '
@@ -26,7 +26,7 @@ test_expect_success 'merge octopus branches' '
 	test_commit octopus-2 &&
 	git checkout master &&
 	git merge octopus-a octopus-b &&
-	check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ"
+	check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ into master"
 '
 
 test_expect_success 'merge tag' '
@@ -35,7 +35,7 @@ test_expect_success 'merge tag' '
 	git checkout master &&
 	test_commit master-3 &&
 	git merge tag-1 &&
-	check_oneline "Merge tag Qtag-1Q"
+	check_oneline "Merge tag Qtag-1Q into master"
 '
 
 test_expect_success 'ambiguous tag' '
@@ -44,7 +44,7 @@ test_expect_success 'ambiguous tag' '
 	git checkout master &&
 	test_commit master-4 &&
 	git merge ambiguous &&
-	check_oneline "Merge tag QambiguousQ"
+	check_oneline "Merge tag QambiguousQ into master"
 '
 
 test_expect_success 'remote-tracking branch' '
@@ -54,7 +54,7 @@ test_expect_success 'remote-tracking branch' '
 	git checkout master &&
 	test_commit master-5 &&
 	git merge origin/master &&
-	check_oneline "Merge remote-tracking branch Qorigin/masterQ"
+	check_oneline "Merge remote-tracking branch Qorigin/masterQ into master"
 '
 
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v4 2/9] send-pack/transport-helper: avoid mentioning a particular branch
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially Johannes Schindelin via GitGitGadget
@ 2020-06-24 14:46       ` Johannes Schindelin via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 3/9] submodule: fall back to remote's HEAD for missing remote.<name>.branch Johannes Schindelin via GitGitGadget
                         ` (8 subsequent siblings)
  10 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-24 14:46 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Philippe Blain, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When trying to push all matching branches, but none match, we offer a
message suggesting to push the `master` branch.

However, we want to step away from making that branch any more special
than any other branch, so let's reword that message to mention no branch
in particular.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 send-pack.c             | 2 +-
 t/t5528-push-default.sh | 6 ++++++
 transport-helper.c      | 2 +-
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/send-pack.c b/send-pack.c
index 0abee22283..19eb9b04e4 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -406,7 +406,7 @@ int send_pack(struct send_pack_args *args,
 
 	if (!remote_refs) {
 		fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
-			"Perhaps you should specify a branch such as 'master'.\n");
+			"Perhaps you should specify a branch.\n");
 		return 0;
 	}
 	if (args->atomic && !atomic_supported)
diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh
index 4d1e0c363e..f0a287d97d 100755
--- a/t/t5528-push-default.sh
+++ b/t/t5528-push-default.sh
@@ -98,6 +98,12 @@ test_expect_success 'push from/to new branch with upstream, matching and simple'
 	test_push_failure upstream
 '
 
+test_expect_success '"matching" fails if none match' '
+	git init --bare empty &&
+	test_must_fail git push empty : 2>actual &&
+	test_i18ngrep "Perhaps you should specify a branch" actual
+'
+
 test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
 	git checkout -b ambiguous &&
 	test_config branch.ambiguous.remote parent1 &&
diff --git a/transport-helper.c b/transport-helper.c
index a46afcb69d..8a711cda29 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -1046,7 +1046,7 @@ static int push_refs(struct transport *transport,
 	if (!remote_refs) {
 		fprintf(stderr,
 			_("No refs in common and none specified; doing nothing.\n"
-			  "Perhaps you should specify a branch such as 'master'.\n"));
+			  "Perhaps you should specify a branch.\n"));
 		return 0;
 	}
 
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v4 3/9] submodule: fall back to remote's HEAD for missing remote.<name>.branch
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially Johannes Schindelin via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 2/9] send-pack/transport-helper: avoid mentioning a particular branch Johannes Schindelin via GitGitGadget
@ 2020-06-24 14:46       ` Johannes Schindelin via GitGitGadget
  2020-06-24 16:17         ` Junio C Hamano
  2020-06-24 14:46       ` [PATCH v4 4/9] docs: add missing diamond brackets Johannes Schindelin via GitGitGadget
                         ` (7 subsequent siblings)
  10 siblings, 1 reply; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-24 14:46 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Philippe Blain, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When `remote.<name>.branch` is not configured, `git submodule update`
currently falls back to using the branch name `master`. A much better
idea, however, is to use the remote `HEAD`: on all Git servers running
reasonably recent Git versions, the symref `HEAD` points to the main
branch.

Note: t7419 demonstrates that there _might_ be use cases out there that
_expect_ `git submodule update --remote` to update submodules to the
remote `master` branch even if the remote `HEAD` points to another
branch. Arguably, this patch makes the behavior more intuitive, but
there is a slight possibility that this might cause regressions in
obscure setups.

Even so, it should be okay to fix this behavior without anything like a
longer transition period:

- The `git submodule update --remote` command is not really common.

- Current Git's behavior when running this command is outright
  confusing, unless the remote repository's current branch _is_ `master`
  (in which case the proposed behavior matches the old behavior).

- If a user encounters a regression due to the changed behavior, the fix
  is actually trivial: setting `submodule.<name>.branch` to `master`
  will reinstate the old behavior.

Helped-by: Philippe Blain <levraiphilippeblain@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-submodule.txt | 12 ++++++------
 Documentation/gitmodules.txt    |  6 +++---
 builtin/submodule--helper.c     |  2 +-
 t/t7406-submodule-update.sh     | 16 ++++++++++++++++
 t/t7419-submodule-set-branch.sh |  7 +++++--
 5 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index c9ed2bf3d5..7e5f995f77 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -183,7 +183,7 @@ set-branch (-d|--default) [--] <path>::
 	Sets the default remote tracking branch for the submodule. The
 	`--branch` option allows the remote branch to be specified. The
 	`--default` option removes the submodule.<name>.branch configuration
-	key, which causes the tracking branch to default to 'master'.
+	key, which causes the tracking branch to default to the remote 'HEAD'.
 
 set-url [--] <path> <newurl>::
 	Sets the URL of the specified submodule to <newurl>. Then, it will
@@ -284,7 +284,7 @@ OPTIONS
 	`.gitmodules` for `update --remote`.  A special value of `.` is used to
 	indicate that the name of the branch in the submodule should be the
 	same name as the current branch in the current repository.  If the
-	option is not specified, it defaults to 'master'.
+	option is not specified, it defaults to the remote 'HEAD'.
 
 -f::
 --force::
@@ -322,10 +322,10 @@ OPTIONS
 	the superproject's recorded SHA-1 to update the submodule, use the
 	status of the submodule's remote-tracking branch.  The remote used
 	is branch's remote (`branch.<name>.remote`), defaulting to `origin`.
-	The remote branch used defaults to `master`, but the branch name may
-	be overridden by setting the `submodule.<name>.branch` option in
-	either `.gitmodules` or `.git/config` (with `.git/config` taking
-	precedence).
+	The remote branch used defaults to the remote `HEAD`, but the branch
+	name may be overridden by setting the `submodule.<name>.branch`
+	option in either `.gitmodules` or `.git/config` (with `.git/config`
+	taking precedence).
 +
 This works for any of the supported update procedures (`--checkout`,
 `--rebase`, etc.).  The only change is the source of the target SHA-1.
diff --git a/Documentation/gitmodules.txt b/Documentation/gitmodules.txt
index 67275fd187..539b4e1997 100644
--- a/Documentation/gitmodules.txt
+++ b/Documentation/gitmodules.txt
@@ -49,9 +49,9 @@ submodule.<name>.update::
 
 submodule.<name>.branch::
 	A remote branch name for tracking updates in the upstream submodule.
-	If the option is not specified, it defaults to 'master'.  A special
-	value of `.` is used to indicate that the name of the branch in the
-	submodule should be the same name as the current branch in the
+	If the option is not specified, it defaults to the remote 'HEAD'.
+	A special value of `.` is used to indicate that the name of the branch
+	in the submodule should be the same name as the current branch in the
 	current repository.  See the `--remote` documentation in
 	linkgit:git-submodule[1] for details.
 
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 46c03d2a12..f55f7b7704 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1981,7 +1981,7 @@ static const char *remote_submodule_branch(const char *path)
 	free(key);
 
 	if (!branch)
-		return "master";
+		return "HEAD";
 
 	if (!strcmp(branch, ".")) {
 		const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 4fb447a143..aa19ff3a2e 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -70,6 +70,22 @@ test_expect_success 'setup a submodule tree' '
 	)
 '
 
+test_expect_success 'update --remote falls back to using HEAD' '
+	test_create_repo main-branch-submodule &&
+	test_commit -C main-branch-submodule initial &&
+
+	test_create_repo main-branch &&
+	git -C main-branch submodule add ../main-branch-submodule &&
+	git -C main-branch commit -m add-submodule &&
+
+	git -C main-branch-submodule switch -c hello &&
+	test_commit -C main-branch-submodule world &&
+
+	git clone --recursive main-branch main-branch-clone &&
+	git -C main-branch-clone submodule update --remote main-branch-submodule &&
+	test_path_exists main-branch-clone/main-branch-submodule/world.t
+'
+
 test_expect_success 'submodule update detaching the HEAD ' '
 	(cd super/submodule &&
 	 git reset --hard HEAD~1
diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh
index fd25f786a3..3b925c302f 100755
--- a/t/t7419-submodule-set-branch.sh
+++ b/t/t7419-submodule-set-branch.sh
@@ -52,12 +52,13 @@ test_expect_success 'test submodule set-branch --branch' '
 '
 
 test_expect_success 'test submodule set-branch --default' '
+	test_commit -C submodule c &&
 	(cd super &&
 		git submodule set-branch --default submodule &&
 		! grep branch .gitmodules &&
 		git submodule update --remote &&
 		cat <<-\EOF >expect &&
-		a
+		c
 		EOF
 		git -C submodule show -s --pretty=%s >actual &&
 		test_cmp expect actual
@@ -65,6 +66,7 @@ test_expect_success 'test submodule set-branch --default' '
 '
 
 test_expect_success 'test submodule set-branch -b' '
+	test_commit -C submodule b &&
 	(cd super &&
 		git submodule set-branch -b topic submodule &&
 		grep "branch = topic" .gitmodules &&
@@ -78,12 +80,13 @@ test_expect_success 'test submodule set-branch -b' '
 '
 
 test_expect_success 'test submodule set-branch -d' '
+	test_commit -C submodule d &&
 	(cd super &&
 		git submodule set-branch -d submodule &&
 		! grep branch .gitmodules &&
 		git submodule update --remote &&
 		cat <<-\EOF >expect &&
-		a
+		d
 		EOF
 		git -C submodule show -s --pretty=%s >actual &&
 		test_cmp expect actual
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v4 4/9] docs: add missing diamond brackets
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                         ` (2 preceding siblings ...)
  2020-06-24 14:46       ` [PATCH v4 3/9] submodule: fall back to remote's HEAD for missing remote.<name>.branch Johannes Schindelin via GitGitGadget
@ 2020-06-24 14:46       ` Johannes Schindelin via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 5/9] init: allow specifying the initial branch name for the new repository Johannes Schindelin via GitGitGadget
                         ` (6 subsequent siblings)
  10 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-24 14:46 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Philippe Blain, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

There were a couple of instances in our manual pages that had an
opening diamond bracket without a corresponding closing one.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-branch.txt | 2 +-
 Documentation/git-clone.txt  | 2 +-
 Documentation/git-init.txt   | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 135206ff4a..03c0824d52 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -12,7 +12,7 @@ SYNOPSIS
 	[-v [--abbrev=<length> | --no-abbrev]]
 	[--column[=<options>] | --no-column] [--sort=<key>]
 	[(--merged | --no-merged) [<commit>]]
-	[--contains [<commit]] [--no-contains [<commit>]]
+	[--contains [<commit>]] [--no-contains [<commit>]]
 	[--points-at <object>] [--format=<format>]
 	[(-r | --remotes) | (-a | --all)]
 	[--list] [<pattern>...]
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 08d6045c4a..c898310099 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -259,7 +259,7 @@ maintain a branch with no references other than a single cloned
 branch. This is useful e.g. to maintain minimal clones of the default
 branch of some repository for search indexing.
 
---recurse-submodules[=<pathspec]::
+--recurse-submodules[=<pathspec>]::
 	After the clone is created, initialize and clone submodules
 	within based on the provided pathspec.  If no pathspec is
 	provided, all submodules are initialized and cloned.
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index adc6adfd38..f9467cc6a4 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
-	  [--separate-git-dir <git dir>] [--object-format=<format]
+	  [--separate-git-dir <git dir>] [--object-format=<format>]
 	  [--shared[=<permissions>]] [directory]
 
 
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v4 5/9] init: allow specifying the initial branch name for the new repository
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                         ` (3 preceding siblings ...)
  2020-06-24 14:46       ` [PATCH v4 4/9] docs: add missing diamond brackets Johannes Schindelin via GitGitGadget
@ 2020-06-24 14:46       ` Johannes Schindelin via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 6/9] init: allow setting the default for the initial branch name via the config Don Goodman-Wilson via GitGitGadget
                         ` (5 subsequent siblings)
  10 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-24 14:46 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Philippe Blain, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

There is a growing number of projects and companies desiring to change
the main branch name of their repositories (see e.g.
https://twitter.com/mislav/status/1270388510684598272 for background on
this).

To change that branch name for new repositories, currently the only way
to do that automatically is by copying all of Git's template directory,
then hard-coding the desired default branch name into the `.git/HEAD`
file, and then configuring `init.templateDir` to point to those copied
template files.

To make this process much less cumbersome, let's introduce a new option:
`--initial-branch=<branch-name>`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-init.txt |  7 +++++++
 builtin/clone.c            |  3 ++-
 builtin/init-db.c          | 33 +++++++++++++++++++++++++++------
 cache.h                    |  2 +-
 t/t0001-init.sh            | 13 +++++++++++++
 5 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index f9467cc6a4..ddfe265da5 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -11,6 +11,7 @@ SYNOPSIS
 [verse]
 'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
 	  [--separate-git-dir <git dir>] [--object-format=<format>]
+	  [-b <branch-name> | --initial-branch=<branch-name>]
 	  [--shared[=<permissions>]] [directory]
 
 
@@ -67,6 +68,12 @@ repository.
 +
 If this is reinitialization, the repository will be moved to the specified path.
 
+-b <branch-name::
+--initial-branch=<branch-name>::
+
+Use the specified name for the initial branch in the newly created repository.
+If not specified, fall back to the default name: `master`.
+
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
 Specify that the Git repository is to be shared amongst several users.  This
diff --git a/builtin/clone.c b/builtin/clone.c
index 2a8e3aaaed..b751bdf13e 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1111,7 +1111,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
+	init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
+		INIT_DB_QUIET);
 
 	if (real_git_dir)
 		git_dir = real_git_dir;
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 0b7222e718..8fdfc334ac 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)
 
 static int create_default_files(const char *template_path,
 				const char *original_git_dir,
+				const char *initial_branch,
 				const struct repository_format *fmt)
 {
 	struct stat st1;
@@ -258,15 +259,26 @@ static int create_default_files(const char *template_path,
 		die("failed to set up refs db: %s", err.buf);
 
 	/*
-	 * Create the default symlink from ".git/HEAD" to the "master"
-	 * branch, if it does not exist yet.
+	 * Point the HEAD symref to the initial branch with if HEAD does
+	 * not yet exist.
 	 */
 	path = git_path_buf(&buf, "HEAD");
 	reinit = (!access(path, R_OK)
 		  || readlink(path, junk, sizeof(junk)-1) != -1);
 	if (!reinit) {
-		if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
+		char *ref;
+
+		if (!initial_branch)
+			initial_branch = "master";
+
+		ref = xstrfmt("refs/heads/%s", initial_branch);
+		if (check_refname_format(ref, 0) < 0)
+			die(_("invalid initial branch name: '%s'"),
+			    initial_branch);
+
+		if (create_symref("HEAD", ref, NULL) < 0)
 			exit(1);
+		free(ref);
 	}
 
 	initialize_repository_version(fmt->hash_algo);
@@ -383,7 +395,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
 }
 
 int init_db(const char *git_dir, const char *real_git_dir,
-	    const char *template_dir, int hash, unsigned int flags)
+	    const char *template_dir, int hash, const char *initial_branch,
+	    unsigned int flags)
 {
 	int reinit;
 	int exist_ok = flags & INIT_DB_EXIST_OK;
@@ -425,7 +438,11 @@ int init_db(const char *git_dir, const char *real_git_dir,
 
 	validate_hash_algorithm(&repo_fmt, hash);
 
-	reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
+	reinit = create_default_files(template_dir, original_git_dir,
+				      initial_branch, &repo_fmt);
+	if (reinit && initial_branch)
+		warning(_("re-init: ignored --initial-branch=%s"),
+			initial_branch);
 
 	create_object_directory();
 
@@ -528,6 +545,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	const char *template_dir = NULL;
 	unsigned int flags = 0;
 	const char *object_format = NULL;
+	const char *initial_branch = NULL;
 	int hash_algo = GIT_HASH_UNKNOWN;
 	const struct option init_db_options[] = {
 		OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ -541,6 +559,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 		OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
 		OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
 			   N_("separate git dir from working tree")),
+		OPT_STRING('b', "initial-branch", &initial_branch, N_("name"),
+			   N_("override the name of the initial branch")),
 		OPT_STRING(0, "object-format", &object_format, N_("hash"),
 			   N_("specify the hash algorithm to use")),
 		OPT_END()
@@ -652,5 +672,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 	UNLEAK(work_tree);
 
 	flags |= INIT_DB_EXIST_OK;
-	return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
+	return init_db(git_dir, real_git_dir, template_dir, hash_algo,
+		       initial_branch, flags);
 }
diff --git a/cache.h b/cache.h
index 0f0485ecfe..654426460c 100644
--- a/cache.h
+++ b/cache.h
@@ -628,7 +628,7 @@ int path_inside_repo(const char *prefix, const char *path);
 
 int init_db(const char *git_dir, const char *real_git_dir,
 	    const char *template_dir, int hash_algo,
-	    unsigned int flags);
+	    const char *initial_branch, unsigned int flags);
 void initialize_repository_version(int hash_algo);
 
 void sanitize_stdfds(void);
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 1edd5aeb8f..386c06b5dd 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -464,4 +464,17 @@ test_expect_success MINGW 'redirect std handles' '
 	grep "Needed a single revision" output.txt
 '
 
+test_expect_success '--initial-branch' '
+	git init --initial-branch=hello initial-branch-option &&
+	git -C initial-branch-option symbolic-ref HEAD >actual &&
+	echo refs/heads/hello >expect &&
+	test_cmp expect actual &&
+
+	: re-initializing should not change the branch name &&
+	git init --initial-branch=ignore initial-branch-option 2>err &&
+	test_i18ngrep "ignored --initial-branch" err &&
+	git -C initial-branch-option symbolic-ref HEAD >actual &&
+	grep hello actual
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v4 6/9] init: allow setting the default for the initial branch name via the config
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                         ` (4 preceding siblings ...)
  2020-06-24 14:46       ` [PATCH v4 5/9] init: allow specifying the initial branch name for the new repository Johannes Schindelin via GitGitGadget
@ 2020-06-24 14:46       ` Don Goodman-Wilson via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 7/9] clone: use configured default branch name when appropriate Johannes Schindelin via GitGitGadget
                         ` (4 subsequent siblings)
  10 siblings, 0 replies; 178+ messages in thread
From: Don Goodman-Wilson via GitGitGadget @ 2020-06-24 14:46 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Philippe Blain, Johannes Schindelin, Don Goodman-Wilson

From: Don Goodman-Wilson <don@goodman-wilson.com>

We just introduced the command-line option
`--initial-branch=<branch-name>` to allow initializing a new repository
with a different initial branch than the hard-coded one.

To allow users to override the initial branch name more permanently
(i.e. without having to specify the name manually for each and every
`git init` invocation), let's introduce the `init.defaultBranch` config
setting.

Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Helped-by: Derrick Stolee <dstolee@microsoft.com>
Signed-off-by: Don Goodman-Wilson <don@goodman-wilson.com>
---
 Documentation/config/init.txt |  4 ++++
 builtin/init-db.c             |  2 +-
 refs.c                        | 30 ++++++++++++++++++++++++++++++
 refs.h                        |  9 +++++++++
 t/t0001-init.sh               | 13 +++++++++++++
 5 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt
index 46fa8c6a08..6ae4a38416 100644
--- a/Documentation/config/init.txt
+++ b/Documentation/config/init.txt
@@ -1,3 +1,7 @@
 init.templateDir::
 	Specify the directory from which templates will be copied.
 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+
+init.defaultBranch::
+	Allows overriding the default branch name when initializing
+	a new repository.
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 8fdfc334ac..cee64823cb 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -269,7 +269,7 @@ static int create_default_files(const char *template_path,
 		char *ref;
 
 		if (!initial_branch)
-			initial_branch = "master";
+			initial_branch = git_default_branch_name();
 
 		ref = xstrfmt("refs/heads/%s", initial_branch);
 		if (check_refname_format(ref, 0) < 0)
diff --git a/refs.c b/refs.c
index 224ff66c7b..b98dea5217 100644
--- a/refs.c
+++ b/refs.c
@@ -560,6 +560,36 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
 		argv_array_pushf(prefixes, *p, len, prefix);
 }
 
+char *repo_default_branch_name(struct repository *r)
+{
+	const char *config_key = "init.defaultbranch";
+	const char *config_display_key = "init.defaultBranch";
+	char *ret = NULL, *full_ref;
+
+	if (repo_config_get_string(r, config_key, &ret) < 0)
+		die(_("could not retrieve `%s`"), config_display_key);
+
+	if (!ret)
+		ret = xstrdup("master");
+
+	full_ref = xstrfmt("refs/heads/%s", ret);
+	if (check_refname_format(full_ref, 0))
+		die(_("invalid branch name: %s = %s"), config_display_key, ret);
+	free(full_ref);
+
+	return ret;
+}
+
+const char *git_default_branch_name(void)
+{
+	static char *ret;
+
+	if (!ret)
+		ret = repo_default_branch_name(the_repository);
+
+	return ret;
+}
+
 /*
  * *string and *len will only be substituted, and *string returned (for
  * later free()ing) if the string passed in is a magic short-hand form
diff --git a/refs.h b/refs.h
index e010f8aec2..f212f8945e 100644
--- a/refs.h
+++ b/refs.h
@@ -154,6 +154,15 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
 int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
 int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
 
+/*
+ * Retrieves the default branch name for newly-initialized repositories.
+ *
+ * The return value of `repo_default_branch_name()` is an allocated string. The
+ * return value of `git_default_branch_name()` is a singleton.
+ */
+const char *git_default_branch_name(void);
+char *repo_default_branch_name(struct repository *r);
+
 /*
  * A ref_transaction represents a collection of reference updates that
  * should succeed or fail together.
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 386c06b5dd..6d2467995e 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -477,4 +477,17 @@ test_expect_success '--initial-branch' '
 	grep hello actual
 '
 
+test_expect_success 'overridden default initial branch name (config)' '
+	test_config_global init.defaultBranch nmb &&
+	git init initial-branch-config &&
+	git -C initial-branch-config symbolic-ref HEAD >actual &&
+	grep nmb actual
+'
+
+test_expect_success 'invalid default branch name' '
+	test_config_global init.defaultBranch "with space" &&
+	test_must_fail git init initial-branch-invalid 2>err &&
+	test_i18ngrep "invalid branch name" err
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread

* [PATCH v4 7/9] clone: use configured default branch name when appropriate
  2020-06-24 14:46     ` [PATCH v4 0/9] Allow overriding the default name of the default branch Johannes Schindelin via GitGitGadget
                         ` (5 preceding siblings ...)
  2020-06-24 14:46       ` [PATCH v4 6/9] init: allow setting the default for the initial branch name via the config Don Goodman-Wilson via GitGitGadget
@ 2020-06-24 14:46       ` Johannes Schindelin via GitGitGadget
  2020-06-24 14:46       ` [PATCH v4 8/9] remote: use the " Johannes Schindelin via GitGitGadget
                         ` (3 subsequent siblings)
  10 siblings, 0 replies; 178+ messages in thread
From: Johannes Schindelin via GitGitGadget @ 2020-06-24 14:46 UTC (permalink / raw)
  To: git
  Cc: don, stolee, peff, sandals, Matt Rogers, Eric Sunshine,
	Taylor Blau, Phillip Wood, Alban Gruin, Johannes Sixt,
	Denton Liu, Ævar Arnfjörð Bjarmason,
	Philippe Blain, Johannes Schindelin, Johannes Schindelin

From: Johannes Schindelin <johannes.schindelin@gmx.de>

When cloning a repository without any branches, Git chooses a default
branch name for the as-yet unborn branch.

As part of the implicit initialization of the local repository, Git just
learned to respect `init.defaultBranch` to choose a different initial
branch name. We now really want that branch name to be used as a
fall-back.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/config/init.txt |  4 ++--
 builtin/clone.c               | 10 +++++++---
 t/t5606-clone-options.sh      | 15 +++++++++++++++
 3 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/Documentation/config/init.txt b/Documentation/config/init.txt
index 6ae4a38416..dc77f8c844 100644
--- a/Documentation/config/init.txt
+++ b/Documentation/config/init.txt
@@ -3,5 +3,5 @@ init.templateDir::
 	(See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
 
 init.defaultBranch::
-	Allows overriding the default branch name when initializing
-	a new repository.
+	Allows overriding the default branch name e.g. when initializing
+	a new repository or when cloning an empty repository.
diff --git a/builtin/clone.c b/builtin/clone.c
index b751bdf13e..9a3f91b268 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1267,9 +1267,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head_points_at = NULL;
 		remote_head = NULL;
 		option_no_checkout = 1;
-		if (!option_bare)
-			install_branch_config(0, "master", option_origin,
-					      "refs/heads/master");
+		if (!option_bare) {
+			const char *branch = git_default_branch_name();
+			char *ref = xstrfmt("refs/heads/%s", branch);
+
+			install_branch_config(0, branch, option_origin, ref);
+			free(ref);
+		}
 	}
 
 	write_refspec_config(src_ref_prefix, our_head_points_at,
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 9e24ec88e6..286bfd93ac 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -35,4 +35,19 @@ test_expect_success 'redirected clone -v does show progress' '
 
 '
 
+test_expect_success 'chooses correct default initial branch name' '
+	git init --bare empty &&
+	git -c init.defaultBranch=up clone empty whats-up &&
+	test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) &&
+	test refs/heads/up = $(git -C whats-up config branch.up.merge)
+'
+
+test_expect_success 'guesses initial branch name correctly' '
+	git init --initial-branch=guess initial-branch &&
+	test_commit -C initial-branch no-spoilers &&
+	git -C initial-branch branch abc guess &&
+	git clone initial-branch is-it &&
+	test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
+'
+
 test_done
-- 
gitgitgadget


^ permalink raw reply	[flat|nested] 178+ messages in thread</