Allow overriding the default name of the default branch
Re: [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially
In reply to Đoàn Trần Công DanhHi Danh,
Quoted 6 lines · Đoàn Trần Công Danh
Quoted 5 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
In the context of many projects renaming their primary branch names away from
master, Git wants to stop treating themasterbranch specially.
Quoted 8 lines
Quoted 4 lines
Let's start with
git fmt-merge-msg.Signed-off-by Johannes Schindelin <[email protected]>---
Hi Dscho,
This change will also affect git-subtree test.
Good point. The patch looks good. I wonder whether we should also address these:
Documentation/git-rebase.txt:* Merge branch 'report-a-bug'
Documentation/git-rebase.txt:* | Merge branch 'refactor-button'
Documentation/git-switch.txt:HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits' Documentation/howto/using-signed-tag-in-pull-request.txt: Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/Documentation/howto/using-signed-tag-in-pull-request.txt: Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/
t/t7606-merge-custom.sh:* (HEAD, master) Merge commit 'c3'
The first three matches are in manual pages, the next two in technical documentation, and the last one in a comment in one of the test scripts. So none of them are super critical, but maybe there are different opinions?
Ciao,
Dscho
Quoted 46 lines
We'll need this patch for subtree:
----------------8<-------------------
From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=
<[email protected]>
Date: Mon, 29 Jun 2020 22:56:37 +0700
Subject: [PATCH] contrib: subtree: adjust test to change in fmt-merge-msg
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bitWe're starting to stop treating `master' specially in fmt-merge-msg. Adjust the test to reflect that change.
Signed-off-by Đoàn Trần Công Danh <[email protected]>--- contrib/subtree/t/t7900-subtree.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)contrib/subtree/t/t7900-subtree.sh +4
-3@@ -196,7 +196,8 @@ test_expect_success 'merge new subproj history into sub dir/ with --prefix' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" + check_equal "$(last_commit_message)" \ + "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into master" ) '@@ -273,7 +274,8 @@ test_expect_success 'merge new subproj history into subdir/ with a slash appende cd "$test_count" && git fetch ./subproj master && git subtree merge --prefix=subdir/ FETCH_HEAD && - check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" + check_equal "$(last_commit_message)" \ + "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into master" ) ' --2.27.0.111.gc72c7da667
Danh
Re: [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially
Hi Dscho,
Quoted 12 lines · Johannes Schindelin
Quoted 1 line
This change will also affect git-subtree test.
Good point. The patch looks good. I wonder whether we should also address these:
Documentation/git-rebase.txt:* Merge branch 'report-a-bug'
Documentation/git-rebase.txt:* | Merge branch 'refactor-button'
Documentation/git-switch.txt:HEAD is now at9fc9555312Merge branch 'cc/shared-index-permbits'Documentation/howto/using-signed-tag-in-pull-request.txt: Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/Documentation/howto/using-signed-tag-in-pull-request.txt: Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/
t/t7606-merge-custom.sh:* (HEAD, master) Merge commit 'c3'
Quoted 4 lines
The first three matches are in manual pages, the next two in technical documentation, and the last one in a comment in one of the test scripts. So none of them are super critical, but maybe there are different opinions?
In _my very opinion_, I don't think it's that critical. We allow git merge --edit and git fmt-merge-msg -m. Someone may have configured their Git to remove branch name already. And some others may always remove the target branch manually. We probably don't want to introduce another master occurence. (For sideline watcher: Please not argue on this,
I don't have any opinions about the word: master.)
If there're a consensus on changing those documentation, I won't mind to do that manual work ;)
The test is a different story, since some (or most?) distro enable check (or test) phase for their build infrastructure. And, we shouldn't break their infrastructures.
Quoted 50 lines
Ciao,
DschoQuoted 46 lines
We'll need this patch for subtree:
----------------8<-------------------
From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=
<[email protected]>
Date: Mon, 29 Jun 2020 22:56:37 +0700
Subject: [PATCH] contrib: subtree: adjust test to change in fmt-merge-msg
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bitWe're starting to stop treating `master' specially in fmt-merge-msg. Adjust the test to reflect that change.
Signed-off-by Đoàn Trần Công Danh <[email protected]>--- contrib/subtree/t/t7900-subtree.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)contrib/subtree/t/t7900-subtree.sh +4
-3@@ -196,7 +196,8 @@ test_expect_success 'merge new subproj history into sub dir/ with --prefix' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" + check_equal "$(last_commit_message)" \ + "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into master" ) '@@ -273,7 +274,8 @@ test_expect_success 'merge new subproj history into subdir/ with a slash appende cd "$test_count" && git fetch ./subproj master && git subtree merge --prefix=subdir/ FETCH_HEAD && - check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" + check_equal "$(last_commit_message)" \ + "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into master" ) ' --2.27.0.111.gc72c7da667
Danh
Signature · 1 line
Danh
Re: [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially
Hi Danh,
Quoted 18 lines · Đoàn Trần Công Danh
Quoted 12 lines · Johannes Schindelin
Quoted 1 line
This change will also affect git-subtree test.
Good point. The patch looks good. I wonder whether we should also address these:
Documentation/git-rebase.txt:* Merge branch 'report-a-bug'
Documentation/git-rebase.txt:* | Merge branch 'refactor-button'
Documentation/git-switch.txt:HEAD is now at9fc9555312Merge branch 'cc/shared-index-permbits'Documentation/howto/using-signed-tag-in-pull-request.txt: Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/Documentation/howto/using-signed-tag-in-pull-request.txt: Merge tag 'frotz-for-xyzzy' of example.com:/git/froboz.git/
t/t7606-merge-custom.sh:* (HEAD, master) Merge commit 'c3'Quoted 4 lines
The first three matches are in manual pages, the next two in technical documentation, and the last one in a comment in one of the test scripts. So none of them are super critical, but maybe there are different opinions?
Quoted 7 lines
In
_myveryopinion_, I don't think it's that critical. We allow git merge --edit and git fmt-merge-msg -m. Someone may have configured their Git to remove branch name already. And some others may always remove the target branch manually. We probably don't want to introduce another master occurence. (For sideline watcher: Please not argue on this,
I don't have any opinions about the word: master.)
True.
Quoted 2 lines
If there're a consensus on changing those documentation, I won't mind to do that manual work ;)
I actually agree that it is not _really_ necessary.
Quoted 3 lines
The test is a different story, since some (or most?) distro enable check (or test) phase for their build infrastructure. And, we shouldn't break their infrastructures.
Actually, the hit in t7606 is in the initial _comment_. So I highly doubt that it would break any build infrastructure to leave it alone.
Ciao,
Dscho
Quoted 55 lines
Quoted 46 lines
Ciao,
DschoQuoted 42 lines
We'll need this patch for subtree:
----------------8<-------------------
From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=
<[email protected]>
Date: Mon, 29 Jun 2020 22:56:37 +0700
Subject: [PATCH] contrib: subtree: adjust test to change in fmt-merge-msg
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bitWe're starting to stop treating `master' specially in fmt-merge-msg. Adjust the test to reflect that change.
Signed-off-by Đoàn Trần Công Danh <[email protected]>--- contrib/subtree/t/t7900-subtree.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)contrib/subtree/t/t7900-subtree.sh +4
-2@@ -196,7 +196,8 @@ test_expect_success 'merge new subproj history into sub dir/ with --prefix' ' cd "$subtree_test_count" && git fetch ./"sub proj" master && git subtree merge --prefix="sub dir" FETCH_HEAD && - check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" + check_equal "$(last_commit_message)" \ + "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into master" ) '@@ -273,7 +274,8 @@ test_expect_success 'merge new subproj history into subdir/ with a slash appende cd "$test_count" && git fetch ./subproj master && git subtree merge --prefix=subdir/ FETCH_HEAD && - check_equal "$(last_commit_message)" "Merge commit '\''$(git rev-parse FETCH_HEAD)'\''" + check_equal "$(last_commit_message)" \ + "Merge commit '\''$(git rev-parse FETCH_HEAD)'\'' into master" ) 'Quoted 4 lines
Quoted 4 lines
--
2.27.0.111.gc72c7da667
Danh--
Danh
Re: [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially
Quoted 9 lines · Johannes Schindelin
Quoted 3 lines
In
_myveryopinion_, I don't think it's that critical. We allow git merge --edit and git fmt-merge-msg -m.
...True.
Quoted 2 lines
If there're a consensus on changing those documentation, I won't mind to do that manual work ;)
Quoted 8 lines
I actually agree that it is not _really_ necessary.
Quoted 3 lines
The test is a different story, since some (or most?) distro enable check (or test) phase for their build infrastructure. And, we shouldn't break their infrastructures.
Actually, the hit in t7606 is in the initial _comment_. So I highly doubt that it would break any build infrastructure to leave it alone.
I guess it's settled, then.
Thank you to all for being extra careful.
PATCH v4 2/9 send-pack/transport-helper: avoid mentioning a particular branch
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When trying to push all matching branches, but none match, we offer a message suggesting to push the master branch.
However, we want to step away from making that branch any more special than any other branch, so let's reword that message to mention no branch in particular.
--- send-pack.c | 2 +- t/t5528-push-default.sh | 6 ++++++ transport-helper.c | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-)
send-pack.c +1 -1
@@ -406,7 +406,7 @@ int send_pack(struct send_pack_args *args,if (!remote_refs) {fprintf (stderr,"No refs in common and none specified; doing nothing.\n" -"Perhaps you should specify a branch such as 'master'.\n" ); +"Perhaps you should specify a branch.\n" );return 0 ; }if (args->atomic && !atomic_supported)
t/t5528-push-default.sh +6 -0
@@ -98,6 +98,12 @@ test_expect_success 'push from/to new branch with upstream, matching and simple' test_push_failure upstream ' +test_expect_success '"matching" fails if none match' ' + git init --bare empty && + test_must_fail git push empty : 2>actual && + test_i18ngrep "Perhaps you should specify a branch" actual +' + test_expect_success 'push ambiguously named branch with upstream, matching and simple' ' git checkout -b ambiguous && test_config branch.ambiguous.remote parent1 &&
transport-helper.c +1 -1
@@ -1046,7 +1046,7 @@ static int push_refs(struct transport *transport,if (!remote_refs) {fprintf (stderr,_ ("No refs in common and none specified; doing nothing.\n" -"Perhaps you should specify a branch such as 'master'.\n" )); +"Perhaps you should specify a branch.\n" ));return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v4 3/9 submodule: fall back to remote's HEAD for missing remote.<name>.branch
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When remote.<name>.branch is not configured, git submodule update currently falls back to using the branch name master. A much better idea, however, is to use the remote HEAD: on all Git servers running reasonably recent Git versions, the symref HEAD points to the main branch.
Note: t7419 demonstrates that there _might_ be use cases out there that _expect_ git submodule update --remote to update submodules to the remote master branch even if the remote HEAD points to another branch. Arguably, this patch makes the behavior more intuitive, but there is a slight possibility that this might cause regressions in obscure setups.
Even so, it should be okay to fix this behavior without anything like a longer transition period:
- The git submodule update --remote command is not really common.
- Current Git's behavior when running this command is outright confusing, unless the remote repository's current branch _is_ master (in which case the proposed behavior matches the old behavior).
- If a user encounters a regression due to the changed behavior, the fix is actually trivial: setting submodule.<name>.branch to master will reinstate the old behavior.
--- Documentation/git-submodule.txt | 12 ++++++------ Documentation/gitmodules.txt | 6 +++--- builtin/submodule--helper.c | 2 +- t/t7406-submodule-update.sh | 16 ++++++++++++++++ t/t7419-submodule-set-branch.sh | 7 +++++-- 5 files changed, 31 insertions(+), 12 deletions(-)
Documentation/git-submodule.txt +6 -6
@@ -183,7 +183,7 @@ set-branch (-d|--default) [--] <path>:: Sets the default remote tracking branch for the submodule. The `--branch` option allows the remote branch to be specified. The `--default` option removes the submodule.<name>.branch configuration - key, which causes the tracking branch to default to 'master'. + key, which causes the tracking branch to default to the remote 'HEAD'. set-url [--] <path> <newurl>:: Sets the URL of the specified submodule to <newurl>. Then, it will
@@ -284,7 +284,7 @@ OPTIONS `.gitmodules` for `update --remote`. A special value of `.` is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository. If the - option is not specified, it defaults to 'master'. + option is not specified, it defaults to the remote 'HEAD'. -f:: --force::
@@ -322,10 +322,10 @@ OPTIONS the superproject's recorded SHA-1 to update the submodule, use the status of the submodule's remote-tracking branch. The remote used is branch's remote (`branch.<name>.remote`), defaulting to `origin`. - The remote branch used defaults to `master`, but the branch name may - be overridden by setting the `submodule.<name>.branch` option in - either `.gitmodules` or `.git/config` (with `.git/config` taking - precedence). + The remote branch used defaults to the remote `HEAD`, but the branch + name may be overridden by setting the `submodule.<name>.branch` + option in either `.gitmodules` or `.git/config` (with `.git/config` + taking precedence). + This works for any of the supported update procedures (`--checkout`, `--rebase`, etc.). The only change is the source of the target SHA-1.
Documentation/gitmodules.txt +3 -3
@@ -49,9 +49,9 @@ submodule.<name>.update:: submodule.<name>.branch:: A remote branch name for tracking updates in the upstream submodule. - If the option is not specified, it defaults to 'master'. A special - value of `.` is used to indicate that the name of the branch in the - submodule should be the same name as the current branch in the + If the option is not specified, it defaults to the remote 'HEAD'. + A special value of `.` is used to indicate that the name of the branch + in the submodule should be the same name as the current branch in the current repository. See the `--remote` documentation in linkgit:git-submodule[1] for details.
builtin/submodule--helper.c +1 -1
@@ -1981,7 +1981,7 @@ static const char *remote_submodule_branch(const char *path)free (key);if (!branch) -return "master" ; +return "HEAD" ;if (!strcmp (branch,"." )) {const char *refname =resolve_ref_unsafe ("HEAD" ,0 ,NULL ,NULL );
t/t7406-submodule-update.sh +16 -0
@@ -70,6 +70,22 @@ test_expect_success 'setup a submodule tree' ' ) ' +test_expect_success 'update --remote falls back to using HEAD' ' + test_create_repo main-branch-submodule && + test_commit -C main-branch-submodule initial && + + test_create_repo main-branch && + git -C main-branch submodule add ../main-branch-submodule && + git -C main-branch commit -m add-submodule && + + git -C main-branch-submodule switch -c hello && + test_commit -C main-branch-submodule world && + + git clone --recursive main-branch main-branch-clone && + git -C main-branch-clone submodule update --remote main-branch-submodule && + test_path_exists main-branch-clone/main-branch-submodule/world.t +' + test_expect_success 'submodule update detaching the HEAD ' ' (cd super/submodule && git reset --hard HEAD~1
t/t7419-submodule-set-branch.sh +5 -2
@@ -52,12 +52,13 @@ test_expect_success 'test submodule set-branch --branch' ' ' test_expect_success 'test submodule set-branch --default' ' + test_commit -C submodule c && (cd super && git submodule set-branch --default submodule && ! grep branch .gitmodules && git submodule update --remote && cat <<-\EOF >expect && - a + c EOF git -C submodule show -s --pretty=%s >actual && test_cmp expect actual
@@ -65,6 +66,7 @@ test_expect_success 'test submodule set-branch --default' ' ' test_expect_success 'test submodule set-branch -b' ' + test_commit -C submodule b && (cd super && git submodule set-branch -b topic submodule && grep "branch = topic" .gitmodules &&
@@ -78,12 +80,13 @@ test_expect_success 'test submodule set-branch -b' ' ' test_expect_success 'test submodule set-branch -d' ' + test_commit -C submodule d && (cd super && git submodule set-branch -d submodule && ! grep branch .gitmodules && git submodule update --remote && cat <<-\EOF >expect && - a + d EOF git -C submodule show -s --pretty=%s >actual && test_cmp expect actual
Signature · 1 line
gitgitgadget
Re: [PATCH v4 3/9] submodule: fall back to remote's HEAD for missing remote.<name>.branch
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 9 lines · writes:
Even so, it should be okay to fix this behavior without anything like a longer transition period:
- The
git submodule update --remotecommand is not really common.- Current Git's behavior when running this command is outright confusing, unless the remote repository's current branch _is_
master(in which case the proposed behavior matches the old behavior).
Quoted 7 lines
- If a user encounters a regression due to the changed behavior, the fix is actually trivial: setting
submodule.<name>.branchtomasterwill reinstate the old behavior.Helped-by Philippe Blain <[email protected]>Signed-off-by Johannes Schindelin <[email protected]>---
Well explained. Thanks.
PATCH v4 4/9 docs: add missing diamond brackets
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
There were a couple of instances in our manual pages that had an opening diamond bracket without a corresponding closing one.
--- Documentation/git-branch.txt | 2 +- Documentation/git-clone.txt | 2 +- Documentation/git-init.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
Documentation/git-branch.txt +1 -1
@@ -12,7 +12,7 @@ SYNOPSIS [-v [--abbrev=<length> | --no-abbrev]] [--column[=<options>] | --no-column] [--sort=<key>] [(--merged | --no-merged) [<commit>]] - [--contains [<commit]] [--no-contains [<commit>]] + [--contains [<commit>]] [--no-contains [<commit>]] [--points-at <object>] [--format=<format>] [(-r | --remotes) | (-a | --all)] [--list] [<pattern>...]
Documentation/git-clone.txt +1 -1
@@ -259,7 +259,7 @@ maintain a branch with no references other than a single cloned branch. This is useful e.g. to maintain minimal clones of the default branch of some repository for search indexing. ---recurse-submodules[=<pathspec]:: +--recurse-submodules[=<pathspec>]:: After the clone is created, initialize and clone submodules within based on the provided pathspec. If no pathspec is provided, all submodules are initialized and cloned.
Documentation/git-init.txt +1 -1
@@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git init' [-q | --quiet] [--bare] [--template=<template_directory>] - [--separate-git-dir <git dir>] [--object-format=<format] + [--separate-git-dir <git dir>] [--object-format=<format>] [--shared[=<permissions>]] [directory]
Signature · 1 line
gitgitgadget
PATCH v4 5/9 init: allow specifying the initial branch name for the new repository
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
There is a growing number of projects and companies desiring to change the main branch name of their repositories (see e.g.
https://twitter.com/mislav/status/1270388510684598272 for background on this).
To change that branch name for new repositories, currently the only way to do that automatically is by copying all of Git's template directory, then hard-coding the desired default branch name into the .git/HEAD file, and then configuring init.templateDir to point to those copied template files.
To make this process much less cumbersome, let's introduce a new option:--initial-branch=<branch-name>.
--- Documentation/git-init.txt | 7 +++++++ builtin/clone.c | 3 ++- builtin/init-db.c | 33 +++++++++++++++++++++++++++------ cache.h | 2 +- t/t0001-init.sh | 13 +++++++++++++ 5 files changed, 50 insertions(+), 8 deletions(-)
Documentation/git-init.txt +7 -0
@@ -11,6 +11,7 @@ SYNOPSIS [verse] 'git init' [-q | --quiet] [--bare] [--template=<template_directory>] [--separate-git-dir <git dir>] [--object-format=<format>] + [-b <branch-name> | --initial-branch=<branch-name>] [--shared[=<permissions>]] [directory]
@@ -67,6 +68,12 @@ repository. + If this is reinitialization, the repository will be moved to the specified path. +-b <branch-name:: +--initial-branch=<branch-name>:: + +Use the specified name for the initial branch in the newly created repository. +If not specified, fall back to the default name: `master`. + --shared[=(false|true|umask|group|all|world|everybody|0xxx)]:: Specify that the Git repository is to be shared amongst several users. This
builtin/clone.c +2 -1
@@ -1111,7 +1111,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix) } } -init_db (git_dir, real_git_dir, option_template,GIT_HASH_UNKNOWN ,INIT_DB_QUIET ); +init_db (git_dir, real_git_dir, option_template,GIT_HASH_UNKNOWN ,NULL , +INIT_DB_QUIET );if (real_git_dir) git_dir = real_git_dir;
builtin/init-db.c +27 -6
@@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)static int create_default_files (const char *template_path,const char *original_git_dir, +const char *initial_branch,const struct repository_format *fmt) {struct stat st1;
@@ -258,15 +259,26 @@ static int create_default_files(const char *template_path,die ("failed to set up refs db: %s" , err.buf);/* -* Create the default symlink from ".git/HEAD" to the "master" -* branch, if it does not exist yet. +* Point the HEAD symref to the initial branch with if HEAD does +* not yet exist. */ path =git_path_buf (&buf,"HEAD" ); reinit = (!access (path,R_OK ) ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) { -if (create_symref ("HEAD" ,"refs/heads/master" ,NULL ) <0 ) +char *ref; + +if (!initial_branch) + initial_branch ="master" ; + + ref =xstrfmt ("refs/heads/%s" , initial_branch); +if (check_refname_format (ref,0 ) <0 ) +die (_ ("invalid initial branch name: '%s'" ), + initial_branch); + +if (create_symref ("HEAD" , ref,NULL ) <0 )exit (1 ); +free (ref); }initialize_repository_version (fmt->hash_algo);
@@ -383,7 +395,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash }int init_db (const char *git_dir,const char *real_git_dir, -const char *template_dir,int hash,unsigned int flags) +const char *template_dir,int hash,const char *initial_branch, +unsigned int flags) {int reinit;int exist_ok = flags &INIT_DB_EXIST_OK ;
@@ -425,7 +438,11 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); - reinit =create_default_files (template_dir, original_git_dir, &repo_fmt); + reinit =create_default_files (template_dir, original_git_dir, + initial_branch, &repo_fmt); +if (reinit && initial_branch) +warning (_ ("re-init: ignored --initial-branch=%s" ), + initial_branch);create_object_directory ();
@@ -528,6 +545,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)const char *template_dir =NULL ;unsigned int flags =0 ;const char *object_format =NULL ; +const char *initial_branch =NULL ;int hash_algo =GIT_HASH_UNKNOWN ;const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ -541,6 +559,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)OPT_BIT ('q' ,"quiet" , &flags,N_ ("be quiet" ),INIT_DB_QUIET ),OPT_STRING (0 ,"separate-git-dir" , &real_git_dir,N_ ("gitdir" ),N_ ("separate git dir from working tree" )), +OPT_STRING ('b' ,"initial-branch" , &initial_branch,N_ ("name" ), +N_ ("override the name of the initial branch" )),OPT_STRING (0 ,"object-format" , &object_format,N_ ("hash" ),N_ ("specify the hash algorithm to use" )),OPT_END ()
@@ -652,5 +672,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)UNLEAK (work_tree); flags |=INIT_DB_EXIST_OK ; -return init_db (git_dir, real_git_dir, template_dir, hash_algo, flags); +return init_db (git_dir, real_git_dir, template_dir, hash_algo, + initial_branch, flags); }
cache.h +1 -1
@@ -628,7 +628,7 @@ int path_inside_repo(const char *prefix, const char *path);int init_db (const char *git_dir,const char *real_git_dir,const char *template_dir,int hash_algo, -unsigned int flags); +const char *initial_branch,unsigned int flags);void initialize_repository_version (int hash_algo);void sanitize_stdfds (void );
t/t0001-init.sh +13 -0
@@ -464,4 +464,17 @@ test_expect_success MINGW 'redirect std handles' ' grep "Needed a single revision" output.txt ' +test_expect_success '--initial-branch' ' + git init --initial-branch=hello initial-branch-option && + git -C initial-branch-option symbolic-ref HEAD >actual && + echo refs/heads/hello >expect && + test_cmp expect actual && + + : re-initializing should not change the branch name && + git init --initial-branch=ignore initial-branch-option 2>err && + test_i18ngrep "ignored --initial-branch" err && + git -C initial-branch-option symbolic-ref HEAD >actual && + grep hello actual +' + test_done
Signature · 1 line
gitgitgadget
PATCH v4 6/9 init: allow setting the default for the initial branch name via the config
In reply to Johannes Schindelin via GitGitGadgetFrom: Don Goodman-Wilson <[email protected]>
We just introduced the command-line option --initial-branch=<branch-name> to allow initializing a new repository with a different initial branch than the hard-coded one.
To allow users to override the initial branch name more permanently (i.e. without having to specify the name manually for each and every git init invocation), let's introduce the init.defaultBranch config setting.
--- Documentation/config/init.txt | 4 ++++ builtin/init-db.c | 2 +- refs.c | 30 ++++++++++++++++++++++++++++++ refs.h | 9 +++++++++ t/t0001-init.sh | 13 +++++++++++++ 5 files changed, 57 insertions(+), 1 deletion(-)
Documentation/config/init.txt +4 -0
@@ -1,3 +1,7 @@ init.templateDir:: Specify the directory from which templates will be copied. (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].) + +init.defaultBranch:: + Allows overriding the default branch name when initializing + a new repository.
builtin/init-db.c +1 -1
@@ -269,7 +269,7 @@ static int create_default_files(const char *template_path,char *ref;if (!initial_branch) - initial_branch ="master" ; + initial_branch =git_default_branch_name (); ref =xstrfmt ("refs/heads/%s" , initial_branch);if (check_refname_format (ref,0 ) <0 )
refs.c +30 -0
@@ -560,6 +560,36 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)argv_array_pushf (prefixes, *p, len, prefix); } +char *repo_default_branch_name (struct repository *r) +{ +const char *config_key ="init.defaultbranch" ; +const char *config_display_key ="init.defaultBranch" ; +char *ret =NULL , *full_ref; + +if (repo_config_get_string (r, config_key, &ret) <0 ) +die (_ ("could not retrieve `%s`" ), config_display_key); + +if (!ret) + ret =xstrdup ("master" ); + + full_ref =xstrfmt ("refs/heads/%s" , ret); +if (check_refname_format (full_ref,0 )) +die (_ ("invalid branch name: %s = %s" ), config_display_key, ret); +free (full_ref); + +return ret; +} + +const char *git_default_branch_name (void ) +{ +static char *ret; + +if (!ret) + ret =repo_default_branch_name (the_repository); + +return ret; +} +/* * *string and *len will only be substituted, and *string returned (for * later free()ing) if the string passed in is a magic short-hand form
refs.h +9 -0
@@ -154,6 +154,15 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_int dwim_ref (const char *str,int len,struct object_id *oid,char **ref);int dwim_log (const char *str,int len,struct object_id *oid,char **ref); +/* +* Retrieves the default branch name for newly-initialized repositories. +* +* The return value of `repo_default_branch_name()` is an allocated string. The +* return value of `git_default_branch_name()` is a singleton. +*/ +const char *git_default_branch_name (void ); +char *repo_default_branch_name (struct repository *r); +/* * A ref_transaction represents a collection of reference updates that * should succeed or fail together.
t/t0001-init.sh +13 -0
@@ -477,4 +477,17 @@ test_expect_success '--initial-branch' ' grep hello actual ' +test_expect_success 'overridden default initial branch name (config)' ' + test_config_global init.defaultBranch nmb && + git init initial-branch-config && + git -C initial-branch-config symbolic-ref HEAD >actual && + grep nmb actual +' + +test_expect_success 'invalid default branch name' ' + test_config_global init.defaultBranch "with space" && + test_must_fail git init initial-branch-invalid 2>err && + test_i18ngrep "invalid branch name" err +' + test_done
Signature · 1 line
gitgitgadget
PATCH v4 7/9 clone: use configured default branch name when appropriate
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When cloning a repository without any branches, Git chooses a default branch name for the as-yet unborn branch.
As part of the implicit initialization of the local repository, Git just learned to respect init.defaultBranch to choose a different initial branch name. We now really want that branch name to be used as a fall-back.
--- Documentation/config/init.txt | 4 ++-- builtin/clone.c | 10 +++++++--- t/t5606-clone-options.sh | 15 +++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-)
Documentation/config/init.txt +2 -2
@@ -3,5 +3,5 @@ init.templateDir:: (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].) init.defaultBranch:: - Allows overriding the default branch name when initializing - a new repository. + Allows overriding the default branch name e.g. when initializing + a new repository or when cloning an empty repository.
builtin/clone.c +7 -3
@@ -1267,9 +1267,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix) remote_head_points_at =NULL ; remote_head =NULL ; option_no_checkout =1 ; -if (!option_bare) -install_branch_config (0 ,"master" , option_origin, -"refs/heads/master" ); +if (!option_bare) { +const char *branch =git_default_branch_name (); +char *ref =xstrfmt ("refs/heads/%s" , branch); + +install_branch_config (0 , branch, option_origin, ref); +free (ref); + } } write_refspec_config(src_ref_prefix, our_head_points_at,
t/t5606-clone-options.sh +15 -0
@@ -35,4 +35,19 @@ test_expect_success 'redirected clone -v does show progress' ' ' +test_expect_success 'chooses correct default initial branch name' ' + git init --bare empty && + git -c init.defaultBranch=up clone empty whats-up && + test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) && + test refs/heads/up = $(git -C whats-up config branch.up.merge) +' + +test_expect_success 'guesses initial branch name correctly' ' + git init --initial-branch=guess initial-branch && + test_commit -C initial-branch no-spoilers && + git -C initial-branch branch abc guess && + git clone initial-branch is-it && + test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) +' + test_done
Signature · 1 line
gitgitgadget
PATCH v4 8/9 remote: use the configured default branch name when appropriate
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When guessing the default branch name of a remote, and there are no refs to guess from, we want to go with the preference specified by the user for the fall-back, i.e. the default name to be used for the initial branch of new repositories (because as far as the user is concerned, a remote that has no branches yet is a new repository).
At the same time, when talking to an older Git server that does not report a symref for HEAD (but instead reports a commit hash), let's try to guess the configured default branch name first. If it does not match the reported commit hash, let's fall back to master as before.
--- remote.c | 14 +++++++++++--- t/t5606-clone-options.sh | 11 ++++++++++- 2 files changed, 21 insertions(+), 4 deletions(-)
remote.c +11 -3
@@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)/* * The branches file would have URL and optionally -* #branch specified. The "master" (or specified) branch is +* #branch specified. The default (or specified) branch is * fetched and stored in the local branch matching the * remote name. */
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)if (frag) *(frag++) ='\0' ;else - frag ="master" ; + frag = (char *)git_default_branch_name ();add_url_alias (remote,strbuf_detach (&buf,NULL )); strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ -2097,8 +2097,16 @@ struct ref *guess_remote_head(const struct ref *head,if (head->symref)return copy_ref (find_ref_by_name (refs, head->symref)); -/* If refs/heads/master could be right, it is. */ +/* If a remote branch exists with the default branch name, let's use it. */ if (!all) { +char *ref =xstrfmt ("refs/heads/%s" ,git_default_branch_name ()); + + r =find_ref_by_name (refs, ref); +free (ref); +if (r &&oideq (&r->old_oid, &head->old_oid)) +return copy_ref (r); + +/* Fall back to the hard-coded historical default */ r =find_ref_by_name (refs,"refs/heads/master" );if (r &&oideq (&r->old_oid, &head->old_oid))return copy_ref (r);
t/t5606-clone-options.sh +10 -1
@@ -47,7 +47,16 @@ test_expect_success 'guesses initial branch name correctly' ' test_commit -C initial-branch no-spoilers && git -C initial-branch branch abc guess && git clone initial-branch is-it && - test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) + test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) && + + git -c init.defaultBranch=none init --bare no-head && + git -C initial-branch push ../no-head guess abc && + git clone no-head is-it2 && + test_must_fail git -C is-it2 symbolic-ref refs/remotes/origin/HEAD && + git -C no-head update-ref --no-deref HEAD refs/heads/guess && + git -c init.defaultBranch=guess clone no-head is-it3 && + test refs/remotes/origin/guess = \ + $(git -C is-it3 symbolic-ref refs/remotes/origin/HEAD) ' test_done
Signature · 1 line
gitgitgadget
PATCH v4 9/9 testsvn: respect `init.defaultBranch`
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The default name of the initial branch in new repositories can now be configured. The testsvn remote helper translates the remote Subversion repository's branch name trunk to the hard-coded name master. Clearly, the intention was to make the name align with Git's defaults.
So while we are not talking about a newly-created repository in the testsvn context, it is a newly-created _Git_ repository, si it _still_ makes sense to use the overridden default name for the initial branch whenever users configured it.
--- remote-testsvn.c | 10 +++++++--- t/t9020-remote-svn.sh | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-)
remote-testsvn.c +7 -3
@@ -13,7 +13,7 @@static const char *url;static int dump_from_file;static const char *private_ref; -static const char *remote_ref ="refs/heads/master" ; +static char *remote_ref;static const char *marksfilename, *notes_ref;struct rev_note {unsigned int rev_nr; };
@@ -286,7 +286,7 @@ int cmd_main(int argc, const char **argv) private_ref_sb =STRBUF_INIT , marksfilename_sb =STRBUF_INIT , notes_ref_sb =STRBUF_INIT ;static struct remote *remote; -const char *url_in; +const char *url_in, *remote_ref_short;setup_git_directory ();if (argc <2 || argc >3 ) {
@@ -294,6 +294,9 @@ int cmd_main(int argc, const char **argv)return 1 ; } + remote_ref_short =git_default_branch_name (); + remote_ref =xstrfmt ("refs/heads/%s" , remote_ref_short); + remote =remote_get (argv[1 ]); url_in = (argc ==3 ) ? argv[2 ] : remote->url[0 ];
@@ -306,7 +309,8 @@ int cmd_main(int argc, const char **argv) url = url_sb.buf; } -strbuf_addf (&private_ref_sb,"refs/svn/%s/master" , remote->name); +strbuf_addf (&private_ref_sb,"refs/svn/%s/%s" , + remote->name, remote_ref_short); private_ref = private_ref_sb.buf;strbuf_addf (¬es_ref_sb,"refs/notes/%s/revs" , remote->name);
t/t9020-remote-svn.sh +6 -0
@@ -84,6 +84,12 @@ test_expect_success REMOTE_SVN 'incremental imports must lead to the same head' test_cmp master.good .git/refs/remotes/svnsim/master ' +test_expect_success REMOTE_SVN 'respects configured default initial branch' ' + git -c init.defaultBranch=trunk remote add -f trunk \ + "testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" && + git rev-parse --verify refs/remotes/trunk/trunk +' + test_debug 'git branch -a' test_done
Signature · 1 line
gitgitgadget
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 9 lines · writes:
Changes since v3:
* We now avoid the phrasing "specify a specific" in the messages.
* The git submodule patch has a better commit title now, and it also adjusts the documentation more completely now (thanks, Philippe!).
Quoted 6 lines
* A code comment in
builtin/init-db.cwas updated to no longer talk about a symlink when it comes to HEAD.* Made it the responsibility of the caller to warn about reinit &&
initial_branch.
It looked all good to me. Will replace.
Thanks. Hopefully we can go 'next' with this round---knock wood...
Hi Junio,
Quoted 16 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 13 lines · writes:
Changes since v3:
* We now avoid the phrasing "specify a specific" in the messages.
* The git submodule patch has a better commit title now, and it also adjusts the documentation more completely now (thanks, Philippe!).
* A code comment in
builtin/init-db.cwas updated to no longer talk about a symlink when it comes to HEAD.
Quoted 6 lines
Quoted 2 lines
* Made it the responsibility of the caller to warn about reinit &&
initial_branch.It looked all good to me. Will replace.
Thanks. Hopefully we can go 'next' with this round---knock wood...
I concur!
Ciao,
Dscho
Quoted 28 lines · Johannes Schindelin via GitGitGadget
A growing number of open source projects aims to avoid the branch name master due to its negative connotation. See [1] for an existing discussion on this. The links [2], [3], and [4] describe community-driven ways for users to rename their default branches or use template edits to set a new default branch name.
[1]
https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/[2] https://twitter.com/mislav/status/1270388510684598272
[3]
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx[4] https://github.com/ethomson/retarget_prs
By necessity, existing repositories require a lot of manual work to move away from that branch name, but it should be much easier for new repositories.
This patch series allows overriding the branch name being used for new repositories' main branch. This can be configured via init.defaultBranch.
The initial patch was started by newcomer Don Goodman-Wilson, as well as the bigger change that morphed into #655, where we demonstrate how to change Git's hard-coded default branch name for new repositories to main based on this here patch series, verifying the approach. Thanks for the contribution!
Quoted 5 lines
This series DOES NOT change the default automatically, but only provides an opt-in mechanism for interested users. The plan for that is to convert the test scripts incrementally (by introducing
GIT_TEST_DEFAULT_MAIN_BRANCH_NAME, which overrides init.defaultBranch, and then converting the tricky test scripts first, one by one, using that environment variable).
I'm very happy with this and the way it's progressed since v1. This seems simpler than earlier designs, and I appreciate the improved focus on avoiding special-casing branches, since I think that will make it easier for folks to choose branch naming that suits them.
Thanks for working on this.
Signature · 2 lines
brian m. carlson: Houston, Texas, US OpenPGP: https://keybase.io/bk2204
Quoted 7 lines · brian m. carlson
I'm very happy with this and the way it's progressed since v1. This seems simpler than earlier designs, and I appreciate the improved focus on avoiding special-casing branches, since I think that will make it easier for folks to choose branch naming that suits them.
Thanks for working on this.
I agree, this is an improvement.
One thing that isn't obvious to me, though, is why templates take precedence over the command-line option. I would expect the command-line option to be the highest priority option given, just like configuration values specified on the command-line override values from configuration files.
Cheers-
-ed
Hi Ed,
Quoted 10 lines · Edward Thomson
Quoted 7 lines · brian m. carlson
I'm very happy with this and the way it's progressed since v1. This seems simpler than earlier designs, and I appreciate the improved focus on avoiding special-casing branches, since I think that will make it easier for folks to choose branch naming that suits them.
Thanks for working on this.
Quoted 7 lines
I agree, this is an improvement.
One thing that isn't obvious to me, though, is why templates take precedence over the command-line option. I would expect the command-line option to be the highest priority option given, just like configuration values specified on the command-line override values from configuration files.
Side note: I have not tested this, but I trust you did, and my reading of the code agrees that it does this.
The reason why it works that way is that while the copy_templates() function is called before the create_symref() call that creates the HEAD symref, the latter call is guarded by the condition that HEAD does not yet exist. Here is a link that highlights both calls (and the code in between):
https://github.com/git/git/blob/v2.27.0/builtin/init-db.c#L229-L270
Now, it is probably not the intention of the code to prohibit the config setting from overriding the template files, but instead it intends to guard against overwriting files by running git init in an _already-initialized_ repository. And I don't think that it possible, really, to change the logic without making the effect quite hard to explain.
The truth is that overriding the default name via editing the templates is just not a very good strategy, it is fraught with peril, as e.g. init.templateDir is a thing that can be easily specified via the command-line (git -c init.templateDir=/tmp/my-templates init).
Ciao,
Dscho
A message that is not in the archive (sent off-list or not yet received): CA+WKDT1GMNTY5N862-7ui70D6-b1u6fuUkvctEYo+57aJGbjmw@mail.gmail.com
Hi Ed,
[re-Cc:ing the list, I hope you don't mind]
Quoted 21 lines · Edward Thomson
Quoted 9 lines · Johannes Schindelin
Quoted 5 lines · Edward Thomson
One thing that isn't obvious to me, though, is why templates take precedence over the command-line option. I would expect the command-line option to be the highest priority option given, just like configuration values specified on the command-line override values from configuration files.
Side note: I have not tested this, but I trust you did, and my reading of the code agrees that it does this.
I was speaking about the notion of configuration options specified with
-con the command line overridding things in configuration files. Like how you overrideinit.templateDiron the command line:Quoted 4 lines
The truth is that overriding the default name via editing the templates is just not a very good strategy, it is fraught with peril, as e.g.
init.templateDiris a thing that can be easily specified via the command-line (git -c init.templateDir=/tmp/my-templates init).
Quoted 5 lines
I agree that setting a template that contains
HEADis perilous. But it's an established and supported bit of peril. I think that the question of configuration specificity is _also_ an established one (and not nearly so perilous). Just like-cinit.defaultBranchoverrides the global configuration, I would expect it to override the templates as well.
Is it really well-established? If so, it might really be worth doing something like this:
-- snip --
builtin/init-db.c +8 -2
@@ -210,7 +210,7 @@ static int create_default_files(const char *template_path,struct strbuf buf =STRBUF_INIT ;char *path;char junk[2 ]; -int reinit; +int reinit, override_HEAD_in_templates =0 ;int filemode;struct strbuf err =STRBUF_INIT ;
@@ -218,6 +218,12 @@ static int create_default_files(const char *template_path, init_db_template_dir =NULL ;/* re-set in case it was set before */ git_config (git_init_db_config,NULL ); +if (initial_branch) { + path =git_path_buf (&buf,"HEAD" ); + override_HEAD_in_templates =access (path,R_OK ) || +readlink (path, junk,sizeof (junk)-1 ) <0 ; + } +/* * First copy the templates -- we might have the default * config file there, in which case we would want to read
@@ -265,7 +271,7 @@ static int create_default_files(const char *template_path, path =git_path_buf (&buf,"HEAD" ); reinit = (!access (path,R_OK ) ||readlink (path, junk,sizeof (junk)-1 ) !=-1 ); -if (!reinit) { +if (!reinit || override_HEAD_in_templates) {char *ref;if (!initial_branch)
-- snap --
Note that I initially considered moving the reinit = [...] part to before the copy_templates() call, but reinit actually does quite a bit more than just guard the symref creation of HEAD: it also guards the core.filemode test, the core.symlinks test and the core.ignoreCase test. There _might_ be legitimate use cases to side-step those by delivering a HEAD in the templates (which is, just as setting the initial branch using templates, a relatively awkward and fragile way to override it, but hey, we're trying to address exactly such a scenario).
However, even having written the patch (which would still lack a regression test), I am not 100% certain that we would want to risk including it in v2.28.0. It strikes me as such a fringe use case (with relatively obvious ways out) while the patch is not completely risk free (I _think_ it should be safe, of course, but it touches a relatively central part of Git).
Ciao,
Dscho
Quoted 5 lines · Johannes Schindelin via GitGitGadget
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_NAMEenvironment 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
Quoted 11 lines · Ævar Arnfjörð Bjarmason
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.
Quoted 7 lines
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.
Quoted 8 lines
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.
Quoted 7 lines
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.
Quoted 6 lines
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
Quoted 3 lines · Jeff King
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
Hi Peff & Ævar,
Quoted 10 lines · Jeff King
Quoted 3 lines · Jeff King
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):
Quoted 5 lines
- 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:
Quoted 5 lines
- 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
Quoted 5 lines · Ævar Arnfjörð Bjarmason
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.
Quoted 8 lines
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.
Quoted 4 lines
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.