mbox series

[0/9] Allow overriding the default name of the default branch

Message ID pull.656.git.1591823971.gitgitgadget@gmail.com (mailing list archive)
Headers show
Series Allow overriding the default name of the default branch | expand

Message

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

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

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

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

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

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

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

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

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

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

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

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

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


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

Comments

Junio C Hamano June 10, 2020, 11:11 p.m. UTC | #1
"Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
writes:

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

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

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

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

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

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

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

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

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

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

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

I've looked over this series, and I have no additional comments beyond
what I've mentioned and what Junio pointed out at the end of the series.
With those provisos, I'm generally happy with it, and glad to see these
patches hit the list.
Taylor Blau June 11, 2020, 1:07 a.m. UTC | #3
Hi Johannes (and Dan)

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

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

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

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

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

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

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

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

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

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

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

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

Thanks,
Taylor
Junio C Hamano June 11, 2020, 5:42 a.m. UTC | #4
Junio C Hamano <gitster@pobox.com> writes:

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

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

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

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

    name=$(git var defaultBranchName)

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

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

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

Similarly, "what is the default branch name" is not just about the
value of one configuration variable.  GIT_TEST_DEFAULT_BRANCH_NAME
environment needs to be consulted, and when there is nothing
configured, it needs to say 'master', so that end-users who use "git
var" do not have to hardcode the string 'master' in their script.
Johannes Schindelin June 11, 2020, 1:44 p.m. UTC | #5
Hi Junio,

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

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

Thanks!

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

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

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

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

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

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

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

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

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

Does that sound like a plan?

Ciao,
Dscho
Johannes Schindelin June 11, 2020, 2:33 p.m. UTC | #6
Hi Taylor,

On Wed, 10 Jun 2020, Taylor Blau wrote:

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

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

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

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

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

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

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

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

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

That is exactly the intention of this patch series.

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

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

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

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

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

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

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

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

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

Ciao,
Dscho
Junio C Hamano June 11, 2020, 2:44 p.m. UTC | #7
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

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

Yes.


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

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

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

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

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

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

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

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

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

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

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

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

Thanks.
Johannes Schindelin June 14, 2020, 10:26 p.m. UTC | #8
Hi Pratyush,

On Mon, 15 Jun 2020, Pratyush Yadav wrote:

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

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

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

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

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

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

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

So I think this example...

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

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

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

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

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

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

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

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

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

Ciao,
Johannes
Pratyush Yadav June 15, 2020, 10:03 a.m. UTC | #9
Hi,

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

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

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

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

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

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

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

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

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

I'll see if I can find time this week to work up a FAQ entry about how
to do this, since it seems to be a common question folks have.  I myself
wasn't aware of "git remote set-head" until the other day, so I don't
expect others to be familiar with it, either.
Denton Liu June 16, 2020, 12:19 a.m. UTC | #11
Hi Dscho,

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

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

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

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

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

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

I think I see three possible solutions to this:

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

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

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

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

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

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

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

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

Thoughts?
Ævar Arnfjörð Bjarmason June 16, 2020, 9:47 a.m. UTC | #12
On Wed, Jun 10 2020, Johannes Schindelin via GitGitGadget wrote:

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

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

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

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

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

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

Specifically:

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

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

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

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

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

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

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

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

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

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

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

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

1. git diff --stat -p @{u}...pr-656/dscho/default-branch-name-option-v2
Jeff King June 16, 2020, 2:09 p.m. UTC | #13
On Tue, Jun 16, 2020 at 11:47:10AM +0200, Ævar Arnfjörð Bjarmason wrote:

> But I do have purely technical concerns about where this is going.
> 
> The part where we just make it easier to do what you could do all along
> with sed(1) or whatever to rename the branch after "git init" is
> obviously correct (or close enough). That part's easy enough.
> 
> The parts I'm concerned about is the behavior of how we make the branch
> name persistent, which is new "while we're at it" behavior in git
> unrelated to the convenience of allowing a configuration of the main
> branch name without "git init --template" or after the fact sed(1)
> munging.

I've read the whole thing and left some specific comments, but your
thinking more or less matches mine, with a few notes below.

> Specifically:
> 
>  1. The special case in fmt-merge-msg we always had for "master" sucked
>     in terms of producing more verbose merge messages for those of us
>     who had repos where the main branch wasn't "master", but at least it
>     was consistent.
> 
>     Now we've created a situation where a user's local config impacts
>     what we put in the machine-generated commit messages.
> 
>     Now, these messages were never "plumbing", and other users could use
>     different git frontends than "core git" etc, but it's a really
>     useful property we've tried to maintain that a user's local
>     configuration doesn't change what we put in these messages. It's why
>     we've left them out of the i18n mechanism.

I'm actually tempted to say that "master" should stop being special.
It's a little nice, I guess, if merges back to the main branch are a
little more terse in their message. But I actually think consistently
saying:

  Merge branch 'jk/foo' into main

