threads / patch / 54691

patch, 3 partsget_default_branch_name(): prepare for showing some advice

Subject: [PATCH 2/3] get_default_branch_name(): prepare for showing some advice

## tl;dr

57 messages between Nov 22, 2020 and Feb 3, 2021. Diffs are folded; open one to read it.

replies: 56people: 5as markdown or json

Johannes Schindelin via GitGitGadget· Nov 22, 2020, 23:23 UTC · lore

[PATCH 0/3] Add helpful advice about init.defaultBranch

It is our designated intention [https://sfconservancy.org/news/2020/jun/23/gitbranchname/] to "to explore changing the name of the first branch created automatically for new repositories away from ‘master’". Further, we promised that we "will minimize disruption for Git's users and will include appropriate deprecation periods".

To that end, introduce a message giving advice to users running git init that the fall-back for init.defaultBranch is subject to change, and how to configure it.

The beauty of this patch series, if I may say so, is that it does not commit us to any concrete plan, but opens the door for all options regarding the default branch name.

Johannes Schindelin (3):
  init: document `init.defaultBranch` better
  get_default_branch_name(): prepare for showing some advice
  init: provide useful advice about init.defaultBranch
 Documentation/git-init.txt    | 11 +++++++----
 builtin/clone.c               |  2 +-
 builtin/init-db.c             |  8 +++++---
 refs.c                        | 19 +++++++++++++++----
 refs.h                        |  4 ++--
 remote.c                      |  5 +++--
 t/t0001-init.sh               |  9 ++++++++-
 t/t1510-repo-setup.sh         |  2 +-
 t/t7414-submodule-mistakes.sh |  2 +-
 t/test-lib-functions.sh       |  3 ++-
 10 files changed, 45 insertions(+), 20 deletions(-)
base-commit: faefdd61ec7c7f6f3c8c9907891465ac9a2a1475
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-921%2Fdscho%2Finit.defaultBranch-advice-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-921/dscho/init.defaultBranch-advice-v1
Pull-Request: https://github.com/git/git/pull/921
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 22, 2020, 23:23 UTC · re: Johannes Schindelin via GitGitGadget · lore
From: Johannes Schindelin <johannes.schindelin@gmx.de>

We are about to introduce a message giving users running `git init` some advice about `init.defaultBranch`. This will necessarily be done in `repo_default_branch_name()`.

Not all code paths want to show that advice, though. In particular, the `git clone` codepath _specifically_ asks for `init_db()` to be quiet, via the `INIT_DB_QUIET` flag.

In preparation for showing users above-mentioned advice, let's change the function signature of `get_default_branch_name()` to accept the parameter `quiet`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/clone.c   | 2 +-
 builtin/init-db.c | 8 +++++---
 refs.c            | 6 +++---
 refs.h            | 4 ++--
 remote.c          | 5 +++--
 5 files changed, 14 insertions(+), 11 deletions(-)
Show changes to 5 files +14 −11

builtin/clone.c, builtin/init-db.c, refs.c, refs.h, remote.c

diff --git a/builtin/clone.c b/builtin/clone.c
index a0841923cf..64b1784011 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1323,7 +1323,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare) {
-			const char *branch = git_default_branch_name();
+			const char *branch = git_default_branch_name(0);
 			char *ref = xstrfmt("refs/heads/%s", branch);
 
 			install_branch_config(0, branch, remote_name, ref);
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 01bc648d41..dcc45bef51 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit)
 static int create_default_files(const char *template_path,
 				const char *original_git_dir,
 				const char *initial_branch,
-				const struct repository_format *fmt)
+				const struct repository_format *fmt,
+				int quiet)
 {
 	struct stat st1;
 	struct strbuf buf = STRBUF_INIT;
@@ -267,7 +268,7 @@ static int create_default_files(const char *template_path,
 		char *ref;
 
 		if (!initial_branch)
-			initial_branch = git_default_branch_name();
+			initial_branch = git_default_branch_name(quiet);
 
 		ref = xstrfmt("refs/heads/%s", initial_branch);
 		if (check_refname_format(ref, 0) < 0)
@@ -438,7 +439,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,
-				      initial_branch, &repo_fmt);
+				      initial_branch, &repo_fmt,
+				      flags & INIT_DB_QUIET);
 	if (reinit && initial_branch)
 		warning(_("re-init: ignored --initial-branch=%s"),
 			initial_branch);
diff --git a/refs.c b/refs.c
index 392f0bbf68..8df03122d6 100644
--- a/refs.c
+++ b/refs.c
@@ -562,7 +562,7 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
-char *repo_default_branch_name(struct repository *r)
+char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
 	const char *config_display_key = "init.defaultBranch";
@@ -585,12 +585,12 @@ char *repo_default_branch_name(struct repository *r)
 	return ret;
 }
 
-const char *git_default_branch_name(void)
+const char *git_default_branch_name(int quiet)
 {
 	static char *ret;
 
 	if (!ret)
-		ret = repo_default_branch_name(the_repository);
+		ret = repo_default_branch_name(the_repository, quiet);
 
 	return ret;
 }
diff --git a/refs.h b/refs.h
index 6695518156..ff05d2e9fe 100644
--- a/refs.h
+++ b/refs.h
@@ -170,8 +170,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
  * 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);
+const char *git_default_branch_name(int quiet);
+char *repo_default_branch_name(struct repository *r, int quiet);
 
 /*
  * A ref_transaction represents a collection of reference updates that
diff --git a/remote.c b/remote.c
index 8a6dbbb903..bdb88d4b7d 100644
--- a/remote.c
+++ b/remote.c
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
 	if (frag)
 		*(frag++) = '\0';
 	else
-		frag = (char *)git_default_branch_name();
+		frag = (char *)git_default_branch_name(0);
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
 	refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s",
@@ -2206,7 +2206,8 @@ struct ref *guess_remote_head(const struct ref *head,
 
 	/* 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());
+		char *ref = xstrfmt("refs/heads/%s",
+				    git_default_branch_name(0));
 
 		r = find_ref_by_name(refs, ref);
 		free(ref);
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 22, 2020, 23:23 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH 1/3] init: document `init.defaultBranch` better

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

Our documentation does not mention any future plan to change 'master' to other value. It is a good idea to document this, though.

Initial-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-init.txt | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
Show changes to Documentation/git-init.txt +7 −4
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 59ecda6c17..19f9f16e6b 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -20,8 +20,9 @@ DESCRIPTION
 
 This command creates an empty Git repository - basically a `.git`
 directory with subdirectories for `objects`, `refs/heads`,
-`refs/tags`, and template files.  An initial `HEAD` file that
-references the HEAD of the master branch is also created.
+`refs/tags`, and template files.  An initial branch without any
+commits will be created (see the `--initial-branch` option below
+for its name).
 
 If the `$GIT_DIR` environment variable is set then it specifies a path
 to use instead of `./.git` for the base of the repository.
@@ -73,8 +74,10 @@ 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`.
+Use the specified name for the initial branch in the newly created
+repository.  If not specified, fall back to the default name (currently
+`master`, but that will be changed in the future; The name can be customized
+via the `init.defaultBranch` configuration variable).
 
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
-- 
gitgitgadget
Junio C Hamano· Nov 22, 2020, 23:40 UTC · re: Johannes Schindelin via GitGitGadget · lore

Re: [PATCH 1/3] init: document `init.defaultBranch` better

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

Show 8 quoted lines
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> Our documentation does not mention any future plan to change 'master' to
> other value. It is a good idea to document this, though.
>
> Initial-patch-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---

It would have been nicer to have a reference to the original patch <xmqqd00a36wc.fsf@gitster.c.googlers.com> here after the three-dash lines, which would have made it easier for me to say that the updated phrasing is much better.

I do not think I deserve credit for this step in the series. Please drop "initial-patch-by" when you do a v2.

Show 16 quoted lines
>  Documentation/git-init.txt | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
> index 59ecda6c17..19f9f16e6b 100644
> --- a/Documentation/git-init.txt
> +++ b/Documentation/git-init.txt
> @@ -20,8 +20,9 @@ DESCRIPTION
>  
>  This command creates an empty Git repository - basically a `.git`
>  directory with subdirectories for `objects`, `refs/heads`,
> -`refs/tags`, and template files.  An initial `HEAD` file that
> -references the HEAD of the master branch is also created.
> +`refs/tags`, and template files.  An initial branch without any
> +commits will be created (see the `--initial-branch` option below
> +for its name).

"branch without any commits" is certainly easier to understand than "unborn branch", which was in my weatherballoon patch.

Stepping back a bit more, I wonder if we want to make reference to implementation details even less, e.g.

    ... an empty Git repository---a `.git` directory to store
    objects, branches and tags, hooks, and template files.
which would be in the same spirit as not mentioning 'HEAD file'.
Show 10 quoted lines
> @@ -73,8 +74,10 @@ 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`.
> +Use the specified name for the initial branch in the newly created
> +repository.  If not specified, fall back to the default name (currently
> +`master`, but that will be changed in the future; The name can be customized
> +via the `init.defaultBranch` configuration variable).

s/The/the/ after semicolon that ends a half-sentence. Or alternatively, s/in the future;/in the future./

>  
>  --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
Johannes Schindelin· Nov 23, 2020, 12:07 UTC · re: Junio C Hamano · lore

Re: [PATCH 1/3] init: document `init.defaultBranch` better

Hi Junio,
On Sun, 22 Nov 2020, Junio C Hamano wrote:
Show 16 quoted lines
> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > Our documentation does not mention any future plan to change 'master' to
> > other value. It is a good idea to document this, though.
> >
> > Initial-patch-by: Junio C Hamano <gitster@pobox.com>
> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> > ---
>
> It would have been nicer to have a reference to the original patch
> <xmqqd00a36wc.fsf@gitster.c.googlers.com> here after the three-dash
> lines, which would have made it easier for me to say that the
> updated phrasing is much better.

This is unfortunately not possible with GitGitGadget, which I use because it takes away so much of my burden when contributing patches.

> I do not think I deserve credit for this step in the series.  Please
> drop "initial-patch-by" when you do a v2.

This is not about "deserving". More than half of the patch is still identical to what you wrote, I only pasted it. This is yours, not mine.

Show 24 quoted lines
> > diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
> > index 59ecda6c17..19f9f16e6b 100644
> > --- a/Documentation/git-init.txt
> > +++ b/Documentation/git-init.txt
> > @@ -20,8 +20,9 @@ DESCRIPTION
> >
> >  This command creates an empty Git repository - basically a `.git`
> >  directory with subdirectories for `objects`, `refs/heads`,
> > -`refs/tags`, and template files.  An initial `HEAD` file that
> > -references the HEAD of the master branch is also created.
> > +`refs/tags`, and template files.  An initial branch without any
> > +commits will be created (see the `--initial-branch` option below
> > +for its name).
>
> "branch without any commits" is certainly easier to understand than
> "unborn branch", which was in my weatherballoon patch.
>
> Stepping back a bit more, I wonder if we want to make reference to
> implementation details even less, e.g.
>
>     ... an empty Git repository---a `.git` directory to store
>     objects, branches and tags, hooks, and template files.
>
> which would be in the same spirit as not mentioning 'HEAD file'.

Hmm. I'm of two minds there. On the one hand, it is nice to have a conciser description. On the other hand, it is nice to have a little bit depth in the description.

For the time being, I'll leave it as-is.
Show 13 quoted lines
> > @@ -73,8 +74,10 @@ 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`.
> > +Use the specified name for the initial branch in the newly created
> > +repository.  If not specified, fall back to the default name (currently
> > +`master`, but that will be changed in the future; The name can be customized
> > +via the `init.defaultBranch` configuration variable).
>
> s/The/the/ after semicolon that ends a half-sentence.  Or
> alternatively, s/in the future;/in the future./
Okay.
> >  --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::

Thanks for the thorough review, Dscho

Johannes Schindelin via GitGitGadget· Nov 22, 2020, 23:23 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH 3/3] init: provide useful advice about init.defaultBranch

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

To give ample warning in case we decide to change the fall-back for an unconfigured `init.defaultBranch`, let's introduce some advice that is shown upon `git init` when that value is not set.

Note: three test cases in Git's test suite want to verify that the
`stderr` output of `git init` is empty. With this patch, that is only
true if `init.defaultBranch` is configured, so let's do exactly that in
those test cases. The same reasoning applies to `test_create_repo()`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 refs.c                        | 13 ++++++++++++-
 t/t0001-init.sh               |  9 ++++++++-
 t/t1510-repo-setup.sh         |  2 +-
 t/t7414-submodule-mistakes.sh |  2 +-
 t/test-lib-functions.sh       |  3 ++-
 5 files changed, 24 insertions(+), 5 deletions(-)
Show changes to 5 files +24 −5

refs.c, t/t0001-init.sh, t/t1510-repo-setup.sh, t/t7414-submodule-mistakes.sh, t/test-lib-functions.sh

diff --git a/refs.c b/refs.c
index 8df03122d6..61d712ca05 100644
--- a/refs.c
+++ b/refs.c
@@ -562,6 +562,14 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
+static const char default_branch_name_advice[] = N_(
+"Using '%s' as the name for the initial branch. This name is subject\n"
+"to change. To configure the name to use as the initial branch name in\n"
+"new repositories, or to silence this warning, run:\n"
+"\n"
+"\tgit config --global init.defaultBranch <name>\n"
+);
+
 char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
@@ -574,8 +582,11 @@ char *repo_default_branch_name(struct repository *r, int quiet)
 	else if (repo_config_get_string(r, config_key, &ret) < 0)
 		die(_("could not retrieve `%s`"), config_display_key);
 
-	if (!ret)
+	if (!ret) {
 		ret = xstrdup("master");
+		if (!quiet)
+			advise(_(default_branch_name_advice), ret);
+	}
 
 	full_ref = xstrfmt("refs/heads/%s", ret);
 	if (check_refname_format(full_ref, 0))
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 69a320489f..754dab3bab 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -163,7 +163,7 @@ test_expect_success 'reinit' '
 	(
 		mkdir again &&
 		cd again &&
-		git init >out1 2>err1 &&
+		git -c init.defaultBranch=initial init >out1 2>err1 &&
 		git init >out2 2>err2
 	) &&
 	test_i18ngrep "Initialized empty" again/out1 &&
@@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' '
 	grep nmb actual
 '
 
+test_expect_success 'advice on unconfigured init.defaultBranch' '
+	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
+		init unconfigured-default-branch-name 2>err &&
+	test_decode_color <err >decoded &&
+	test_i18ngrep "<YELLOW>hint: " decoded
+'
+
 test_expect_success 'overridden default main branch name (env)' '
 	test_config_global init.defaultBranch nmb &&
 	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 9974457f56..5189a520a2 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -79,7 +79,7 @@ setup_repo () {
 	name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
 	sane_unset GIT_DIR GIT_WORK_TREE &&
 
-	git init "$name" &&
+	git -c init.defaultBranch=repo init "$name" &&
 	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
 	maybe_config "$name/.git/config" core.bare "$barecfg" &&
 	mkdir -p "$name/sub/sub" &&
diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh
index f2e7df59cf..0ed02938f9 100755
--- a/t/t7414-submodule-mistakes.sh
+++ b/t/t7414-submodule-mistakes.sh
@@ -30,7 +30,7 @@ test_expect_success 'no warning when updating entry' '
 
 test_expect_success 'submodule add does not warn' '
 	test_when_finished "git rm -rf submodule .gitmodules" &&
-	git submodule add ./embed submodule 2>stderr &&
+	git -c init.defaultBranch=x submodule add ./embed submodule 2>stderr &&
 	test_i18ngrep ! warning stderr
 '
 
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 59bbf75e83..772152320a 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1202,7 +1202,8 @@ test_create_repo () {
 	mkdir -p "$repo"
 	(
 		cd "$repo" || error "Cannot setup test environment"
-		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
+		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
+			-c init.defaultBranch=master 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
-- 
gitgitgadget
Junio C Hamano· Nov 22, 2020, 23:53 UTC · re: Johannes Schindelin via GitGitGadget · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

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

Show 5 quoted lines
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> To give ample warning in case we decide to change the fall-back for an
> unconfigured `init.defaultBranch`, let's introduce some advice that is
> shown upon `git init` when that value is not set.
I know this means well.  

I however doubt "ample warning" before we announce an actual decision makes user's life any easier in practice, though. Until they know what it will be changed to (if we decide not to change anything, treat it as changing it to 'master'), they would not be able to decide if the name is more suitable for their use case.

I further suspect that their choice will be influenced the most by the choice made by the projects they most often interact with, and not by our plan.

> +static const char default_branch_name_advice[] = N_(
> +"Using '%s' as the name for the initial branch. This name is subject\n"
> +"to change. To configure the name to use as the initial branch name in\n"
> +"new repositories, or to silence this warning, run:\n"

s/new repositories/all of your new repositories/ as that is the whole point of using --global option below.

> +"\n"
> +"\tgit config --global init.defaultBranch <name>\n"
> +);
> +
Show 7 quoted lines
> +test_expect_success 'advice on unconfigured init.defaultBranch' '
> +	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
> +		init unconfigured-default-branch-name 2>err &&
> +	test_decode_color <err >decoded &&
> +	test_i18ngrep "<YELLOW>hint: " decoded
> +'
> +
Show 12 quoted lines
> diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh
> index f2e7df59cf..0ed02938f9 100755
> --- a/t/t7414-submodule-mistakes.sh
> +++ b/t/t7414-submodule-mistakes.sh
> @@ -30,7 +30,7 @@ test_expect_success 'no warning when updating entry' '
>  
>  test_expect_success 'submodule add does not warn' '
>  	test_when_finished "git rm -rf submodule .gitmodules" &&
> -	git submodule add ./embed submodule 2>stderr &&
> +	git -c init.defaultBranch=x submodule add ./embed submodule 2>stderr &&
>  	test_i18ngrep ! warning stderr
>  '

It is a bit subtle that this not only tests whatever "git submodule" test it originally wanted to do but also serves as a test that the new advice message is squelched by the presence of the configuration.

Show 11 quoted lines
> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> index 59bbf75e83..772152320a 100644
> --- a/t/test-lib-functions.sh
> +++ b/t/test-lib-functions.sh
> @@ -1202,7 +1202,8 @@ test_create_repo () {
>  	mkdir -p "$repo"
>  	(
>  		cd "$repo" || error "Cannot setup test environment"
> -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
> +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
> +			-c init.defaultBranch=master init \
I wonder if this should be more like
	-c init.defaultBranch=${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}

so that tests that want a particular branch name would get what they want?

Eventually we would need to do the s/master/X/ if/when the actual default change happens.

>  			"--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
Junio C Hamano· Nov 23, 2020, 02:07 UTC · re: Junio C Hamano · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

Junio C Hamano <gitster@pobox.com> writes:
Show 12 quoted lines
>> +static const char default_branch_name_advice[] = N_(
>> +"Using '%s' as the name for the initial branch. This name is subject\n"
>> +"to change. To configure the name to use as the initial branch name in\n"
>> +"new repositories, or to silence this warning, run:\n"
>
> s/new repositories/all of your new repositories/ as that is the
> whole point of using --global option below.
>
>> +"\n"
>> +"\tgit config --global init.defaultBranch <name>\n"
>> +);
>> +

The above may give a valuable lesson to those who want to use one branch name across new repositories, but it does not tell those who wanted 'trunk' (to match the project, perhaps github.com/cli/cli, with which they intend to interact) how to recover from having already created the 'master' branch. We may want to add some text to suggest "branch -M" after giving the advice for the permanent option.

Also, it is unclear to those who do not have a good <name> in mind (or, those who do not care to choose a <name> for themselves), what <name> they should give to take the "or to silence this warning" part of the advice. It probably is a good idea to rephrase and say either:

    ... To configure ... in all your new repositories and squelch
    this message, run:
	git config --global init.defaultBranch <name>
or
    ... To configure ... in all your new repositories, run:
	git config --global init.defaultBranch <name>
    Note that this message won't appear after doing so.
I am offhand not sure which one is better.
Thanks.
Johannes Schindelin· Nov 23, 2020, 12:28 UTC · re: Junio C Hamano · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

Hi Junio,
On Sun, 22 Nov 2020, Junio C Hamano wrote:
Show 22 quoted lines
> Junio C Hamano <gitster@pobox.com> writes:
>
> >> +static const char default_branch_name_advice[] = N_(
> >> +"Using '%s' as the name for the initial branch. This name is subject\n"
> >> +"to change. To configure the name to use as the initial branch name in\n"
> >> +"new repositories, or to silence this warning, run:\n"
> >
> > s/new repositories/all of your new repositories/ as that is the
> > whole point of using --global option below.
> >
> >> +"\n"
> >> +"\tgit config --global init.defaultBranch <name>\n"
> >> +);
> >> +
>
> The above may give a valuable lesson to those who want to use one
> branch name across new repositories, but it does not tell those who
> wanted 'trunk' (to match the project, perhaps github.com/cli/cli,
> with which they intend to interact) how to recover from having
> already created the 'master' branch.  We may want to add some text
> to suggest "branch -M" after giving the advice for the permanent
> option.
Good point.
> Also, it is unclear to those who do not have a good <name> in mind
> (or, those who do not care to choose a <name> for themselves), what
> <name> they should give to take the "or to silence this warning"
> part of the advice.
Also a good point.
Show 15 quoted lines
> It probably is a good idea to rephrase and say
> either:
>
>     ... To configure ... in all your new repositories and squelch
>     this message, run:
>
> 	git config --global init.defaultBranch <name>
>
> or
>
>     ... To configure ... in all your new repositories, run:
>
> 	git config --global init.defaultBranch <name>
>
>     Note that this message won't appear after doing so.
I came up with this, which I intend to submit with v2:

static const char default_branch_name_advice[] = N_( "Using '%s' as the name for the initial branch. This name is subject\n" "to change. To configure the initial branch name to use in all of your\n" "new repositories (or to suppress this warning), run:\n" "\n" "\tgit config --global init.defaultBranch <name>\n" "\n" "Common names are 'main', 'trunk' and 'development'. The initial branch\n" "can be renamed via this command:\n" "\n" "\tgit branch -m <name>\n" );

Ciao, Dscho

Junio C Hamano· Nov 23, 2020, 18:40 UTC · re: Johannes Schindelin · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
Show 16 quoted lines
>> The above may give a valuable lesson to those who want to use one
>> branch name across new repositories, but it does not tell those who
>> wanted 'trunk' (to match the project, perhaps github.com/cli/cli,
>> with which they intend to interact) how to recover from having
>> already created the 'master' branch.  We may want to add some text
>> to suggest "branch -M" after giving the advice for the permanent
>> option.
>
> Good point.
>
>> Also, it is unclear to those who do not have a good <name> in mind
>> (or, those who do not care to choose a <name> for themselves), what
>> <name> they should give to take the "or to silence this warning"
>> part of the advice.
>
> Also a good point.
Show 6 quoted lines
> I came up with this, which I intend to submit with v2:
>
> static const char default_branch_name_advice[] = N_(
> "Using '%s' as the name for the initial branch. This name is subject\n"
> "to change. To configure the initial branch name to use in all of your\n"
> "new repositories (or to suppress this warning), run:\n"
The same issue around "to suppress" is here, though.
Show 7 quoted lines
> "\n"
> "\tgit config --global init.defaultBranch <name>\n"
> "\n"
> "Common names are 'main', 'trunk' and 'development'. The initial branch\n"
> "can be renamed via this command:\n"
> "\n"
> "\tgit branch -m <name>\n"

It is very likely that the users are on an unborn branch when they see this message and "git branch -m/-M <name>" does not work. We'd probably want to update "git branch" to allow renaming the current branch that is unborn.

In the meantime, you could do "git checkout --orphan <name>" here, but once <name> exists as a branch that would not work, so...

> );
>
> Ciao,
> Dscho
Johannes Schindelin· Nov 23, 2020, 20:46 UTC · re: Junio C Hamano · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

Hi Junio,
On Mon, 23 Nov 2020, Junio C Hamano wrote:
Show 27 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> >> The above may give a valuable lesson to those who want to use one
> >> branch name across new repositories, but it does not tell those who
> >> wanted 'trunk' (to match the project, perhaps github.com/cli/cli,
> >> with which they intend to interact) how to recover from having
> >> already created the 'master' branch.  We may want to add some text
> >> to suggest "branch -M" after giving the advice for the permanent
> >> option.
> >
> > Good point.
> >
> >> Also, it is unclear to those who do not have a good <name> in mind
> >> (or, those who do not care to choose a <name> for themselves), what
> >> <name> they should give to take the "or to silence this warning"
> >> part of the advice.
> >
> > Also a good point.
>
> > I came up with this, which I intend to submit with v2:
> >
> > static const char default_branch_name_advice[] = N_(
> > "Using '%s' as the name for the initial branch. This name is subject\n"
> > "to change. To configure the initial branch name to use in all of your\n"
> > "new repositories (or to suppress this warning), run:\n"
>
> The same issue around "to suppress" is here, though.

Hmm. I would like to believe that readers understand that setting it to _any_ name would suppress this warning.

Show 12 quoted lines
> > "\n"
> > "\tgit config --global init.defaultBranch <name>\n"
> > "\n"
> > "Common names are 'main', 'trunk' and 'development'. The initial branch\n"
> > "can be renamed via this command:\n"
> > "\n"
> > "\tgit branch -m <name>\n"
>
> It is very likely that the users are on an unborn branch when they
> see this message and "git branch -m/-M <name>" does not work.  We'd
> probably want to update "git branch" to allow renaming the current
> branch that is unborn.

Ouch, good point, I had not even realized that that does not work. In v2, I will include a patch that lets it work.

> In the meantime, you could do "git checkout --orphan <name>" here,
> but once <name> exists as a branch that would not work, so...

Careful. We should start thinking about phasing out either `checkout` or `switch`. The latter was intended to supersede the former with respect to working on branches, so I would think of phasing out `checkout` and favor `switch` instead.

That issue aside, `git switch --orphan <name>` is not necessarily a good UI here. Its documentation talks about creating a new branch, deleting all tracked files. While it is technically still correct that this command, when run on an unborn branch, does the same as renaming said branch, it is highly unintuitive to think about it that way. ("I don't want to create a new branch, I want to rename the current one! And whoa, delete tracked files? I don't want to delete _any_ files! What do you mean: there aren't any tracked files, so none are deleted? Why do you talk about deleting files, then?")

So in the interest of _reducing_ confusion, I would really, really, _really_ like to avoid mentioning that command in this advice.

It really is much better to make `git branch -m <name>` work in this scenario.

Ciao, Dscho

Show 7 quoted lines
>
>
> > );
> >
> > Ciao,
> > Dscho
>
Junio C Hamano· Nov 23, 2020, 21:28 UTC · re: Johannes Schindelin · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> Hmm. I would like to believe that readers understand that setting it to
> _any_ name would suppress this warning.

Yes, and the point raised in an earlier messages was that it is not clear that there is no recourse for those who do NOT want to choose but still want to suppress.

> It really is much better to make `git branch -m <name>` work in this
> scenario.
Yes, if we can make it work, that is much more preferred.
Johannes Schindelin· Nov 23, 2020, 12:26 UTC · re: Junio C Hamano · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

Hi Junio,
On Sun, 22 Nov 2020, Junio C Hamano wrote:
Show 13 quoted lines
> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > To give ample warning in case we decide to change the fall-back for an
> > unconfigured `init.defaultBranch`, let's introduce some advice that is
> > shown upon `git init` when that value is not set.
>
> I know this means well.
>
> I however doubt "ample warning" before we announce an actual
> decision makes user's life any easier in practice, though.

I reworded the commit message to make the rationale more obvious: the ample warning is to give users a chance to override whatever is Git's default branch name by configuring `init.defaultBranch`. If they care at all.

Show 15 quoted lines
> Until they know what it will be changed to (if we decide not to change
> anything, treat it as changing it to 'master'), they would not be able
> to decide if the name is more suitable for their use case.
>
> I further suspect that their choice will be influenced the most by
> the choice made by the projects they most often interact with, and
> not by our plan.
>
> > +static const char default_branch_name_advice[] = N_(
> > +"Using '%s' as the name for the initial branch. This name is subject\n"
> > +"to change. To configure the name to use as the initial branch name in\n"
> > +"new repositories, or to silence this warning, run:\n"
>
> s/new repositories/all of your new repositories/ as that is the
> whole point of using --global option below.
Makes sense.
Show 29 quoted lines
> > +"\n"
> > +"\tgit config --global init.defaultBranch <name>\n"
> > +);
> > +
>
> > +test_expect_success 'advice on unconfigured init.defaultBranch' '
> > +	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
> > +		init unconfigured-default-branch-name 2>err &&
> > +	test_decode_color <err >decoded &&
> > +	test_i18ngrep "<YELLOW>hint: " decoded
> > +'
> > +
>
> > diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh
> > index f2e7df59cf..0ed02938f9 100755
> > --- a/t/t7414-submodule-mistakes.sh
> > +++ b/t/t7414-submodule-mistakes.sh
> > @@ -30,7 +30,7 @@ test_expect_success 'no warning when updating entry' '
> >
> >  test_expect_success 'submodule add does not warn' '
> >  	test_when_finished "git rm -rf submodule .gitmodules" &&
> > -	git submodule add ./embed submodule 2>stderr &&
> > +	git -c init.defaultBranch=x submodule add ./embed submodule 2>stderr &&
> >  	test_i18ngrep ! warning stderr
> >  '
>
> It is a bit subtle that this not only tests whatever "git submodule"
> test it originally wanted to do but also serves as a test that the
> new advice message is squelched by the presence of the configuration.
Thank you for catching this. It is a debugging left-over.

The real fix for the underlying issue is in the previous commit, which silences the warning when `init_db()` is called via `clone`, as is the case here.

I removed it from v2.
Show 18 quoted lines
> > diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> > index 59bbf75e83..772152320a 100644
> > --- a/t/test-lib-functions.sh
> > +++ b/t/test-lib-functions.sh
> > @@ -1202,7 +1202,8 @@ test_create_repo () {
> >  	mkdir -p "$repo"
> >  	(
> >  		cd "$repo" || error "Cannot setup test environment"
> > -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
> > +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
> > +			-c init.defaultBranch=master init \
>
> I wonder if this should be more like
>
> 	-c init.defaultBranch=${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}
>
> so that tests that want a particular branch name would get what they
> want?

As is custom with our `GIT_TEST_*` variables, `GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME` overrides `init.defaultBranch`.

Therefore, _technically_ what you suggested is not even necessary here.
> Eventually we would need to do the s/master/X/ if/when the actual
> default change happens.

However, _practically_, what you suggested is very helpful, as it will make it easy to find when (if?) we finish the transition to a new fall-back.

Thank you for your thorough feedback, Dscho

> >  			"--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
>
Philip Oakley· Nov 23, 2020, 12:49 UTC · re: Johannes Schindelin via GitGitGadget · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

hi dscho,
On 22/11/2020 23:23, Johannes Schindelin via GitGitGadget wrote:
Show 31 quoted lines
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> To give ample warning in case we decide to change the fall-back for an
> unconfigured `init.defaultBranch`, let's introduce some advice that is
> shown upon `git init` when that value is not set.
>
> Note: three test cases in Git's test suite want to verify that the
> `stderr` output of `git init` is empty. With this patch, that is only
> true if `init.defaultBranch` is configured, so let's do exactly that in
> those test cases. The same reasoning applies to `test_create_repo()`.
>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  refs.c                        | 13 ++++++++++++-
>  t/t0001-init.sh               |  9 ++++++++-
>  t/t1510-repo-setup.sh         |  2 +-
>  t/t7414-submodule-mistakes.sh |  2 +-
>  t/test-lib-functions.sh       |  3 ++-
>  5 files changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/refs.c b/refs.c
> index 8df03122d6..61d712ca05 100644
> --- a/refs.c
> +++ b/refs.c
> @@ -562,6 +562,14 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
>  		strvec_pushf(prefixes, *p, len, prefix);
>  }
>  
> +static const char default_branch_name_advice[] = N_(
> +"Using '%s' as the name for the initial branch. This name is subject\n"
> +"to change. 

This sounds like Git will change the branch name within the user's repo, rather than "The default" being subject to change.  So maybe s/This/The default/   ?

Philip
Show 89 quoted lines
> To configure the name to use as the initial branch name in\n"
> +"new repositories, or to silence this warning, run:\n"
> +"\n"
> +"\tgit config --global init.defaultBranch <name>\n"
> +);
> +
>  char *repo_default_branch_name(struct repository *r, int quiet)
>  {
>  	const char *config_key = "init.defaultbranch";
> @@ -574,8 +582,11 @@ char *repo_default_branch_name(struct repository *r, int quiet)
>  	else if (repo_config_get_string(r, config_key, &ret) < 0)
>  		die(_("could not retrieve `%s`"), config_display_key);
>  
> -	if (!ret)
> +	if (!ret) {
>  		ret = xstrdup("master");
> +		if (!quiet)
> +			advise(_(default_branch_name_advice), ret);
> +	}
>  
>  	full_ref = xstrfmt("refs/heads/%s", ret);
>  	if (check_refname_format(full_ref, 0))
> diff --git a/t/t0001-init.sh b/t/t0001-init.sh
> index 69a320489f..754dab3bab 100755
> --- a/t/t0001-init.sh
> +++ b/t/t0001-init.sh
> @@ -163,7 +163,7 @@ test_expect_success 'reinit' '
>  	(
>  		mkdir again &&
>  		cd again &&
> -		git init >out1 2>err1 &&
> +		git -c init.defaultBranch=initial init >out1 2>err1 &&
>  		git init >out2 2>err2
>  	) &&
>  	test_i18ngrep "Initialized empty" again/out1 &&
> @@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' '
>  	grep nmb actual
>  '
>  
> +test_expect_success 'advice on unconfigured init.defaultBranch' '
> +	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
> +		init unconfigured-default-branch-name 2>err &&
> +	test_decode_color <err >decoded &&
> +	test_i18ngrep "<YELLOW>hint: " decoded
> +'
> +
>  test_expect_success 'overridden default main branch name (env)' '
>  	test_config_global init.defaultBranch nmb &&
>  	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
> diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
> index 9974457f56..5189a520a2 100755
> --- a/t/t1510-repo-setup.sh
> +++ b/t/t1510-repo-setup.sh
> @@ -79,7 +79,7 @@ setup_repo () {
>  	name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
>  	sane_unset GIT_DIR GIT_WORK_TREE &&
>  
> -	git init "$name" &&
> +	git -c init.defaultBranch=repo init "$name" &&
>  	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
>  	maybe_config "$name/.git/config" core.bare "$barecfg" &&
>  	mkdir -p "$name/sub/sub" &&
> diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh
> index f2e7df59cf..0ed02938f9 100755
> --- a/t/t7414-submodule-mistakes.sh
> +++ b/t/t7414-submodule-mistakes.sh
> @@ -30,7 +30,7 @@ test_expect_success 'no warning when updating entry' '
>  
>  test_expect_success 'submodule add does not warn' '
>  	test_when_finished "git rm -rf submodule .gitmodules" &&
> -	git submodule add ./embed submodule 2>stderr &&
> +	git -c init.defaultBranch=x submodule add ./embed submodule 2>stderr &&
>  	test_i18ngrep ! warning stderr
>  '
>  
> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> index 59bbf75e83..772152320a 100644
> --- a/t/test-lib-functions.sh
> +++ b/t/test-lib-functions.sh
> @@ -1202,7 +1202,8 @@ test_create_repo () {
>  	mkdir -p "$repo"
>  	(
>  		cd "$repo" || error "Cannot setup test environment"
> -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
> +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
> +			-c init.defaultBranch=master 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
Johannes Schindelin· Nov 23, 2020, 20:47 UTC · re: Philip Oakley · lore

Re: [PATCH 3/3] init: provide useful advice about init.defaultBranch

Hi Philip,
On Mon, 23 Nov 2020, Philip Oakley wrote:
Show 35 quoted lines
> On 22/11/2020 23:23, Johannes Schindelin via GitGitGadget wrote:
> > From: Johannes Schindelin <johannes.schindelin@gmx.de>
> >
> > To give ample warning in case we decide to change the fall-back for an
> > unconfigured `init.defaultBranch`, let's introduce some advice that is
> > shown upon `git init` when that value is not set.
> >
> > Note: three test cases in Git's test suite want to verify that the
> > `stderr` output of `git init` is empty. With this patch, that is only
> > true if `init.defaultBranch` is configured, so let's do exactly that in
> > those test cases. The same reasoning applies to `test_create_repo()`.
> >
> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> > ---
> >  refs.c                        | 13 ++++++++++++-
> >  t/t0001-init.sh               |  9 ++++++++-
> >  t/t1510-repo-setup.sh         |  2 +-
> >  t/t7414-submodule-mistakes.sh |  2 +-
> >  t/test-lib-functions.sh       |  3 ++-
> >  5 files changed, 24 insertions(+), 5 deletions(-)
> >
> > diff --git a/refs.c b/refs.c
> > index 8df03122d6..61d712ca05 100644
> > --- a/refs.c
> > +++ b/refs.c
> > @@ -562,6 +562,14 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
> >  		strvec_pushf(prefixes, *p, len, prefix);
> >  }
> >
> > +static const char default_branch_name_advice[] = N_(
> > +"Using '%s' as the name for the initial branch. This name is subject\n"
> > +"to change.
> This sounds like Git will change the branch name within the user's repo,
> rather than "The default" being subject to change.  So maybe
> s/This/The default/   ?

Yes, that sounds clearer to me. Thank you, Dscho

Show 94 quoted lines
>
> Philip
>
> > To configure the name to use as the initial branch name in\n"
> > +"new repositories, or to silence this warning, run:\n"
> > +"\n"
> > +"\tgit config --global init.defaultBranch <name>\n"
> > +);
> > +
> >  char *repo_default_branch_name(struct repository *r, int quiet)
> >  {
> >  	const char *config_key = "init.defaultbranch";
> > @@ -574,8 +582,11 @@ char *repo_default_branch_name(struct repository *r, int quiet)
> >  	else if (repo_config_get_string(r, config_key, &ret) < 0)
> >  		die(_("could not retrieve `%s`"), config_display_key);
> >
> > -	if (!ret)
> > +	if (!ret) {
> >  		ret = xstrdup("master");
> > +		if (!quiet)
> > +			advise(_(default_branch_name_advice), ret);
> > +	}
> >
> >  	full_ref = xstrfmt("refs/heads/%s", ret);
> >  	if (check_refname_format(full_ref, 0))
> > diff --git a/t/t0001-init.sh b/t/t0001-init.sh
> > index 69a320489f..754dab3bab 100755
> > --- a/t/t0001-init.sh
> > +++ b/t/t0001-init.sh
> > @@ -163,7 +163,7 @@ test_expect_success 'reinit' '
> >  	(
> >  		mkdir again &&
> >  		cd again &&
> > -		git init >out1 2>err1 &&
> > +		git -c init.defaultBranch=initial init >out1 2>err1 &&
> >  		git init >out2 2>err2
> >  	) &&
> >  	test_i18ngrep "Initialized empty" again/out1 &&
> > @@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' '
> >  	grep nmb actual
> >  '
> >
> > +test_expect_success 'advice on unconfigured init.defaultBranch' '
> > +	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
> > +		init unconfigured-default-branch-name 2>err &&
> > +	test_decode_color <err >decoded &&
> > +	test_i18ngrep "<YELLOW>hint: " decoded
> > +'
> > +
> >  test_expect_success 'overridden default main branch name (env)' '
> >  	test_config_global init.defaultBranch nmb &&
> >  	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
> > diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
> > index 9974457f56..5189a520a2 100755
> > --- a/t/t1510-repo-setup.sh
> > +++ b/t/t1510-repo-setup.sh
> > @@ -79,7 +79,7 @@ setup_repo () {
> >  	name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
> >  	sane_unset GIT_DIR GIT_WORK_TREE &&
> >
> > -	git init "$name" &&
> > +	git -c init.defaultBranch=repo init "$name" &&
> >  	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
> >  	maybe_config "$name/.git/config" core.bare "$barecfg" &&
> >  	mkdir -p "$name/sub/sub" &&
> > diff --git a/t/t7414-submodule-mistakes.sh b/t/t7414-submodule-mistakes.sh
> > index f2e7df59cf..0ed02938f9 100755
> > --- a/t/t7414-submodule-mistakes.sh
> > +++ b/t/t7414-submodule-mistakes.sh
> > @@ -30,7 +30,7 @@ test_expect_success 'no warning when updating entry' '
> >
> >  test_expect_success 'submodule add does not warn' '
> >  	test_when_finished "git rm -rf submodule .gitmodules" &&
> > -	git submodule add ./embed submodule 2>stderr &&
> > +	git -c init.defaultBranch=x submodule add ./embed submodule 2>stderr &&
> >  	test_i18ngrep ! warning stderr
> >  '
> >
> > diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> > index 59bbf75e83..772152320a 100644
> > --- a/t/test-lib-functions.sh
> > +++ b/t/test-lib-functions.sh
> > @@ -1202,7 +1202,8 @@ test_create_repo () {
> >  	mkdir -p "$repo"
> >  	(
> >  		cd "$repo" || error "Cannot setup test environment"
> > -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
> > +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
> > +			-c init.defaultBranch=master 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
>
>
Johannes Schindelin via GitGitGadget· Nov 23, 2020, 23:20 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v2 0/4] Add helpful advice about init.defaultBranch

It is our designated intention [https://sfconservancy.org/news/2020/jun/23/gitbranchname/] to "to explore changing the name of the first branch created automatically for new repositories away from ‘master’". Further, we promised that we "will minimize disruption for Git's users and will include appropriate deprecation periods".

To that end, we first clarify git init's documentation (a lightly edited version of Junio's patch [https://lore.kernel.org/git/xmqqd00a36wc.fsf@gitster.c.googlers.com]), and then introduce a message giving advice to users running git init that the fall-back for init.defaultBranch is subject to change, and how to override Git's fall-back manually.

The beauty of this patch series, if I may say so, is that it does not commit us to any concrete plan, but opens the door for all options regarding the default branch name.

Changes since v1:
 * Grammar fix
 * Reworded advice and commit messages
 * test_create_repo already respected GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME,
   but now does so more obviously
 * Allowed git branch -m <name> to rename unborn branches, so that the
   advice actually works
Johannes Schindelin (4):
  init: document `init.defaultBranch` better
  branch -m: allow renaming a yet-unborn branch
  get_default_branch_name(): prepare for showing some advice
  init: provide useful advice about init.defaultBranch
 Documentation/git-init.txt | 11 +++++++----
 builtin/branch.c           |  3 ++-
 builtin/clone.c            |  2 +-
 builtin/init-db.c          |  8 +++++---
 refs.c                     | 25 +++++++++++++++++++++----
 refs.h                     |  4 ++--
 remote.c                   |  5 +++--
 t/t0001-init.sh            | 15 ++++++++++++++-
 t/t1510-repo-setup.sh      |  2 +-
 t/test-lib-functions.sh    |  3 ++-
 10 files changed, 58 insertions(+), 20 deletions(-)
base-commit: faefdd61ec7c7f6f3c8c9907891465ac9a2a1475
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-921%2Fdscho%2Finit.defaultBranch-advice-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-921/dscho/init.defaultBranch-advice-v2
Pull-Request: https://github.com/git/git/pull/921
Range-diff vs v1:
 1:  1518387eaa ! 1:  483e490349 init: document `init.defaultBranch` better
     @@ Documentation/git-init.txt: If this is reinitialization, the repository will be
      -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 (currently
     -+`master`, but that will be changed in the future; The name can be customized
     ++`master`, but that will be changed in the future; the name can be customized
      +via the `init.defaultBranch` configuration variable).
       
       --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 -:  ---------- > 2:  8de0c0eb22 branch -m: allow renaming a yet-unborn branch
 2:  42f6940043 = 3:  03314f7ac6 get_default_branch_name(): prepare for showing some advice
 3:  253d6706e6 ! 4:  bccef95391 init: provide useful advice about init.defaultBranch
     @@ Metadata
       ## Commit message ##
          init: provide useful advice about init.defaultBranch
      
     -    To give ample warning in case we decide to change the fall-back for an
     -    unconfigured `init.defaultBranch`, let's introduce some advice that is
     -    shown upon `git init` when that value is not set.
     +    To give ample warning for users wishing to override Git's the fall-back
     +    for an unconfigured `init.defaultBranch` (in case we decide to change it
     +    in a future Git version), let's introduce some advice that is shown upon
     +    `git init` when that value is not set.
      
     -    Note: three test cases in Git's test suite want to verify that the
     +    Note: two test cases in Git's test suite want to verify that the
          `stderr` output of `git init` is empty. With this patch, that is only
          true if `init.defaultBranch` is configured, so let's do exactly that in
          those test cases. The same reasoning applies to `test_create_repo()`.
     @@ refs.c: void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
       }
       
      +static const char default_branch_name_advice[] = N_(
     -+"Using '%s' as the name for the initial branch. This name is subject\n"
     -+"to change. To configure the name to use as the initial branch name in\n"
     -+"new repositories, or to silence this warning, run:\n"
     ++"Using '%s' as the name for the initial branch. This default branch name\n"
     ++"is subject to change. To configure the initial branch name to use in all\n"
     ++"of your new repositories, run:\n"
      +"\n"
      +"\tgit config --global init.defaultBranch <name>\n"
     ++"\n"
     ++"Common names are 'main', 'trunk' and 'development'. If you merely wish\n"
     ++"to suppress this warning, you can also use the current default branch\n"
     ++"name. The current branch can be renamed via this command:\n"
     ++"\n"
     ++"\tgit branch -m <name>\n"
      +);
      +
       char *repo_default_branch_name(struct repository *r, int quiet)
     @@ t/t1510-repo-setup.sh: setup_repo () {
       	maybe_config "$name/.git/config" core.bare "$barecfg" &&
       	mkdir -p "$name/sub/sub" &&
      
     - ## t/t7414-submodule-mistakes.sh ##
     -@@ t/t7414-submodule-mistakes.sh: test_expect_success 'no warning when updating entry' '
     - 
     - test_expect_success 'submodule add does not warn' '
     - 	test_when_finished "git rm -rf submodule .gitmodules" &&
     --	git submodule add ./embed submodule 2>stderr &&
     -+	git -c init.defaultBranch=x submodule add ./embed submodule 2>stderr &&
     - 	test_i18ngrep ! warning stderr
     - '
     - 
     -
       ## t/test-lib-functions.sh ##
      @@ t/test-lib-functions.sh: test_create_repo () {
       	mkdir -p "$repo"
     @@ t/test-lib-functions.sh: test_create_repo () {
       		cd "$repo" || error "Cannot setup test environment"
      -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
      +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
     -+			-c init.defaultBranch=master init \
     ++			-c init.defaultBranch=${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master} 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
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 23, 2020, 23:20 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v2 1/4] init: document `init.defaultBranch` better

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

Our documentation does not mention any future plan to change 'master' to other value. It is a good idea to document this, though.

Initial-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-init.txt | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
Show changes to Documentation/git-init.txt +7 −4
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 59ecda6c17..2b399cb73d 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -20,8 +20,9 @@ DESCRIPTION
 
 This command creates an empty Git repository - basically a `.git`
 directory with subdirectories for `objects`, `refs/heads`,
-`refs/tags`, and template files.  An initial `HEAD` file that
-references the HEAD of the master branch is also created.
+`refs/tags`, and template files.  An initial branch without any
+commits will be created (see the `--initial-branch` option below
+for its name).
 
 If the `$GIT_DIR` environment variable is set then it specifies a path
 to use instead of `./.git` for the base of the repository.
@@ -73,8 +74,10 @@ 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`.
+Use the specified name for the initial branch in the newly created
+repository.  If not specified, fall back to the default name (currently
+`master`, but that will be changed in the future; the name can be customized
+via the `init.defaultBranch` configuration variable).
 
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 23, 2020, 23:20 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v2 3/4] get_default_branch_name(): prepare for showing some advice

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

We are about to introduce a message giving users running `git init` some advice about `init.defaultBranch`. This will necessarily be done in `repo_default_branch_name()`.

Not all code paths want to show that advice, though. In particular, the `git clone` codepath _specifically_ asks for `init_db()` to be quiet, via the `INIT_DB_QUIET` flag.

In preparation for showing users above-mentioned advice, let's change the function signature of `get_default_branch_name()` to accept the parameter `quiet`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/clone.c   | 2 +-
 builtin/init-db.c | 8 +++++---
 refs.c            | 6 +++---
 refs.h            | 4 ++--
 remote.c          | 5 +++--
 5 files changed, 14 insertions(+), 11 deletions(-)
Show changes to 5 files +14 −11

builtin/clone.c, builtin/init-db.c, refs.c, refs.h, remote.c

diff --git a/builtin/clone.c b/builtin/clone.c
index a0841923cf..64b1784011 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1323,7 +1323,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare) {
-			const char *branch = git_default_branch_name();
+			const char *branch = git_default_branch_name(0);
 			char *ref = xstrfmt("refs/heads/%s", branch);
 
 			install_branch_config(0, branch, remote_name, ref);
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 01bc648d41..dcc45bef51 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit)
 static int create_default_files(const char *template_path,
 				const char *original_git_dir,
 				const char *initial_branch,
-				const struct repository_format *fmt)
+				const struct repository_format *fmt,
+				int quiet)
 {
 	struct stat st1;
 	struct strbuf buf = STRBUF_INIT;
@@ -267,7 +268,7 @@ static int create_default_files(const char *template_path,
 		char *ref;
 
 		if (!initial_branch)
-			initial_branch = git_default_branch_name();
+			initial_branch = git_default_branch_name(quiet);
 
 		ref = xstrfmt("refs/heads/%s", initial_branch);
 		if (check_refname_format(ref, 0) < 0)
@@ -438,7 +439,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,
-				      initial_branch, &repo_fmt);
+				      initial_branch, &repo_fmt,
+				      flags & INIT_DB_QUIET);
 	if (reinit && initial_branch)
 		warning(_("re-init: ignored --initial-branch=%s"),
 			initial_branch);
diff --git a/refs.c b/refs.c
index 392f0bbf68..8df03122d6 100644
--- a/refs.c
+++ b/refs.c
@@ -562,7 +562,7 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
-char *repo_default_branch_name(struct repository *r)
+char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
 	const char *config_display_key = "init.defaultBranch";
@@ -585,12 +585,12 @@ char *repo_default_branch_name(struct repository *r)
 	return ret;
 }
 
-const char *git_default_branch_name(void)
+const char *git_default_branch_name(int quiet)
 {
 	static char *ret;
 
 	if (!ret)
-		ret = repo_default_branch_name(the_repository);
+		ret = repo_default_branch_name(the_repository, quiet);
 
 	return ret;
 }
diff --git a/refs.h b/refs.h
index 6695518156..ff05d2e9fe 100644
--- a/refs.h
+++ b/refs.h
@@ -170,8 +170,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
  * 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);
+const char *git_default_branch_name(int quiet);
+char *repo_default_branch_name(struct repository *r, int quiet);
 
 /*
  * A ref_transaction represents a collection of reference updates that
diff --git a/remote.c b/remote.c
index 8a6dbbb903..bdb88d4b7d 100644
--- a/remote.c
+++ b/remote.c
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
 	if (frag)
 		*(frag++) = '\0';
 	else
-		frag = (char *)git_default_branch_name();
+		frag = (char *)git_default_branch_name(0);
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
 	refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s",
@@ -2206,7 +2206,8 @@ struct ref *guess_remote_head(const struct ref *head,
 
 	/* 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());
+		char *ref = xstrfmt("refs/heads/%s",
+				    git_default_branch_name(0));
 
 		r = find_ref_by_name(refs, ref);
 		free(ref);
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 23, 2020, 23:20 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v2 2/4] branch -m: allow renaming a yet-unborn branch

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

In one of the next commits, we would like to give users some advice regarding the initial branch name, and how to modify it.

To that end, it would be good if `git branch -m <name>` worked in a freshly initialized repository without any commits. Let's make it so.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/branch.c | 3 ++-
 t/t0001-init.sh  | 6 ++++++
 2 files changed, 8 insertions(+), 1 deletion(-)
Show changes to 2 files +8 −1

builtin/branch.c, t/t0001-init.sh

diff --git a/builtin/branch.c b/builtin/branch.c
index efb30b8820..10609981e6 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -538,7 +538,8 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 		strbuf_addf(&logmsg, "Branch: renamed %s to %s",
 			    oldref.buf, newref.buf);
 
-	if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
+	if (!copy && (oldname != head || !is_null_oid(&head_oid)) &&
+	    rename_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch rename failed"));
 	if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch copy failed"));
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 69a320489f..69c5ad179c 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -571,4 +571,10 @@ test_expect_success 'invalid default branch name' '
 	test_i18ngrep "invalid branch name" err
 '
 
+test_expect_success 'branch -m with the initial branch' '
+	git init rename-initial-branch &&
+	git -C rename-initial-branch branch -m renamed &&
+	test renamed = $(git -C rename-initial-branch symbolic-ref --short HEAD)
+'
+
 test_done
-- 
gitgitgadget
Junio C Hamano· Nov 23, 2020, 23:45 UTC · re: Johannes Schindelin via GitGitGadget · lore

Re: [PATCH v2 2/4] branch -m: allow renaming a yet-unborn branch

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

Show 6 quoted lines
> @@ -538,7 +538,8 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
>  		strbuf_addf(&logmsg, "Branch: renamed %s to %s",
>  			    oldref.buf, newref.buf);
>  
> -	if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
> +	if (!copy && (oldname != head || !is_null_oid(&head_oid)) &&

It always makes readers uneasy to see pointer comparison of two strings.

Does this mean, after "git -c init.defaultbranch=master init",
	git branch -m master main
would not work while
	git branch -m main

would? It would be easy to see with the attached patch to the test, I guess.

Show 19 quoted lines
> +	    rename_ref(oldref.buf, newref.buf, logmsg.buf))
>  		die(_("Branch rename failed"));
>  	if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
>  		die(_("Branch copy failed"));
> diff --git a/t/t0001-init.sh b/t/t0001-init.sh
> index 69a320489f..69c5ad179c 100755
> --- a/t/t0001-init.sh
> +++ b/t/t0001-init.sh
> @@ -571,4 +571,10 @@ test_expect_success 'invalid default branch name' '
>  	test_i18ngrep "invalid branch name" err
>  '
>  
> +test_expect_success 'branch -m with the initial branch' '
> +	git init rename-initial-branch &&
> +	git -C rename-initial-branch branch -m renamed &&
> +	test renamed = $(git -C rename-initial-branch symbolic-ref --short HEAD)
> +'
> +
>  test_done
Thanks.
 t/t0001-init.sh | 6 ++++++
 1 file changed, 6 insertions(+)
Show changes to diff +6 −0
diff --git c/t/t0001-init.sh w/t/t0001-init.sh
index 69c5ad179c..07c34431d9 100755
--- c/t/t0001-init.sh
+++ w/t/t0001-init.sh
@@ -577,4 +577,10 @@ test_expect_success 'branch -m with the initial branch' '
 	test renamed = $(git -C rename-initial-branch symbolic-ref --short HEAD)
 '
 
+test_expect_success 'branch -m with the initial branch' '
+	git -c init.defaultBranch=initial init rename-unborn-branch &&
+	git -C rename-unborn-branch branch -m initial renamed &&
+	test renamed = $(git -C rename-unborn-branch symbolic-ref --short HEAD)
+'
+
 test_done
Johannes Schindelin· Nov 24, 2020, 05:47 UTC · re: Junio C Hamano · lore

Re: [PATCH v2 2/4] branch -m: allow renaming a yet-unborn branch

Hi Junio,
On Mon, 23 Nov 2020, Junio C Hamano wrote:
Show 12 quoted lines
> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > @@ -538,7 +538,8 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
> >  		strbuf_addf(&logmsg, "Branch: renamed %s to %s",
> >  			    oldref.buf, newref.buf);
> >
> > -	if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
> > +	if (!copy && (oldname != head || !is_null_oid(&head_oid)) &&
>
> It always makes readers uneasy to see pointer comparison of two
> strings.
Even if it was on purpose ;-)
Show 10 quoted lines
> Does this mean, after "git -c init.defaultbranch=master init",
>
> 	git branch -m master main
>
> would not work while
>
> 	git branch -m main
>
> would?  It would be easy to see with the attached patch to the test,
> I guess.

At first, I thought that it would be inappropriate to do that because it would not work with unborn branches in a worktree other than the current one. Like,

	git worktree add --no-checkout --detach other
	git -C other switch --orphan start-over-again
	git branch -m start-over-again fresh-new-start

On second thought, that's a really obscure use case, anyway. It is not even possible to create a secondary worktree! I started down that rabbit hole, but think I'd better let it be. This is where I stopped:

-- snip --
Show changes to 2 files +19 −3

builtin/branch.c, t/t0001-init.sh

diff --git a/builtin/branch.c b/builtin/branch.c
index 200da319f1d..c84bffe9632 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -489,6 +489,16 @@ static void reject_rebase_or_bisect_branch(const char *target)
 	free_worktrees(worktrees);
 }

+static int is_unborn_branch(const char *branch_name, const char *full_ref_name)
+{
+	int flags;
+
+	return (head && !strcmp(branch_name, head) && is_null_oid(&head_oid)) ||
+		(!resolve_ref_unsafe(full_ref_name, RESOLVE_REF_READING, NULL,
+				     &flags) &&
+		 find_shared_symref("HEAD", full_ref));
+}
+
 static void copy_or_rename_branch(const char *oldname, const char *newname, int copy, int force)
 {
 	struct strbuf oldref = STRBUF_INIT, newref = STRBUF_INIT, logmsg = STRBUF_INIT;
@@ -538,8 +548,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 		strbuf_addf(&logmsg, "Branch: renamed %s to %s",
 			    oldref.buf, newref.buf);

-	if (!copy &&
-	    (!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) &&
+	if (!copy && !is_unborn_branch(oldname, oldref.buf) &&
 	    rename_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch rename failed"));
 	if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 84047ac64e6..124abeedf19 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -586,4 +586,12 @@ test_expect_success 'branch -m with the initial branch' '
 	test again = $(git -C rename-initial symbolic-ref --short HEAD)
 '

+test_expect_success 'branch -m with the initial branch in another worktree' '
+	git -c init.defaultBranch=initial init rename-two &&
+	test_commit -C rename-two initial &&
+	git -C rename-two worktree add --no-checkout ../rename-worktree &&
+	git -C rename-worktree switch --orphan brand-new-day &&
+	git -C rename-two branch -m brand-new-day renamed
+'
+
 test_done
-- snap --

Having said that, I fixed the `git branch -m <current-unborn> <new-name>`
use case; the fix will be part of v3.

Ciao,
Dscho
Junio C Hamano· Nov 24, 2020, 20:14 UTC · re: Johannes Schindelin · lore

Re: [PATCH v2 2/4] branch -m: allow renaming a yet-unborn branch

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
Show 7 quoted lines
>> > -	if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
>> > +	if (!copy && (oldname != head || !is_null_oid(&head_oid)) &&
>>
>> It always makes readers uneasy to see pointer comparison of two
>> strings.
>
> Even if it was on purpose ;-)

FWIW, for fun I dropped "oldname != head ||" and tried to run the whole testsuite (plus the "branch -m src dst" form test I gave earlier), and it almost passed all of them except one, which was surprising.

> +	if (!copy && !is_unborn_branch(oldname, oldref.buf) &&
>  	    rename_ref(oldref.buf, newref.buf, logmsg.buf))
Yeah, a helper function makes it much more clear what is going on.
> Having said that, I fixed the `git branch -m <current-unborn> <new-name>`
> use case; the fix will be part of v3.
;-)
Johannes Schindelin via GitGitGadget· Nov 23, 2020, 23:20 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v2 4/4] init: provide useful advice about init.defaultBranch

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

To give ample warning for users wishing to override Git's the fall-back for an unconfigured `init.defaultBranch` (in case we decide to change it in a future Git version), let's introduce some advice that is shown upon `git init` when that value is not set.

Note: two test cases in Git's test suite want to verify that the
`stderr` output of `git init` is empty. With this patch, that is only
true if `init.defaultBranch` is configured, so let's do exactly that in
those test cases. The same reasoning applies to `test_create_repo()`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 refs.c                  | 19 ++++++++++++++++++-
 t/t0001-init.sh         |  9 ++++++++-
 t/t1510-repo-setup.sh   |  2 +-
 t/test-lib-functions.sh |  3 ++-
 4 files changed, 29 insertions(+), 4 deletions(-)
Show changes to 4 files +29 −4

refs.c, t/t0001-init.sh, t/t1510-repo-setup.sh, t/test-lib-functions.sh

diff --git a/refs.c b/refs.c
index 8df03122d6..67275858fc 100644
--- a/refs.c
+++ b/refs.c
@@ -562,6 +562,20 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
+static const char default_branch_name_advice[] = N_(
+"Using '%s' as the name for the initial branch. This default branch name\n"
+"is subject to change. To configure the initial branch name to use in all\n"
+"of your new repositories, run:\n"
+"\n"
+"\tgit config --global init.defaultBranch <name>\n"
+"\n"
+"Common names are 'main', 'trunk' and 'development'. If you merely wish\n"
+"to suppress this warning, you can also use the current default branch\n"
+"name. The current branch can be renamed via this command:\n"
+"\n"
+"\tgit branch -m <name>\n"
+);
+
 char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
@@ -574,8 +588,11 @@ char *repo_default_branch_name(struct repository *r, int quiet)
 	else if (repo_config_get_string(r, config_key, &ret) < 0)
 		die(_("could not retrieve `%s`"), config_display_key);
 
-	if (!ret)
+	if (!ret) {
 		ret = xstrdup("master");
+		if (!quiet)
+			advise(_(default_branch_name_advice), ret);
+	}
 
 	full_ref = xstrfmt("refs/heads/%s", ret);
 	if (check_refname_format(full_ref, 0))
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 69c5ad179c..6f693d9609 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -163,7 +163,7 @@ test_expect_success 'reinit' '
 	(
 		mkdir again &&
 		cd again &&
-		git init >out1 2>err1 &&
+		git -c init.defaultBranch=initial init >out1 2>err1 &&
 		git init >out2 2>err2
 	) &&
 	test_i18ngrep "Initialized empty" again/out1 &&
@@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' '
 	grep nmb actual
 '
 
+test_expect_success 'advice on unconfigured init.defaultBranch' '
+	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
+		init unconfigured-default-branch-name 2>err &&
+	test_decode_color <err >decoded &&
+	test_i18ngrep "<YELLOW>hint: " decoded
+'
+
 test_expect_success 'overridden default main branch name (env)' '
 	test_config_global init.defaultBranch nmb &&
 	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 9974457f56..5189a520a2 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -79,7 +79,7 @@ setup_repo () {
 	name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
 	sane_unset GIT_DIR GIT_WORK_TREE &&
 
-	git init "$name" &&
+	git -c init.defaultBranch=repo init "$name" &&
 	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
 	maybe_config "$name/.git/config" core.bare "$barecfg" &&
 	mkdir -p "$name/sub/sub" &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 59bbf75e83..68305a4939 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1202,7 +1202,8 @@ test_create_repo () {
 	mkdir -p "$repo"
 	(
 		cd "$repo" || error "Cannot setup test environment"
-		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
+		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
+			-c init.defaultBranch=${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master} 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
-- 
gitgitgadget
Junio C Hamano· Nov 23, 2020, 23:53 UTC · re: Johannes Schindelin via GitGitGadget · lore

Re: [PATCH v2 4/4] init: provide useful advice about init.defaultBranch

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

> +static const char default_branch_name_advice[] = N_(
> +"Using '%s' as the name for the initial branch. This default branch name\n"
> +"is subject to change. To configure the initial branch name to use in all\n"
> +"of your new repositories, run:\n"

I think this is good, assuming that "subject to change" covers the case where we end up doing nothing after all. I'd feel safer if we said "s/is subject to change/may change in the future/", but this is not a strong preference.

Show 6 quoted lines
> +"\n"
> +"\tgit config --global init.defaultBranch <name>\n"
> +"\n"
> +"Common names are 'main', 'trunk' and 'development'. If you merely wish\n"
> +"to suppress this warning, you can also use the current default branch\n"
> +"name. The current branch can be renamed via this command:\n"

I think this is worse than the previous one. Those who merely wish to suppress the message without wanting to commit to a particular name (i.e. they just want to take whatever the default we give them) would be mislead and be frozen in time forever. We do not give "I'll just accept the default of the day" choice, and that is OK, but we want to be clear about it, which is why I've kept raising this as an issue.

    To configure the initial branch name to use in all of your new
    repositories and squelch this message, run:

may be better---it makes it clear that the offered two choices are (1) do nothing and see this message every time, or (2) commit to a name and not see this message again.

Thanks.
Johannes Schindelin· Nov 24, 2020, 05:57 UTC · re: Junio C Hamano · lore

Re: [PATCH v2 4/4] init: provide useful advice about init.defaultBranch

Hi Junio,
On Mon, 23 Nov 2020, Junio C Hamano wrote:
Show 12 quoted lines
> "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
> writes:
>
> > +static const char default_branch_name_advice[] = N_(
> > +"Using '%s' as the name for the initial branch. This default branch name\n"
> > +"is subject to change. To configure the initial branch name to use in all\n"
> > +"of your new repositories, run:\n"
>
> I think this is good, assuming that "subject to change" covers the
> case where we end up doing nothing after all.  I'd feel safer if we
> said "s/is subject to change/may change in the future/", but this is
> not a strong preference.
I'd rather keep the current form, as it sounds a bit more firm to me.
Show 21 quoted lines
> > +"\n"
> > +"\tgit config --global init.defaultBranch <name>\n"
> > +"\n"
> > +"Common names are 'main', 'trunk' and 'development'. If you merely wish\n"
> > +"to suppress this warning, you can also use the current default branch\n"
> > +"name. The current branch can be renamed via this command:\n"
>
> I think this is worse than the previous one.  Those who merely wish
> to suppress the message without wanting to commit to a particular
> name (i.e. they just want to take whatever the default we give them)
> would be mislead and be frozen in time forever.  We do not give
> "I'll just accept the default of the day" choice, and that is OK,
> but we want to be clear about it, which is why I've kept raising this
> as an issue.
>
>     To configure the initial branch name to use in all of your new
>     repositories and squelch this message, run:
>
> may be better---it makes it clear that the offered two choices are
> (1) do nothing and see this message every time, or (2) commit to a
> name and not see this message again.

Well, I think I finally understand what you are saying: there is a legitimate need for a way to go with Git's preference but still suppress that message.

I introduced `advice.defaultBranchName` to that end, and now display prominently, at the top of the message, how to use that flag to avoid seeing this advice ever again.

Ciao, Dscho

Junio C Hamano· Nov 24, 2020, 20:53 UTC · re: Johannes Schindelin · lore

Re: [PATCH v2 4/4] init: provide useful advice about init.defaultBranch

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
Show 10 quoted lines
>>     To configure the initial branch name to use in all of your new
>>     repositories and squelch this message, run:
>>
>> may be better---it makes it clear that the offered two choices are
>> (1) do nothing and see this message every time, or (2) commit to a
>> name and not see this message again.
>
> Well, I think I finally understand what you are saying: there is a
> legitimate need for a way to go with Git's preference but still suppress
> that message.

I am not saying it is a legitimate need. I just wanted to make it clear that we deliberately chose not to grant that wish in the message. An advice flag in this context means that the users can choose to let their distro and sysadm to flip the default silently, which is much worse than having to see the message every time they start a new repository with "git init".

Johannes Schindelin· Dec 9, 2020, 14:47 UTC · re: Junio C Hamano · lore

Re: [PATCH v2 4/4] init: provide useful advice about init.defaultBranch

Hi Junio,
On Tue, 24 Nov 2020, Junio C Hamano wrote:
Show 19 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> >>     To configure the initial branch name to use in all of your new
> >>     repositories and squelch this message, run:
> >>
> >> may be better---it makes it clear that the offered two choices are
> >> (1) do nothing and see this message every time, or (2) commit to a
> >> name and not see this message again.
> >
> > Well, I think I finally understand what you are saying: there is a
> > legitimate need for a way to go with Git's preference but still suppress
> > that message.
>
> I am not saying it is a legitimate need.  I just wanted to make it
> clear that we deliberately chose not to grant that wish in the
> message.  An advice flag in this context means that the users can
> choose to let their distro and sysadm to flip the default silently,
> which is much worse than having to see the message every time they
> start a new repository with "git init".

The distribution already can add patches, so this objection is a red herring. The sysadm can pick a different value for `init.defaultBranch` and dictate to the user silently what initial branch name to use, so that is also a red herring.

I still think that there is a legitimate need for this config option to turn the advice off, without having to override Git's default branch name.

In particular in this context, I would think that most users will want to just go with whatever is Git's default.

Ciao, Dscho

Junio C Hamano· Dec 9, 2020, 22:15 UTC · re: Johannes Schindelin · lore

Re: [PATCH v2 4/4] init: provide useful advice about init.defaultBranch

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
Show 13 quoted lines
> On Tue, 24 Nov 2020, Junio C Hamano wrote:
>
>> I am not saying it is a legitimate need.  I just wanted to make it
>> clear that we deliberately chose not to grant that wish in the
>> message.  An advice flag in this context means that the users can
>> choose to let their distro and sysadm to flip the default silently,
>> which is much worse than having to see the message every time they
>> start a new repository with "git init".
>
> The distribution already can add patches, so this objection is a red
> herring. The sysadm can pick a different value for `init.defaultBranch`
> and dictate to the user silently what initial branch name to use, so that
> is also a red herring.

The "setting init.defaultBranch is the only way to squelch" approach means the ~/.gitconfig will have the settings soon after the user starts using Git and /etc/gitconfig will not allow administrators to force their will over what the user decides to use. Distros adding patches to strip configurability by setting init.defaultBranch in user's ~/.gitconfig? Is that the kind of possibilities worth discussing?

So, no, your counter-argument above is nothing but a red-herring.

If you want a counter-argument, please explain why "I am fine to see the default flipped to whatever the tool picks and having no control over when the flipping happens" can be a sensible choice for users with what kind of workflows. The only folks I can think of who would be fine with that are (1) those who do not create the second branch in the repository and will stay on the primary branch forever, and (2) those who immediately rename the branch to what they want after "git init". For other folks, such a choice is a disaster waiting to happen, and it just feels irresponsible to offer such a choice, at least to me.

Thanks.
Johannes Schindelin· Dec 10, 2020, 12:12 UTC · re: Junio C Hamano · lore

Re: [PATCH v2 4/4] init: provide useful advice about init.defaultBranch

Hi Junio,
On Wed, 9 Dec 2020, Junio C Hamano wrote:
Show 36 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> > On Tue, 24 Nov 2020, Junio C Hamano wrote:
> >
> >> I am not saying it is a legitimate need.  I just wanted to make it
> >> clear that we deliberately chose not to grant that wish in the
> >> message.  An advice flag in this context means that the users can
> >> choose to let their distro and sysadm to flip the default silently,
> >> which is much worse than having to see the message every time they
> >> start a new repository with "git init".
> >
> > The distribution already can add patches, so this objection is a red
> > herring. The sysadm can pick a different value for `init.defaultBranch`
> > and dictate to the user silently what initial branch name to use, so that
> > is also a red herring.
>
> The "setting init.defaultBranch is the only way to squelch" approach
> means the ~/.gitconfig will have the settings soon after the user
> starts using Git and /etc/gitconfig will not allow administrators to
> force their will over what the user decides to use.  Distros adding
> patches to strip configurability by setting init.defaultBranch in
> user's ~/.gitconfig?  Is that the kind of possibilities worth
> discussing?
>
> So, no, your counter-argument above is nothing but a red-herring.
>
> If you want a counter-argument, please explain why "I am fine to see
> the default flipped to whatever the tool picks and having no control
> over when the flipping happens" can be a sensible choice for users
> with what kind of workflows.  The only folks I can think of who
> would be fine with that are (1) those who do not create the second
> branch in the repository and will stay on the primary branch
> forever, and (2) those who immediately rename the branch to what
> they want after "git init".  For other folks, such a choice is a
> disaster waiting to happen, and it just feels irresponsible to offer
> such a choice, at least to me.
I'll make this short.

I talked to a couple Git users whether they'd be fine if `git init` used a different branch name by default, and everybody I asked said essentially "yeah, whatever, I don't really care".

For that reason, Git for Windows' installer has that option, and will keep offering it.

Ciao, Dscho

Junio C Hamano· Dec 10, 2020, 23:32 UTC · re: Johannes Schindelin · lore

Re: [PATCH v2 4/4] init: provide useful advice about init.defaultBranch

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> I talked to a couple Git users whether they'd be fine if `git init` used a
> different branch name by default, and everybody I asked said essentially
> "yeah, whatever, I don't really care".

Yeah, I would expect that, too. They would not have asked about the details on when that switchover of the default would happen, and would not have been told that the timing is not under their control. I would answer to such a question with "yeah, whatever." that does not give you an assurance that I won't complain when the switchover actually happens ;-).

Felipe Contreras· Dec 10, 2020, 00:40 UTC · re: Johannes Schindelin · lore

Re: [PATCH v2 4/4] init: provide useful advice about init.defaultBranch

On Wed, Dec 9, 2020 at 5:24 PM Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

> On Tue, 24 Nov 2020, Junio C Hamano wrote:
> The distribution already can add patches, so this objection is a red
> herring. The sysadm can pick a different value for `init.defaultBranch`
> and dictate to the user silently what initial branch name to use, so that
> is also a red herring.

Yes, but if they do; they have picked the ball. The user would blame them--and not Git--for any unexpected change in behavior.

Cheers.
-- 
Felipe Contreras
Johannes Schindelin via GitGitGadget· Nov 24, 2020, 15:07 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v3 0/4] Add helpful advice about init.defaultBranch

It is our designated intention [https://sfconservancy.org/news/2020/jun/23/gitbranchname/] to "to explore changing the name of the first branch created automatically for new repositories away from ‘master’". Further, we promised that we "will minimize disruption for Git's users and will include appropriate deprecation periods".

To that end, we first clarify git init's documentation (a lightly edited version of Junio's patch [https://lore.kernel.org/git/xmqqd00a36wc.fsf@gitster.c.googlers.com]), and then introduce a message giving advice to users running git init that the fall-back for init.defaultBranch is subject to change, and how to override Git's fall-back manually.

The beauty of this patch series, if I may say so, is that it does not commit us to any concrete plan, but opens the door for all options regarding the default branch name.

Changes since v2:
 * git branch -m <initial> <renamed> now works, too
 * The config setting advice.defaultBranchName was introduced to allow
   suppressing this warning specifically
 * The advice now first talks about the current default branch name, then
   how to suppress the advice, and only then explains how to override the
   default branch name (and that that will also prevent the message from
   being shown)
Changes since v1:
 * Grammar fix
 * Reworded advice and commit messages
 * test_create_repo already respected GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME,
   but now does so more obviously
 * Allowed git branch -m <name> to rename unborn branches, so that the
   advice actually works
Johannes Schindelin (4):
  init: document `init.defaultBranch` better
  branch -m: allow renaming a yet-unborn branch
  get_default_branch_name(): prepare for showing some advice
  init: provide useful advice about init.defaultBranch
 Documentation/git-init.txt | 11 +++++++----
 advice.c                   |  1 +
 advice.h                   |  1 +
 builtin/branch.c           |  4 +++-
 builtin/clone.c            |  2 +-
 builtin/init-db.c          |  8 +++++---
 refs.c                     | 29 +++++++++++++++++++++++++----
 refs.h                     |  4 ++--
 remote.c                   |  5 +++--
 t/t0001-init.sh            | 17 ++++++++++++++++-
 t/t1510-repo-setup.sh      |  2 +-
 t/test-lib-functions.sh    |  3 ++-
 12 files changed, 67 insertions(+), 20 deletions(-)
base-commit: faefdd61ec7c7f6f3c8c9907891465ac9a2a1475
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-921%2Fdscho%2Finit.defaultBranch-advice-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-921/dscho/init.defaultBranch-advice-v3
Pull-Request: https://github.com/git/git/pull/921
Range-diff vs v2:
 1:  483e490349 = 1:  483e490349 init: document `init.defaultBranch` better
 2:  8de0c0eb22 ! 2:  6cbd6692c6 branch -m: allow renaming a yet-unborn branch
     @@ builtin/branch.c: static void copy_or_rename_branch(const char *oldname, const c
       			    oldref.buf, newref.buf);
       
      -	if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
     -+	if (!copy && (oldname != head || !is_null_oid(&head_oid)) &&
     ++	if (!copy &&
     ++	    (!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) &&
      +	    rename_ref(oldref.buf, newref.buf, logmsg.buf))
       		die(_("Branch rename failed"));
       	if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
     @@ t/t0001-init.sh: test_expect_success 'invalid default branch name' '
       '
       
      +test_expect_success 'branch -m with the initial branch' '
     -+	git init rename-initial-branch &&
     -+	git -C rename-initial-branch branch -m renamed &&
     -+	test renamed = $(git -C rename-initial-branch symbolic-ref --short HEAD)
     ++	git init rename-initial &&
     ++	git -C rename-initial branch -m renamed &&
     ++	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
     ++	git -C rename-initial branch -m renamed again &&
     ++	test again = $(git -C rename-initial symbolic-ref --short HEAD)
      +'
      +
       test_done
 3:  03314f7ac6 = 3:  5fc15f7b9a get_default_branch_name(): prepare for showing some advice
 4:  bccef95391 ! 4:  87c9306877 init: provide useful advice about init.defaultBranch
     @@ Commit message
          `git init` when that value is not set.
      
          Note: two test cases in Git's test suite want to verify that the
     -    `stderr` output of `git init` is empty. With this patch, that is only
     -    true if `init.defaultBranch` is configured, so let's do exactly that in
     -    those test cases. The same reasoning applies to `test_create_repo()`.
     +    `stderr` output of `git init` is empty. It is now necessary to suppress
     +    the advice using the newly-added `advice.defaultBranchName` setting.
     +    While not strictly necessary, we also set this to `false` in
     +    `test_create_repo()`.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     + ## advice.c ##
     +@@ advice.c: static struct {
     + 	[ADVICE_AM_WORK_DIR] 				= { "amWorkDir", 1 },
     + 	[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] 	= { "checkoutAmbiguousRemoteBranchName", 1 },
     + 	[ADVICE_COMMIT_BEFORE_MERGE]			= { "commitBeforeMerge", 1 },
     ++	[ADVICE_DEFAULT_BRANCH_NAME]			= { "defaultBranchName", 1 },
     + 	[ADVICE_DETACHED_HEAD]				= { "detachedHead", 1 },
     + 	[ADVICE_FETCH_SHOW_FORCED_UPDATES]		= { "fetchShowForcedUpdates", 1 },
     + 	[ADVICE_GRAFT_FILE_DEPRECATED]			= { "graftFileDeprecated", 1 },
     +
     + ## advice.h ##
     +@@ advice.h: extern int advice_add_empty_pathspec;
     + 	ADVICE_AM_WORK_DIR,
     + 	ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME,
     + 	ADVICE_COMMIT_BEFORE_MERGE,
     ++	ADVICE_DEFAULT_BRANCH_NAME,
     + 	ADVICE_DETACHED_HEAD,
     + 	ADVICE_FETCH_SHOW_FORCED_UPDATES,
     + 	ADVICE_GRAFT_FILE_DEPRECATED,
     +
       ## refs.c ##
     +@@
     + #include "strvec.h"
     + #include "repository.h"
     + #include "sigchain.h"
     ++#include "advice.h"
     + 
     + /*
     +  * List of all available backends
      @@ refs.c: void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
       		strvec_pushf(prefixes, *p, len, prefix);
       }
       
      +static const char default_branch_name_advice[] = N_(
      +"Using '%s' as the name for the initial branch. This default branch name\n"
     -+"is subject to change. To configure the initial branch name to use in all\n"
     -+"of your new repositories, run:\n"
     ++"is subject to change. To suppress this warning, run:\n"
     ++"\n"
     ++"\tgit config --global advice.defaultBranchName false\n"
     ++"\n"
     ++"Alternatively, you can configure the initial branch name to use in all\n"
     ++"of your new repositories, which will also suppress this warning:\n"
      +"\n"
      +"\tgit config --global init.defaultBranch <name>\n"
      +"\n"
     -+"Common names are 'main', 'trunk' and 'development'. If you merely wish\n"
     -+"to suppress this warning, you can also use the current default branch\n"
     -+"name. The current branch can be renamed via this command:\n"
     ++"Common names are 'main', 'trunk' and 'development'. The initial branch\n"
     ++"that was created can be renamed via this command:\n"
      +"\n"
      +"\tgit branch -m <name>\n"
      +);
     @@ refs.c: char *repo_default_branch_name(struct repository *r, int quiet)
      -	if (!ret)
      +	if (!ret) {
       		ret = xstrdup("master");
     -+		if (!quiet)
     ++		if (!quiet && advice_enabled(ADVICE_DEFAULT_BRANCH_NAME))
      +			advise(_(default_branch_name_advice), ret);
      +	}
       
     @@ t/t0001-init.sh: test_expect_success 'reinit' '
       		mkdir again &&
       		cd again &&
      -		git init >out1 2>err1 &&
     -+		git -c init.defaultBranch=initial init >out1 2>err1 &&
     ++		git -c advice.defaultBranchName=false init >out1 2>err1 &&
       		git init >out2 2>err2
       	) &&
       	test_i18ngrep "Initialized empty" again/out1 &&
     @@ t/t1510-repo-setup.sh: setup_repo () {
       	sane_unset GIT_DIR GIT_WORK_TREE &&
       
      -	git init "$name" &&
     -+	git -c init.defaultBranch=repo init "$name" &&
     ++	git -c advice.defaultBranchName=false init "$name" &&
       	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
       	maybe_config "$name/.git/config" core.bare "$barecfg" &&
       	mkdir -p "$name/sub/sub" &&
     @@ t/test-lib-functions.sh: test_create_repo () {
       		cd "$repo" || error "Cannot setup test environment"
      -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
      +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
     -+			-c init.defaultBranch=${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master} init \
     ++			-c advice.defaultBranchName=false 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
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 24, 2020, 15:07 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v3 1/4] init: document `init.defaultBranch` better

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

Our documentation does not mention any future plan to change 'master' to other value. It is a good idea to document this, though.

Initial-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-init.txt | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
Show changes to Documentation/git-init.txt +7 −4
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 59ecda6c17..2b399cb73d 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -20,8 +20,9 @@ DESCRIPTION
 
 This command creates an empty Git repository - basically a `.git`
 directory with subdirectories for `objects`, `refs/heads`,
-`refs/tags`, and template files.  An initial `HEAD` file that
-references the HEAD of the master branch is also created.
+`refs/tags`, and template files.  An initial branch without any
+commits will be created (see the `--initial-branch` option below
+for its name).
 
 If the `$GIT_DIR` environment variable is set then it specifies a path
 to use instead of `./.git` for the base of the repository.
@@ -73,8 +74,10 @@ 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`.
+Use the specified name for the initial branch in the newly created
+repository.  If not specified, fall back to the default name (currently
+`master`, but that will be changed in the future; the name can be customized
+via the `init.defaultBranch` configuration variable).
 
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 24, 2020, 15:07 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v3 4/4] init: provide useful advice about init.defaultBranch

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

To give ample warning for users wishing to override Git's the fall-back for an unconfigured `init.defaultBranch` (in case we decide to change it in a future Git version), let's introduce some advice that is shown upon `git init` when that value is not set.

Note: two test cases in Git's test suite want to verify that the
`stderr` output of `git init` is empty. It is now necessary to suppress
the advice using the newly-added `advice.defaultBranchName` setting.
While not strictly necessary, we also set this to `false` in
`test_create_repo()`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 advice.c                |  1 +
 advice.h                |  1 +
 refs.c                  | 23 ++++++++++++++++++++++-
 t/t0001-init.sh         |  9 ++++++++-
 t/t1510-repo-setup.sh   |  2 +-
 t/test-lib-functions.sh |  3 ++-
 6 files changed, 35 insertions(+), 4 deletions(-)
Show changes to 6 files +35 −4

advice.c, advice.h, refs.c, t/t0001-init.sh, t/t1510-repo-setup.sh, t/test-lib-functions.sh

diff --git a/advice.c b/advice.c
index 164742305f..8a14640193 100644
--- a/advice.c
+++ b/advice.c
@@ -108,6 +108,7 @@ static struct {
 	[ADVICE_AM_WORK_DIR] 				= { "amWorkDir", 1 },
 	[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] 	= { "checkoutAmbiguousRemoteBranchName", 1 },
 	[ADVICE_COMMIT_BEFORE_MERGE]			= { "commitBeforeMerge", 1 },
+	[ADVICE_DEFAULT_BRANCH_NAME]			= { "defaultBranchName", 1 },
 	[ADVICE_DETACHED_HEAD]				= { "detachedHead", 1 },
 	[ADVICE_FETCH_SHOW_FORCED_UPDATES]		= { "fetchShowForcedUpdates", 1 },
 	[ADVICE_GRAFT_FILE_DEPRECATED]			= { "graftFileDeprecated", 1 },
diff --git a/advice.h b/advice.h
index bc2432980a..1ae99a1b31 100644
--- a/advice.h
+++ b/advice.h
@@ -46,6 +46,7 @@ extern int advice_add_empty_pathspec;
 	ADVICE_AM_WORK_DIR,
 	ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME,
 	ADVICE_COMMIT_BEFORE_MERGE,
+	ADVICE_DEFAULT_BRANCH_NAME,
 	ADVICE_DETACHED_HEAD,
 	ADVICE_FETCH_SHOW_FORCED_UPDATES,
 	ADVICE_GRAFT_FILE_DEPRECATED,
diff --git a/refs.c b/refs.c
index 8df03122d6..c56bc1bcfb 100644
--- a/refs.c
+++ b/refs.c
@@ -18,6 +18,7 @@
 #include "strvec.h"
 #include "repository.h"
 #include "sigchain.h"
+#include "advice.h"
 
 /*
  * List of all available backends
@@ -562,6 +563,23 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
+static const char default_branch_name_advice[] = N_(
+"Using '%s' as the name for the initial branch. This default branch name\n"
+"is subject to change. To suppress this warning, run:\n"
+"\n"
+"\tgit config --global advice.defaultBranchName false\n"
+"\n"
+"Alternatively, you can configure the initial branch name to use in all\n"
+"of your new repositories, which will also suppress this warning:\n"
+"\n"
+"\tgit config --global init.defaultBranch <name>\n"
+"\n"
+"Common names are 'main', 'trunk' and 'development'. The initial branch\n"
+"that was created can be renamed via this command:\n"
+"\n"
+"\tgit branch -m <name>\n"
+);
+
 char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
@@ -574,8 +592,11 @@ char *repo_default_branch_name(struct repository *r, int quiet)
 	else if (repo_config_get_string(r, config_key, &ret) < 0)
 		die(_("could not retrieve `%s`"), config_display_key);
 
-	if (!ret)
+	if (!ret) {
 		ret = xstrdup("master");
+		if (!quiet && advice_enabled(ADVICE_DEFAULT_BRANCH_NAME))
+			advise(_(default_branch_name_advice), ret);
+	}
 
 	full_ref = xstrfmt("refs/heads/%s", ret);
 	if (check_refname_format(full_ref, 0))
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index bb23e56a16..84047ac64e 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -163,7 +163,7 @@ test_expect_success 'reinit' '
 	(
 		mkdir again &&
 		cd again &&
-		git init >out1 2>err1 &&
+		git -c advice.defaultBranchName=false init >out1 2>err1 &&
 		git init >out2 2>err2
 	) &&
 	test_i18ngrep "Initialized empty" again/out1 &&
@@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' '
 	grep nmb actual
 '
 
+test_expect_success 'advice on unconfigured init.defaultBranch' '
+	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
+		init unconfigured-default-branch-name 2>err &&
+	test_decode_color <err >decoded &&
+	test_i18ngrep "<YELLOW>hint: " decoded
+'
+
 test_expect_success 'overridden default main branch name (env)' '
 	test_config_global init.defaultBranch nmb &&
 	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 9974457f56..5305566167 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -79,7 +79,7 @@ setup_repo () {
 	name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
 	sane_unset GIT_DIR GIT_WORK_TREE &&
 
-	git init "$name" &&
+	git -c advice.defaultBranchName=false init "$name" &&
 	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
 	maybe_config "$name/.git/config" core.bare "$barecfg" &&
 	mkdir -p "$name/sub/sub" &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 59bbf75e83..781d47a4bb 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1202,7 +1202,8 @@ test_create_repo () {
 	mkdir -p "$repo"
 	(
 		cd "$repo" || error "Cannot setup test environment"
-		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
+		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
+			-c advice.defaultBranchName=false 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
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 24, 2020, 15:07 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v3 2/4] branch -m: allow renaming a yet-unborn branch

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

In one of the next commits, we would like to give users some advice regarding the initial branch name, and how to modify it.

To that end, it would be good if `git branch -m <name>` worked in a freshly initialized repository without any commits. Let's make it so.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/branch.c | 4 +++-
 t/t0001-init.sh  | 8 ++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
Show changes to 2 files +11 −1

builtin/branch.c, t/t0001-init.sh

diff --git a/builtin/branch.c b/builtin/branch.c
index efb30b8820..200da319f1 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -538,7 +538,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 		strbuf_addf(&logmsg, "Branch: renamed %s to %s",
 			    oldref.buf, newref.buf);
 
-	if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
+	if (!copy &&
+	    (!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) &&
+	    rename_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch rename failed"));
 	if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch copy failed"));
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 69a320489f..bb23e56a16 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -571,4 +571,12 @@ test_expect_success 'invalid default branch name' '
 	test_i18ngrep "invalid branch name" err
 '
 
+test_expect_success 'branch -m with the initial branch' '
+	git init rename-initial &&
+	git -C rename-initial branch -m renamed &&
+	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
+	git -C rename-initial branch -m renamed again &&
+	test again = $(git -C rename-initial symbolic-ref --short HEAD)
+'
+
 test_done
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Nov 24, 2020, 15:07 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v3 3/4] get_default_branch_name(): prepare for showing some advice

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

We are about to introduce a message giving users running `git init` some advice about `init.defaultBranch`. This will necessarily be done in `repo_default_branch_name()`.

Not all code paths want to show that advice, though. In particular, the `git clone` codepath _specifically_ asks for `init_db()` to be quiet, via the `INIT_DB_QUIET` flag.

In preparation for showing users above-mentioned advice, let's change the function signature of `get_default_branch_name()` to accept the parameter `quiet`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/clone.c   | 2 +-
 builtin/init-db.c | 8 +++++---
 refs.c            | 6 +++---
 refs.h            | 4 ++--
 remote.c          | 5 +++--
 5 files changed, 14 insertions(+), 11 deletions(-)
Show changes to 5 files +14 −11

builtin/clone.c, builtin/init-db.c, refs.c, refs.h, remote.c

diff --git a/builtin/clone.c b/builtin/clone.c
index a0841923cf..64b1784011 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1323,7 +1323,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare) {
-			const char *branch = git_default_branch_name();
+			const char *branch = git_default_branch_name(0);
 			char *ref = xstrfmt("refs/heads/%s", branch);
 
 			install_branch_config(0, branch, remote_name, ref);
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 01bc648d41..dcc45bef51 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit)
 static int create_default_files(const char *template_path,
 				const char *original_git_dir,
 				const char *initial_branch,
-				const struct repository_format *fmt)
+				const struct repository_format *fmt,
+				int quiet)
 {
 	struct stat st1;
 	struct strbuf buf = STRBUF_INIT;
@@ -267,7 +268,7 @@ static int create_default_files(const char *template_path,
 		char *ref;
 
 		if (!initial_branch)
-			initial_branch = git_default_branch_name();
+			initial_branch = git_default_branch_name(quiet);
 
 		ref = xstrfmt("refs/heads/%s", initial_branch);
 		if (check_refname_format(ref, 0) < 0)
@@ -438,7 +439,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,
-				      initial_branch, &repo_fmt);
+				      initial_branch, &repo_fmt,
+				      flags & INIT_DB_QUIET);
 	if (reinit && initial_branch)
 		warning(_("re-init: ignored --initial-branch=%s"),
 			initial_branch);
diff --git a/refs.c b/refs.c
index 392f0bbf68..8df03122d6 100644
--- a/refs.c
+++ b/refs.c
@@ -562,7 +562,7 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
-char *repo_default_branch_name(struct repository *r)
+char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
 	const char *config_display_key = "init.defaultBranch";
@@ -585,12 +585,12 @@ char *repo_default_branch_name(struct repository *r)
 	return ret;
 }
 
-const char *git_default_branch_name(void)
+const char *git_default_branch_name(int quiet)
 {
 	static char *ret;
 
 	if (!ret)
-		ret = repo_default_branch_name(the_repository);
+		ret = repo_default_branch_name(the_repository, quiet);
 
 	return ret;
 }
diff --git a/refs.h b/refs.h
index 6695518156..ff05d2e9fe 100644
--- a/refs.h
+++ b/refs.h
@@ -170,8 +170,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
  * 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);
+const char *git_default_branch_name(int quiet);
+char *repo_default_branch_name(struct repository *r, int quiet);
 
 /*
  * A ref_transaction represents a collection of reference updates that
diff --git a/remote.c b/remote.c
index 8a6dbbb903..bdb88d4b7d 100644
--- a/remote.c
+++ b/remote.c
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
 	if (frag)
 		*(frag++) = '\0';
 	else
-		frag = (char *)git_default_branch_name();
+		frag = (char *)git_default_branch_name(0);
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
 	refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s",
@@ -2206,7 +2206,8 @@ struct ref *guess_remote_head(const struct ref *head,
 
 	/* 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());
+		char *ref = xstrfmt("refs/heads/%s",
+				    git_default_branch_name(0));
 
 		r = find_ref_by_name(refs, ref);
 		free(ref);
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Dec 10, 2020, 21:58 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v4 0/4] Add helpful advice about init.defaultBranch

It is our designated intention [https://sfconservancy.org/news/2020/jun/23/gitbranchname/] to "to explore changing the name of the first branch created automatically for new repositories away from ‘master’". Further, we promised that we "will minimize disruption for Git's users and will include appropriate deprecation periods".

To that end, we first clarify git init's documentation (a lightly edited version of Junio's patch [https://lore.kernel.org/git/xmqqd00a36wc.fsf@gitster.c.googlers.com]), and then introduce a message giving advice to users running git init that the fall-back for init.defaultBranch is subject to change, and how to override Git's fall-back manually.

The beauty of this patch series, if I may say so, is that it does not commit us to any concrete plan, but opens the door for all options regarding the default branch name.

Changes since v3:
 * Kicked out advice.defaultBranchName again. The advice can now only be
   suppressed by setting init.defaultBranch.
Changes since v2:
 * git branch -m <initial> <renamed> now works, too
 * The config setting advice.defaultBranchName was introduced to allow
   suppressing this warning specifically
 * The advice now first talks about the current default branch name, then
   how to suppress the advice, and only then explains how to override the
   default branch name (and that that will also prevent the message from
   being shown)
Changes since v1:
 * Grammar fix
 * Reworded advice and commit messages
 * test_create_repo already respected GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME,
   but now does so more obviously
 * Allowed git branch -m <name> to rename unborn branches, so that the
   advice actually works
Johannes Schindelin (4):
  init: document `init.defaultBranch` better
  branch -m: allow renaming a yet-unborn branch
  get_default_branch_name(): prepare for showing some advice
  init: provide useful advice about init.defaultBranch
 Documentation/git-init.txt | 11 +++++++----
 builtin/branch.c           |  4 +++-
 builtin/clone.c            |  2 +-
 builtin/init-db.c          |  8 +++++---
 refs.c                     | 24 ++++++++++++++++++++----
 refs.h                     |  4 ++--
 remote.c                   |  5 +++--
 t/t0001-init.sh            | 17 ++++++++++++++++-
 t/t1510-repo-setup.sh      |  2 +-
 t/test-lib-functions.sh    |  4 +++-
 10 files changed, 61 insertions(+), 20 deletions(-)
base-commit: faefdd61ec7c7f6f3c8c9907891465ac9a2a1475
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-921%2Fdscho%2Finit.defaultBranch-advice-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-921/dscho/init.defaultBranch-advice-v4
Pull-Request: https://github.com/git/git/pull/921
Range-diff vs v3:
 1:  483e4903491 = 1:  483e4903491 init: document `init.defaultBranch` better
 2:  6cbd6692c6a = 2:  6cbd6692c6a branch -m: allow renaming a yet-unborn branch
 3:  5fc15f7b9ad = 3:  5fc15f7b9ad get_default_branch_name(): prepare for showing some advice
 4:  87c93068771 ! 4:  2f21c505d56 init: provide useful advice about init.defaultBranch
     @@ Commit message
      
          Note: two test cases in Git's test suite want to verify that the
          `stderr` output of `git init` is empty. It is now necessary to suppress
     -    the advice using the newly-added `advice.defaultBranchName` setting.
     -    While not strictly necessary, we also set this to `false` in
     +    the advice, we now do that via the `init.defaultBranch` setting. While
     +    not strictly necessary, we also set this to `false` in
          `test_create_repo()`.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     - ## advice.c ##
     -@@ advice.c: static struct {
     - 	[ADVICE_AM_WORK_DIR] 				= { "amWorkDir", 1 },
     - 	[ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME] 	= { "checkoutAmbiguousRemoteBranchName", 1 },
     - 	[ADVICE_COMMIT_BEFORE_MERGE]			= { "commitBeforeMerge", 1 },
     -+	[ADVICE_DEFAULT_BRANCH_NAME]			= { "defaultBranchName", 1 },
     - 	[ADVICE_DETACHED_HEAD]				= { "detachedHead", 1 },
     - 	[ADVICE_FETCH_SHOW_FORCED_UPDATES]		= { "fetchShowForcedUpdates", 1 },
     - 	[ADVICE_GRAFT_FILE_DEPRECATED]			= { "graftFileDeprecated", 1 },
     -
     - ## advice.h ##
     -@@ advice.h: extern int advice_add_empty_pathspec;
     - 	ADVICE_AM_WORK_DIR,
     - 	ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME,
     - 	ADVICE_COMMIT_BEFORE_MERGE,
     -+	ADVICE_DEFAULT_BRANCH_NAME,
     - 	ADVICE_DETACHED_HEAD,
     - 	ADVICE_FETCH_SHOW_FORCED_UPDATES,
     - 	ADVICE_GRAFT_FILE_DEPRECATED,
     -
       ## refs.c ##
     -@@
     - #include "strvec.h"
     - #include "repository.h"
     - #include "sigchain.h"
     -+#include "advice.h"
     - 
     - /*
     -  * List of all available backends
      @@ refs.c: void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
       		strvec_pushf(prefixes, *p, len, prefix);
       }
       
      +static const char default_branch_name_advice[] = N_(
      +"Using '%s' as the name for the initial branch. This default branch name\n"
     -+"is subject to change. To suppress this warning, run:\n"
     -+"\n"
     -+"\tgit config --global advice.defaultBranchName false\n"
     -+"\n"
     -+"Alternatively, you can configure the initial branch name to use in all\n"
     -+"of your new repositories, which will also suppress this warning:\n"
     ++"is subject to change. To configure the initial branch name to use in all\n"
     ++"of your new repositories, which will suppress this warning, call:\n"
      +"\n"
      +"\tgit config --global init.defaultBranch <name>\n"
      +"\n"
     @@ refs.c: char *repo_default_branch_name(struct repository *r, int quiet)
      -	if (!ret)
      +	if (!ret) {
       		ret = xstrdup("master");
     -+		if (!quiet && advice_enabled(ADVICE_DEFAULT_BRANCH_NAME))
     ++		if (!quiet)
      +			advise(_(default_branch_name_advice), ret);
      +	}
       
     @@ t/t0001-init.sh: test_expect_success 'reinit' '
       		mkdir again &&
       		cd again &&
      -		git init >out1 2>err1 &&
     -+		git -c advice.defaultBranchName=false init >out1 2>err1 &&
     ++		git -c init.defaultBranch=initial init >out1 2>err1 &&
       		git init >out2 2>err2
       	) &&
       	test_i18ngrep "Initialized empty" again/out1 &&
     @@ t/t1510-repo-setup.sh: setup_repo () {
       	sane_unset GIT_DIR GIT_WORK_TREE &&
       
      -	git init "$name" &&
     -+	git -c advice.defaultBranchName=false init "$name" &&
     ++	git -c init.defaultBranch=initial init "$name" &&
       	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
       	maybe_config "$name/.git/config" core.bare "$barecfg" &&
       	mkdir -p "$name/sub/sub" &&
     @@ t/test-lib-functions.sh: test_create_repo () {
       	(
       		cd "$repo" || error "Cannot setup test environment"
      -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
     -+		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" \
     -+			-c advice.defaultBranchName=false init \
     ++		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" -c \
     ++			init.defaultBranch="${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}" \
     ++			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
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Dec 10, 2020, 21:58 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v4 4/4] init: provide useful advice about init.defaultBranch

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

To give ample warning for users wishing to override Git's the fall-back for an unconfigured `init.defaultBranch` (in case we decide to change it in a future Git version), let's introduce some advice that is shown upon `git init` when that value is not set.

Note: two test cases in Git's test suite want to verify that the
`stderr` output of `git init` is empty. It is now necessary to suppress
the advice, we now do that via the `init.defaultBranch` setting. While
not strictly necessary, we also set this to `false` in
`test_create_repo()`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 refs.c                  | 18 +++++++++++++++++-
 t/t0001-init.sh         |  9 ++++++++-
 t/t1510-repo-setup.sh   |  2 +-
 t/test-lib-functions.sh |  4 +++-
 4 files changed, 29 insertions(+), 4 deletions(-)
Show changes to 4 files +29 −4

refs.c, t/t0001-init.sh, t/t1510-repo-setup.sh, t/test-lib-functions.sh

diff --git a/refs.c b/refs.c
index 8df03122d69..6e047b3d1b4 100644
--- a/refs.c
+++ b/refs.c
@@ -562,6 +562,19 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
+static const char default_branch_name_advice[] = N_(
+"Using '%s' as the name for the initial branch. This default branch name\n"
+"is subject to change. To configure the initial branch name to use in all\n"
+"of your new repositories, which will suppress this warning, call:\n"
+"\n"
+"\tgit config --global init.defaultBranch <name>\n"
+"\n"
+"Common names are 'main', 'trunk' and 'development'. The initial branch\n"
+"that was created can be renamed via this command:\n"
+"\n"
+"\tgit branch -m <name>\n"
+);
+
 char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
@@ -574,8 +587,11 @@ char *repo_default_branch_name(struct repository *r, int quiet)
 	else if (repo_config_get_string(r, config_key, &ret) < 0)
 		die(_("could not retrieve `%s`"), config_display_key);
 
-	if (!ret)
+	if (!ret) {
 		ret = xstrdup("master");
+		if (!quiet)
+			advise(_(default_branch_name_advice), ret);
+	}
 
 	full_ref = xstrfmt("refs/heads/%s", ret);
 	if (check_refname_format(full_ref, 0))
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index bb23e56a165..0803994874f 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -163,7 +163,7 @@ test_expect_success 'reinit' '
 	(
 		mkdir again &&
 		cd again &&
-		git init >out1 2>err1 &&
+		git -c init.defaultBranch=initial init >out1 2>err1 &&
 		git init >out2 2>err2
 	) &&
 	test_i18ngrep "Initialized empty" again/out1 &&
@@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' '
 	grep nmb actual
 '
 
+test_expect_success 'advice on unconfigured init.defaultBranch' '
+	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
+		init unconfigured-default-branch-name 2>err &&
+	test_decode_color <err >decoded &&
+	test_i18ngrep "<YELLOW>hint: " decoded
+'
+
 test_expect_success 'overridden default main branch name (env)' '
 	test_config_global init.defaultBranch nmb &&
 	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 9974457f561..bbfe05b8e4a 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -79,7 +79,7 @@ setup_repo () {
 	name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
 	sane_unset GIT_DIR GIT_WORK_TREE &&
 
-	git init "$name" &&
+	git -c init.defaultBranch=initial init "$name" &&
 	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
 	maybe_config "$name/.git/config" core.bare "$barecfg" &&
 	mkdir -p "$name/sub/sub" &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 59bbf75e832..9910102ae1f 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1202,7 +1202,9 @@ test_create_repo () {
 	mkdir -p "$repo"
 	(
 		cd "$repo" || error "Cannot setup test environment"
-		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
+		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" -c \
+			init.defaultBranch="${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}" \
+			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
-- 
gitgitgadget
Felipe Contreras· Dec 11, 2020, 00:15 UTC · re: Johannes Schindelin via GitGitGadget · lore

Re: [PATCH v4 4/4] init: provide useful advice about init.defaultBranch

On Thu, Dec 10, 2020 at 3:58 PM Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:

Show 8 quoted lines
> +static const char default_branch_name_advice[] = N_(
> +"Using '%s' as the name for the initial branch. This default branch name\n"
> +"is subject to change. To configure the initial branch name to use in all\n"
> +"of your new repositories, which will suppress this warning, call:\n"
> +"\n"
> +"\tgit config --global init.defaultBranch <name>\n"
> +"\n"
> +"Common names are 'main', 'trunk' and 'development'. The initial branch\n"

This is disingenuous; the most common name is "master"... by far. In a couple years this might change, but not right now.

If you don't want to mention "master", then don't mention "common names" that are not really the most common names.

Cheers.
-- 
Felipe Contreras
Junio C Hamano· Dec 11, 2020, 01:22 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 4/4] init: provide useful advice about init.defaultBranch

Felipe Contreras <felipe.contreras@gmail.com> writes:
Show 17 quoted lines
> On Thu, Dec 10, 2020 at 3:58 PM Johannes Schindelin via GitGitGadget
> <gitgitgadget@gmail.com> wrote:
>
>> +static const char default_branch_name_advice[] = N_(
>> +"Using '%s' as the name for the initial branch. This default branch name\n"
>> +"is subject to change. To configure the initial branch name to use in all\n"
>> +"of your new repositories, which will suppress this warning, call:\n"
>> +"\n"
>> +"\tgit config --global init.defaultBranch <name>\n"
>> +"\n"
>> +"Common names are 'main', 'trunk' and 'development'. The initial branch\n"
>
> This is disingenuous; the most common name is "master"... by far. In a
> couple years this might change, but not right now.
>
> If you don't want to mention "master", then don't mention "common
> names" that are not really the most common names.

Names commonly chosen by those who want to move away from 'master' are...

Felipe Contreras· Dec 11, 2020, 02:00 UTC · re: Junio C Hamano · lore

Re: [PATCH v4 4/4] init: provide useful advice about init.defaultBranch

On Thu, Dec 10, 2020 at 7:23 PM Junio C Hamano <gitster@pobox.com> wrote:
Show 23 quoted lines
>
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
> > On Thu, Dec 10, 2020 at 3:58 PM Johannes Schindelin via GitGitGadget
> > <gitgitgadget@gmail.com> wrote:
> >
> >> +static const char default_branch_name_advice[] = N_(
> >> +"Using '%s' as the name for the initial branch. This default branch name\n"
> >> +"is subject to change. To configure the initial branch name to use in all\n"
> >> +"of your new repositories, which will suppress this warning, call:\n"
> >> +"\n"
> >> +"\tgit config --global init.defaultBranch <name>\n"
> >> +"\n"
> >> +"Common names are 'main', 'trunk' and 'development'. The initial branch\n"
> >
> > This is disingenuous; the most common name is "master"... by far. In a
> > couple years this might change, but not right now.
> >
> > If you don't want to mention "master", then don't mention "common
> > names" that are not really the most common names.
>
> Names commonly chosen by those who want to move away from 'master'
> are...
But we don't want to spill drama into the user interface.

I think the vast majority of users haven't heard of this drama. Just like the vast majority of users had not heard of the git-foo obsoletion even after several years. Our vantage point is skewed for being too close to Git development.

Those users will ask: "who wants to move away from 'master'?"
If we don't presume our users have the same knowledge as us, we have to explain:
  Names commonly chosen by those who want to move away from 'master'
  are; 'main', 'trunk', and 'development'. For more information read
  this post:
  https://dev.to/rhymu8354/git-renaming-the-master-branch-137b.

I say don't. If the user wants to know why anyone would want to change "the default branch name", she can google it and find out.

Cheer.
-- 
Felipe Contreras
Johannes Schindelin· Dec 11, 2020, 00:47 UTC · re: Junio C Hamano · lore

Re: [PATCH v4 4/4] init: provide useful advice about init.defaultBranch

Hi Junio,
On Thu, 10 Dec 2020, Junio C Hamano wrote:
Show 22 quoted lines
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
> > On Thu, Dec 10, 2020 at 3:58 PM Johannes Schindelin via GitGitGadget
> > <gitgitgadget@gmail.com> wrote:
> >
> >> +static const char default_branch_name_advice[] = N_(
> >> +"Using '%s' as the name for the initial branch. This default branch name\n"
> >> +"is subject to change. To configure the initial branch name to use in all\n"
> >> +"of your new repositories, which will suppress this warning, call:\n"
> >> +"\n"
> >> +"\tgit config --global init.defaultBranch <name>\n"
> >> +"\n"
> >> +"Common names are 'main', 'trunk' and 'development'. The initial branch\n"
> >
> > This is disingenuous; the most common name is "master"... by far. In a
> > couple years this might change, but not right now.
> >
> > If you don't want to mention "master", then don't mention "common
> > names" that are not really the most common names.
>
> Names commonly chosen by those who want to move away from 'master'
> are...

"those who want to move away" sounds a bit too non-committal for my liking. So I changed it to:

	Names commonly chosen instead of 'master' are 'main', 'trunk'
	and 'development'.
While at it, I also improved the next sentence:
	 The just-created branch can be renamed via this command:

Ciao, Dscho

Johannes Schindelin via GitGitGadget· Dec 10, 2020, 21:58 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v4 2/4] branch -m: allow renaming a yet-unborn branch

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

In one of the next commits, we would like to give users some advice regarding the initial branch name, and how to modify it.

To that end, it would be good if `git branch -m <name>` worked in a freshly initialized repository without any commits. Let's make it so.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/branch.c | 4 +++-
 t/t0001-init.sh  | 8 ++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
Show changes to 2 files +11 −1

builtin/branch.c, t/t0001-init.sh

diff --git a/builtin/branch.c b/builtin/branch.c
index efb30b88206..200da319f1d 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -538,7 +538,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 		strbuf_addf(&logmsg, "Branch: renamed %s to %s",
 			    oldref.buf, newref.buf);
 
-	if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
+	if (!copy &&
+	    (!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) &&
+	    rename_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch rename failed"));
 	if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch copy failed"));
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 69a320489fc..bb23e56a165 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -571,4 +571,12 @@ test_expect_success 'invalid default branch name' '
 	test_i18ngrep "invalid branch name" err
 '
 
+test_expect_success 'branch -m with the initial branch' '
+	git init rename-initial &&
+	git -C rename-initial branch -m renamed &&
+	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
+	git -C rename-initial branch -m renamed again &&
+	test again = $(git -C rename-initial symbolic-ref --short HEAD)
+'
+
 test_done
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Dec 10, 2020, 21:58 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v4 1/4] init: document `init.defaultBranch` better

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

Our documentation does not mention any future plan to change 'master' to other value. It is a good idea to document this, though.

Initial-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-init.txt | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
Show changes to Documentation/git-init.txt +7 −4
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 59ecda6c17d..2b399cb73d7 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -20,8 +20,9 @@ DESCRIPTION
 
 This command creates an empty Git repository - basically a `.git`
 directory with subdirectories for `objects`, `refs/heads`,
-`refs/tags`, and template files.  An initial `HEAD` file that
-references the HEAD of the master branch is also created.
+`refs/tags`, and template files.  An initial branch without any
+commits will be created (see the `--initial-branch` option below
+for its name).
 
 If the `$GIT_DIR` environment variable is set then it specifies a path
 to use instead of `./.git` for the base of the repository.
@@ -73,8 +74,10 @@ 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`.
+Use the specified name for the initial branch in the newly created
+repository.  If not specified, fall back to the default name (currently
+`master`, but that will be changed in the future; the name can be customized
+via the `init.defaultBranch` configuration variable).
 
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
-- 
gitgitgadget
Felipe Contreras· Dec 11, 2020, 00:24 UTC · re: Johannes Schindelin via GitGitGadget · lore

Re: [PATCH v4 1/4] init: document `init.defaultBranch` better

On Thu, Dec 10, 2020 at 3:58 PM Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com> wrote:

Show 22 quoted lines
>
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
>
> Our documentation does not mention any future plan to change 'master' to
> other value. It is a good idea to document this, though.
>
> Initial-patch-by: Junio C Hamano <gitster@pobox.com>
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
>  Documentation/git-init.txt | 11 +++++++----
>  1 file changed, 7 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
> index 59ecda6c17d..2b399cb73d7 100644
> --- a/Documentation/git-init.txt
> +++ b/Documentation/git-init.txt
> @@ -20,8 +20,9 @@ DESCRIPTION
>
>  This command creates an empty Git repository - basically a `.git`
>  directory with subdirectories for `objects`, `refs/heads`,
> -`refs/tags`, and template files.  An initial `HEAD` file that
> -references the HEAD of the master branch is also created.

The current sentence: "An initial `HEAD` file that references the HEAD of the master branch is also created." is still true. There's no need to change that (yet).

> +`refs/tags`, and template files.  An initial branch without any
> +commits will be created (see the `--initial-branch` option below
> +for its name).
Perhaps: (see the `--initial-branch` option below to choose another name).
Show 9 quoted lines
>  If the `$GIT_DIR` environment variable is set then it specifies a path
>  to use instead of `./.git` for the base of the repository.
> @@ -73,8 +74,10 @@ 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`.
> +Use the specified name for the initial branch in the newly created
Again; the default name has not changed.
> +repository.  If not specified, fall back to the default name (currently
> +`master`, but that will be changed in the future; the name can be customized
> +via the `init.defaultBranch` configuration variable).

Wait a second. The advice warning said "this is subject to change", and the documentation says "that will be changed in the future". Which is it?

"I might give you a fine", and "I will give you a fine" are most definitely not the same thing.

Either say "this is subject to change" in both the documentation and the warning. Or say "that will be changed in the future".

Don't say one thing in one and another thing in the other.
Cheers.
-- 
Felipe Contreras
Junio C Hamano· Dec 11, 2020, 05:47 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 1/4] init: document `init.defaultBranch` better

Felipe Contreras <felipe.contreras@gmail.com> writes:
Show 9 quoted lines
>> -`refs/tags`, and template files.  An initial `HEAD` file that
>> -references the HEAD of the master branch is also created.
>> +`refs/tags`, and template files.  An initial branch without any
>> +commits will be created (see the `--initial-branch` option below
>> +for its name).
>
> The current sentence: "An initial `HEAD` file that references the HEAD
> of the master branch is also created." is still true. There's no need
> to change that (yet).

The change updates the description for readability, lowering the technical level of description, and correcting inaccuracies.

 - The readers in the context of understanding what "git init"
   performs does not have to know nor care that HEAD is implemented
   as a file.  In fact, there is an effort to introduce HEAD and
   other refs that are implemented as individual files under
   $GIT_DIR/.  Dropping the word "file" is to correct these.
 - Also we no longer say "the HEAD of" a branch, even if we used to
   use that expression.  When we really need to refer to the commit
   directly pointed at by a branch ref, we say "the tip of" instead
   there days.
 - It used to be left unsaid that the initial branch begins its life
   without any commit.  Now it does.
None of these is about "'master' or any other name?" issue.
> Perhaps: (see the `--initial-branch` option below to choose another name).

That changes the meaning of the explanation. It is compensating for not saying what the name of the initial branch is, and is not trying to teach that the name can be changed. The text in the patch is good as-is.

Felipe Contreras· Dec 11, 2020, 06:26 UTC · re: Junio C Hamano · lore

Re: [PATCH v4 1/4] init: document `init.defaultBranch` better

On Thu, Dec 10, 2020 at 11:47 PM Junio C Hamano <gitster@pobox.com> wrote:
Show 15 quoted lines
>
> Felipe Contreras <felipe.contreras@gmail.com> writes:
>
> >> -`refs/tags`, and template files.  An initial `HEAD` file that
> >> -references the HEAD of the master branch is also created.
> >> +`refs/tags`, and template files.  An initial branch without any
> >> +commits will be created (see the `--initial-branch` option below
> >> +for its name).
> >
> > The current sentence: "An initial `HEAD` file that references the HEAD
> > of the master branch is also created." is still true. There's no need
> > to change that (yet).
>
> The change updates the description for readability, lowering the
> technical level of description, and correcting inaccuracies.
OK.
Show 5 quoted lines
>  - The readers in the context of understanding what "git init"
>    performs does not have to know nor care that HEAD is implemented
>    as a file.  In fact, there is an effort to introduce HEAD and
>    other refs that are implemented as individual files under
>    $GIT_DIR/.  Dropping the word "file" is to correct these.
Right.
>  - Also we no longer say "the HEAD of" a branch, even if we used to
>    use that expression.  When we really need to refer to the commit
>    directly pointed at by a branch ref, we say "the tip of" instead
>    there days.
Sure.
>  - It used to be left unsaid that the initial branch begins its life
>    without any commit.  Now it does.
OK.
> None of these is about "'master' or any other name?" issue.
Indeed, but the commit message clearly states:
  Our documentation does not mention any future plan to change 'master'
  to other value. It is a good idea to document this, though.

It doesn't say anything about improving the documentation of "git init", nor any of your three points. The main intention is clear.

On top of your three points it sneaks another change; avoiding the "master" branch name. If this really had nothing to do with the "master" branch name, it could very well be sent as a separate independent patch.

The following text has your three valid points, but doesn't sneak in the extra change:

  An initial "master" branch without any commits will be created (see
  the `--initial-branch` option below to choose another name).
Show 6 quoted lines
> > Perhaps: (see the `--initial-branch` option below to choose another name).
>
> That changes the meaning of the explanation.  It is compensating for
> not saying what the name of the initial branch is, and is not trying
> to teach that the name can be changed.  The text in the patch is good
> as-is.

In English parentheses are used to clarify information, and typically it's *supplementary* information. That is; the sentence must stand on its own without them.

This sentence is missing crucial information and it doesn't stand on its own:
  An initial branch without any commits will be created.
This one does stand on its own:
  An initial "master" branch without any commits will be created.
(and doesn't omit any current information.)
Cheers.
-- 
Felipe Contreras
Junio C Hamano· Dec 11, 2020, 05:59 UTC · re: Felipe Contreras · lore

Re: [PATCH v4 1/4] init: document `init.defaultBranch` better

Felipe Contreras <felipe.contreras@gmail.com> writes:
Show 12 quoted lines
> On Thu, Dec 10, 2020 at 3:58 PM Johannes Schindelin via GitGitGadget
>
>> +repository.  If not specified, fall back to the default name (currently
>> +`master`, but that will be changed in the future; the name can be customized
>> +via the `init.defaultBranch` configuration variable).
>
> Wait a second. The advice warning said "this is subject to change",
> and the documentation says "that will be changed in the future". Which
> is it?
>
> "I might give you a fine", and "I will give you a fine" are most
> definitely not the same thing.

I think we say "this is subject to change" in other places, and I agree that this part should match to avoid confusing readers, especially the non-native ones like me.

    If not specified, fall back to the default name (currently
    `master`, but this is subject to change in the future; ...
would be more consistent.
Johannes Schindelin via GitGitGadget· Dec 10, 2020, 21:58 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v4 3/4] get_default_branch_name(): prepare for showing some advice

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

We are about to introduce a message giving users running `git init` some advice about `init.defaultBranch`. This will necessarily be done in `repo_default_branch_name()`.

Not all code paths want to show that advice, though. In particular, the `git clone` codepath _specifically_ asks for `init_db()` to be quiet, via the `INIT_DB_QUIET` flag.

In preparation for showing users above-mentioned advice, let's change the function signature of `get_default_branch_name()` to accept the parameter `quiet`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/clone.c   | 2 +-
 builtin/init-db.c | 8 +++++---
 refs.c            | 6 +++---
 refs.h            | 4 ++--
 remote.c          | 5 +++--
 5 files changed, 14 insertions(+), 11 deletions(-)
Show changes to 5 files +14 −11

builtin/clone.c, builtin/init-db.c, refs.c, refs.h, remote.c

diff --git a/builtin/clone.c b/builtin/clone.c
index a0841923cfe..64b17840112 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1323,7 +1323,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare) {
-			const char *branch = git_default_branch_name();
+			const char *branch = git_default_branch_name(0);
 			char *ref = xstrfmt("refs/heads/%s", branch);
 
 			install_branch_config(0, branch, remote_name, ref);
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 01bc648d416..dcc45bef514 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit)
 static int create_default_files(const char *template_path,
 				const char *original_git_dir,
 				const char *initial_branch,
-				const struct repository_format *fmt)
+				const struct repository_format *fmt,
+				int quiet)
 {
 	struct stat st1;
 	struct strbuf buf = STRBUF_INIT;
@@ -267,7 +268,7 @@ static int create_default_files(const char *template_path,
 		char *ref;
 
 		if (!initial_branch)
-			initial_branch = git_default_branch_name();
+			initial_branch = git_default_branch_name(quiet);
 
 		ref = xstrfmt("refs/heads/%s", initial_branch);
 		if (check_refname_format(ref, 0) < 0)
@@ -438,7 +439,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,
-				      initial_branch, &repo_fmt);
+				      initial_branch, &repo_fmt,
+				      flags & INIT_DB_QUIET);
 	if (reinit && initial_branch)
 		warning(_("re-init: ignored --initial-branch=%s"),
 			initial_branch);
diff --git a/refs.c b/refs.c
index 392f0bbf68b..8df03122d69 100644
--- a/refs.c
+++ b/refs.c
@@ -562,7 +562,7 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
-char *repo_default_branch_name(struct repository *r)
+char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
 	const char *config_display_key = "init.defaultBranch";
@@ -585,12 +585,12 @@ char *repo_default_branch_name(struct repository *r)
 	return ret;
 }
 
-const char *git_default_branch_name(void)
+const char *git_default_branch_name(int quiet)
 {
 	static char *ret;
 
 	if (!ret)
-		ret = repo_default_branch_name(the_repository);
+		ret = repo_default_branch_name(the_repository, quiet);
 
 	return ret;
 }
diff --git a/refs.h b/refs.h
index 66955181569..ff05d2e9fe2 100644
--- a/refs.h
+++ b/refs.h
@@ -170,8 +170,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
  * 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);
+const char *git_default_branch_name(int quiet);
+char *repo_default_branch_name(struct repository *r, int quiet);
 
 /*
  * A ref_transaction represents a collection of reference updates that
diff --git a/remote.c b/remote.c
index 8a6dbbb9030..bdb88d4b7dd 100644
--- a/remote.c
+++ b/remote.c
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
 	if (frag)
 		*(frag++) = '\0';
 	else
-		frag = (char *)git_default_branch_name();
+		frag = (char *)git_default_branch_name(0);
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
 	refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s",
@@ -2206,7 +2206,8 @@ struct ref *guess_remote_head(const struct ref *head,
 
 	/* 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());
+		char *ref = xstrfmt("refs/heads/%s",
+				    git_default_branch_name(0));
 
 		r = find_ref_by_name(refs, ref);
 		free(ref);
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Dec 11, 2020, 11:36 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v5 0/4] Add helpful advice about init.defaultBranch

It is our designated intention [https://sfconservancy.org/news/2020/jun/23/gitbranchname/] to "to explore changing the name of the first branch created automatically for new repositories away from ‘master’". Further, we promised that we "will minimize disruption for Git's users and will include appropriate deprecation periods".

To that end, we first clarify git init's documentation (a lightly edited version of Junio's patch [https://lore.kernel.org/git/xmqqd00a36wc.fsf@gitster.c.googlers.com]), and then introduce a message giving advice to users running git init that the fall-back for init.defaultBranch is subject to change, and how to override Git's fall-back manually.

The beauty of this patch series, if I may say so, is that it does not commit us to any concrete plan, but opens the door for all options regarding the default branch name.

Changes since v4:
 * Reworded the documentation to weaken the "will be changed in the future"
   to "is subject to change".
 * Reworded the advice to explicitly mention "instead of 'master'".
Changes since v3:
 * Kicked out advice.defaultBranchName again. The advice can now only be
   suppressed by setting init.defaultBranch.
Changes since v2:
 * git branch -m <initial> <renamed> now works, too
 * The config setting advice.defaultBranchName was introduced to allow
   suppressing this warning specifically
 * The advice now first talks about the current default branch name, then
   how to suppress the advice, and only then explains how to override the
   default branch name (and that that will also prevent the message from
   being shown)
Changes since v1:
 * Grammar fix
 * Reworded advice and commit messages
 * test_create_repo already respected GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME,
   but now does so more obviously
 * Allowed git branch -m <name> to rename unborn branches, so that the
   advice actually works
Johannes Schindelin (4):
  init: document `init.defaultBranch` better
  branch -m: allow renaming a yet-unborn branch
  get_default_branch_name(): prepare for showing some advice
  init: provide useful advice about init.defaultBranch
 Documentation/git-init.txt | 11 +++++++----
 builtin/branch.c           |  4 +++-
 builtin/clone.c            |  2 +-
 builtin/init-db.c          |  8 +++++---
 refs.c                     | 24 ++++++++++++++++++++----
 refs.h                     |  4 ++--
 remote.c                   |  5 +++--
 t/t0001-init.sh            | 17 ++++++++++++++++-
 t/t1510-repo-setup.sh      |  2 +-
 t/test-lib-functions.sh    |  4 +++-
 10 files changed, 61 insertions(+), 20 deletions(-)
base-commit: faefdd61ec7c7f6f3c8c9907891465ac9a2a1475
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-921%2Fdscho%2Finit.defaultBranch-advice-v5
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-921/dscho/init.defaultBranch-advice-v5
Pull-Request: https://github.com/git/git/pull/921
Range-diff vs v4:
 1:  483e4903491 ! 1:  ce35cf3da65 init: document `init.defaultBranch` better
     @@ Documentation/git-init.txt: If this is reinitialization, the repository will be
      -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 (currently
     -+`master`, but that will be changed in the future; the name can be customized
     -+via the `init.defaultBranch` configuration variable).
     ++`master`, but this is subject to change in the future; the name can be
     ++customized via the `init.defaultBranch` configuration variable).
       
       --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
       
 2:  6cbd6692c6a = 2:  ac7b352a0ba branch -m: allow renaming a yet-unborn branch
 3:  5fc15f7b9ad = 3:  aba72340c87 get_default_branch_name(): prepare for showing some advice
 4:  2f21c505d56 ! 4:  ce26446b1a2 init: provide useful advice about init.defaultBranch
     @@ refs.c: void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
      +"\n"
      +"\tgit config --global init.defaultBranch <name>\n"
      +"\n"
     -+"Common names are 'main', 'trunk' and 'development'. The initial branch\n"
     -+"that was created can be renamed via this command:\n"
     ++"Names commonly chosen instead of 'master' are 'main', 'trunk' and\n"
     ++"'development'. The just-created branch can be renamed via this command:\n"
      +"\n"
      +"\tgit branch -m <name>\n"
      +);
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Dec 11, 2020, 11:36 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v5 2/4] branch -m: allow renaming a yet-unborn branch

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

In one of the next commits, we would like to give users some advice regarding the initial branch name, and how to modify it.

To that end, it would be good if `git branch -m <name>` worked in a freshly initialized repository without any commits. Let's make it so.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/branch.c | 4 +++-
 t/t0001-init.sh  | 8 ++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)
Show changes to 2 files +11 −1

builtin/branch.c, t/t0001-init.sh

diff --git a/builtin/branch.c b/builtin/branch.c
index efb30b88206..200da319f1d 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -538,7 +538,9 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 		strbuf_addf(&logmsg, "Branch: renamed %s to %s",
 			    oldref.buf, newref.buf);
 
-	if (!copy && rename_ref(oldref.buf, newref.buf, logmsg.buf))
+	if (!copy &&
+	    (!head || strcmp(oldname, head) || !is_null_oid(&head_oid)) &&
+	    rename_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch rename failed"));
 	if (copy && copy_existing_ref(oldref.buf, newref.buf, logmsg.buf))
 		die(_("Branch copy failed"));
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 69a320489fc..bb23e56a165 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -571,4 +571,12 @@ test_expect_success 'invalid default branch name' '
 	test_i18ngrep "invalid branch name" err
 '
 
+test_expect_success 'branch -m with the initial branch' '
+	git init rename-initial &&
+	git -C rename-initial branch -m renamed &&
+	test renamed = $(git -C rename-initial symbolic-ref --short HEAD) &&
+	git -C rename-initial branch -m renamed again &&
+	test again = $(git -C rename-initial symbolic-ref --short HEAD)
+'
+
 test_done
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Dec 11, 2020, 11:36 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v5 1/4] init: document `init.defaultBranch` better

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

Our documentation does not mention any future plan to change 'master' to other value. It is a good idea to document this, though.

Initial-patch-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 Documentation/git-init.txt | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
Show changes to Documentation/git-init.txt +7 −4
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index 59ecda6c17d..b611d80697d 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -20,8 +20,9 @@ DESCRIPTION
 
 This command creates an empty Git repository - basically a `.git`
 directory with subdirectories for `objects`, `refs/heads`,
-`refs/tags`, and template files.  An initial `HEAD` file that
-references the HEAD of the master branch is also created.
+`refs/tags`, and template files.  An initial branch without any
+commits will be created (see the `--initial-branch` option below
+for its name).
 
 If the `$GIT_DIR` environment variable is set then it specifies a path
 to use instead of `./.git` for the base of the repository.
@@ -73,8 +74,10 @@ 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`.
+Use the specified name for the initial branch in the newly created
+repository.  If not specified, fall back to the default name (currently
+`master`, but this is subject to change in the future; the name can be
+customized via the `init.defaultBranch` configuration variable).
 
 --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
 
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Dec 11, 2020, 11:36 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v5 3/4] get_default_branch_name(): prepare for showing some advice

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

We are about to introduce a message giving users running `git init` some advice about `init.defaultBranch`. This will necessarily be done in `repo_default_branch_name()`.

Not all code paths want to show that advice, though. In particular, the `git clone` codepath _specifically_ asks for `init_db()` to be quiet, via the `INIT_DB_QUIET` flag.

In preparation for showing users above-mentioned advice, let's change the function signature of `get_default_branch_name()` to accept the parameter `quiet`.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin/clone.c   | 2 +-
 builtin/init-db.c | 8 +++++---
 refs.c            | 6 +++---
 refs.h            | 4 ++--
 remote.c          | 5 +++--
 5 files changed, 14 insertions(+), 11 deletions(-)
Show changes to 5 files +14 −11

builtin/clone.c, builtin/init-db.c, refs.c, refs.h, remote.c

diff --git a/builtin/clone.c b/builtin/clone.c
index a0841923cfe..64b17840112 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -1323,7 +1323,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		remote_head = NULL;
 		option_no_checkout = 1;
 		if (!option_bare) {
-			const char *branch = git_default_branch_name();
+			const char *branch = git_default_branch_name(0);
 			char *ref = xstrfmt("refs/heads/%s", branch);
 
 			install_branch_config(0, branch, remote_name, ref);
diff --git a/builtin/init-db.c b/builtin/init-db.c
index 01bc648d416..dcc45bef514 100644
--- a/builtin/init-db.c
+++ b/builtin/init-db.c
@@ -202,7 +202,8 @@ void initialize_repository_version(int hash_algo, int reinit)
 static int create_default_files(const char *template_path,
 				const char *original_git_dir,
 				const char *initial_branch,
-				const struct repository_format *fmt)
+				const struct repository_format *fmt,
+				int quiet)
 {
 	struct stat st1;
 	struct strbuf buf = STRBUF_INIT;
@@ -267,7 +268,7 @@ static int create_default_files(const char *template_path,
 		char *ref;
 
 		if (!initial_branch)
-			initial_branch = git_default_branch_name();
+			initial_branch = git_default_branch_name(quiet);
 
 		ref = xstrfmt("refs/heads/%s", initial_branch);
 		if (check_refname_format(ref, 0) < 0)
@@ -438,7 +439,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,
-				      initial_branch, &repo_fmt);
+				      initial_branch, &repo_fmt,
+				      flags & INIT_DB_QUIET);
 	if (reinit && initial_branch)
 		warning(_("re-init: ignored --initial-branch=%s"),
 			initial_branch);
diff --git a/refs.c b/refs.c
index 392f0bbf68b..8df03122d69 100644
--- a/refs.c
+++ b/refs.c
@@ -562,7 +562,7 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
-char *repo_default_branch_name(struct repository *r)
+char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
 	const char *config_display_key = "init.defaultBranch";
@@ -585,12 +585,12 @@ char *repo_default_branch_name(struct repository *r)
 	return ret;
 }
 
-const char *git_default_branch_name(void)
+const char *git_default_branch_name(int quiet)
 {
 	static char *ret;
 
 	if (!ret)
-		ret = repo_default_branch_name(the_repository);
+		ret = repo_default_branch_name(the_repository, quiet);
 
 	return ret;
 }
diff --git a/refs.h b/refs.h
index 66955181569..ff05d2e9fe2 100644
--- a/refs.h
+++ b/refs.h
@@ -170,8 +170,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
  * 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);
+const char *git_default_branch_name(int quiet);
+char *repo_default_branch_name(struct repository *r, int quiet);
 
 /*
  * A ref_transaction represents a collection of reference updates that
diff --git a/remote.c b/remote.c
index 8a6dbbb9030..bdb88d4b7dd 100644
--- a/remote.c
+++ b/remote.c
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)
 	if (frag)
 		*(frag++) = '\0';
 	else
-		frag = (char *)git_default_branch_name();
+		frag = (char *)git_default_branch_name(0);
 
 	add_url_alias(remote, strbuf_detach(&buf, NULL));
 	refspec_appendf(&remote->fetch, "refs/heads/%s:refs/heads/%s",
@@ -2206,7 +2206,8 @@ struct ref *guess_remote_head(const struct ref *head,
 
 	/* 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());
+		char *ref = xstrfmt("refs/heads/%s",
+				    git_default_branch_name(0));
 
 		r = find_ref_by_name(refs, ref);
 		free(ref);
-- 
gitgitgadget
Johannes Schindelin via GitGitGadget· Dec 11, 2020, 11:36 UTC · re: Johannes Schindelin via GitGitGadget · lore

[PATCH v5 4/4] init: provide useful advice about init.defaultBranch

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

To give ample warning for users wishing to override Git's the fall-back for an unconfigured `init.defaultBranch` (in case we decide to change it in a future Git version), let's introduce some advice that is shown upon `git init` when that value is not set.

Note: two test cases in Git's test suite want to verify that the
`stderr` output of `git init` is empty. It is now necessary to suppress
the advice, we now do that via the `init.defaultBranch` setting. While
not strictly necessary, we also set this to `false` in
`test_create_repo()`.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 refs.c                  | 18 +++++++++++++++++-
 t/t0001-init.sh         |  9 ++++++++-
 t/t1510-repo-setup.sh   |  2 +-
 t/test-lib-functions.sh |  4 +++-
 4 files changed, 29 insertions(+), 4 deletions(-)
Show changes to 4 files +29 −4

refs.c, t/t0001-init.sh, t/t1510-repo-setup.sh, t/test-lib-functions.sh

diff --git a/refs.c b/refs.c
index 8df03122d69..13dc2c3291b 100644
--- a/refs.c
+++ b/refs.c
@@ -562,6 +562,19 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
 		strvec_pushf(prefixes, *p, len, prefix);
 }
 
+static const char default_branch_name_advice[] = N_(
+"Using '%s' as the name for the initial branch. This default branch name\n"
+"is subject to change. To configure the initial branch name to use in all\n"
+"of your new repositories, which will suppress this warning, call:\n"
+"\n"
+"\tgit config --global init.defaultBranch <name>\n"
+"\n"
+"Names commonly chosen instead of 'master' are 'main', 'trunk' and\n"
+"'development'. The just-created branch can be renamed via this command:\n"
+"\n"
+"\tgit branch -m <name>\n"
+);
+
 char *repo_default_branch_name(struct repository *r, int quiet)
 {
 	const char *config_key = "init.defaultbranch";
@@ -574,8 +587,11 @@ char *repo_default_branch_name(struct repository *r, int quiet)
 	else if (repo_config_get_string(r, config_key, &ret) < 0)
 		die(_("could not retrieve `%s`"), config_display_key);
 
-	if (!ret)
+	if (!ret) {
 		ret = xstrdup("master");
+		if (!quiet)
+			advise(_(default_branch_name_advice), ret);
+	}
 
 	full_ref = xstrfmt("refs/heads/%s", ret);
 	if (check_refname_format(full_ref, 0))
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index bb23e56a165..0803994874f 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -163,7 +163,7 @@ test_expect_success 'reinit' '
 	(
 		mkdir again &&
 		cd again &&
-		git init >out1 2>err1 &&
+		git -c init.defaultBranch=initial init >out1 2>err1 &&
 		git init >out2 2>err2
 	) &&
 	test_i18ngrep "Initialized empty" again/out1 &&
@@ -558,6 +558,13 @@ test_expect_success 'overridden default initial branch name (config)' '
 	grep nmb actual
 '
 
+test_expect_success 'advice on unconfigured init.defaultBranch' '
+	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
+		init unconfigured-default-branch-name 2>err &&
+	test_decode_color <err >decoded &&
+	test_i18ngrep "<YELLOW>hint: " decoded
+'
+
 test_expect_success 'overridden default main branch name (env)' '
 	test_config_global init.defaultBranch nmb &&
 	GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh
index 9974457f561..bbfe05b8e4a 100755
--- a/t/t1510-repo-setup.sh
+++ b/t/t1510-repo-setup.sh
@@ -79,7 +79,7 @@ setup_repo () {
 	name=$1 worktreecfg=$2 gitfile=$3 barecfg=$4 &&
 	sane_unset GIT_DIR GIT_WORK_TREE &&
 
-	git init "$name" &&
+	git -c init.defaultBranch=initial init "$name" &&
 	maybe_config "$name/.git/config" core.worktree "$worktreecfg" &&
 	maybe_config "$name/.git/config" core.bare "$barecfg" &&
 	mkdir -p "$name/sub/sub" &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 59bbf75e832..9910102ae1f 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1202,7 +1202,9 @@ test_create_repo () {
 	mkdir -p "$repo"
 	(
 		cd "$repo" || error "Cannot setup test environment"
-		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
+		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" -c \
+			init.defaultBranch="${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}" \
+			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
-- 
gitgitgadget
SZEDER Gábor· Feb 2, 2021, 21:24 UTC · re: Johannes Schindelin via GitGitGadget · lore

Re: [PATCH v5 4/4] init: provide useful advice about init.defaultBranch

On Fri, Dec 11, 2020 at 11:36:57AM +0000, Johannes Schindelin via GitGitGadget wrote:
Show 15 quoted lines
> From: Johannes Schindelin <johannes.schindelin@gmx.de>
> 
> To give ample warning for users wishing to override Git's the fall-back
> for an unconfigured `init.defaultBranch` (in case we decide to change it
> in a future Git version), let's introduce some advice that is shown upon
> `git init` when that value is not set.
> 
> Note: two test cases in Git's test suite want to verify that the
> `stderr` output of `git init` is empty. It is now necessary to suppress
> the advice, we now do that via the `init.defaultBranch` setting. While
> not strictly necessary, we also set this to `false` in
> `test_create_repo()`.
> 
> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
> ---
Show 13 quoted lines
> diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
> index 59bbf75e832..9910102ae1f 100644
> --- a/t/test-lib-functions.sh
> +++ b/t/test-lib-functions.sh
> @@ -1202,7 +1202,9 @@ test_create_repo () {
>  	mkdir -p "$repo"
>  	(
>  		cd "$repo" || error "Cannot setup test environment"
> -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
> +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" -c \
> +			init.defaultBranch="${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}" \
> +			init \
>  			"--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||

This breaks GIT_TEST_INSTALLED when the given Git version doesn't yet contain 8b1fa77867 (Allow passing of configuration parameters in the command line, 2010-03-26):

  $ GIT_TEST_INSTALLED=.../v1.6.0/bin/ ./t9999-test.sh -x
  Unknown option: -c
  usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]
  error: cannot run git init -- have you built things yet?
>  		error "cannot run git init -- have you built things yet?"
>  		mv .git/hooks .git/hooks-disabled
> -- 
> gitgitgadget
Junio C Hamano· Feb 2, 2021, 22:25 UTC · re: SZEDER Gábor · lore

Re: [PATCH v5 4/4] init: provide useful advice about init.defaultBranch

SZEDER Gábor <szeder.dev@gmail.com> writes:
Show 9 quoted lines
>> -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
>> +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" -c \
>> +			init.defaultBranch="${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}" \
>> +			init \
>>  			"--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
>
> This breaks GIT_TEST_INSTALLED when the given Git version doesn't yet
> contain 8b1fa77867 (Allow passing of configuration parameters in the
> command line, 2010-03-26):

Yes, but test-installed is about running an old version of Git on the current Git test suite. In the tests we make liberal use of "git -c <var>=<val>", which such an old version of Git has no chance of passing. So...

SZEDER Gábor· Feb 3, 2021, 05:20 UTC · re: Junio C Hamano · lore

Re: [PATCH v5 4/4] init: provide useful advice about init.defaultBranch

On Tue, Feb 02, 2021 at 02:25:01PM -0800, Junio C Hamano wrote:
Show 16 quoted lines
> SZEDER Gábor <szeder.dev@gmail.com> writes:
> 
> >> -		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
> >> +		"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" -c \
> >> +			init.defaultBranch="${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME-master}" \
> >> +			init \
> >>  			"--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
> >
> > This breaks GIT_TEST_INSTALLED when the given Git version doesn't yet
> > contain 8b1fa77867 (Allow passing of configuration parameters in the
> > command line, 2010-03-26):
> 
> Yes, but test-installed is about running an old version of Git on
> the current Git test suite.  In the tests we make liberal use of
> "git -c <var>=<val>", which such an old version of Git has no chance
> of passing.  So...

I've never run the whole test suite with GIT_TEST_INSTALLED for the exact reason you mentioned. However, I do regularly use it with custom tests using only commands and options that already existed as early as v1.6.0 (my go-to "old" version) to check when some interesting or puzzling behavior appeared, and did just that yesterday as well.

← back to recent threads