_even if it's the main branch_ is actually pretty sane. It conveys more
information about what happened that could be useful later, and I don't
think it makes the result less readable.

>  2. The whole core.mainBranch thing rubs me the wrong way. So now if we
>     rename a branch we munge it, but if you've got an older git version
>     or whatever you get different results and the config isn't carried
>     forward.
> 
>     I'd *really* like to avoid having what's essentially a refstore
>     side-value if we can.

I think it's necessary if we're going to have parts of the code that say
"this is the special branch in this repo". Because we must leave the
unconfigured state as "master is the special branch" in order to avoid
regressing existing repositories. It _could_ be a flag that says "I was
configured using init.mainBranch, so use that value". But I don't think
that solves your fundamental concerns.

However, I wonder if we can get away with saying "there is no special
branch" entirely. The things that care about the special branch are:

 - guessing HEAD; but this is guessing what the _remote_ side wants
   anyway, so it really has nothing to do with your local
   core.mainBranch (plus that guess shouldn't even be used much with
   modern git anyway).

 - the default branch for submodules; this is basically the same boat,
   and really ought to just be using the remote HEAD anyway.

 - slightly shorter merge messages. See above.

 - various "perhaps you should specify a branch such as master"
   messages. These could be reworded to avoid mentioning a specific
   branch, or could pick a real branch name.

 - fast-export anonymization. We could probably use HEAD as "ref0"
   instead (or do the output-map thing I mentioned, which is a much
   better solution anyway).

I think with that, we could ditch core.mainBranch entirely, with no
notion at all of "this branch is special in this repo". We use HEAD
where appropriate, and otherwise avoid any specialness.

>  3. Whatever we do with the submodule guess-a-name functionality, I
>     think it's the wrong path to make it proceed in lockstep with
>     MAIN_BRANCH_FOR_INIT.
> 
>     When you decide to change your branch names != when the rest of the
>     world does it.

Yeah, this was my main concern for the whole series: what will break in
a world of mixed main-branch names. Thankfully very little, it seems.
But as much as possible we should be not just choosing our preferred
value, but trying to match possible states. I think teaching the
HEAD-guessing to try a few names, plus using HEAD for submodules, will
pretty much do it (see my replies to individual patches for more
details).

-Peff
Jeff King June 16, 2020, 2:24 p.m. UTC | #14
On Tue, Jun 16, 2020 at 10:09:32AM -0400, Jeff King wrote:

> I think with that, we could ditch core.mainBranch entirely, with no
> notion at all of "this branch is special in this repo". We use HEAD
> where appropriate, and otherwise avoid any specialness.

One obvious exception is that third-party tools may want to know the
"special" branch for some reason. But I'm inclined to say that they
should (in this order):

  - consider whether they really need a special branch at all, or if the
    mechanism can be made more generic

  - consider whether HEAD is the best value for a special branch (e.g.,
    GitHub pull requests default to targeting HEAD)

  - rely on per-tool config for what's special (because it really may
    vary between tools, and that's more flexible anyway)

But I'm open to hearing about cases where some tool really wants to know
"what did the user consider the special branch at the time of creation".

-Peff
Junio C Hamano June 17, 2020, 8:28 p.m. UTC | #15
Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:

>  1. The special case in fmt-merge-msg we always had for "master" sucked
>     in terms of producing more verbose merge messages for those of us
>     who had repos where the main branch wasn't "master", but at least it
>     was consistent.
>
>     Now we've created a situation where a user's local config impacts
>     what we put in the machine-generated commit messages.
>
>     Now, these messages were never "plumbing", and other users could use
>     different git frontends than "core git" etc, but it's a really
>     useful property we've tried to maintain that a user's local
>     configuration doesn't change what we put in these messages. It's why
>     we've left them out of the i18n mechanism.

I doubt the last sentence reflects the reality.  As the person who
invented the fmt-merge-msg's mechanism (including it special casing
of 'master'), I know that it was the sentence lego that made it
impossible to localize and left the code pretty much intact since
the days it was introduced.

Having said that, I am personally inclined to vote for getting rid
of the special casing of any branch by "git fmt-merge-msg" and "git
fast-export --anonymize".  We still need a mechanism to let users
configure the word used by "git init" to give the first branch it
creates as its name, but that is merely the first branch created in
the repository and does not have to be the primary.

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

And we can get rid of this worry at the same time by doing so.
Johannes Schindelin June 23, 2020, 8:10 p.m. UTC | #16
Hi Denton,

On Mon, 15 Jun 2020, Denton Liu wrote:

> On Mon, Jun 15, 2020 at 12:26:03AM +0200, Johannes Schindelin wrote:
> > > For example, my vim plugins are submodules in the '~/.vim/bundle'
> > > directory. When I want to update them, I run:
> > >
> > >   git submodule foreach 'git remote update && git reset --hard origin/master'
> > >
> > > With this change hitting a Git release, more and more people would call
> > > their main branch different names they like. So what is the recommended
> > > way to do something like this now? How do I checkout the tip of the main
> > > branch? How do I push to the main branch? How do I pull from the main
> > > branch? And so on...
> >
> > ... has less to do with a new Git release, but more with the decision of
> > an existing project to change their main branch name.
> >
> > That's something users already had to deal with, of course. For example,
> > projects switching to the Git Flow model will start to use the main branch
> > name `development`.
>
> I brought this concern up in a parallel thread but I'll bring it up here
> too since it's relevant. Currently, in the .gitmodules file, if the
> branch is not specified, it defaults to 'master'.
>
> When I want to update my vim plugins, I run
> `git submodule update --remote` which pulls in all of my submodules'
> 'master' branches. By convention, a lack of `branch` key in .gitmodules
> conventionally means 'master'.
>
> With your change, it becomes the value of git_main_branch_name(), which
> is fine for now. However, if this value changes to something else, then
> when I update my Git, suddenly `git submodule update --remote` will be
> broken for me as all of the new repositories that I pull will be for an
> incorrect (and possibly missing) branch.
>
> This leaves us in a scenario where one developer running an older
> version of Git would have submodule updates work perfectly fine while a
> developer with a newer version would have it suddenly broken. This might
> be hard to debug, especially for someone who doesn't follow the release
> notes around Git and doesn't realise why the default has suddenly
> changed.
>
> This problem gets much worse if we allow the main branch name to be
> configurable as then the *private* configurations that a developer has
> may have an effect on the *publicly visible* behaviour of a repository.
>
> I think I see three possible solutions to this:
>
> 	1. Special case 'master' in submodules to retain backwards
> 	compatibility.
>
> 	I don't think this is very appealing as if the change is made to
> 	use another default branch name, then the "default" branch for
> 	submodules would be "master" even though the new default
> 	everywhere else would be different. And in the future, someone
> 	who doesn't know the context behind all of this would be very
> 	confused where there are two different default branch names.
>
> 	2. Disable 'update --remote' support for submodules that don't
> 	specify a branch.
>
> 	If Git detects that a branch key is missing when trying to do an
> 	'update --remote', it should just quit out and refuse to do
> 	anything. Of course, this a very backwards incompatible change
> 	and it would require several release cycles to implement where
> 	we warn users about this impending change before we actually
> 	make it happen.
>
> 	3. Make 'update --remote' get HEAD.
>
> 	I argue that this is how it always should've been implemented
> 	but, alas, I can't go back in time and fix it. Regardless, it
> 	might be good to flip this to be the default if we're going to
> 	be making the change anyway.
>
> 	Unfortunately, this suffers from both the problems of 1 and 2.
> 	As with 1, we'll end up in a situation where users with
> 	different versions of Git may experience different behaviours
> 	given the same public repository and I think this is definitely
> 	undesirable. With 2, this change will also require a long
> 	deprecation period which I don't think it compatible with how
> 	people seem to want the default branch switch to happen this
> 	release.
>
> So I dunno. I think my opinion leans on not changing the default branch
> at all. Since it seems like the consensus is generally that it _will_
> change, I think I would prefer options 3, 2 and 1 in that order.
>
> Thoughts?

My intuition matches your preference, and I have a strong preference for
3.

It took some banging my head (not my HEAD...) against the code to convince
myself that the patch I prepared for v3 is good: I managed to confuse
myself what with all those submodules and clones in t7406.

Ciao,
Dscho
Johannes Schindelin June 23, 2020, 8:28 p.m. UTC | #17
Hi Peff & Ævar,

On Tue, 16 Jun 2020, Jeff King wrote:

> On Tue, Jun 16, 2020 at 10:09:32AM -0400, Jeff King wrote:
>
> > I think with that, we could ditch core.mainBranch entirely, with no
> > notion at all of "this branch is special in this repo". We use HEAD
> > where appropriate, and otherwise avoid any specialness.
>
> One obvious exception is that third-party tools may want to know the
> "special" branch for some reason. But I'm inclined to say that they
> should (in this order):
>
>   - consider whether they really need a special branch at all, or if the
>     mechanism can be made more generic
>
>   - consider whether HEAD is the best value for a special branch (e.g.,
>     GitHub pull requests default to targeting HEAD)

Indeed, this is applicable in many circumstances. For example, instead of
https://github.com/git/git/blob/master/README.md it is just as easy (and
more robust) to write https://github.com/git/git/blob/HEAD/README.md.

The same goes for `git ls-remote origin HEAD` and as a consequence, `git
fetch origin HEAD`: it fetches the default branch of the remote
repository.

And with that, I could imagine that this is not actually necessary:

>   - rely on per-tool config for what's special (because it really may
>     vary between tools, and that's more flexible anyway)
>
> But I'm open to hearing about cases where some tool really wants to know
> "what did the user consider the special branch at the time of creation".

I cannot think of any use cases, apart from essentially creating a new
repository, where a tool or a user would want to know of such a
preference.

Ciao,
Dscho