Allow overriding the default name of the default branch
cover Allow overriding the default name of the default branch
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
Signature · 1 line
gitgitgadget
PATCH 1/9 init: allow overriding the default branch name for new repositories
From: Don Goodman-Wilson <[email protected]>
There is a growing number of projects trying to avoid the non-inclusive name master in their repositories. For existing repositories, this requires manual work. For new repositories, the only way to do that automatically is by copying all of Git's template directory, then hard-coding the desired default branch name into the .git/HEAD file, and then configuring init.templateDir to point to those copied template files.
To make this process much less cumbersome, let's introduce support for core.defaultBranchName. That way, users won't need to keep their copied template files up to date, and won't interfere with default hooks installed by their administrators.
While at it, also let users set the default branch name via the environment variable GIT_TEST_DEFAULT_BRANCH_NAME, in preparation for adjusting Git's test suite to a more inclusive default branch name. As is common in Git, the GIT_TEST_* variable takes precedence over the config setting.
Note: we use the prefix core. instead of init. because we want to adjust also git clone, git fmt-merge-msg and other commands over the course of the next commits to respect this setting.
--- builtin/init-db.c | 8 +++++--- refs.c | 34 ++++++++++++++++++++++++++++++++++ refs.h | 6 ++++++ t/t0001-init.sh | 20 ++++++++++++++++++++ 4 files changed, 65 insertions(+), 3 deletions(-)
builtin/init-db.c +5 -3
@@ -258,15 +258,17 @@ static int create_default_files(const char *template_path,die ("failed to set up refs db: %s" , err.buf);/* -* Create the default symlink from ".git/HEAD" to the "master" -* branch, if it does not exist yet. +* Create the default symlink from ".git/HEAD" to the default +* branch name, if it does not exist yet. */ path =git_path_buf (&buf,"HEAD" ); reinit = (!access (path,R_OK ) ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) { -if (create_symref ("HEAD" ,"refs/heads/master" ,NULL ) <0 ) +char *default_ref =git_default_branch_name (0 ); +if (create_symref ("HEAD" , default_ref,NULL ) <0 )exit (1 ); +free (default_ref); }initialize_repository_version (fmt->hash_algo);
refs.c +34 -0
@@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)argv_array_pushf (prefixes, *p, len, prefix); } +char *git_default_branch_name (int short_name) +{ +const char *branch_name =getenv ("GIT_TEST_DEFAULT_BRANCH_NAME" ); +char *from_config =NULL , *prefixed; + +/* +* If the default branch name was not specified via the environment +* variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config +* setting core.defaultBranchName. If neither are set, fall back to the +* hard-coded default. +*/ +if (!branch_name || !*branch_name) { +if (git_config_get_string ("core.defaultbranchname" , + &from_config) <0 ) +die (_ ("Could not retrieve `core.defaultBranchName`" )); + +if (from_config) + branch_name = from_config; +else + branch_name ="master" ; + } + +if (short_name) +return from_config ? from_config :xstrdup (branch_name); + +/* prepend "refs/heads/" to the branch name */ + prefixed =xstrfmt ("refs/heads/%s" , branch_name); +if (check_refname_format (prefixed,0 )) +die (_ ("invalid default branch name: '%s'" ), branch_name); + +free (from_config); +return prefixed; +} +/* * *string and *len will only be substituted, and *string returned (for * later free()ing) if the string passed in is a magic short-hand form
refs.h +6 -0
@@ -154,6 +154,12 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_int dwim_ref (const char *str,int len,struct object_id *oid,char **ref);int dwim_log (const char *str,int len,struct object_id *oid,char **ref); +/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/". +*/ +char *git_default_branch_name (int short_name); +/* * A ref_transaction represents a collection of reference updates that * should succeed or fail together.
t/t0001-init.sh +20 -0
@@ -464,4 +464,24 @@ test_expect_success MINGW 'redirect std handles' ' grep "Needed a single revision" output.txt ' +test_expect_success 'custom default branch name from config' ' + git config --global core.defaultbranchname nmb && + GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config && + git config --global --unset core.defaultbranchname && + git -C custom-config symbolic-ref HEAD >actual && + grep nmb actual +' + +test_expect_success 'custom default branch name from env' ' + GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env && + git -C custom-env symbolic-ref HEAD >actual && + grep nmb actual +' + +test_expect_success 'invalid custom default branch name' ' + test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \ + git init custom-invalid 2>err && + test_i18ngrep "invalid default branch name" err +' + test_done
Signature · 1 line
gitgitgadget
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 591
Quoted 4 lines · Don Goodman-Wilson via GitGitGadget
refs.c +4
-0+/* prepend "refs/heads/" to the branch name */ + prefixed =xstrfmt ("refs/heads/%s" , branch_name); +if (check_refname_format (prefixed,0 )) +die (_ ("invalid default branch name: '%s'" ), branch_name);
I'm glad to see this part and a check for it in the test below. We wouldn't want a typo to create a broken branch name.
Quoted 6 lines
t/t0001-init.sh +6
-0+test_expect_success 'invalid custom default branch name' ' + test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \ + git init custom-invalid 2>err && + test_i18ngrep "invalid default branch name" err +' +
Signature · 2 lines
brian m. carlson: Houston, Texas, US OpenPGP: https://keybase.io/bk2204
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
In reply to Don Goodman-Wilson via GitGitGadgetrefs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 560
Quoted 11 lines · Don Goodman-Wilson via GitGitGadget
[...]
To make this process much less cumbersome, let's introduce support forcore.defaultBranchName. That way, users won't need to keep their copied template files up to date, and won't interfere with default hooks installed by their administrators.[...]Signed-off-by Don Goodman-Wilson <[email protected]>---
refs.c +1
-0@@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) +die (_ ("Could not retrieve `core.defaultBranchName`" ));
Nit: here the error message is capitalized...
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 582
Quoted 4 lines
refs.c +4
-0+if (from_config) + branch_name = from_config; +else + branch_name ="master" ;
Non-actionable nit: could be written:
branch_name = from_config ? from_config : "master";
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 586
Quoted 4 lines
refs.c +4
-0+ } + +if (short_name) +return from_config ? from_config :xstrdup (branch_name);
The logic overall is a bit difficult to follow when trying to understand when and when not to duplicate the string and when and when not to free(), but seems to be correct.
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 591
Quoted 4 lines
refs.c +4
-0+/* prepend "refs/heads/" to the branch name */ + prefixed =xstrfmt ("refs/heads/%s" , branch_name); +if (check_refname_format (prefixed,0 )) +die (_ ("invalid default branch name: '%s'" ), branch_name);
Here, the error message is not capitalized. It would be nice for both messages to share a common capitalization scheme. These days, we tend to favor _not_ capitalizing error messages, so perhaps remove capitalization from the earlier one.
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 577
Quoted 5 lines
refs.c +5
-0+/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/". +*/ +char *git_default_branch_name (int short_name);
Overall, the internal logic regarding duplicating/freeing strings would probably be easier to grok if there were two separate functions:
char *git_default_branch_name(void);
char *git_default_ref_name(void);but that's subjective.
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Hi Eric,
Quoted 15 lines · Eric Sunshine
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 560
Quoted 11 lines · Don Goodman-Wilson via GitGitGadget
[...]
To make this process much less cumbersome, let's introduce support forcore.defaultBranchName. That way, users won't need to keep their copied template files up to date, and won't interfere with default hooks installed by their administrators.[...]Signed-off-by Don Goodman-Wilson <[email protected]>---
refs.c +1
-0@@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) +die (_ ("Could not retrieve `core.defaultBranchName`" ));Nit: here the error message is capitalized...
I downcased it...
Quoted 8 lines
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 582
Quoted 4 lines
refs.c +4
-0+if (from_config) + branch_name = from_config; +else + branch_name ="master" ;Non-actionable nit: could be written:
branch_name = from_config ? from_config : "master";
Good call.
Quoted 8 lines
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 586
Quoted 4 lines
refs.c +4
-0+ } + +if (short_name) +return from_config ? from_config :xstrdup (branch_name);The logic overall is a bit difficult to follow when trying to understand when and when not to duplicate the string and when and when not to
free(), but seems to be correct.
I agree that it is a bit hard to follow, but then, the function is really short, so I hoped it is okay.
Quoted 19 lines
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 591
Quoted 4 lines
refs.c +4
-0+/* prepend "refs/heads/" to the branch name */ + prefixed =xstrfmt ("refs/heads/%s" , branch_name); +if (check_refname_format (prefixed,0 )) +die (_ ("invalid default branch name: '%s'" ), branch_name);Here, the error message is not capitalized. It would be nice for both messages to share a common capitalization scheme. These days, we tend to favor _not_ capitalizing error messages, so perhaps remove capitalization from the earlier one.
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 577
Quoted 5 lines
refs.c +5
-0+/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/". +*/ +char *git_default_branch_name (int short_name);Overall, the internal logic regarding duplicating/freeing strings would probably be easier to grok if there were two separate functions:
Quoted 4 lines
char *git_default_branch_name(void); char *git_default_ref_name(void);but that's subjective.
For such a tiny nuance, I'd rather keep it as one function...
Thank you,
Dscho
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Quoted 9 lines · Johannes Schindelin
Quoted 7 lines
Overall, the internal logic regarding duplicating/freeing strings would probably be easier to grok if there were two separate functions:
char *git_default_branch_name(void); char *git_default_ref_name(void);but that's subjective.
For such a tiny nuance, I'd rather keep it as one function...
And you'd need two functions, default and primary, possibly full and short. Splitting these into two here would mean you'd need four.
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
In reply to Eric SunshineQuoted 9 lines · Eric Sunshine
refs.h int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ · line 161
Quoted 5 lines
refs.h +5
-0+/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/". +*/ +char *git_default_branch_name (int short_name);Overall, the internal logic regarding duplicating/freeing strings would probably be easier to grok if there were two separate functions:
Quoted 4 lines
char *git_default_branch_name(void); char *git_default_ref_name(void);but that's subjective.
Having seen one of the callers, might it be worth avoiding handing off ownership of the string entirely?
I.e., this comes from a string that's already owned for the lifetime of the process (either the environment, or a string stored by the config machinery). Could we just pass that back (or if we want to be more careful about getenv() lifetimes, we can copy it into a static owned by this function)?
Then all of the callers can stop dealing with the extra free(), and you can do:
const char *git_default_branch_name(void)
{
return skip_prefix("refs/heads/", git_default_ref_name());}
-Peff
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Quoted 25 lines · Jeff King
Quoted 9 lines · Eric Sunshine
refs.h int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ · line 161
Quoted 5 lines
refs.h +5
-0+/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/". +*/ +char *git_default_branch_name (int short_name);Overall, the internal logic regarding duplicating/freeing strings would probably be easier to grok if there were two separate functions:
Quoted 4 lines
char *git_default_branch_name(void); char *git_default_ref_name(void);but that's subjective.
Having seen one of the callers, might it be worth avoiding handing off ownership of the string entirely?
I.e., this comes from a string that's already owned for the lifetime of the process (either the environment, or a string stored by the config machinery). Could we just pass that back (or if we want to be more careful about
getenv()lifetimes, we can copy it into a static owned by this function)?
Quoted 7 lines
Then all of the callers can stop dealing with the extra
free(), and you can do:const char
*git_default_branch_name(void){ return skip_prefix("refs/heads/", git_default_ref_name());}
Actually, one small hiccup is that the config option specifies the branch name, not the ref name. So you really would have to prepare a static-owned copy of it to turn "foo" into "refs/heads/foo" to get the refname.
On the other hand, that would also be a good time to run check_ref_format(). In the patch as-is, the "short" return does not check that the branch is a valid name.
-Peff
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Hi Peff,
Quoted 35 lines · Jeff King
Quoted 25 lines · Jeff King
Quoted 9 lines · Eric Sunshine
refs.h int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ · line 161
Quoted 5 lines
refs.h +5
-0+/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/". +*/ +char *git_default_branch_name (int short_name);Overall, the internal logic regarding duplicating/freeing strings would probably be easier to grok if there were two separate functions:
Quoted 4 lines
char *git_default_branch_name(void); char *git_default_ref_name(void);but that's subjective.
Having seen one of the callers, might it be worth avoiding handing off ownership of the string entirely?
I.e., this comes from a string that's already owned for the lifetime of the process (either the environment, or a string stored by the config machinery). Could we just pass that back (or if we want to be more careful about
getenv()lifetimes, we can copy it into a static owned by this function)?Quoted 7 lines
Then all of the callers can stop dealing with the extra
free(), and you can do:const char
*git_default_branch_name(void){ return skip_prefix("refs/heads/", git_default_ref_name());}
Quoted 8 lines
Actually, one small hiccup is that the config option specifies the branch name, not the ref name. So you really would have to prepare a static-owned copy of it to turn "foo" into "refs/heads/foo" to get the refname.
On the other hand, that would also be a good time to run
check_ref_format(). In the patch as-is, the "short" return does not check that the branch is a valid name.
Legit.
I will work on this.
Thanks,
Dscho
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
In reply to Jeff KingHi Peff,
Quoted 11 lines · Jeff King
Quoted 9 lines · Eric Sunshine
refs.h int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ · line 161
Quoted 5 lines
refs.h +5
-0+/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/". +*/ +char *git_default_branch_name (int short_name);Overall, the internal logic regarding duplicating/freeing strings would probably be easier to grok if there were two separate functions:
Quoted 7 lines
Quoted 4 lines
char *git_default_branch_name(void); char *git_default_ref_name(void);but that's subjective.
Having seen one of the callers, might it be worth avoiding handing off ownership of the string entirely?
For git_default_branch_name(): yes. For repo_default_branch_name(), not really, as that is potentially repository-specific.
(Side note: while I cannot really think of a use case where you would want to set init.defaultBranch in a repository-local config, there _might_ be use cases for that out there, and it _is_ how our config machinery works.)
Quoted 6 lines
I.e., this comes from a string that's already owned for the lifetime of the process (either the environment, or a string stored by the config machinery). Could we just pass that back (or if we want to be more careful about
getenv()lifetimes, we can copy it into a static owned by this function)?
Quoted 7 lines
Then all of the callers can stop dealing with the extra
free(), and you can do:const char
*git_default_branch_name(void){ return skip_prefix("refs/heads/", git_default_ref_name());}
For ease of use, I decided to only ever return the branch name (but check the full ref).
Those callers that actually need the full ref usually also need the branch name, and it is easy enough to call xstrfmt("refs/heads/%s", ...).
It might make the code a bit less efficient (but who cares, it's not like we're setting up a gazillion repositories per second all the time), but quite a bit easier to reason about.
Ciao,
Dscho
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
In reply to Don Goodman-Wilson via GitGitGadgetQuoted 4 lines · Don Goodman-Wilson via GitGitGadget
From: Don Goodman-Wilson <[email protected]>
There is a growing number of projects trying to avoid the non-inclusive name
masterin their repositories.
I think it would be helpful to explain why 'master' is no-inclusive even if it originates from the concept of a master copy. i.e. it suggests master/slave even if git is not based on that concept.
Have you got some examples of projects that have changed and the names that they are using? I think it would be helpful if we can agree on a replacement for master - if every repository uses a different name for its main branch it adds an extra complication for new contributors to those projects.
For existing repositories, this
Quoted 6 lines
requires manual work. For new repositories, the only way to do that automatically is by copying all of Git's template directory, then hard-coding the desired default branch name into the
.git/HEADfile, and then configuringinit.templateDirto point to those copied template files.
Quoted 7 lines
To make this process much less cumbersome, let's introduce support for
core.defaultBranchName. That way, users won't need to keep their copied template files up to date, and won't interfere with default hooks installed by their administrators.While at it, also let users set the default branch name via the environment variable
GIT_TEST_DEFAULT_BRANCH_NAME,
I'm not sure we usually promote the use of GIT_TEST_... environment variables outside of the test suite.
Quoted 66 lines
in preparation for
adjusting Git's test suite to a more inclusive default branch name. As is common in Git, theGIT_TEST_*variable takes precedence over the config setting.Note: we use the prefix
core.instead ofinit.because we want to adjust alsogit clone,git fmt-merge-msgand other commands over the course of the next commits to respect this setting.Helped-by Johannes Schindelin <[email protected]>Helped-by Derrick Stolee <[email protected]>Signed-off-by Don Goodman-Wilson <[email protected]>--- builtin/init-db.c | 8 +++++--- refs.c | 34 ++++++++++++++++++++++++++++++++++ refs.h | 6 ++++++ t/t0001-init.sh | 20 ++++++++++++++++++++ 4 files changed, 65 insertions(+), 3 deletions(-)builtin/init-db.c +5
-3@@ -258,15 +258,17 @@ static int create_default_files(const char *template_path,die ("failed to set up refs db: %s" , err.buf);/* -* Create the default symlink from ".git/HEAD" to the "master" -* branch, if it does not exist yet. +* Create the default symlink from ".git/HEAD" to the default +* branch name, if it does not exist yet. */ path =git_path_buf (&buf,"HEAD" ); reinit = (!access (path,R_OK ) ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) { -if (create_symref ("HEAD" ,"refs/heads/master" ,NULL ) <0 ) +char *default_ref =git_default_branch_name (0 ); +if (create_symref ("HEAD" , default_ref,NULL ) <0 )exit (1 ); +free (default_ref); }initialize_repository_version (fmt->hash_algo);refs.c +14
-0@@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)argv_array_pushf (prefixes, *p, len, prefix); } +char *git_default_branch_name (int short_name) +{ +const char *branch_name =getenv ("GIT_TEST_DEFAULT_BRANCH_NAME" ); +char *from_config =NULL , *prefixed; + +/* +* If the default branch name was not specified via the environment +* variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config +* setting core.defaultBranchName. If neither are set, fall back to the +* hard-coded default. +*/ +if (!branch_name || !*branch_name) { +if (git_config_get_string ("core.defaultbranchname" , + &from_config) <0 )
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 586
Quoted 10 lines
refs.c +10
-0+die (_ ("Could not retrieve `core.defaultBranchName`" )); + +if (from_config) + branch_name = from_config; +else + branch_name ="master" ; + } + +if (short_name) +return from_config ? from_config :xstrdup (branch_name);
If short_name is set we return without validating the name is that intentional?
Quoted 18 lines
refs.c +10
-0+ +/* prepend "refs/heads/" to the branch name */ + prefixed =xstrfmt ("refs/heads/%s" , branch_name); +if (check_refname_format (prefixed,0 )) +die (_ ("invalid default branch name: '%s'" ), branch_name); + +free (from_config); +return prefixed; +} +/* * *string and *len will only be substituted, and *string returned (for * later free()ing) if the string passed in is a magic short-hand form refs.h +0
-0
refs.h int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ · line 159
Quoted 6 lines
refs.h +3
-0@@ -154,6 +154,12 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_int dwim_ref (const char *str,int len,struct object_id *oid,char **ref);int dwim_log (const char *str,int len,struct object_id *oid,char **ref); +/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/".
Isn't the other way around - the branch name is prefixed with "refs/heads/" if short is zero.
Quoted 11 lines
refs.h +3
-0+*/ +char *git_default_branch_name (int short_name); +/* * A ref_transaction represents a collection of reference updates that * should succeed or fail together. t/t0001-init.sh +0
-0
t/t0001-init.sh test_expect_success MINGW 'redirect std handles' ' · line 468
Quoted 5 lines
t/t0001-init.sh +2
-0@@ -464,4 +464,24 @@ test_expect_success MINGW 'redirect std handles' ' grep "Needed a single revision" output.txt ' +test_expect_success 'custom default branch name from config' ' + git config --global core.defaultbranchname nmb &&
In tests we usually use 'test_config' rather than 'git config' as the former automatically cleans up the config at the end of the test.
t/t0001-init.sh test_expect_success MINGW 'redirect std handles' ' · line 476
Quoted 8 lines
t/t0001-init.sh +8
-0+ GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config && + git config --global --unset core.defaultbranchname && + git -C custom-config symbolic-ref HEAD >actual && + grep nmb actual +' + +test_expect_success 'custom default branch name from env' ' + GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env &&
It would be good to test that this overrides the config setting
Best Wishes
Phillip
Quoted 12 lines
t/t0001-init.sh +10
-0+ git -C custom-env symbolic-ref HEAD >actual && + grep nmb actual +' + +test_expect_success 'invalid custom default branch name' ' + test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \ + git init custom-invalid 2>err && + test_i18ngrep "invalid default branch name" err +' + test_done
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Hi Phillip,
Quoted 9 lines · Phillip Wood
Quoted 4 lines · Don Goodman-Wilson via GitGitGadget
From: Don Goodman-Wilson <[email protected]>
There is a growing number of projects trying to avoid the non-inclusive name
masterin their repositories.I think it would be helpful to explain why 'master' is no-inclusive even if it originates from the concept of a master copy. i.e. it suggests master/slave even if git is not based on that concept.
Unfortunately, we do not even have that defense: the term master was copied from BitKeeper, which firmly uses it in the master/slave context. See e.g.
https://mail.gnome.org/archives/desktop-devel-list/2019-May/msg00066.html
I added a _brief_ extension to the context to the first commit's commit message. However, I do not want to go into details here because _this_ patch series is only about empowering users to change their default main branch name.
Quoted 2 lines
Have you got some examples of projects that have changed and the names that they are using?
Yes, there are plenty examples, and I do not want to pick a tiny subset to demonstrate that. A more useful resource is probably this post:
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx
Quoted 3 lines
I think it would be helpful if we can agree on a replacement for master
- if every repository uses a different name for its main branch it adds an extra complication for new contributors to those projects.
Sure, and that's what I thought we'd discuss, too, maybe at the meeting I proposed elsewhere (Emily started a new thread about it:
https://lore.kernel.org/git/[email protected]/).
Quoted 12 lines
Quoted 12 lines
For existing repositories, this
requires manual work. For new repositories, the only way to do that automatically is by copying all of Git's template directory, then hard-coding the desired default branch name into the.git/HEADfile, and then configuringinit.templateDirto point to those copied template files.To make this process much less cumbersome, let's introduce support for
core.defaultBranchName. That way, users won't need to keep their copied template files up to date, and won't interfere with default hooks installed by their administrators.
Quoted 5 lines
Quoted 2 lines
While at it, also let users set the default branch name via the environment variable
GIT_TEST_DEFAULT_BRANCH_NAME,I'm not sure we usually promote the use of
GIT_TEST_... environment variables outside of the test suite.
True. Together with Alban's suggestion to make this purely work in the test suite (i.e. not even adjust the C code to respect that environment variable), you convinced me to (re-)move that part of the commit.
Quoted 27 lines
Quoted 27 lines
refs.c +19
-0@@ -560,6 +560,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)argv_array_pushf (prefixes, *p, len, prefix); } +char *git_default_branch_name (int short_name) +{ +const char *branch_name =getenv ("GIT_TEST_DEFAULT_BRANCH_NAME" ); +char *from_config =NULL , *prefixed; + +/* +* If the default branch name was not specified via the environment +* variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config +* setting core.defaultBranchName. If neither are set, fall back to the +* hard-coded default. +*/ +if (!branch_name || !*branch_name) { +if (git_config_get_string ("core.defaultbranchname" , + &from_config) <0 ) +die (_ ("Could not retrieve `core.defaultBranchName`" )); + +if (from_config) + branch_name = from_config; +else
Quoted 8 lines
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 586
Quoted 5 lines
refs.c +5
-0+ branch_name ="master" ; + } + +if (short_name) +return from_config ? from_config :xstrdup (branch_name);If
short_nameis set we return without validating the name is that intentional?
No, unintentional. Thank you for pointing this out. It will be fixed in v2 (still working on it).
Quoted 21 lines
Quoted 21 lines
refs.c +10
-0+ +/* prepend "refs/heads/" to the branch name */ + prefixed =xstrfmt ("refs/heads/%s" , branch_name); +if (check_refname_format (prefixed,0 )) +die (_ ("invalid default branch name: '%s'" ), branch_name); + +free (from_config); +return prefixed; +} +/* * *string and *len will only be substituted, and *string returned (for * later free()ing) if the string passed in is a magic short-hand form refs.h +0
-0@@ -154,6 +154,12 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_int dwim_ref (const char *str,int len,struct object_id *oid,char **ref);int dwim_log (const char *str,int len,struct object_id *oid,char **ref);
Quoted 6 lines
refs.h int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ · line 159
Quoted 3 lines
refs.h +3
-0+/* +* Retrieves the name of the default branch. If `short_name` is non-zero, the +* branch name will be prefixed with "refs/heads/". Isn't the other way around - the branch name is prefixed with "refs/heads/" if short is zero.
Absolutely. Thank you for your careful review, I read past this at least half a dozen times.
Quoted 14 lines
Quoted 14 lines
refs.h +3
-0+*/ +char *git_default_branch_name (int short_name); +/* * A ref_transaction represents a collection of reference updates that * should succeed or fail together. t/t0001-init.sh +0
-0@@ -464,4 +464,24 @@ test_expect_success MINGW 'redirect std handles' ' grep "Needed a single revision" output.txt '
Quoted 5 lines
t/t0001-init.sh test_expect_success MINGW 'redirect std handles' ' · line 468
Quoted 2 lines
t/t0001-init.sh +2
-0+test_expect_success 'custom default branch name from config' ' + git config --global core.defaultbranchname nmb &&In tests we usually use '
test_config' rather than 'git config' as the former automatically cleans up the config at the end of the test.
Right, and in this instance it is test_config_global.
Quoted 10 lines
t/t0001-init.sh test_expect_success MINGW 'redirect std handles' ' · line 476
Quoted 8 lines
t/t0001-init.sh +8
-0+ GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config && + git config --global --unset core.defaultbranchname && + git -C custom-config symbolic-ref HEAD >actual && + grep nmb actual +' + +test_expect_success 'custom default branch name from env' ' + GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env &&It would be good to test that this overrides the config setting
Except that we'll make this a thing that is internal to the test suite now. So this test case can go.
Thank you for helping me improve the patch series! Dscho
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Quoted 4 lines · Johannes Schindelin
I added a _brief_ extension to the context to the first commit's commit message. However, I do not want to go into details here because _this_ patch series is only about empowering users to change their default main branch name.
Sensible.
And I do not think the planned follow-up work to rename 'master' to something else needs to be defended with lengthy history lessons.
Sufficiently large part of the user population are unhappy with the use of the word 'master' as the default name of the primary branch in a newly created repository, and the mere fact that we are aware of that is good enough justification to move _away_ from 'master'. In other words, we do not have to explain why 'master' was bad, as it does not have to be bad for everybody to be replaced.
But you need to defend that the new word you picked is something everybody is happy with. That is much harder ;-).
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Quoted 7 lines · Junio C Hamano
Quoted 4 lines · Johannes Schindelin
I added a _brief_ extension to the context to the first commit's commit message. However, I do not want to go into details here because _this_ patch series is only about empowering users to change their default main branch name.
Quoted 8 lines
[...]
Sufficiently large part of the user population are unhappy with the use of the word 'master' as the default name of the primary branch in a newly created repository, and the mere fact that we are aware of that is good enough justification to move _away_ from 'master'. In other words, we do not have to explain why 'master' was bad, as it does not have to be bad for everybody to be replaced.
This expresses what I was trying to get at with my comments much more clearly than I managed - Thank you
Quoted 3 lines
But you need to defend that the new word you picked is something everybody is happy with. That is much harder ;-).
Indeed, though I am more optimistic about that having seen a couple of people have indicated that they don't mind too much what we choose so long as it unlikely to cause future problems.
Best Wishes
Phillip
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
In reply to Junio C HamanoHi Junio,
Quoted 11 lines · Junio C Hamano
Quoted 4 lines · Johannes Schindelin
I added a _brief_ extension to the context to the first commit's commit message. However, I do not want to go into details here because _this_ patch series is only about empowering users to change their default main branch name.
Sensible.
And I do not think the planned follow-up work to rename 'master' to something else needs to be defended with lengthy history lessons.
Yes, I agree. It is probably sufficient to just point at a couple high-profile projects that already made the switch to main.
Quoted 4 lines
Sufficiently large part of the user population are unhappy with the use of the word 'master' as the default name of the primary branch in a newly created repository, and the mere fact that we are aware of that is good enough justification to move _away_ from 'master'.
Yes, even Pasky says he regrets the choice of term (see
https://twitter.com/xpasky/status/1271477451756056577):
I picked the names "master" (and "origin") in the early Git tooling back in 2005.
(this probably means you shouldn't give much weight to my name preferences :) )
I have wished many times I would have named them "main" (and "upstream") instead.
Quoted 5 lines
In other words, we do not have to explain why 'master' was bad, as it does not have to be bad for everybody to be replaced.
But you need to defend that the new word you picked is something everybody is happy with. That is much harder ;-).
To be honest, I stopped looking for got arguments in favor of one name after a couple days, and instead focused on the consensus I
saw: Chrome [*1*] and node.js [*2*] apparently stated publicly that they want to change their main branches to main, and GitLab [*3*] and GitHub [*4*] seem to intend to change the default for new repositories accordingly.
It is not like we have to decide for the community (as we did back in 2005). I am actually quite relieved about that.
Ciao,
Dscho
URL *1*: https://twitter.com/Una/status/1271180494944829441
URL *2*: https://github.com/nodejs/node/issues/33864
URL *3*: https://gitlab.com/gitlab-org/gitlab/-/issues/221164
URL *4*: https://twitter.com/natfriedman/status/1271253144442253312
(this is not really a public announcement, I agree, but it is a public Tweet by the CEO)
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
In reply to Don Goodman-Wilson via GitGitGadgetHi Don & Johannes,
Le 10/06/2020 à 23:19, Don Goodman-Wilson via GitGitGadget a écrit :
Quoted 15 lines
From: Don Goodman-Wilson <[email protected]>
There is a growing number of projects trying to avoid the non-inclusive name
masterin their repositories. For existing repositories, this requires manual work. For new repositories, the only way to do that automatically is by copying all of Git's template directory, then hard-coding the desired default branch name into the.git/HEADfile, and then configuringinit.templateDirto point to those copied template files.To make this process much less cumbersome, let's introduce support for
core.defaultBranchName. That way, users won't need to keep their copied template files up to date, and won't interfere with default hooks installed by their administrators.
Quoted 6 lines
While at it, also let users set the default branch name via the environment variable
GIT_TEST_DEFAULT_BRANCH_NAME, in preparation for adjusting Git's test suite to a more inclusive default branch name. As is common in Git, theGIT_TEST_*variable takes precedence over the config setting.
Why adding yet another environment variable instead of relying only on a config option? I understand it's for the tests, but can't we add a shell function in test-lib.sh (and friends) that tries to read GIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, sets core.defaultBranchName'?
Cheers,
Alban
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Quoted 5 lines · Alban Gruin
Why adding yet another environment variable instead of relying only on a config option? I understand it's for the tests, but can't we add a shell function in
test-lib.sh(and friends) that tries to readGIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, setscore.defaultBranchName'?
Can you produce such a patch that does it cleanly? My knee jerk reaction is that I would suspect that you end up having to touch many places in the t/ scripts, but if you prove otherwise, that would certainly be appreciated.
And no,
git () { command git -c core.defaultBranchName=master "$@" }is not an acceptable solution.
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Quoted 13 lines · Junio C Hamano
Quoted 5 lines · Alban Gruin
Why adding yet another environment variable instead of relying only on a config option? I understand it's for the tests, but can't we add a shell function in
test-lib.sh(and friends) that tries to readGIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, setscore.defaultBranchName'?Can you produce such a patch that does it cleanly? My knee jerk reaction is that I would suspect that you end up having to touch many places in the t/ scripts, but if you prove otherwise, that would certainly be appreciated.
Quoted 5 lines
And no,
git () { command git -c core.defaultBranchName=master "$@" }is not an acceptable solution.
I would also be delighted to see such a solution, but my experience with the SHA-256 work tells me there's unlikely to be one. We do a lot of "git init" operations in random places in the test suite and as a consequence it's very hard to make a change without touching a large number of tests.
If we were writing things today, perhaps we would use a function (e.g., test_init_repo or such) to wrap this case, but we unfortunately didn't think about that and we're stuck with what we have now unless someone retrofits the test suite.
Signature · 2 lines
brian m. carlson: Houston, Texas, US OpenPGP: https://keybase.io/bk2204
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Hi brian,
Quoted 18 lines · brian m. carlson
Quoted 17 lines · Junio C Hamano
Quoted 5 lines · Alban Gruin
Why adding yet another environment variable instead of relying only on a config option? I understand it's for the tests, but can't we add a shell function in
test-lib.sh(and friends) that tries to readGIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, setscore.defaultBranchName'?Can you produce such a patch that does it cleanly? My knee jerk reaction is that I would suspect that you end up having to touch many places in the t/ scripts, but if you prove otherwise, that would certainly be appreciated.
And no,
git () { command git -c core.defaultBranchName=master "$@" }
Quoted 7 lines
Quoted 1 line
is not an acceptable solution.
I would also be delighted to see such a solution, but my experience with the SHA-256 work tells me there's unlikely to be one. We do a lot of "git init" operations in random places in the test suite and as a consequence it's very hard to make a change without touching a large number of tests.
That's a valid point, indeed.
Quoted 4 lines
If we were writing things today, perhaps we would use a function (e.g.,
test_init_repoor such) to wrap this case, but we unfortunately didn't think about that and we're stuck with what we have now unless someone retrofits the test suite.
There is actually test_create_repo (see
https://github.com/git/git/blob/v2.27.0/t/test-lib-functions.sh#L1145-L1159):
# Most tests can use the created repository, but some may need to create
# more.
# Usage: test_create_repo <directory>
test_create_repo () {
test "$#" = 1 ||
BUG "not 1 parameter to test-create-repo"
repo="$1"
mkdir -p "$repo"
(
cd "$repo" || error "Cannot setup test environment"
"${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
"--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
) || exit
}But I agree that few test scripts use it:
$ git grep 'git init' v2.27.0 -- t/ | wc -l 765
$ git grep 'test_create_repo' v2.27.0 -- t/ | wc -l 296
Ciao,
Dscho
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
In reply to Junio C HamanoHi Junio,
Le 12/06/2020 à 01:14, Junio C Hamano a écrit :
Quoted 13 lines
Quoted 5 lines · Alban Gruin
Why adding yet another environment variable instead of relying only on a config option? I understand it's for the tests, but can't we add a shell function in
test-lib.sh(and friends) that tries to readGIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, setscore.defaultBranchName'?Can you produce such a patch that does it cleanly? My knee jerk reaction is that I would suspect that you end up having to touch many places in the t/ scripts, but if you prove otherwise, that would certainly be appreciated.
Quoted 6 lines
And no,
git () { command git -c core.defaultBranchName=master "$@" }is not an acceptable solution.
I wanted to to do something like this:
if test -n "$GIT_TEST_DEFAULT_BRANCH_NAME";
then
git config core.defaultBranchName "$GIT_TEST_DEFAULT_BRANCH_NAME"
fi
But since we do not have a repository to store the config, it won't work. Sorry for the noise.
Alban
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Hi Alban,
Quoted 25 lines · Alban Gruin
Hi Junio,
Le 12/06/2020 à 01:14, Junio C Hamano a écrit :
Quoted 13 lines
Quoted 5 lines · Alban Gruin
Why adding yet another environment variable instead of relying only on a config option? I understand it's for the tests, but can't we add a shell function in
test-lib.sh(and friends) that tries to readGIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, setscore.defaultBranchName'?Can you produce such a patch that does it cleanly? My knee jerk reaction is that I would suspect that you end up having to touch many places in the t/ scripts, but if you prove otherwise, that would certainly be appreciated.
Quoted 6 lines
And no,
git () { command git -c core.defaultBranchName=master "$@" }is not an acceptable solution.
I wanted to to do something like this:
Quoted 7 lines
if test -n "$GIT_TEST_DEFAULT_BRANCH_NAME";
then
git config core.defaultBranchName "$GIT_TEST_DEFAULT_BRANCH_NAME"
fiBut since we do not have a repository to store the config, it won't work. Sorry for the noise.
We actually would have ~/.gitconfig because HOME is set to t/trash directory.<test-name>/.
However, that would cause all kinds of issues when test scripts expect the directory to be pristine, containing only .git/ but not .gitconfig.
It was a good idea to bring up; I share brian's sentiment that it would have been nice if it would have worked out.
Ciao,
Dscho
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Quoted 25 lines · Johannes Schindelin
Quoted 25 lines
Quoted 11 lines
Quoted 5 lines
Why adding yet another environment variable instead of relying only on a config option? I understand it's for the tests, but can't we add a shell function in
test-lib.sh(and friends) that tries to readGIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, setscore.defaultBranchName'?Can you produce such a patch that does it cleanly? My knee jerk reaction is that I would suspect that you end up having to touch many places in the t/ scripts, but if you prove otherwise, that would certainly be appreciated.
Quoted 6 lines
And no,
git () { command git -c core.defaultBranchName=master "$@" }is not an acceptable solution.
I wanted to to do something like this:
if test -n "$GIT_TEST_DEFAULT_BRANCH_NAME";
then
git config core.defaultBranchName "$GIT_TEST_DEFAULT_BRANCH_NAME"
fi
Quoted 8 lines
Quoted 2 lines
But since we do not have a repository to store the config, it won't work. Sorry for the noise.
We actually would have
~/.gitconfigbecauseHOMEis set tot/trash directory.<test-name>/.However, that would cause all kinds of issues when test scripts expect the directory to be pristine, containing only
.git/but not.gitconfig.
Putting:
GIT_CONFIG_PARAMETERS="'core.defaultBranchName=...'"
into the environment would work (and yes, you need the single quotes embedded in the variable), and solves all of the complaints above. Further "git -c" invocations properly append to it. But:
- there are a few tests which explicitly tweak that variable
- it technically changes any tests of "-c" because now we'd never cover the case where we start without the variable defined
I think baking in a special environment variable like you have is not so bad. If this did become too common a pattern, though (special test-only environment variables that do have a separate config option), I wouldn't be opposed to a GIT_TEST_CONFIG_PARAMETERS which takes precedence over other config, and comes with a big warning label that it shouldn't be relied upon outside the test suite. That's equally ugly to GIT_TEST_DEFAULT_BRANCH_NAME, but at least solves the problem once for all of them. I'm just not sure we have enough "all of them" to make it worth doing.
-Peff
Re: [PATCH 1/9] init: allow overriding the default branch name for new repositories
Hi Peff,
Quoted 40 lines · Jeff King
Quoted 25 lines · Johannes Schindelin
Quoted 25 lines
Quoted 11 lines
Quoted 5 lines
Why adding yet another environment variable instead of relying only on a config option? I understand it's for the tests, but can't we add a shell function in
test-lib.sh(and friends) that tries to readGIT_TEST_DEFAULT_BRANCH_NAME', and, if it exists, setscore.defaultBranchName'?Can you produce such a patch that does it cleanly? My knee jerk reaction is that I would suspect that you end up having to touch many places in the t/ scripts, but if you prove otherwise, that would certainly be appreciated.
Quoted 6 lines
And no,
git () { command git -c core.defaultBranchName=master "$@" }is not an acceptable solution.
I wanted to to do something like this:
if test -n "$GIT_TEST_DEFAULT_BRANCH_NAME";
then
git config core.defaultBranchName "$GIT_TEST_DEFAULT_BRANCH_NAME"
fiQuoted 8 lines
Quoted 2 lines
But since we do not have a repository to store the config, it won't work. Sorry for the noise.
We actually would have
~/.gitconfigbecauseHOMEis set tot/trash directory.<test-name>/.However, that would cause all kinds of issues when test scripts expect the directory to be pristine, containing only
.git/but not.gitconfig.Putting:
GIT_CONFIG_PARAMETERS="'core.defaultBranchName=...'"
Quoted 8 lines
into the environment would work (and yes, you need the single quotes embedded in the variable), and solves all of the complaints above. Further "git -c" invocations properly append to it. But:
- there are a few tests which explicitly tweak that variable
- it technically changes any tests of "-c" because now we'd never cover the case where we start without the variable defined
Indeed.
Quoted 9 lines
I think baking in a special environment variable like you have is not so bad. If this did become too common a pattern, though (special test-only environment variables that do have a separate config option), I wouldn't be opposed to a
GIT_TEST_CONFIG_PARAMETERSwhich takes precedence over other config, and comes with a big warning label that it shouldn't be relied upon outside the test suite. That's equally ugly toGIT_TEST_DEFAULT_BRANCH_NAME, but at least solves the problem once for all of them. I'm just not sure we have enough "all of them" to make it worth doing.
FWIW I do not plan on using that variable for a long time. And it is not in this here patch series any longer, so let's discuss it in the future patch contribution of mine.
Thanks,
Dscho
PATCH 2/9 remote: respect `core.defaultBranchName`
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.
--- remote.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
remote.c +8 -4
@@ -256,7 +256,7 @@ static void read_remotes_file(struct remote *remote)static void read_branches_file (struct remote *remote) { -char *frag; +char *frag, *default_branch_name =NULL ;struct strbuf buf =STRBUF_INIT ;FILE *f =fopen_or_warn (git_path ("branches/%s" , remote->name),"r" );
@@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)/* * The branches file would have URL and optionally -* #branch specified. The "master" (or specified) branch is +* #branch specified. The default (or specified) branch is * fetched and stored in the local branch matching the * remote name. */
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)if (frag) *(frag++) ='\0' ;else - frag ="master" ; + frag = default_branch_name =git_default_branch_name (1 );add_url_alias (remote,strbuf_detach (&buf,NULL )); strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ -299,6 +299,7 @@ static void read_branches_file(struct remote *remote)strbuf_addf (&buf,"HEAD:refs/heads/%s" , frag);refspec_append (&remote->push, buf.buf); remote->fetch_tags =1 ;/* always auto-follow */ +free (default_branch_name);strbuf_release (&buf); }
@@ -2099,7 +2100,10 @@ struct ref *guess_remote_head(const struct ref *head,/* If refs/heads/master could be right, it is. */ if (!all) { - r =find_ref_by_name (refs,"refs/heads/master" ); +char *name =git_default_branch_name (0 ); + + r =find_ref_by_name (refs, name); +free (name);if (r &&oideq (&r->old_oid, &head->old_oid))return copy_ref (r); }
Signature · 1 line
gitgitgadget
Re: [PATCH 2/9] remote: respect `core.defaultBranchName`
remote.c struct ref *guess_remote_head(const struct ref *head, · line 2109
Quoted 12 lines · Johannes Schindelin via GitGitGadget
remote.c +4
-1@@ -2099,7 +2100,10 @@ struct ref *guess_remote_head(const struct ref *head,/* If refs/heads/master could be right, it is. */ if (!all) { - r =find_ref_by_name (refs,"refs/heads/master" ); +char *name =git_default_branch_name (0 ); + + r =find_ref_by_name (refs, name); +free (name);if (r &&oideq (&r->old_oid, &head->old_oid))return copy_ref (r); }
You'd perhaps want to update the comment above, too.
However, I think we should be a bit more lenient on the "reading" side default names. Just because "foo" is _my_ default branch name, does not mean it is the default on the remote side. We cannot know what the other side's default preference is, but in a world where we have 15 years of repos that may have been created with "master", it is probably still a good guess.
I.e., I think this probably ought to check the preferred name, and then fall back to the existing behavior, like:
if (!all) {
char *name;
/* try the user's preferred default branch name */
name = git_default_branch_name(0);
r = find_ref_by_name(refs, name);
free(name);
if (r && oideq(&r->old_oid, &head->old_oid))
return copy_ref(r);
/* otherwise, try "master", which is the historical default */
r = find_ref_by_name(refs, "refs/heads/master");
if (r && oideq(&r->old_oid, &head->old_oid))
return copy_ref(r);}
That will help minimize fallout when git_default_branch_name() changes, either by user config or if we switch the baked-in default. In the latter case, we might also consider hard-coding that as a guess between the user's preferred name and the historical "master".
Hopefully this would not matter _too_ much either way, as most servers would support the symref extension these days. But I still think we should do our best to minimize spots where the user may see a regression.
-Peff
Re: [PATCH 2/9] remote: respect `core.defaultBranchName`
Hi Peff,
Quoted 48 lines · Jeff King
remote.c struct ref *guess_remote_head(const struct ref *head, · line 2109
Quoted 12 lines · Johannes Schindelin via GitGitGadget
remote.c +4
-1@@ -2099,7 +2100,10 @@ struct ref *guess_remote_head(const struct ref *head,/* If refs/heads/master could be right, it is. */ if (!all) { - r =find_ref_by_name (refs,"refs/heads/master" ); +char *name =git_default_branch_name (0 ); + + r =find_ref_by_name (refs, name); +free (name);if (r &&oideq (&r->old_oid, &head->old_oid))return copy_ref (r); }You'd perhaps want to update the comment above, too.
However, I think we should be a bit more lenient on the "reading" side default names. Just because "foo" is _my_ default branch name, does not mean it is the default on the remote side. We cannot know what the other side's default preference is, but in a world where we have 15 years of repos that may have been created with "master", it is probably still a good guess.
I.e., I think this probably ought to check the preferred name, and then fall back to the existing behavior, like:
if (!all) { char *name; /* try the user's preferred default branch name */ name = git_default_branch_name(0); r = find_ref_by_name(refs, name); free(name); if (r && oideq(&r->old_oid, &head->old_oid)) return copy_ref(r); /* otherwise, try "master", which is the historical default */ r = find_ref_by_name(refs, "refs/heads/master"); if (r && oideq(&r->old_oid, &head->old_oid)) return copy_ref(r);}
That will help minimize fallout when
git_default_branch_name()changes, either by user config or if we switch the baked-in default. In the latter case, we might also consider hard-coding that as a guess between the user's preferred name and the historical "master".
Quoted 4 lines
Hopefully this would not matter _too_ much either way, as most servers would support the symref extension these days. But I still think we should do our best to minimize spots where the user may see a regression.
Sure, we could just leave this alone, or we can just ditch the special-casing of master here.
As you say, this does not affect any modern Git version, and IIRC the code after that special-casing tries to find any remote ref that matches the remote HEAD.
So it's not like we _need_ this special-casing, anyway.
Ciao,
Dscho
Re: [PATCH 2/9] remote: respect `core.defaultBranchName`
Quoted 11 lines · Johannes Schindelin
Quoted 4 lines
Hopefully this would not matter _too_ much either way, as most servers would support the symref extension these days. But I still think we should do our best to minimize spots where the user may see a regression.
Sure, we could just leave this alone, or we can just ditch the special-casing of
masterhere.As you say, this does not affect any modern Git version, and IIRC the code after that special-casing tries to find any remote ref that matches the remote
HEAD.
I think we need to be a little careful with "any modern Git", because a modern client against an old (or perhaps an alternative implementation) server might still use it. I have to imagine it's pretty rare, but I think it's still useful to return _some_ value.
But as you note, even without a symref extension, we already try to guess based on a unique branch. Probably even choosing the first one alphabetically would be reasonable. But I'd rather err on the side of historical compatibility if we can do so easily. Looking for init.mainBranch, followed by master, accomplishes that and isn't many lines of code.
-Peff
Re: [PATCH 2/9] remote: respect `core.defaultBranchName`
Hi Peff,
Quoted 19 lines · Jeff King
Quoted 11 lines · Johannes Schindelin
Quoted 4 lines
Hopefully this would not matter _too_ much either way, as most servers would support the symref extension these days. But I still think we should do our best to minimize spots where the user may see a regression.
Sure, we could just leave this alone, or we can just ditch the special-casing of
masterhere.As you say, this does not affect any modern Git version, and IIRC the code after that special-casing tries to find any remote ref that matches the remote
HEAD.I think we need to be a little careful with "any modern Git", because a modern client against an old (or perhaps an alternative implementation) server might still use it. I have to imagine it's pretty rare, but I think it's still useful to return _some_ value.
Quoted 6 lines
But as you note, even without a symref extension, we already try to guess based on a unique branch. Probably even choosing the first one alphabetically would be reasonable. But I'd rather err on the side of historical compatibility if we can do so easily. Looking for init.mainBranch, followed by master, accomplishes that and isn't many lines of code.
I ended up using init.defaultBranch as preference, falling back to master, and then falling back to the first ref matching the given commit hash.
That should be safe enough.
Ciao,
Dscho
PATCH 3/9 send-pack/transport-helper: respect `core.defaultBranchName`
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When mentioning the default branch name in an error message, we want to go with the preference specified by the user.
--- send-pack.c | 6 +++++- transport-helper.c | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-)
send-pack.c +5 -1
@@ -405,8 +405,12 @@ int send_pack(struct send_pack_args *args, }if (!remote_refs) { +char *branch_name =git_default_branch_name (1 ); +fprintf (stderr,"No refs in common and none specified; doing nothing.\n" -"Perhaps you should specify a branch such as 'master'.\n" ); +"Perhaps you should specify a branch such as '%s'.\n" , + branch_name); +free (branch_name);return 0 ; }if (args->atomic && !atomic_supported)
transport-helper.c +5 -1
@@ -1044,9 +1044,13 @@ static int push_refs(struct transport *transport, }if (!remote_refs) { +char *branch_name =git_default_branch_name (1 ); +fprintf (stderr,_ ("No refs in common and none specified; doing nothing.\n" -"Perhaps you should specify a branch such as 'master'.\n" )); +"Perhaps you should specify a branch such as '%s'.\n" ), + branch_name); +free (branch_name);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH 4/9 testsvn: respect `core.defaultBranchName`
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
Since the default branch name can now be configured, the testsvn remote helper needs to be told about it.
--- remote-testsvn.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
remote-testsvn.c +8 -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, *default_branch;setup_git_directory ();if (argc <2 || argc >3 ) {
@@ -294,6 +294,10 @@ int cmd_main(int argc, const char **argv)return 1 ; } + remote_ref =git_default_branch_name (0 ); +if (!skip_prefix (remote_ref,"refs/heads/" , &default_branch)) +BUG ("unexpected remote_ref '%s'" , remote_ref); + remote =remote_get (argv[1 ]); url_in = (argc ==3 ) ? argv[2 ] : remote->url[0 ];
@@ -306,7 +310,8 @@ int cmd_main(int argc, const char **argv) url = url_sb.buf; } -strbuf_addf (&private_ref_sb,"refs/svn/%s/master" , remote->name); +strbuf_addf (&private_ref_sb,"refs/svn/%s/%s" , + remote->name, default_branch); private_ref = private_ref_sb.buf;strbuf_addf (¬es_ref_sb,"refs/notes/%s/revs" , remote->name);
Signature · 1 line
gitgitgadget
PATCH 5/9 submodule: use the (possibly overridden) default branch name
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
To allow for overriding the default branch name, we have introduced a config setting. With this patch, the git submodule command learns about this, too.
--- builtin/submodule--helper.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
builtin/submodule--helper.c +8 -2
@@ -1980,8 +1980,14 @@ static const char *remote_submodule_branch(const char *path) branch = sub->branch;free (key); -if (!branch) -return "master" ; +if (!branch) { +static char *default_branch; + +if (!default_branch) + default_branch =git_default_branch_name (1 ); + +return default_branch; + }if (!strcmp (branch,"." )) {const char *refname =resolve_ref_unsafe ("HEAD" ,0 ,NULL ,NULL );
Signature · 1 line
gitgitgadget
Re: [PATCH 5/9] submodule: use the (possibly overridden) default branch name
Quoted 7 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
To allow for overriding the default branch name, we have introduced a config setting. With this patch, the
git submodulecommand learns about this, too.Signed-off-by Johannes Schindelin <[email protected]>
One thing to consider: in the future, if we move away from "master" or even allow the value to be configurable, we're gonna end up breaking a lot of repositories this way.
If a developer regularly pulls in submodule updates via git submodule update --remote, when the default branch name changes, this will suddenly stop working. This will require developers who use submodules to "fix" their .gitmodules file.
If it's configurable, this problem might be even worse. It could lead to scenarios where one developer might go "works for me" while another developer (who may set the configuration and forget about it) would be confused about why it's not working for them.
Just a couple thoughts I had while looking at this patch.
PATCH 6/9 clone: learn about the possibly-configured default branch name
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.
Now that we can configure what the default branch name should be, we will want git clone to respect that setting.
--- builtin/clone.c | 14 +++++++++++--- t/t5609-clone-branch.sh | 9 +++++++++ 2 files changed, 20 insertions(+), 3 deletions(-)
builtin/clone.c +11 -3
@@ -1263,9 +1263,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix) remote_head_points_at =NULL ; remote_head =NULL ; option_no_checkout =1 ; -if (!option_bare) -install_branch_config (0 ,"master" , option_origin, -"refs/heads/master" ); +if (!option_bare) { +char *default_branch =git_default_branch_name (0 ); +const char *nick; + +if (!skip_prefix (default_branch,"refs/heads/" , &nick)) +BUG ("unexpected default branch '%s'" , + default_branch); +install_branch_config (0 , nick, option_origin, + default_branch); +free (default_branch); + } } write_refspec_config(src_ref_prefix, our_head_points_at,
t/t5609-clone-branch.sh +9 -0
@@ -67,4 +67,13 @@ test_expect_success 'clone -b not allowed with empty repos' ' test_must_fail git clone -b branch empty clone-branch-empty ' +test_expect_success 'chooses correct default branch name' ' + GIT_TEST_DEFAULT_BRANCH_NAME= \ + git -c core.defaultBranchName=up clone empty whats-up && + test_write_lines refs/heads/up refs/heads/up >expect && + git -C whats-up symbolic-ref HEAD >actual && + git -C whats-up config branch.up.merge >>actual && + test_cmp expect actual +' + test_done
Signature · 1 line
gitgitgadget
Re: [PATCH 6/9] clone: learn about the possibly-configured default branch name
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 8 lines · writes:
builtin/clone.c +1
-3@@ -1263,9 +1263,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix) remote_head_points_at =NULL ; remote_head =NULL ; option_no_checkout =1 ; -if (!option_bare) -install_branch_config (0 ,"master" , option_origin, -"refs/heads/master" ); +if (!option_bare) {
builtin/clone.c int cmd_clone(int argc, const char **argv, const char *prefix) · line 1276
Quoted 10 lines
builtin/clone.c +10
-0+char *default_branch =git_default_branch_name (0 ); +const char *nick; + +if (!skip_prefix (default_branch,"refs/heads/" , &nick)) +BUG ("unexpected default branch '%s'" , + default_branch); +install_branch_config (0 , nick, option_origin, + default_branch); +free (default_branch); + }
Good catch. Normal clone would follow whatever primary branch the other side uses by pointing at it with its "HEAD" but this codepath to deal with a clone of an empty repository needs to use a default, so this is an appropriate change.
Quoted 19 lines
builtin/clone.c +0
-0write_refspec_config(src_ref_prefix, our_head_points_at,t/t5609-clone-branch.sh +9
-0@@ -67,4 +67,13 @@ test_expect_success 'clone -b not allowed with empty repos' ' test_must_fail git clone -b branch empty clone-branch-empty ' +test_expect_success 'chooses correct default branch name' ' + GIT_TEST_DEFAULT_BRANCH_NAME= \ + git -c core.defaultBranchName=up clone empty whats-up && + test_write_lines refs/heads/up refs/heads/up >expect && + git -C whats-up symbolic-ref HEAD >actual && + git -C whats-up config branch.up.merge >>actual && + test_cmp expect actual +' + test_done
PATCH 7/9 fmt-merge-msg: learn about the possibly-configured default branch name
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When formatting the commit message for merge commits, Git appends "into <branch-name>" unless the current branch is the default branch.
Now that we can configure what the default branch name should be, we will want to respect that setting in that scenario rather than using the compiled-in default branch name.
--- fmt-merge-msg.c | 6 ++++-- t/t6200-fmt-merge-msg.sh | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-)
fmt-merge-msg.c +4 -2
@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out, const char *current_branch) {int i =0 ; -char *sep ="" ; +char *sep ="" , *default_branch_name;strbuf_addstr (out,"Merge " );for (i =0 ; i < srcs.nr; i++) {
@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } -if (!strcmp ("master" , current_branch)) + default_branch_name =git_default_branch_name (1 ); +if (!strcmp (default_branch_name, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (default_branch_name); } static void fmt_tag_signature(struct strbuf *tagbuf,
t/t6200-fmt-merge-msg.sh +8 -0
@@ -158,6 +158,14 @@ test_expect_success 'setup FETCH_HEAD' ' git fetch . left ' +test_expect_success 'with overridden default branch name' ' + test_config core.defaultBranchName default && + test_when_finished "git switch master" && + git switch -c default && + git fmt-merge-msg <.git/FETCH_HEAD >actual && + ! grep "into default" actual +' + test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && Merge branch ${apos}left${apos}
Signature · 1 line
gitgitgadget
Re: [PATCH 7/9] fmt-merge-msg: learn about the possibly-configured default branch name
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 30 lines · writes:
From: Johannes Schindelin <[email protected]>
When formatting the commit message for merge commits, Git appends "into <branch-name>" unless the current branch is the default branch.
Now that we can configure what the default branch name should be, we will want to respect that setting in that scenario rather than using the compiled-in default branch name.
Signed-off-by Johannes Schindelin <[email protected]>--- fmt-merge-msg.c | 6 ++++-- t/t6200-fmt-merge-msg.sh | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-)fmt-merge-msg.c +1
-1@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out, const char *current_branch) {int i =0 ; -char *sep ="" ; +char *sep ="" , *default_branch_name;strbuf_addstr (out,"Merge " );for (i =0 ; i < srcs.nr; i++) {@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string);
fmt-merge-msg.c static void fmt_merge_msg_title(struct strbuf *out, · line 460
Quoted 10 lines
fmt-merge-msg.c +3
-1} -if (!strcmp ("master" , current_branch)) + default_branch_name =git_default_branch_name (1 ); +if (!strcmp (default_branch_name, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (default_branch_name); }
Good. J6t reminded me earlier about this one when I said "except for 'init' and 'clone' (when it cannot tell what primary branch the source of the clone uses), we do not need a hardcoded 'master'", and the series covers this case. Very pleased.
Quoted 20 lines
fmt-merge-msg.c +0
-0static void fmt_tag_signature(struct strbuf *tagbuf,t/t6200-fmt-merge-msg.sh +8
-0@@ -158,6 +158,14 @@ test_expect_success 'setup FETCH_HEAD' ' git fetch . left ' +test_expect_success 'with overridden default branch name' ' + test_config core.defaultBranchName default && + test_when_finished "git switch master" && + git switch -c default && + git fmt-merge-msg <.git/FETCH_HEAD >actual && + ! grep "into default" actual +' + test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && Merge branch ${apos}left${apos}
PATCH 8/9 fast-export: respect the possibly-overridden default branch name
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When anonymizing commit history, we are careful to leave the branch name of the default branch alone.
When the default branch name is overridden via the config or via the environment variable, we will want git fast-export to use that overridden name instead.
--- builtin/fast-export.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
builtin/fast-export.c +7 -3
@@ -515,13 +515,17 @@ static const char *anonymize_refname(const char *refname) };static struct hashmap refs;static struct strbuf anon =STRBUF_INIT ; +static char *default_branch_name;int i;/* -* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* We also leave the default branch name as a special case, since it +* does not reveal anything interesting. */ -if (!strcmp (refname,"refs/heads/master" )) +if (!default_branch_name) + default_branch_name =git_default_branch_name (0 ); + +if (!strcmp (refname, default_branch_name))return refname;strbuf_reset (&anon);
Signature · 1 line
gitgitgadget
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 524
Quoted 5 lines
builtin/fast-export.c +2
-2-* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* We also leave the default branch name as a special case, since it +* does not reveal anything interesting. */
I feel this is a weird thing to do, since you're trying to anonymize the branch name,and now the default branch is identifiable with your config file. For example, if the default branch contains the name of my project/repo then this sounds like a recipe for accidentally sharing it. I feel a better alternative would
be to exclude nothing from the anonymization or the proposed default default branch name
Quoted 11 lines
builtin/fast-export.c +4
-2-if (!strcmp (refname,"refs/heads/master" )) +if (!default_branch_name) + default_branch_name =git_default_branch_name (0 ); + +if (!strcmp (refname, default_branch_name))return refname;strbuf_reset (&anon); --gitgitgadget
Signature · 1 line
Matthew Rogers
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 5 lines · Matt Rogers
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 524
Quoted 5 lines
builtin/fast-export.c +2
-2-* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* We also leave the default branch name as a special case, since it +* does not reveal anything interesting. */
Quoted 7 lines
I feel this is a weird thing to do, since you're trying to anonymize the branch name,and now the default branch is identifiable with your config file. For example, if the default branch contains the name of my project/repo then this sounds like a recipe for accidentally sharing it. I feel a better alternative would
be to exclude nothing from the anonymization or the proposed default default branch name
I wonder if anything bad happens if we keep *no* refs intact in this function. "Since it does not reveal anything interesting" is an excuse why not munging it may be OK, but it does not explain why we prefer not munging it actively.
If there is no reason to keep _some_ refs as-is, I agree that it is perfectly sensible not to have this special case at all.
Thanks.
Quoted 11 lines
Quoted 11 lines
builtin/fast-export.c +4
-2-if (!strcmp (refname,"refs/heads/master" )) +if (!default_branch_name) + default_branch_name =git_default_branch_name (0 ); + +if (!strcmp (refname, default_branch_name))return refname;strbuf_reset (&anon); --gitgitgadget
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
In reply to Matt RogersQuoted 5 lines · Matt Rogers
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 524
Quoted 5 lines
builtin/fast-export.c +2
-2-* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* We also leave the default branch name as a special case, since it +* does not reveal anything interesting. */
Quoted 7 lines
I feel this is a weird thing to do, since you're trying to anonymize the branch name,and now the default branch is identifiable with your config file. For example, if the default branch contains the name of my project/repo then this sounds like a recipe for accidentally sharing it. I feel a better alternative would
be to exclude nothing from the anonymization or the proposed default default branch name
I think this is fine because it only reveals the name of your particular choice of default branch. The goal of the --anonymize option is to allow people to maintain the structure of their repositories while stripping private information from them, primarily for debugging purposes (e.g., providing to us for troubleshooting).
The things people want to prevent exposing are their code, data, project names, user names, etc.: that is, anything identifying, privileged, or private. The default branch name isn't any of those things; we know you have one, and for troubleshooting purposes, we aren't that interested in what you called it. You've almost certainly picked it out of a set of one of 20 words that people use for this purpose, none of which are private, and all of which are shared by millions of other repositories.
In the extremely unlikely case that it does matter, invoking git with something like "-c default.branch=$(git hash-object /dev/null)" would be sufficient to anonymize all branches.
I should point out that people frequently ask for the output of "git config -l" for troubleshooting, and most people wouldn't consider their default branch name to be worth sanitizing there.
Signature · 2 lines
brian m. carlson: Houston, Texas, US OpenPGP: https://keybase.io/bk2204
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 6 lines
I think this is fine because it only reveals the name of your particular choice of default branch. The goal of the --anonymize option is to allow people to maintain the structure of their repositories while stripping private information from them, primarily for debugging purposes (e.g., providing to us for troubleshooting).
Quoted 8 lines
The things people want to prevent exposing are their code, data, project names, user names, etc.: that is, anything identifying, privileged, or private. The default branch name isn't any of those things; we know you have one, and for troubleshooting purposes, we aren't that interested in what you called it. You've almost certainly picked it out of a set of one of 20 words that people use for this purpose, none of which are private, and all of which are shared by millions of other repositories.
I think that's not very convincing. If branch names in general are identifying enough to warrant anonymization then shouldn't the default name be too?
Quoted 7 lines
In the extremely unlikely case that it does matter, invoking git with something like "-c default.branch=$(git hash-object
/dev/null)" would be sufficient to anonymize all branches.I should point out that people frequently ask for the output of "git config -l" for troubleshooting, and most people wouldn't consider their default branch name to be worth sanitizing there.
I think this is a little presumptuous, most people wouldn't consider it to be worth sanitizing because there isn't currently such a config setting. If I give you the the output of "git config -l" then I think it's obvious that all of my configuration settings will be included (and therefore I can choose to sanitize accordingly), but if I'm giving an exported repository I think should be anonymized, but my default branch, which someone could innocently base on a project or company name, could easily be accidentally included in that output which could lead to a frustrating experience
Quoted 3 lines
--
brian m. carlson: Houston, Texas, US
OpenPGP: https://keybase.io/bk2204
Signature · 1 line
Matthew Rogers
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 2 lines · Matt Rogers
I think that's not very convincing. If branch names in general are identifying enough to warrant anonymization then shouldn't the default name be too?
It is a good argument. I also heard a rumor that often branch names contain codewords given to pre-released hardware that are highly confidential in certain circles, and heard that it is one of the reasons why Gerrit has server side ACL that lets you hide some branches from authenticated users that can access other branches.
Again, the original comment explains why 'master' without such a configuration knob was not worth protecting, but what it does not explain is why keeping it (and only that branch name) unmunged gives a more useful result than munging everything. From the point of view of "I want to debug the shape of the DAG, without the actual user data", munging 'master' to 'ref47' while other branches like 'next' are munged to 'ref%d' does not make it harder to use or less useful for the debugging than only 'master' is kept intact in the output stream.
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Hi,
Quoted 10 lines · Junio C Hamano
Quoted 2 lines · Matt Rogers
I think that's not very convincing. If branch names in general are identifying enough to warrant anonymization then shouldn't the default name be too?
It is a good argument. I also heard a rumor that often branch names contain codewords given to pre-released hardware that are highly confidential in certain circles, and heard that it is one of the reasons why Gerrit has server side ACL that lets you hide some branches from authenticated users that can access other branches.
Yes, branch names in general _can_ contain information users may prefer to keep private.
However, we're not talking about branch names in general. We are talking about the default name of the main branch, to be picked in _all_ of your new repositories.
Quoted 9 lines
Again, the original comment explains why 'master' without such a configuration knob was not worth protecting, but what it does not explain is why keeping it (and only that branch name) unmunged gives a more useful result than munging everything. From the point of view of "I want to debug the shape of the DAG, without the actual user data", munging 'master' to 'ref47' while other branches like 'next' are munged to 'ref%d' does not make it harder to use or less useful for the debugging than only 'master' is kept intact in the output stream.
Yes. And you're unlikely to configure the default name to be used for all of your future git init operations to be something non-generic.
I am still highly doubtful of Matt's suggestion that it would be worth protecting the default name of the main branch to be used for _each_ and _any_ new repository.
Now, if you suggest that git fast-export --anonymize should either not special-case the main branch, or at least have a configurable set of names it skips from protecting, then I will be much more in favor of those suggestions. However, those suggestions are quite a bit orthogonal to the patch series at hand, so I would want to discuss them in their own code contribution instead of here.
Ciao,
Dscho
Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 6 lines · Johannes Schindelin
Quoted 5 lines
It is a good argument. I also heard a rumor that often branch names contain codewords given to pre-released hardware that are highly confidential in certain circles, and heard that it is one of the reasons why Gerrit has server side ACL that lets you hide some branches from authenticated users that can access other branches.
Quoted 6 lines
Yes, branch names in general _can_ contain information users may prefer to keep private.
However, we're not talking about branch names in general. We are talking about the default name of the main branch, to be picked in _all_ of your new repositories.
No, we are talking about the name of the branch, chosen to be the primary one, in one particular repository whose contents are exported via fast-export with explicit request from the user to anonymize end-user data.
Quoted 9 lines
Yes. And you're unlikely to configure the default name to be used for all of your future
git initoperations to be something non-generic.Now, if you suggest that
git fast-export --anonymizeshould either not special-case the main branch, or at least have a configurable set of names it skips from protecting, then I will be much more in favor of those suggestions. However, those suggestions are quite a bit orthogonal to the patch series at hand, so I would want to discuss them in their own code contribution instead of here.
I think after writing the message about your "two variable" approach, you would retract the "something non-generic" part in the above sentence. The original "we redact branch names but 'master' is used by and known by everybody so there is no need to redact" would have been a good argument. Perhaps there is a value to keep the primary branch identifiable even in an export stream that has all the refnames and payload anonymized, and leaving 'master' intact would have been a viable approach for solving that issue.
That trick NO LONGER applies once you allow the name of the primary branch customizable, and the end user has used a name that is not to be exposed. Yes, "we want to ensure that readers of the export stream can identify which ref is the primary branch of the repository" is orthogonal from "how do we make primary branch configurable in a live repository?" and "how do we make the default name used for the primary branch in repositories newly created?". But because the old solution would not work in the new world order this topic created, a new solution needs to be found when you move the world to the new order.
An easy solution would be to reserve "ref0" for the primary branch in the repository and anonymize other refs "ref1", "ref2", ...
That can be done as a preparatory step regardless of the "'master' may not be in the name of the primary branch in this repository" topic.
-- >8 --
Subject: [PATCH] fast-export: do anonymize the primary branch name
In a fast-export stream with --anonymize option, all the end-user data including refnames are munged to prevent exposure, but the 'master' branch is left intact.
There is a comment that explains why it is OK to leave 'master' unanonymized (because everybody calls the primary branch 'master' and it is no secret), but that does not justify why it is bad to anonymize 'master' and make it undistinguishable from other branches. Assuming there _is_ a need to allow the readers of the output to tell where the tip of the primary branch is, let's keep the special casing of 'master', but still anonymize it to "ref0". Because all other branches will be given ref+N where N is a positive integer, this will keep the primary branch identifiable in the output stream, without exposing what the name of the primary branch is in the repository the export stream was taken from.
This is in preparation for introducing a mechanism to affect the name of the primary branch used in the repository. Once the mechanism is in use, the name of the primary branch won't be 'master', and may not be allowed to be exposed.
--- builtin/fast-export.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
builtin/fast-export.c +2 -2
@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len) {static int counter;struct strbuf out =STRBUF_INIT ; -strbuf_addf (&out,"ref%d" , counter++); +strbuf_addf (&out,"ref%d" , ++counter);return strbuf_detach (&out, len); }
@@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)* anything interesting. */ if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "ref0" ;strbuf_reset (&anon);for (i =0 ; i <ARRAY_SIZE (prefixes); i++) {
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 25 lines · Junio C Hamano
But because the old solution would not work in the new world order this topic created, a new solution needs to be found when you move the world to the new order.
An easy solution would be to reserve "ref0" for the primary branch in the repository and anonymize other refs "ref1", "ref2", ...
That can be done as a preparatory step regardless of the "'master' may not be in the name of the primary branch in this repository" topic.
...builtin/fast-export.c +1
-1@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len) {static int counter;struct strbuf out =STRBUF_INIT ; -strbuf_addf (&out,"ref%d" , counter++); +strbuf_addf (&out,"ref%d" , ++counter);return strbuf_detach (&out, len); }
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 525
Quoted 5 lines
builtin/fast-export.c +1
-1@@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)* anything interesting. */ if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "ref0" ;
This is obviously wrong. It should return "refs/heads/ref0".
But another thing we could do, which is probably more backward compatible, is to return "refs/heads/master" from here. That way, consumers of "fast-export" stream that expect 'master' to be the primary branch would not get upset when the data source runs a newer version of Git that allows the primary branch name to be customized.
Which means that, before such a change to allow the primary branch name to be customized happens, there is no need for such a preparatory patch, because the status quo is just fine. So, I'm OK with retracting the above. "ref0" is not special, so there is no need to have the first hunk above, either.
However, when the customization being discussed is implemented via the "get_default_branch_name()" and "get_primary_branch_name()" functions, we should update these lines like so:
- if (!strcmp(refname, "refs/heads/master"))
- return "refs/heads/master";
+ if (!strcmp(refname, get_primary_branch_name(DO_NOT_ABBREV)))
+ return get_default_branch_name(DO_NOT_ABBREV);
That is, the name of the "primary" branch used at the data source is replaced by the more generic "this is the default" branch name used in a random "git init" repository.
Imagine that there is a project that has an integration branch per each device type, named after the confidential device name, owned by a company. An employee of the company works on one device type in his own clone of the repository, and the primary branch in the repository is set to that confidential device's name.
The employee can create an anonymized output, replacing the confidential name with a generic "default" name that is not confidential, like 'main' in the new world order or 'master' in the backward compatible world order, with such an updated code.
After having thought about it a bit longer, I actually do prefer to use the "ref0" approach, as it is possible for the employee in the above example to have the "default" branch name tied to the primary branch for the hardware type the emploee works on in the ~/.gitconfig so the "alternative" I suggested in this message will reveal the confidential name.
So, I guess we should just fix the patch I am responding to to return "refs/heads/ref0" instead of "ref0", and queue it as one of the preparatory steps.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 13 lines · Junio C Hamano
Quoted 13 lines
builtin/fast-export.c +1
-1@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len) {static int counter;struct strbuf out =STRBUF_INIT ; -strbuf_addf (&out,"ref%d" , counter++); +strbuf_addf (&out,"ref%d" , ++counter);return strbuf_detach (&out, len); }
Quoted 12 lines
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 525
Quoted 6 lines
builtin/fast-export.c +1
-1@@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)* anything interesting. */ if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "ref0" ;This is obviously wrong. It should return "refs/heads/ref0".
...
So, I guess we should just fix the patch I am responding to to return "refs/heads/ref0" instead of "ref0", and queue it as one of the preparatory steps.
... and the follow-up step to become part of the series you are working on to allow customing what the primary branch is called would turn the second hunk to
- if (!strcmp(refname, "refs/heads/master")) + if (!strcmp(refname, get_primary_branch_name(0))) return "refs/heads/ref0";
By the way, with your "two variables" approach to make both the "default" (for 'init' and 'clone') and the "primary" (for 'fmt-merge-msg' and 'fast-export') configurable, we'd need accessor function(s) for the primary branch name for the given repository. The get_primary_branch_name() helper function might want to take a "struct repository *" argument in addition to "please give me an abbreviated refname" boolean, given the recent push to pass the struct to everybody.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Hi Junio,
Quoted 28 lines · Junio C Hamano
Quoted 13 lines · Junio C Hamano
Quoted 13 lines
builtin/fast-export.c +1
-1@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len) {static int counter;struct strbuf out =STRBUF_INIT ; -strbuf_addf (&out,"ref%d" , counter++); +strbuf_addf (&out,"ref%d" , ++counter);return strbuf_detach (&out, len); }Quoted 12 lines
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 525
Quoted 6 lines
builtin/fast-export.c +1
-1@@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)* anything interesting. */ if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "ref0" ;This is obviously wrong. It should return "refs/heads/ref0".
...
So, I guess we should just fix the patch I am responding to to return "refs/heads/ref0" instead of "ref0", and queue it as one of the preparatory steps.
Quoted 7 lines
... and the follow-up step to become part of the series you are working on to allow customing what the primary branch is called would turn the second hunk to
- if (!strcmp(refname, "refs/heads/master")) + if (!strcmp(refname, get_primary_branch_name(0))) return "refs/heads/ref0";
Right.
Quoted 8 lines
By the way, with your "two variables" approach to make both the "default" (for 'init' and 'clone') and the "primary" (for 'fmt-merge-msg' and 'fast-export') configurable, we'd need accessor function(s) for the primary branch name for the given repository. The
get_primary_branch_name()helper function might want to take a "struct repository *" argument in addition to "please give me an abbreviated refname" boolean, given the recent push to pass the struct to everybody.
My current state defines a repo_main_branch_name(flags) function where the flags can be MAIN_BRANCH_SHORT_NAME and MAIN_BRANCH_FOR_INIT.
So I think we're on the same page.
BTW I heard from a couple sides that "primary" would imply that there is also a "secondary" branch, and potentially an ordering of all branches, which is why I did not really consider "primary" as candidate. Besides, it is so much more awkward to type than "main" (especially when you're as tired as I am right now...).
That's why I try to stay with "main" for the moment.
Ciao,
Dscho
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 7 lines · Johannes Schindelin
BTW I heard from a couple sides that "primary" would imply that there is also a "secondary" branch, and potentially an ordering of all branches, which is why I did not really consider "primary" as candidate. Besides, it is so much more awkward to type than "main" (especially when you're as tired as I am right now...).
That's why I try to stay with "main" for the moment.
You are reading too much into it. I used "primary" because I needed a word that clearly conveys the concept of being a special among others, a word that is about the concept which is different from the concept of "default", and that is clearly different from any of the candidates floated as concrete words to replace 'master'. Because I wanted to say things like:
In the context of fast-export, you'd want to special case the "primary" branch name, because unlike the "default" branch name (which we envision to be 'main' for most people in the new world order, so it may be less worth anonymizing because of the same reason the current code keeps 'master' as-is), its name can be sensitive.
without becoming unnecessarily ambiguous (replace 'primary' with 'main' in the above).
It was not because I do not want us to pick 'main' as the replacement word for 'master' as the default branch name.
And a set of things, among which there is a concept of "one thing that is special and different from all the others", does not necessarily have to be a totally ordered set. When cloning, we say that the (often bare) repository at the other end indicates which branch is the primary branch of the project by pointing at it with its HEAD (which is the reason why we try to fork it to our local branch namespace and check it out after cloning). There is no "secondary" in such a use case, and there is no need to have one.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
In reply to Junio C HamanoHi Junio,
Quoted 31 lines · Junio C Hamano
Quoted 6 lines · Johannes Schindelin
Quoted 5 lines
It is a good argument. I also heard a rumor that often branch names contain codewords given to pre-released hardware that are highly confidential in certain circles, and heard that it is one of the reasons why Gerrit has server side ACL that lets you hide some branches from authenticated users that can access other branches.
Quoted 6 lines
Yes, branch names in general _can_ contain information users may prefer to keep private.
However, we're not talking about branch names in general. We are talking about the default name of the main branch, to be picked in _all_ of your new repositories.
No, we are talking about the name of the branch, chosen to be the primary one, in one particular repository whose contents are exported via fast-export with explicit request from the user to anonymize end-user data.
Quoted 9 lines
Yes. And you're unlikely to configure the default name to be used for all of your future
git initoperations to be something non-generic.Now, if you suggest that
git fast-export --anonymizeshould either not special-case the main branch, or at least have a configurable set of names it skips from protecting, then I will be much more in favor of those suggestions. However, those suggestions are quite a bit orthogonal to the patch series at hand, so I would want to discuss them in their own code contribution instead of here.
Quoted 3 lines
I think after writing the message about your "two variable" approach, you would retract the "something non-generic" part in the above sentence.
You are absolutely correct!
Quoted 3 lines
[...]
-- >8 --
Subject: [PATCH] fast-export: do anonymize the primary branch name
I like this approach a lot. Do you want me to integrate it into this patch series, or rather have it as a stand-alone patch?
Ciao,
Dscho
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 4 lines · Johannes Schindelin
Quoted 1 line
Subject: [PATCH] fast-export: do anonymize the primary branch name
I like this approach a lot. Do you want me to integrate it into this patch series, or rather have it as a stand-alone patch?
I do not see any need for an off-series preparation step. Without configurable primary branch, keeping 'master' as 'master' used in the current code is an OK way to anonymize refs and still keep the primary line of development in the output identifyable. The "ref0" trick becomes necessary only when we introduce configurable primary; even though it would not hurt to switch to the "ref0" approach to anonymize-but-still-the-primary-is-identifiable early, it just is not necessary to do so.
I'd say that we should take <[email protected]> with two changes,
- see if the "refname" matches the fully
spelled primary branch name by asking repo_main_branch_name(repo, 0), instead of comparing with "refs/heads/master", and
- if matches return "refs/heads/ref0" instead of "ref0".
and replace your [PATCH 8/9] (or whichever the counterpart patch is in the rerolled series) with it.
Thanks.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
In reply to Junio C HamanoHi Junio,
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 525
Quoted 10 lines · Junio C Hamano
builtin/fast-export.c +1
-1@@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)* anything interesting. */ if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "ref0" ;
I just realized that the comment above reads:
/*
* We also leave "master" as a special case, since it does not reveal
* anything interesting.
*/
Obviously, we need to change that comment here because we do not leave the name unchanged. How about this?
/*
* We special-case the main branch, anonymizing it to `ref0`.
*/Ciao,
Dscho
Quoted 4 lines
builtin/fast-export.c +0
-0strbuf_reset (&anon);for (i =0 ; i <ARRAY_SIZE (prefixes); i++) {
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Hi Junio,
Quoted 21 lines · Johannes Schindelin
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 525
Quoted 10 lines · Junio C Hamano
builtin/fast-export.c +1
-1@@ -522,7 +522,7 @@ static const char *anonymize_refname(const char *refname)* anything interesting. */ if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "ref0" ;I just realized that the comment above reads:
/*
* We also leave "master" as a special case, since it does not reveal
* anything interesting.
*/
Quoted 6 lines
Obviously, we need to change that comment here because we do not leave the name unchanged. How about this?
/* * We special-case the main branch, anonymizing it to `ref0`. */
Also, t9351 obviously needs to be adjusted. This one works for me:
-- snipsnap --
From: Junio C Hamano <[email protected]>
Date: Thu, 11 Jun 2020 08:05:38 -0700
Subject: [PATCH] fast-export: do anonymize the primary branch name
In a fast-export stream with --anonymize option, all the end-user data including refnames are munged to prevent exposure, but the 'master' branch is left intact.
There is a comment that explains why it is OK to leave 'master' unanonymized (because everybody calls the primary branch 'master' and it is no secret), but that does not justify why it is bad to anonymize 'master' and make it undistinguishable from other branches. Assuming there _is_ a need to allow the readers of the output to tell where the tip of the primary branch is, let's keep the special casing of 'master', but still anonymize it to "ref0". Because all other branches will be given ref+N where N is a positive integer, this will keep the primary branch identifiable in the output stream, without exposing what the name of the primary branch is in the repository the export stream was taken from.
This is in preparation for introducing a mechanism to affect the name of the primary branch used in the repository. Once the mechanism is in use, the name of the primary branch won't be 'master', and may not be allowed to be exposed.
--- builtin/fast-export.c | 7 +++---- t/t9351-fast-export-anonymize.sh | 9 +++++---- 2 files changed, 8 insertions(+), 8 deletions(-)
builtin/fast-export.c +3 -4
@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len) {static int counter;struct strbuf out =STRBUF_INIT ; -strbuf_addf (&out,"ref%d" , counter++); +strbuf_addf (&out,"ref%d" , ++counter);return strbuf_detach (&out, len); }
@@ -518,11 +518,10 @@ static const char *anonymize_refname(const char *refname)int i;/* -* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* We special-case the main branch, anonymizing it to `ref0`. */ if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "refs/heads/ref0" ;strbuf_reset (&anon);for (i =0 ; i <ARRAY_SIZE (prefixes); i++) {
t/t9351-fast-export-anonymize.sh +5 -4
@@ -26,8 +26,9 @@ test_expect_success 'stream omits path names' ' ! grep xyzzy stream ' -test_expect_success 'stream allows master as refname' ' - grep master stream +test_expect_success 'stream translates master to ref0' ' + grep refs/heads/ref0 stream && + ! grep master stream ' test_expect_success 'stream omits other refnames' '
@@ -57,7 +58,7 @@ test_expect_success 'import stream to new repository' ' test_expect_success 'result has two branches' ' git for-each-ref --format="%(refname)" refs/heads >branches && test_line_count = 2 branches && - other_branch=$(grep -v refs/heads/master branches) + other_branch=$(grep -v refs/heads/ref0 branches) ' test_expect_success 'repo has original shape and timestamps' '
@@ -65,7 +66,7 @@ test_expect_success 'repo has original shape and timestamps' ' git log --format="%m %ct" --left-right --boundary "$@" } && (cd .. && shape master...other) >expect && - shape master...$other_branch >actual && + shape ref0...$other_branch >actual && test_cmp expect actual '
--
2.26.0.windows.1
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 23 lines · Johannes Schindelin
Also, t9351 obviously needs to be adjusted. This one works for me:
-- snipsnap --
From: Junio C Hamano <[email protected]>
Date: Thu, 11 Jun 2020 08:05:38 -0700
Subject: [PATCH] fast-export: do anonymize the primary branch nameIn a fast-export stream with --anonymize option, all the end-user data including refnames are munged to prevent exposure, but the 'master' branch is left intact.
...
This is in preparation for introducing a mechanism to affect the name of the primary branch used in the repository. Once the mechanism is in use, the name of the primary branch won't be 'master', and may not be allowed to be exposed.Signed-off-by Junio C Hamano <[email protected]>Signed-off-by Johannes Schindelin <[email protected]>--- builtin/fast-export.c | 7 +++---- t/t9351-fast-export-anonymize.sh | 9 +++++---- 2 files changed, 8 insertions(+), 8 deletions(-)...
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 524
Quoted 3 lines
builtin/fast-export.c +1
-1if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "refs/heads/ref0" ;
As I said already, I personally do not think that this needs to be a preparatory patch to anonymize 'master' that cannot be configured to something else into 'ref0'. This will become necessary when we make the primary branch configurable, so I think it is easier to replace the counterpart to your [PATCH 8/9] in the original series with it in the v2 series.
Regarding the update to the comment before this "special case", I would suggest to explain "why" not just "what".
Thanks.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 6 lines · Junio C Hamano
As I said already, I personally do not think that this needs to be a preparatory patch to anonymize 'master' that cannot be configured to something else into 'ref0'. This will become necessary when we make the primary branch configurable, so I think it is easier to replace the counterpart to your [PATCH 8/9] in the original series with it in the v2 series.
Ah, I forgot to say, if you think it is easier to manage the main set of patches for the topic to eject as much preparatory changes as possible, I do not at all mind treating this as one of the preparatory step and queue it separately, making the main series depend on it. I just wanted to say that it is not necessary, even though it does not hurt.
Quoted 4 lines
Regarding the update to the comment before this "special case", I would suggest to explain "why" not just "what".
Thanks.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Hi Junio,
Quoted 9 lines · Junio C Hamano
Quoted 6 lines · Junio C Hamano
As I said already, I personally do not think that this needs to be a preparatory patch to anonymize 'master' that cannot be configured to something else into 'ref0'. This will become necessary when we make the primary branch configurable, so I think it is easier to replace the counterpart to your [PATCH 8/9] in the original series with it in the v2 series.
Quoted 6 lines
Ah, I forgot to say, if you think it is easier to manage the main set of patches for the topic to eject as much preparatory changes as possible, I do not at all mind treating this as one of the preparatory step and queue it separately, making the main series depend on it. I just wanted to say that it is not necessary, even though it does not hurt.
Due to the need to adjust t9351, I think it is clearer if it is a two-part
change: one to introduce the "main branch -> ref0" change, and another one to respect core.mainBranch. Those are separate concerns in my mind.
I moved the first one to the beginning of the patch series so that you're still at liberty to take it early vs keeping it within the topic branch.
Thanks,
Dscho
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
In reply to Johannes SchindelinQuoted 8 lines · Johannes Schindelin
I just realized that the comment above reads:
/*
* We also leave "master" as a special case, since it does not reveal
* anything interesting.
*/
Quoted 6 lines
Obviously, we need to change that comment here because we do not leave the name unchanged. How about this?
/* * We special-case the main branch, anonymizing it to `ref0`. */
If you are going to update it, why not make it useful?
I complained number of times during the discussion that the original comment explains why leaving 'master' as-is does not reveal anything useful to adversaries but does not justify what the code attempts to achieve by special casing 'master' in the first place.
It is not an improvement to literally adjust that inadequate comment to the new world order to just parrot what the code already says without explaining why it does so.
/*
* Anonymize the name used for the primary branch in this
* repository, but reserve ref0 for it, so that it can
* be identified among other refs in the output. */
is the minimum I would expect before calling it an improvement. We could add
It is often main for new repositories (and master for aged ones) and such well-known names may not need anonymizing, but it could be configured to use a secret word that the user may not want to reveal.
at the end to explain the motivation behind anonymizing even more, if we wanted to.
Now, "so that ..." part is totally a fabrication based on my best guess. I do not know what the original author was thinking when the decision to leave the master as-is was made.
Thanks.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Am 12.06.20 um 17:14 schrieb Junio C Hamano:
Quoted 9 lines
/*
* Anonymize the name used for the primary branch in this
* repository, but reserveref0for it, so that it can
* be identified among other refs in the output. */is the minimum I would expect before calling it an improvement. We could add
Quoted 7 lines
It is often
mainfor new repositories (andmasterfor aged ones) and such well-known names may not need anonymizing, but it could be configured to use a secret word that the user may not want to reveal.at the end to explain the motivation behind anonymizing even more, if we wanted to.
IMO, making the primary branch identifiable is a reasonable justification to treat it specially. But then, why does it have to be renamed to 'ref0'? Couldn't it just be renamed to Git's default primary branch name, be it 'master' today or 'main' or whatever in the future? After the anonymization, nobody will know whether that was the real name of the primary branch or not. Leaving it at 'master'/'main' reduces the mental burden of the recipient of the anonymous repo.
-- Hannes
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 15 lines · Johannes Sixt
Am 12.06.20 um 17:14 schrieb Junio C Hamano:
Quoted 14 lines
/*
* Anonymize the name used for the primary branch in this
* repository, but reserveref0for it, so that it can
* be identified among other refs in the output. */is the minimum I would expect before calling it an improvement. We could add
It is often
mainfor new repositories (andmasterfor aged ones) and such well-known names may not need anonymizing, but it could be configured to use a secret word that the user may not want to reveal.
Quoted 7 lines
Quoted 2 lines
at the end to explain the motivation behind anonymizing even more, if we wanted to.
IMO, making the primary branch identifiable is a reasonable justification to treat it specially. But then, why does it have to be renamed to 'ref0'? Couldn't it just be renamed to Git's default primary branch name, be it 'master' today or 'main' or whatever in the future?
That comes from https://lore.kernel.org/git/[email protected]/
But I agree with you 100% if you literally mean 'master' (or 'main') hardcoded without any end-user customization. What I rejected and replaced with the vanilla "ref0" was to return the configured name that will be used for the primary branch in new repositories. The above proposal suggested a faulty:
- if (!strcmp(refname, "refs/heads/master"))
- return refname;
+ if (!strcmp(refname, get_primary_branch_name(DO_NOT_ABBREV)))
+ return get_default_branch_name(DO_NOT_ABBREV);
A corrected code should return a hardwired constant 'main' (it probably gets behind a C preprocessor macro, but the point is that we do not want end-user customization) for the reason stated in that message.
Thanks.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Hi Junio & Hannes,
Quoted 38 lines · Junio C Hamano
Quoted 15 lines · Johannes Sixt
Am 12.06.20 um 17:14 schrieb Junio C Hamano:
Quoted 14 lines
/*
* Anonymize the name used for the primary branch in this
* repository, but reserveref0for it, so that it can
* be identified among other refs in the output. */is the minimum I would expect before calling it an improvement. We could add
It is often
mainfor new repositories (andmasterfor aged ones) and such well-known names may not need anonymizing, but it could be configured to use a secret word that the user may not want to reveal.Quoted 7 lines
Quoted 2 lines
at the end to explain the motivation behind anonymizing even more, if we wanted to.
IMO, making the primary branch identifiable is a reasonable justification to treat it specially. But then, why does it have to be renamed to 'ref0'? Couldn't it just be renamed to Git's default primary branch name, be it 'master' today or 'main' or whatever in the future?
That comes from https://lore.kernel.org/git/[email protected]/
But I agree with you 100% if you literally mean 'master' (or 'main') hardcoded without any end-user customization. What I rejected and replaced with the vanilla "ref0" was to return the configured name that will be used for the primary branch in new repositories. The above proposal suggested a faulty:
(quoted diff) +2
-2- if (!strcmp(refname, "refs/heads/master")) - return refname; + if (!strcmp(refname, get_primary_branch_name(DO_NOT_ABBREV))) + return get_default_branch_name(DO_NOT_ABBREV);
Quoted 4 lines
A corrected code should return a hardwired constant 'main' (it probably gets behind a C preprocessor macro, but the point is that we do not want end-user customization) for the reason stated in that message.
I like ref0 better, for two reasons:
- it is more consistent to just have all anonymized branches be named ref<N>, and
- using main both for an original main and an original master can be a bit confusing, as the reader might assume that this branch name (as it does not follow the ref<N> convention) was _not_ anonymized, when it very well might have been.
Ciao,
Dscho
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 7 lines · Johannes Schindelin
Quoted 4 lines
A corrected code should return a hardwired constant 'main' (it probably gets behind a C preprocessor macro, but the point is that we do not want end-user customization) for the reason stated in that message.
I like
ref0better, for two reasons:
Quoted 7 lines
- it is more consistent to just have all anonymized branches be named
ref<N>, and- using
mainboth for an originalmainand an originalmastercan be a bit confusing, as the reader might assume that this branch name (as it does not follow theref<N>convention) was _not_ anonymized, when it very well might have been.
A pro for keeping a hardcoded 'master' is that it is compatible with the current world order, and flipping it to hardcoded 'main' upon transition is just to use the moral equivalent, so we do not need to immediately have to change anything. The _new_ consistency across ref<N> does feel attractive, but because it is new, there always is a pushback not to "fix" what is not broken.
I am personally OK either way.
By the way, we'd need to devise a transition plan for switching the default branch name (i.e. the name used for the primary branch in a newly created repository unless the user configures it to some other value) to 'main' (oh, I just found one reason why I will not want to use that name in my project(s)---it is too close to 'maint').
It might roughly go like:
1. We introduce core.defaultBranchName; when it is not set, its value defaults to 'master' in the 1st phase of the transition. "git init" and "git clone" however issue a warning that says "unless you configure core.defaultBranchName, we use 'master' for now for backward compatibility but we will start using 'main' in three major releases of Git in the future". These commands use the default branch name when creating a new repository in the 1st phase, and set core.primaryBranchName to that name in the resulting repository.
This is to encourage early adopters to set it to 'maint'^W'main' (eek, see, I again made that typo), while allowing those who have toolset that depends more heavily on the current default branch name than other people to set it to 'master' for stability.
In the 1st phase, a few commands that care about what the primary branch is in a repository (i.e. fmt-merge-msg and fast-export are the two we have identified so far) pay attention to the core.primaryBranchName configuration, and default to 'master' if the configuration does not exist.
These commands issue a warning that says "unless you configure core.primaryBranchName in the repository, we use 'master' for now but we will start using 'main' in three major releases of Git in the future".
The above two warning messages will be squelched once the user sets respective configuration variable.
2. We flip the default for the two variables from 'master' to 'main' in three major releases of Git (i.e. 24-30 weeks from the 1st phase). The two warning messages added for the 1st phase will be reworded for the updated default. We no longer need to say "in three major releases" in there.
3. After long time passes, remove the warning.
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Hi Junio,
Quoted 24 lines · Junio C Hamano
Quoted 7 lines · Johannes Schindelin
Quoted 4 lines
A corrected code should return a hardwired constant 'main' (it probably gets behind a C preprocessor macro, but the point is that we do not want end-user customization) for the reason stated in that message.
I like
ref0better, for two reasons:Quoted 7 lines
- it is more consistent to just have all anonymized branches be named
ref<N>, and- using
mainboth for an originalmainand an originalmastercan be a bit confusing, as the reader might assume that this branch name (as it does not follow theref<N>convention) was _not_ anonymized, when it very well might have been.A pro for keeping a hardcoded 'master' is that it is compatible with the current world order, and flipping it to hardcoded 'main' upon transition is just to use the moral equivalent, so we do not need to immediately have to change anything. The _new_ consistency across ref<N> does feel attractive, but because it is new, there always is a pushback not to "fix" what is not broken.
Quoted 7 lines
I am personally OK either way.
By the way, we'd need to devise a transition plan for switching the default branch name (i.e. the name used for the primary branch in a newly created repository unless the user configures it to some other value) to 'main' (oh, I just found one reason why I will not want to use that name in my project(s)---it is too close to 'maint').
Yes, the trouble with maint did cross my mind, but I try not to "overfit" to git/git. :-)
Quoted 32 lines
It might roughly go like:
1. We introduce core.defaultBranchName; when it is not set, its value defaults to 'master' in the 1st phase of the transition. "git init" and "git clone" however issue a warning that says "unless you configure core.defaultBranchName, we use 'master' for now for backward compatibility but we will start using 'main' in three major releases of Git in the future". These commands use the default branch name when creating a new repository in the 1st phase, and set core.primaryBranchName to that name in the resulting repository.
This is to encourage early adopters to set it to 'maint'^W'main' (eek, see, I again made that typo), while allowing those who have toolset that depends more heavily on the current default branch name than other people to set it to 'master' for stability.
In the 1st phase, a few commands that care about what the primary branch is in a repository (i.e. fmt-merge-msg and fast-export are the two we have identified so far) pay attention to the core.primaryBranchName configuration, and default to 'master' if the configuration does not exist.
These commands issue a warning that says "unless you configure core.primaryBranchName in the repository, we use 'master' for now but we will start using 'main' in three major releases of Git in the future".
The above two warning messages will be squelched once the user sets respective configuration variable.
Quoted 7 lines
2. We flip the default for the two variables from 'master' to 'main' in three major releases of Git (i.e. 24-30 weeks from the 1st phase). The two warning messages added for the 1st phase will be reworded for the updated default. We no longer need to say "in three major releases" in there.
3. After long time passes, remove the warning.
Yes, that's what I had in my mind, too (modulo the concrete part about the three major versions, which is something I would have asked about at some stage, thank you for answering that question already!).
Thank you,
Dscho
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 2 lines · Johannes Schindelin
Yes, the trouble with
maintdid cross my mind, but I try not to "overfit" to git/git. :-)
I do not think it is overfitting; if the solution cannot even support the originating project well, there is something wrong.
Most likely, I'd be tempted to rename it myself away from any name that is too similar to 'maint'; perhaps to 'stable' (or 'devo', h/t tla ;-).
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Hi Junio,
Quoted 11 lines · Junio C Hamano
Quoted 2 lines · Johannes Schindelin
Yes, the trouble with
maintdid cross my mind, but I try not to "overfit" to git/git. :-)I do not think it is overfitting; if the solution cannot even support the originating project well, there is something wrong.
Most likely, I'd be tempted to rename it myself away from any name that is too similar to 'maint'; perhaps to 'stable' (or 'devo', h/t tla ;-).
You could also use next instead of master, which would make intuitive sense because the commits that make it into that branch are slated to be part of the next major Git version.
And a relatively obvious name for the current next might be cooking.
I refrained from proposing this earlier, thinking that this would be too disruptive, but since pu was renamed to seen...
:-)
Ciao,
Dscho
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 8 lines · Johannes Schindelin
You could also use
nextinstead ofmaster, which would make intuitive sense because the commits that make it into that branch are slated to be part of the next major Git version.And a relatively obvious name for the current
nextmight becooking.I refrained from proposing this earlier, thinking that this would be too disruptive, but since
puwas renamed toseen...
Renaming 'pu' away from two-letter has a positive technical and social effect. Using 'next' for anything but what it currently means does not have any such upside and only the downside of confusing people.
As to 'cooking', I am not sure. Personally I consider that the topics that are in 'next' plus those that are soon to be in 'next' are all 'cooking'. But I do not think anybody's dying to rename 'next', so...
Re: Re* [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
In reply to Junio C HamanoHi Junio,
Quoted 17 lines · Junio C Hamano
Quoted 8 lines · Johannes Schindelin
I just realized that the comment above reads:
/*
* We also leave "master" as a special case, since it does not reveal
* anything interesting.
*/Quoted 6 lines
Obviously, we need to change that comment here because we do not leave the name unchanged. How about this?
/* * We special-case the main branch, anonymizing it to `ref0`. */
Quoted 6 lines
If you are going to update it, why not make it useful?
I complained number of times during the discussion that the original comment explains why leaving 'master' as-is does not reveal anything useful to adversaries but does not justify what the code attempts to achieve by special casing 'master' in the first place.
True. Sorry about forgetting that when adjusting the code comment.
In my defense, I am/was much more worried about transmogrifying the patch series to reflect the separation between init.defaultBranch and core.mainBranch and the associated fall-out (I highly doubt that the range-diff between v1 and v2 will be useful...).
Quoted 9 lines
It is not an improvement to literally adjust that inadequate comment to the new world order to just parrot what the code already says without explaining why it does so.
/*
* Anonymize the name used for the primary branch in this
* repository, but reserveref0for it, so that it can
* be identified among other refs in the output. */
That is indeed an improvement, thank you so much.
Quoted 10 lines
is the minimum I would expect before calling it an improvement. We could add
It is often
mainfor new repositories (andmasterfor aged ones) and such well-known names may not need anonymizing, but it could be configured to use a secret word that the user may not want to reveal.at the end to explain the motivation behind anonymizing even more, if we wanted to.
Maybe we add that to the comment in the patch that teaches fast-export about core.mainBranch? Yeah, I think I like that idea best.
Quoted 3 lines
Now, "so that ..." part is totally a fabrication based on my best guess. I do not know what the original author was thinking when the decision to leave the master as-is was made.
This comment comes from a8722750985 (teach fast-export an --anonymize option, 2014-08-27), and I agree that there is no explicit explanation why the main branch is special-cased.
However, I think that your guess is a good one: it might be an interesting aspect to identify the commits from the main branch, without necessarily needing to know the actual name of said branch, e.g. to reproduce a reported issue.
Ciao,
Dscho
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
In reply to Matt RogersHi Matt,
Quoted 5 lines · Matt Rogers
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 524
Quoted 5 lines
builtin/fast-export.c +2
-2-* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* We also leave the default branch name as a special case, since it +* does not reveal anything interesting. */
Quoted 7 lines
I feel this is a weird thing to do, since you're trying to anonymize the branch name,and now the default branch is identifiable with your config file. For example, if the default branch contains the name of my project/repo then this sounds like a recipe for accidentally sharing it. I feel a better alternative would
be to exclude nothing from the anonymization or the proposed default default branch name
I don't think that the name of the main branch should be subject to anonymizing, whether it be master or anything else.
Ciao,
Dscho
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Quoted 17 lines · Johannes Schindelin
Hi Matt,
Quoted 5 lines · Matt Rogers
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 524
Quoted 5 lines
builtin/fast-export.c +2
-2-* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* We also leave the default branch name as a special case, since it +* does not reveal anything interesting. */ Quoted 7 lines
I feel this is a weird thing to do, since you're trying to anonymize the branch name,and now the default branch is identifiable with your config file. For example, if the default branch contains the name of my project/repo then this sounds like a recipe for accidentally sharing it. I feel a better alternative would
be to exclude nothing from the anonymization or the proposed default default branch name
Quoted 2 lines
I don't think that the name of the main branch should be subject to anonymizing, whether it be
masteror anything else.
"Here is why" is missing ;-) I think you realized that it needs to be, after you wrote the "ah, we need two, the default for new ones and the name of the primary branch in a particular repository", as we are dealing with the latter here.
Thanks.
Re: [PATCH 8/9] fast-export: respect the possibly-overridden default branch name
Hi Junio,
Quoted 19 lines · Junio C Hamano
Quoted 17 lines · Johannes Schindelin
Hi Matt,
Quoted 12 lines · Matt Rogers
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 524
Quoted 5 lines
builtin/fast-export.c +2
-2-* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* We also leave the default branch name as a special case, since it +* does not reveal anything interesting. */ I feel this is a weird thing to do, since you're trying to anonymize the branch name,and now the default branch is identifiable with your config file. For example, if the default branch contains the name of my project/repo then this sounds like a recipe for accidentally sharing it. I feel a better alternative would
be to exclude nothing from the anonymization or the proposed default default branch name
Quoted 7 lines
Quoted 2 lines
I don't think that the name of the main branch should be subject to anonymizing, whether it be
masteror anything else."Here is why" is missing ;-) I think you realized that it needs to be, after you wrote the "ah, we need two, the default for new ones and the name of the primary branch in a particular repository", as we are dealing with the latter here.
Yep, absolutely.
Thanks,
Dscho
PATCH 9/9 Document how the default branch name can be overridden
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
There is a GIT_TEST_* environment variable and a core. config setting (with the former taking precendence over the latter) to allow overriding what name Git uses by default as main branch of new repositories.
Now that all kinds of Git operations have learned to respect those, let's document them.
--- Documentation/config/core.txt | 4 ++++ t/README | 4 ++++ 2 files changed, 8 insertions(+)
Documentation/config/core.txt +4 -0
@@ -626,3 +626,7 @@ core.abbrev:: in your repository, which hopefully is enough for abbreviated object names to stay unique for some time. The minimum length is 4. + +core.defaultBranchName:: + Allows overriding the default branch name e.g. when initializing + a new repository or when cloning an empty repository.
t/README +4 -0
@@ -421,6 +421,10 @@ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is the default when running tests), errors out when an abbreviated option is used. +GIT_TEST_DEFAULT_BRANCH_NAME allows overriding the default branch name +that is used for example when initializing new repositories, or when +cloning a repository that has no branches yet. + Naming Tests ------------
Signature · 1 line
gitgitgadget
Re: [PATCH 9/9] Document how the default branch name can be overridden
"Johannes Schindelin via GitGitGadget" <[email protected]>
Documentation/config/core.txt core.abbrev:: · line 632
Quoted 12 lines · writes:
Documentation/config/core.txt +4
-0@@ -626,3 +626,7 @@ core.abbrev:: in your repository, which hopefully is enough for abbreviated object names to stay unique for some time. The minimum length is 4. + +core.defaultBranchName:: + Allows overriding the default branch name e.g. when initializing + a new repository or when cloning an empty repository.
As we saw in [PATCH 7/9], it also affects for which branch an auto-generated merge message omits "into $branch" at the end.
The behaviour change of "merge" might matter more than we think here in a hand-wavy way, and it certainly does affect more than 'init' and 'clone' (both of which are one time operation per repository), because setting this in ~/.gitconfig would affect all the repositories, whose merges into their 'master' suddenly starts saying "into master" at the end, unlike existing merges. So it probably is worth highlighting it here.
Quoted 14 lines
t/README +4
-0@@ -421,6 +421,10 @@ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is the default when running tests), errors out when an abbreviated option is used. +GIT_TEST_DEFAULT_BRANCH_NAME allows overriding the default branch name +that is used for example when initializing new repositories, or when +cloning a repository that has no branches yet. + Naming Tests ------------
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 5 lines · 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.
Quoted 5 lines
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.
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'.
Quoted 36 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]> writes:
...Quoted 5 lines
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.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/gitconfigor ~/.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.
Quoted 7 lines
(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.
Hi Junio,
Quoted 9 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 5 lines · 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.
Quoted 3 lines
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!
Quoted 34 lines
Quoted 6 lines
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.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/gitconfigor ~/.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.
Quoted 7 lines
(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
Quoted 5 lines · Johannes Schindelin
I read this (way too late) last night and slept over it. Together with your comment on the
fmt-merge-msgpatch, I think you are really on to
something: we need _two_ config settings, as there are two distinct concepts at play here:
Quoted 7 lines
- One setting to specify the default branch name for newly-initialized repositories (such as
git init, unless it re-initializes, andgit clonewhen the cloned repository does not yet contain any branches).This should probably be called
init.defaultBranchName(even ifgit clonepicks it up, too), and be overrideable byGIT_TEST_DEFAULT_BRANCH_NAME.
Yes.
Quoted 2 lines
- 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.
Quoted 10 lines
and
git clone. For repositories where it is not set, we would assumemasterfor 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 justmain).
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.
Quoted 2 lines
And then
git fmt-merge-msg(and your proposedgit varaddition, which I like a lot, maybegit 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).
Quoted 5 lines
That way, existing repositories would not be affected by
GIT_TEST_DEFAULT_BRANCH_NAMEorinit.defaultBranchNameat 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.
Quoted 29 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. 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".
Quoted 8 lines
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_NAMEenvironment 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.
Signature · 2 lines
brian m. carlson: Houston, Texas, US OpenPGP: https://keybase.io/bk2204
Hi Johannes (and Dan)
Quoted 11 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/
Quoted 8 lines
[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.
Quoted 4 lines
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.
Quoted 4 lines
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".
Quoted 8 lines
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_NAMEenvironment 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.
Quoted 32 lines
Don Goodman-Wilson (1):
init: allow overriding the default branch name for new repositoriesJohannes Schindelin (8):
remote: respectcore.defaultBranchNamesend-pack/transport-helper: respectcore.defaultBranchName
testsvn: respectcore.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 overriddenDocumentation/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(-)
Quoted 6 lines
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
Hi Taylor,
Quoted 21 lines · Taylor Blau
Quoted 11 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/Quoted 8 lines
[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.
Quoted 8 lines
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.
Quoted 7 lines
Quoted 4 lines
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 ;-)
Quoted 5 lines
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.
Quoted 13 lines
Quoted 4 lines
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".Quoted 8 lines
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_NAMEenvironment variable could be used to update test scripts on an individual basis instead of all-at-once.
Quoted 4 lines
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.
Quoted 4 lines
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.
Quoted 7 lines
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.
Quoted 7 lines
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
Hi,
Quoted 29 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. 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".
Quoted 8 lines
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_NAMEenvironment 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...
Signature · 2 lines
Regards, Pratyush Yadav
Hi Pratyush,
Quoted 9 lines · Pratyush Yadav
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.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.
Quoted 9 lines
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...
Quoted 10 lines
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
Hi Dscho,
Quoted 11 lines · Johannes Schindelin
Quoted 10 lines
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...
Quoted 6 lines
... 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 rungit 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?
Hi Denton,
Quoted 83 lines · Denton Liu
Quoted 11 lines · Johannes Schindelin
Quoted 10 lines
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...
Quoted 6 lines
... 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 --remotewhich pulls in all of my submodules' 'master' branches. By convention, a lack ofbranchkey 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, suddenlygit submodule update --remotewill 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.
Quoted 5 lines
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
Quoted 10 lines · Pratyush Yadav
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.
Signature · 2 lines
brian m. carlson: Houston, Texas, US OpenPGP: https://keybase.io/bk2204
v2 cover Allow overriding the default name of the default branch
In reply to Johannes Schindelin via GitGitGadgetA growing number of open source projects aims to avoid the branch name master due to its negative connotation. See [1] for an existing discussion on this. The links [2], [3], and [4] describe community-driven ways for users to rename their default branches or use template edits to set a new default branch name.
[1]
https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/
[2] https://twitter.com/mislav/status/1270388510684598272
[3]
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx
[4] https://github.com/ethomson/retarget_prs
By necessity, existing repositories require a lot of manual work to move away from that branch name, but it should be much easier for new repositories.
This patch series allows overriding the branch name being used for new repositories' main branch, as well as telling Git about a renamed main branch in an already-existing repository. The former would be configured via init.defaultBranch and the latter via core.mainBranch (which is now automatically configured in git init).
Shell scripts can find out what the current repository's main branch name is called via
main_branch=$(git config core.mainBranch || echo master)
This is even future proof because all future git init invocations will configure that setting.
The initial patch was started by newcomer Don Goodman-Wilson, as well as the bigger change that morphed into #655, where we demonstrate how to change Git's hard-coded default main branch name to main based on this here patch series, verifying the approach. Thanks for the contribution!
This series DOES NOT change the default automatically, but only provides an opt-in mechanism for interested users. The plan for that is to convert the test scripts incrementally (by introducing GIT_TEST_DEFAULT_MAIN_BRANCH_NAME , which overrides init.defaultBranch, and then converting the tricky test scripts first, one by one, using that environment variable).
Changes since v1:
* The modifications to respect GIT_TEST_DEFAULT_BRANCH_NAME have been backed out from this patch series, as they are only relevant once we start converting the test suite to accommodate for a new default main branch name.
* An error message that started with an upper-case letter was downcased.
* git_default_branch_name()'s logic was simplified by replacing an if ... else ... by a ternary assignment.
* The git_default_branch_name() function was renamed to git_main_branch_name() and a corresponding repo_main_branch_name() was introduced.
* The "init" commit message's first paragraph now elaborates a little bit on the reasoning why projects want to move away from the current default branch name.
* The "init" commit was split into two.
* There are now two config settings: init.defaultBranch (defining the branch name to use when initializing new repositories) and core.mainBranch (which is now configured by init_db(), declaring what the name of the main branch is in this repository).
* The commits were re-ordered to introduce the concept of core.mainBranch first because technically, this is something that we could do even without changing git init at all.
* git fast-export --anonymize now always uses the ref name ref0 for the main branch, no matter whether it was overridden or whether the fall-back is in effect.
* The code comment regarding anonymizing the main branch to ref0 in git fast-export --anonymize was enhanced.
* A new patch was added to rename core.mainBranch if the main branch is renamed via git branch -m.
* Added a patch that introduces support for git init --main-branch=<branch-name>.
* Where possible, I added tests (although I did not try to extend test coverage to all changes: the send-pack.c/transport-helper.c patch only adds a test for the send-pack.c adjustment, for example).
Don Goodman-Wilson (1):
init: allow overriding the default main branch name via the config
Johannes Schindelin (10):
fmt-merge-msg: introduce a way to override the main branch name send-pack/transport-helper: respect core.mainBranch git_main_branch_name(): optionally report the full ref name
fast-export: handle overridden main branch names correctly branch -m: adjust core.mainBranch if necessary
init: allow specifying the main branch name for the new repository
clone: handle overridden main branch names
remote: learn about the possibly-overridden default main branch name
submodule: use the correct default for the main branch name
testsvn: respect init.defaultBranch
Junio C Hamano (1):
fast-export: do anonymize the primary branch name
Documentation/config/core.txt | 5 +++++ Documentation/config/init.txt | 4 ++++ Documentation/git-init.txt | 7 +++++++ builtin/branch.c | 9 ++++++++ builtin/clone.c | 19 +++++++++++++---- builtin/fast-export.c | 20 +++++++++++++----- builtin/init-db.c | 36 +++++++++++++++++++++++++------- builtin/submodule--helper.c | 10 +++++++-- cache.h | 2 +- fmt-merge-msg.c | 6 ++++-- refs.c | 34 ++++++++++++++++++++++++++++++ refs.h | 15 +++++++++++++ remote-testsvn.c | 12 ++++++++--- remote.c | 15 ++++++++----- send-pack.c | 6 +++++- t/t0001-init.sh | 31 +++++++++++++++++++++++++++ t/t3200-branch.sh | 9 ++++++++ t/t5528-push-default.sh | 7 +++++++ t/t5606-clone-options.sh | 26 +++++++++++++++++++++++ t/t6200-fmt-merge-msg.sh | 7 +++++++ t/t7406-submodule-update.sh | 7 +++++++ t/t9020-remote-svn.sh | 6 ++++++ t/t9351-fast-export-anonymize.sh | 15 +++++++++---- transport-helper.c | 6 +++++- 24 files changed, 279 insertions(+), 35 deletions(-)
base-commit: 0313f36c6ebecb3bffe6f15cf25a4883100f0214
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-656%2Fdscho%2Fdefault-branch-name-option-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-656/dscho/default-branch-name-option-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/656
Range-diff vs v1:
-: ----------- > 1: ebd10f73cd7 fast-export: do anonymize the primary branch name
7: e849def4a8c ! 2: f4d54739153 fmt-merge-msg: learn about the possibly-configured default branch name
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- fmt-merge-msg: learn about the possibly-configured default branch name
+ fmt-merge-msg: introduce a way to override the main branch name
- When formatting the commit message for merge commits, Git appends "into
- <branch-name>" unless the current branch is the default branch.
+ There is a growing number of projects and companies desiring to change
+ the main branch name of their repositories (see e.g.
+ https://twitter.com/mislav/status/1270388510684598272 for background on
+ this).
- Now that we can configure what the default branch name should be, we
- will want to respect that setting in that scenario rather than using the
- compiled-in default branch name.
+ However, there are a couple of hard-coded spots in Git's source code
+ that make this endeavor harder than necessary. For example, when
+ formatting the commit message for merge commits, Git appends "into
+ <branch-name>" unless the current branch is the `master` branch.
+
+ Clearly, this is not what one wants when already having gone through all
+ the steps to manually rename the main branch (and taking care of all the
+ fall-out such as re-targeting existing Pull Requests).
+
+ Let's introduce a way to override Git's hard-coded default:
+ `core.mainBranch`.
+
+ We will start supporting this config option in the `git fmt-merge-msg`
+ command and successively adjust all other places where the main branch
+ name is hard-coded.
Signed-off-by: Johannes Schindelin <[email protected]>
+ ## Documentation/config/core.txt ##
+@@ Documentation/config/core.txt: core.abbrev::
+ in your repository, which hopefully is enough for
+ abbreviated object names to stay unique for some time.
+ The minimum length is 4.
++
++core.mainBranch::
++ The name of the main (or: primary) branch in the current repository.
++ For historical reasons, `master` is used as the fall-back for this
++ setting.
+
## fmt-merge-msg.c ##
@@ fmt-merge-msg.c: static void fmt_merge_msg_title(struct strbuf *out,
const char *current_branch)
{
int i = 0;
- char *sep = "";
-+ char *sep = "", *default_branch_name;
++ char *sep = "", *main_branch;
strbuf_addstr(out, "Merge ");
for (i = 0; i < srcs.nr; i++) {
@@ fmt-merge-msg.c: static void fmt_merge_msg_title(struct strbuf *out,
}
- if (!strcmp("master", current_branch))
-+ default_branch_name = git_default_branch_name(1);
-+ if (!strcmp(default_branch_name, current_branch))
++ main_branch = git_main_branch_name();
++ if (!strcmp(main_branch, current_branch))
strbuf_addch(out, '\n');
else
strbuf_addf(out, " into %s\n", current_branch);
-+ free(default_branch_name);
++ free(main_branch);
}
static void fmt_tag_signature(struct strbuf *tagbuf,
+ ## refs.c ##
+@@ refs.c: void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
+ argv_array_pushf(prefixes, *p, len, prefix);
+ }
+
++char *repo_main_branch_name(struct repository *r)
++{
++ const char *config_key = "core.mainbranch";
++ const char *config_display_key = "core.mainBranch";
++ const char *fall_back = "master";
++ char *name = NULL, *ret;
++
++ if (repo_config_get_string(r, config_key, &name) < 0)
++ die(_("could not retrieve `%s`"), config_display_key);
++
++ ret = name ? name : xstrdup(fall_back);
++
++ if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
++ die(_("invalid branch name: %s = %s"),
++ config_display_key, name);
++
++ if (name != ret)
++ free(name);
++
++ return ret;
++}
++
++char *git_main_branch_name(void)
++{
++ return repo_main_branch_name(the_repository);
++}
++
+ /*
+ * *string and *len will only be substituted, and *string returned (for
+ * later free()ing) if the string passed in is a magic short-hand form
+
+ ## refs.h ##
+@@ refs.h: int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
+ int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
+ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
+
++/*
++ * Retrieves the name of the main (or: primary) branch of the given
++ * repository.
++ */
++char *git_main_branch_name(void);
++char *repo_main_branch_name(struct repository *r);
++
+ /*
+ * A ref_transaction represents a collection of reference updates that
+ * should succeed or fail together.
+
## t/t6200-fmt-merge-msg.sh ##
@@ t/t6200-fmt-merge-msg.sh: test_expect_success 'setup FETCH_HEAD' '
git fetch . left
'
+test_expect_success 'with overridden default branch name' '
-+ test_config core.defaultBranchName default &&
+ test_when_finished "git switch master" &&
+ git switch -c default &&
-+ git fmt-merge-msg <.git/FETCH_HEAD >actual &&
++ git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual &&
+ ! grep "into default" actual
+'
+ 3: c9c9c81068e ! 3: bd8af3755ad send-pack/transport-helper: respect core.defaultBranchName
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- send-pack/transport-helper: respect core.defaultBranchName
+ send-pack/transport-helper: respect core.mainBranch
- When mentioning the default branch name in an error message, we want to
- go with the preference specified by the user.
+ When mentioning the main branch name in an error message, we want to go
+ with the preference specified by the user, only falling back to Git's
+ own, hard-coded default when none was configured explicitly.
@@ send-pack.c: int send_pack(struct send_pack_args *args,
}
if (!remote_refs) {
-+ char *branch_name = git_default_branch_name(1);
++ char *branch_name = git_main_branch_name();
+
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
- "Perhaps you should specify a branch such as 'master'.\n");
@@ send-pack.c: int send_pack(struct send_pack_args *args,
}
if (args->atomic && !atomic_supported)
+ ## t/t5528-push-default.sh ##
+@@ t/t5528-push-default.sh: test_expect_success 'push from/to new branch with upstream, matching and simple'
+ test_push_failure upstream
+ '
+
++test_expect_success '"matching" fails if none match' '
++ git init --bare empty &&
++ test_must_fail git -c core.mainBranch=unmatch push empty : 2>actual &&
++ needle="Perhaps you should specify a branch such as '\''unmatch'\''" &&
++ test_i18ngrep "$needle" actual
++'
++
+ test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
+ git checkout -b ambiguous &&
+ test_config branch.ambiguous.remote parent1 &&
+
## transport-helper.c ##
@@ transport-helper.c: static int push_refs(struct transport *transport,
}
if (!remote_refs) {
-+ char *branch_name = git_default_branch_name(1);
++ char *branch_name = git_main_branch_name();
+
fprintf(stderr,
_("No refs in common and none specified; doing nothing.\n"
-: ----------- > 4: ca1c63c3e01 git_main_branch_name(): optionally report the full ref name 8: 1efe848f2b0 ! 5: a3be4f39aa2 fast-export: respect the possibly-overridden default branch name
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- fast-export: respect the possibly-overridden default branch name
+ fast-export: handle overridden main branch names correctly
- When anonymizing commit history, we are careful to leave the branch name
- of the default branch alone.
+ When anonymizing commit history, we are careful to translate the main
+ branch name to ref0.
- When the default branch name is overridden via the config or via the
- environment variable, we will want git fast-export to use that
- overridden name instead.
+ When the main branch name is overridden via the config, we will want
+ git fast-export to use that overridden name instead.
@@ builtin/fast-export.c: static const char *anonymize_refname(const char *refname)
};
static struct hashmap refs;
static struct strbuf anon = STRBUF_INIT;
-+ static char *default_branch_name;
++ static char *main_branch;
int i;
/*
-- * We also leave "master" as a special case, since it does not reveal
-- * anything interesting.
-+ * We also leave the default branch name as a special case, since it
-+ * does not reveal anything interesting.
+ * In certain circumstances, it might be interesting to be able to
+ * identify the main branch. For that reason, let's force its name to
+ * be anonymized to ref0.
++ *
++ * While the main branch name might often be main for new
++ * repositories (and master for aged ones), and such well-known names
++ * may not necessarily need anonymizing, it could be configured to use
++ * a secret word that the user may not want to reveal.
*/
- if (!strcmp(refname, "refs/heads/master"))
-+ if (!default_branch_name)
-+ default_branch_name = git_default_branch_name(0);
++ if (!main_branch)
++ main_branch = git_main_branch_name(MAIN_BRANCH_FULL_NAME);
+
-+ if (!strcmp(refname, default_branch_name))
- return refname;
++ if (!strcmp(refname, main_branch))
+ return "refs/heads/ref0";
strbuf_reset(&anon);
+
+ ## t/t9351-fast-export-anonymize.sh ##
+@@ t/t9351-fast-export-anonymize.sh: test_expect_success 'stream translates master to ref0' '
+ ! grep master stream
+ '
+
++test_expect_success 'respects configured main branch' '
++ git -c core.mainBranch=does-not-exist \
++ fast-export --anonymize --all >stream-without-ref0 &&
++ ! grep ref0 stream-without-ref0
++'
++
+ test_expect_success 'stream omits other refnames' '
+ ! grep other stream &&
+ ! grep mytag stream
-: ----------- > 6: 933e314813d branch -m: adjust `core.mainBranch` if necessary 1: 90912e32da1 ! 7: 0ec04b2086e init: allow overriding the default branch name for new repositories
@@
## Metadata ##
-Author: Don Goodman-Wilson <[email protected]> +Author: Johannes Schindelin <[email protected]>
## Commit message ##
- init: allow overriding the default branch name for new repositories
+ init: allow specifying the main branch name for the new repository
There is a growing number of projects trying to avoid the non-inclusive
- name master in their repositories. For existing repositories, this
- requires manual work. For new repositories, the only way to do that
- automatically is by copying all of Git's template directory, then
- hard-coding the desired default branch name into the .git/HEAD file,
- and then configuring init.templateDir to point to those copied
+ name master in their repositories: The master/slave terminology is
+ insensitive and perpetuates injustice. This master/slave idea is
+ actually where Git's naming comes from, as it was inherited from
+ BitKeeper which uses the term in exactly this way, see
+ https://mail.gnome.org/archives/desktop-devel-list/2019-May/msg00066.html
+
+ To change that branch name for new repositories, currently the only way
+ to do that automatically is by copying all of Git's template directory,
+ then hard-coding the desired default branch name into the .git/HEAD
+ file, and then configuring init.templateDir to point to those copied
template files.
- To make this process much less cumbersome, let's introduce support for
- core.defaultBranchName. That way, users won't need to keep their
- copied template files up to date, and won't interfere with default hooks
- installed by their administrators.
+ To make this process much less cumbersome, let's introduce a new option:
+ --main-branch=<branch-name>.
- While at it, also let users set the default branch name via the
- environment variable GIT_TEST_DEFAULT_BRANCH_NAME, in preparation for
- adjusting Git's test suite to a more inclusive default branch name. As
- is common in Git, the GIT_TEST_* variable takes precedence over the
- config setting.
+ This will not only initialize the repository with the specified initial
+ branch; It will also record that branch name in core.mainBranch.
- Note: we use the prefix core. instead of init. because we want to
- adjust also git clone, git fmt-merge-msg and other commands over the
- course of the next commits to respect this setting.
+ Signed-off-by: Johannes Schindelin <[email protected]>
- Helped-by: Johannes Schindelin <[email protected]>
- Helped-by: Derrick Stolee <[email protected]>
- Signed-off-by: Don Goodman-Wilson <[email protected]>
+ ## Documentation/git-init.txt ##
+@@ Documentation/git-init.txt: SYNOPSIS
+ [verse]
+ 'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
+ [--separate-git-dir <git dir>] [--object-format=<format]
++ [-b <branch-name> | --main-branch=<branch-name>]
+ [--shared[=<permissions>]] [directory]
+
+
+@@ Documentation/git-init.txt: repository.
+ +
+ If this is reinitialization, the repository will be moved to the specified path. +
++-b <branch-name::
++--main-branch=<branch-name>::
++
++Use the specified name for the main (or: initial) branch in the newly created ++repository. If not specified, fall back to the default name: master. ++
+ --shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
+
+ Specify that the Git repository is to be shared amongst several users. This +
+ ## builtin/clone.c ##
+@@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
+ }
+ }
+
+- init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
++ init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
++ INIT_DB_QUIET);
+
+ if (real_git_dir)
+ git_dir = real_git_dir;
## builtin/init-db.c ##
+@@ builtin/init-db.c: void initialize_repository_version(int hash_algo) +
+ static int create_default_files(const char *template_path,
+ const char *original_git_dir,
++ const char *main_branch,
+ const struct repository_format *fmt)
+ {
+ struct stat st1;
@@ builtin/init-db.c: static int create_default_files(const char *template_path,
die("failed to set up refs db: %s", err.buf);
@@ builtin/init-db.c: static int create_default_files(const char *template_path,
|| readlink(path, junk, sizeof(junk)-1) != -1);
if (!reinit) {
- if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
-+ char *default_ref = git_default_branch_name(0);
-+ if (create_symref("HEAD", default_ref, NULL) < 0)
++ char *ref;
++
++ if (!main_branch)
++ main_branch = "master";
++
++ ref = xstrfmt("refs/heads/%s", main_branch);
++ if (check_refname_format(ref, 0) < 0)
++ die(_("invalid main branch name: '%s'"), main_branch);
++
++ if (create_symref("HEAD", ref, NULL) < 0)
exit(1);
-+ free(default_ref);
- }
+- }
++ free(ref);
++
++ git_config_set("core.mainbranch", main_branch);
++ } else if (main_branch)
++ warning(_("re-init: ignoring --main-branch=%s"), main_branch);
initialize_repository_version(fmt->hash_algo);
-
- ## refs.c ##
-@@ refs.c: void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
- argv_array_pushf(prefixes, *p, len, prefix);
+
+@@ builtin/init-db.c: static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
}
-+char *git_default_branch_name(int short_name)
-+{
-+ const char *branch_name = getenv("GIT_TEST_DEFAULT_BRANCH_NAME");
-+ char *from_config = NULL, *prefixed;
-+
-+ /*
-+ * If the default branch name was not specified via the environment
-+ * variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config
-+ * setting core.defaultBranchName. If neither are set, fall back to the
-+ * hard-coded default.
-+ */
-+ if (!branch_name || !*branch_name) {
-+ if (git_config_get_string("core.defaultbranchname",
-+ &from_config) < 0)
-+ die(_("Could not retrieve core.defaultBranchName"));
-+
-+ if (from_config)
-+ branch_name = from_config;
-+ else
-+ branch_name = "master";
-+ }
-+
-+ if (short_name)
-+ return from_config ? from_config : xstrdup(branch_name);
-+
-+ /* prepend "refs/heads/" to the branch name */
-+ prefixed = xstrfmt("refs/heads/%s", branch_name);
-+ if (check_refname_format(prefixed, 0))
-+ die(_("invalid default branch name: '%s'"), branch_name);
-+
-+ free(from_config);
-+ return prefixed;
-+}
-+
- /*
- * *string and *len will only be substituted, and *string returned (for
- * later free()ing) if the string passed in is a magic short-hand form
+ int init_db(const char *git_dir, const char *real_git_dir,
+- const char *template_dir, int hash, unsigned int flags)
++ const char *template_dir, int hash, const char *main_branch,
++ unsigned int flags)
+ {
+ int reinit;
+ int exist_ok = flags & INIT_DB_EXIST_OK;
+@@ builtin/init-db.c: int init_db(const char *git_dir, const char *real_git_dir, +
+ validate_hash_algorithm(&repo_fmt, hash);
+
+- reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
++ reinit = create_default_files(template_dir, original_git_dir,
++ main_branch, &repo_fmt);
+
+ create_object_directory();
+
+@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *prefix)
+ const char *template_dir = NULL;
+ unsigned int flags = 0;
+ const char *object_format = NULL;
++ const char *main_branch = NULL;
+ int hash_algo = GIT_HASH_UNKNOWN;
+ const struct option init_db_options[] = {
+ OPT_STRING(0, "template", &template_dir, N_("template-directory"),
+@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *prefix)
+ OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
+ OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
+ N_("separate git dir from working tree")),
++ OPT_STRING('b', "main-branch", &main_branch, N_("name"),
++ N_("override the name of the main branch")),
+ OPT_STRING(0, "object-format", &object_format, N_("hash"),
+ N_("specify the hash algorithm to use")),
+ OPT_END()
+@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *prefix)
+ UNLEAK(work_tree);
+
+ flags |= INIT_DB_EXIST_OK;
+- return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
++ return init_db(git_dir, real_git_dir, template_dir, hash_algo,
++ main_branch, flags);
+ }
- ## refs.h ##
-@@ refs.h: int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
- int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
- int dwim_log(const char *str, int len, struct object_id *oid, char **ref); -
-+/*
-+ * Retrieves the name of the default branch. If short_name is non-zero, the -+ * branch name will be prefixed with "refs/heads/".
-+ */
-+char *git_default_branch_name(int short_name);
-+
- /*
- * A ref_transaction represents a collection of reference updates that
- * should succeed or fail together.
+ ## cache.h ##
+@@ cache.h: int path_inside_repo(const char *prefix, const char *path);
+
+ int init_db(const char *git_dir, const char *real_git_dir,
+ const char *template_dir, int hash_algo,
+- unsigned int flags);
++ const char *main_branch, unsigned int flags);
+ void initialize_repository_version(int hash_algo);
+
+ void sanitize_stdfds(void);
## t/t0001-init.sh ##
@@ t/t0001-init.sh: test_expect_success MINGW 'redirect std handles' '
grep "Needed a single revision" output.txt
'
-+test_expect_success 'custom default branch name from config' '
-+ git config --global core.defaultbranchname nmb &&
-+ GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config &&
-+ git config --global --unset core.defaultbranchname &&
-+ git -C custom-config symbolic-ref HEAD >actual &&
-+ grep nmb actual
-+'
-+
-+test_expect_success 'custom default branch name from env' '
-+ GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env &&
-+ git -C custom-env symbolic-ref HEAD >actual &&
-+ grep nmb actual
-+'
++test_expect_success '--main-branch' '
++ git init --main-branch=hello main-branch-option &&
++ git -C main-branch-option symbolic-ref HEAD >actual &&
++ echo refs/heads/hello >expect &&
++ test_cmp expect actual &&
+
-+test_expect_success 'invalid custom default branch name' '
-+ test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \
-+ git init custom-invalid 2>err &&
-+ test_i18ngrep "invalid default branch name" err
++ : re-initializing should not change the main branch name &&
++ git init --main-branch=ignore main-branch-option 2>err &&
++ test_i18ngrep "ignoring --main-branch" err &&
++ git -C main-branch-option symbolic-ref HEAD >actual &&
++ grep hello actual &&
++ git -C main-branch-option config core.mainBranch >actual &&
++ grep hello actual
+'
+
test_done
-: ----------- > 8: c711eba7e76 init: allow overriding the default main branch name via the config
6: cce86c06bbf ! 9: 0e59b618169 clone: learn about the possibly-configured default branch name
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- clone: learn about the possibly-configured default branch name
+ clone: handle overridden main branch names
When cloning a repository without any branches, Git chooses a default
branch name for the as-yet unborn branch.
- Now that we can configure what the default branch name should be, we
- will want `git clone` to respect that setting.
+ As part of the implicit initialization of the local repository, Git
+ just learned to respect `init.defaultBranch` to choose a different main
+ branch name. We now really want that branch name to be used as a
+ fall-back.
+
+ At the same time, we also want to make sure that `core.mainBranch` is
+ set correctly, reflecting the name of the main branch. In case we detect
+ a main branch, we do have to do that explicitly, otherwise `init_db()`
+ will already have done that for us.
Signed-off-by: Johannes Schindelin <[email protected]>
+ ## Documentation/config/init.txt ##
+@@ Documentation/config/init.txt: init.templateDir::
+ (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+
+ init.defaultBranch::
+- Allows overriding the default branch name when initializing
+- a new repository.
++ Allows overriding the default branch name e.g. when initializing
++ a new repository or when cloning an empty repository.
+
## builtin/clone.c ##
+@@ builtin/clone.c: static void update_head(const struct ref *our, const struct ref *remote,
+ /* Local default branch link */
+ if (create_symref("HEAD", our->name, NULL) < 0)
+ die(_("unable to update HEAD"));
++ git_config_set("core.mainbranch", head);
+ if (!option_bare) {
+ update_ref(msg, "HEAD", &our->old_oid, NULL, 0,
+ UPDATE_REFS_DIE_ON_ERR);
@@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
remote_head_points_at = NULL;
remote_head = NULL;
@@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
- install_branch_config(0, "master", option_origin,
- "refs/heads/master");
+ if (!option_bare) {
-+ char *default_branch = git_default_branch_name(0);
++ char *main_branch =
++ git_main_branch_name(MAIN_BRANCH_FULL_NAME);
+ const char *nick;
+
-+ if (!skip_prefix(default_branch, "refs/heads/", &nick))
++ if (!skip_prefix(main_branch, "refs/heads/", &nick))
+ BUG("unexpected default branch '%s'",
-+ default_branch);
++ main_branch);
+ install_branch_config(0, nick, option_origin,
-+ default_branch);
-+ free(default_branch);
++ main_branch);
++ free(main_branch);
+ }
}
write_refspec_config(src_ref_prefix, our_head_points_at,
- ## t/t5609-clone-branch.sh ##
-@@ t/t5609-clone-branch.sh: test_expect_success 'clone -b not allowed with empty repos' '
- test_must_fail git clone -b branch empty clone-branch-empty
+ ## t/t5606-clone-options.sh ##
+@@ t/t5606-clone-options.sh: test_expect_success 'redirected clone -v does show progress' '
+
'
-+test_expect_success 'chooses correct default branch name' '
-+ GIT_TEST_DEFAULT_BRANCH_NAME= \
-+ git -c core.defaultBranchName=up clone empty whats-up &&
-+ test_write_lines refs/heads/up refs/heads/up >expect &&
-+ git -C whats-up symbolic-ref HEAD >actual &&
-+ git -C whats-up config branch.up.merge >>actual &&
-+ test_cmp expect actual
++test_expect_success 'chooses correct default main branch name' '
++ git init --bare empty &&
++ git -c init.defaultBranch=up clone empty whats-up &&
++ test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) &&
++ test up = $(git -C whats-up config core.mainBranch) &&
++ test refs/heads/up = $(git -C whats-up config branch.up.merge)
++'
++
++test_expect_success 'guesses main branch name correctly' '
++ git init --main-branch=guess main-branch &&
++ test_commit -C main-branch no-spoilers &&
++ git -C main-branch branch abc guess &&
++ git clone main-branch is-it &&
++ test guess = $(git -C is-it config core.mainBranch) &&
++ test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
+'
+
test_done
2: 06a2cea051c ! 10: 59b8f4cfbb2 remote: respect `core.defaultBranchName`
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- remote: respect `core.defaultBranchName`
+ remote: learn about the possibly-overridden default main branch name
When guessing the default branch name of a remote, and there are no refs
to guess from, we want to go with the preference specified by the user
- for the fall-back.
+ for the fall-back, i.e. the default name to be used for the main branch
+ of new repositories (because as far as the user is concerned, a remote
+ that has no branches yet is a new repository).
Signed-off-by: Johannes Schindelin <[email protected]>
@@ remote.c: static void read_remotes_file(struct remote *remote)
static void read_branches_file(struct remote *remote)
{
- char *frag;
-+ char *frag, *default_branch_name = NULL;
++ char *frag, *main_branch = NULL;
struct strbuf buf = STRBUF_INIT;
FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r");
@@ remote.c: static void read_branches_file(struct remote *remote)
/*
* The branches file would have URL and optionally
- * #branch specified. The "master" (or specified) branch is
-+ * #branch specified. The default (or specified) branch is
++ * #branch specified. The main (or specified) branch is
* fetched and stored in the local branch matching the
* remote name.
*/
@@ remote.c: static void read_branches_file(struct remote *remote)
*(frag++) = '\0';
else
- frag = "master";
-+ frag = default_branch_name = git_default_branch_name(1);
++ frag = main_branch = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
add_url_alias(remote, strbuf_detach(&buf, NULL));
strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ remote.c: static void read_branches_file(struct remote *remote)
strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
refspec_append(&remote->push, buf.buf);
remote->fetch_tags = 1; /* always auto-follow */
-+ free(default_branch_name);
++ free(main_branch);
strbuf_release(&buf);
}
@@ remote.c: struct ref *guess_remote_head(const struct ref *head,
+ if (head->symref)
+ return copy_ref(find_ref_by_name(refs, head->symref));
- /* If refs/heads/master could be right, it is. */
+- /* If refs/heads/master could be right, it is. */
++ /* If a remote branch exists with the main branch name, let's use it. */
if (!all) {
- r = find_ref_by_name(refs, "refs/heads/master");
-+ char *name = git_default_branch_name(0);
++ char *name = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
++ MAIN_BRANCH_FOR_INIT);
+
+ r = find_ref_by_name(refs, name);
+ free(name);
if (r && oideq(&r->old_oid, &head->old_oid))
return copy_ref(r);
}
+
+ ## t/t5606-clone-options.sh ##
+@@ t/t5606-clone-options.sh: test_expect_success 'guesses main branch name correctly' '
+ git -C main-branch branch abc guess &&
+ git clone main-branch is-it &&
+ test guess = $(git -C is-it config core.mainBranch) &&
+- test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
++ test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) &&
++
++ git -c init.defaultBranch=none init --bare no-head &&
++ git -C main-branch push ../no-head guess abc &&
++ git clone no-head is-it2 &&
++ test_must_fail git -C is-it2 symbolic-ref refs/remotes/origin/HEAD &&
++ git -C no-head update-ref --no-deref HEAD refs/heads/guess &&
++ git -c init.defaultBranch=guess clone no-head is-it3 &&
++ test refs/remotes/origin/guess = \
++ $(git -C is-it3 symbolic-ref refs/remotes/origin/HEAD)
+ '
+
+ test_done
5: 06ef42052d5 ! 11: 59d6267f099 submodule: use the (possibly overridden) default branch name
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- submodule: use the (possibly overridden) default branch name
+ submodule: use the correct default for the main branch name
To allow for overriding the default branch name, we have introduced a
config setting. With this patch, the `git submodule` command learns
@@ builtin/submodule--helper.c: static const char *remote_submodule_branch(const ch
- if (!branch)
- return "master";
+ if (!branch) {
-+ static char *default_branch;
++ static char *fall_back;
+
-+ if (!default_branch)
-+ default_branch = git_default_branch_name(1);
++ if (!fall_back)
++ fall_back = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
+
-+ return default_branch;
++ return fall_back;
+ }
if (!strcmp(branch, ".")) {
const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
+
+ ## t/t7406-submodule-update.sh ##
+@@ t/t7406-submodule-update.sh: test_expect_success 'setup a submodule tree' '
+ )
+ '
+
++test_expect_success 'update --remote uses configured default main branch' '
++ git clone super main-branch &&
++ test_must_fail git -C main-branch -c init.defaultBranch=hello \
++ submodule update --init --remote submodule 2>err &&
++ test_i18ngrep origin/hello err
++'
++
+ test_expect_success 'submodule update detaching the HEAD ' '
+ (cd super/submodule &&
+ git reset --hard HEAD~1
4: 73cb567cd33 ! 12: e09f857f068 testsvn: respect `core.defaultBranchName`
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- testsvn: respect `core.defaultBranchName`
+ testsvn: respect `init.defaultBranch`
- Since the default branch name can now be configured, the `testsvn`
- remote helper needs to be told about it.
+ The default name of the main branch in new repositories can now be
+ configured. The `testsvn` remote helper translates the remote Subversion
+ repository's branch name `trunk` to the hard-coded name `master`.
+ Clearly, the intention was to make the name align with Git's detaults.
+
+ So while we are not talking about a newly-created repository in the
+ `testsvn` context, it _still_ makes sense to use the overridden default
+ name for the main branch whenever users configured it.
Signed-off-by: Johannes Schindelin <[email protected]>
@@ remote-testsvn.c: int cmd_main(int argc, const char **argv)
notes_ref_sb = STRBUF_INIT;
static struct remote *remote;
- const char *url_in;
-+ const char *url_in, *default_branch;
++ const char *url_in, *remote_ref_short;
setup_git_directory();
if (argc < 2 || argc > 3) {
@@ remote-testsvn.c: int cmd_main(int argc, const char **argv)
return 1;
}
-+ remote_ref = git_default_branch_name(0);
-+ if (!skip_prefix(remote_ref, "refs/heads/", &default_branch))
++ remote_ref = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
++ MAIN_BRANCH_FOR_INIT);
++ if (!skip_prefix(remote_ref, "refs/heads/", &remote_ref_short))
+ BUG("unexpected remote_ref '%s'", remote_ref);
+
remote = remote_get(argv[1]);
@@ remote-testsvn.c: int cmd_main(int argc, const char **argv)
- strbuf_addf(&private_ref_sb, "refs/svn/%s/master", remote->name);
+ strbuf_addf(&private_ref_sb, "refs/svn/%s/%s",
-+ remote->name, default_branch);
++ remote->name, remote_ref_short);
private_ref = private_ref_sb.buf;
strbuf_addf(¬es_ref_sb, "refs/notes/%s/revs", remote->name);
+
+ ## t/t9020-remote-svn.sh ##
+@@ t/t9020-remote-svn.sh: test_expect_success REMOTE_SVN 'incremental imports must lead to the same head'
+ test_cmp master.good .git/refs/remotes/svnsim/master
+ '
+
++test_expect_success REMOTE_SVN 'respects configured default main branch' '
++ git -c init.defaultBranch=trunk remote add -f trunk \
++ "testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" &&
++ git rev-parse --verify refs/remotes/trunk/trunk
++'
++
+ test_debug 'git branch -a'
+
+ test_done 9: f680e66dd6d < -: ----------- Document how the default branch name can be overridden
Signature · 1 line
gitgitgadget
PATCH v2 1/12 fast-export: do anonymize the primary branch name
From: Junio C Hamano <[email protected]>
In a fast-export stream with --anonymize option, all the end-user data including refnames are munged to prevent exposure, but the 'master' branch is left intact.
There is a comment that explains why it is OK to leave 'master' unanonymized (because everybody calls the primary branch 'master' and it is no secret), but that does not justify why it is bad to anonymize 'master' and make it indistinguishable from other branches. Assuming there _is_ a need to allow the readers of the output to tell where the tip of the primary branch is, let's keep the special casing of 'master', but still anonymize it to "ref0". Because all other branches will be given ref+N where N is a positive integer, this will keep the primary branch identifiable in the output stream, without exposing what the name of the primary branch is in the repository the export stream was taken from.
This is in preparation for introducing a mechanism to affect the name of the primary branch used in the repository. Once the mechanism is in use, the name of the primary branch won't be 'master', and may not be allowed to be exposed.
--- builtin/fast-export.c | 9 +++++---- t/t9351-fast-export-anonymize.sh | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-)
builtin/fast-export.c +5 -4
@@ -497,7 +497,7 @@ static void *anonymize_ref_component(const void *old, size_t *len) {static int counter;struct strbuf out =STRBUF_INIT ; -strbuf_addf (&out,"ref%d" , counter++); +strbuf_addf (&out,"ref%d" , ++counter);return strbuf_detach (&out, len); }
@@ -518,11 +518,12 @@ static const char *anonymize_refname(const char *refname)int i;/* -* We also leave "master" as a special case, since it does not reveal -* anything interesting. +* In certain circumstances, it might be interesting to be able to +* identify the main branch. For that reason, let's force its name to +* be anonymized to `ref0`. */ if (!strcmp (refname,"refs/heads/master" )) -return refname; +return "refs/heads/ref0" ;strbuf_reset (&anon);for (i =0 ; i <ARRAY_SIZE (prefixes); i++) {
t/t9351-fast-export-anonymize.sh +5 -4
@@ -26,8 +26,9 @@ test_expect_success 'stream omits path names' ' ! grep xyzzy stream ' -test_expect_success 'stream allows master as refname' ' - grep master stream +test_expect_success 'stream translates master to ref0' ' + grep refs/heads/ref0 stream && + ! grep master stream ' test_expect_success 'stream omits other refnames' '
@@ -57,7 +58,7 @@ test_expect_success 'import stream to new repository' ' test_expect_success 'result has two branches' ' git for-each-ref --format="%(refname)" refs/heads >branches && test_line_count = 2 branches && - other_branch=$(grep -v refs/heads/master branches) + other_branch=$(grep -v refs/heads/ref0 branches) ' test_expect_success 'repo has original shape and timestamps' '
@@ -65,7 +66,7 @@ test_expect_success 'repo has original shape and timestamps' ' git log --format="%m %ct" --left-right --boundary "$@" } && (cd .. && shape master...other) >expect && - shape master...$other_branch >actual && + shape ref0...$other_branch >actual && test_cmp expect actual '
Signature · 1 line
gitgitgadget
Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
Quoted 11 lines · Junio C Hamano via GitGitGadget
There is a comment that explains why it is OK to leave 'master' unanonymized (because everybody calls the primary branch 'master' and it is no secret), but that does not justify why it is bad to anonymize 'master' and make it indistinguishable from other branches. Assuming there _is_ a need to allow the readers of the output to tell where the tip of the primary branch is, let's keep the special casing of 'master', but still anonymize it to "ref0". Because all other branches will be given ref+N where N is a positive integer, this will keep the primary branch identifiable in the output stream, without exposing what the name of the primary branch is in the repository the export stream was taken from.
I think this is fine. The reason I left "master" as-is in the original is that it is potentially helpful to have an idea of its specialness when reproducing a traversal in the anonymized. I.e., if you know that a bug is shown by "git rev-list master~17..master~3", then you can reproduce it with the same command in the anonymized repo. Losing any idea of where the primary branch is would make that impossible. But with this patch, you can swap it out for "ref0~17", etc, which is OK.
Of course that only helps you for _one_ branch. A more generally useful mechanism would be to teach fast-export to write the ref mapping (and perhaps file mappings, etc) to a separate file. Then you could convert any reproduction recipe to use the anonymized names, and share only that recipe along with the anonymized dump. But that's _way_ outside the scope of your series. This seems like a good interim step to retain the status quo.
-Peff
Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
Quoted 7 lines · Jeff King
Of course that only helps you for _one_ branch. A more generally useful mechanism would be to teach fast-export to write the ref mapping (and perhaps file mappings, etc) to a separate file. Then you could convert any reproduction recipe to use the anonymized names, and share only that recipe along with the anonymized dump. But that's _way_ outside the scope of your series. This seems like a good interim step to retain the status quo.
Actually, dropping this special case, and dropping the other special case with fmt-merge-msg, we can do without the notion of the "primary" branch.
We still need to have the default name, when user does not specify one, given to the first branch "git init" creates and "git clone" that cannot figure out what the HEAD at the origin points at uses, but one less thing to worry about is always better ;-)
Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
Quoted 10 lines · Junio C Hamano
Quoted 7 lines · Jeff King
Of course that only helps you for _one_ branch. A more generally useful mechanism would be to teach fast-export to write the ref mapping (and perhaps file mappings, etc) to a separate file. Then you could convert any reproduction recipe to use the anonymized names, and share only that recipe along with the anonymized dump. But that's _way_ outside the scope of your series. This seems like a good interim step to retain the status quo.
Quoted 3 lines
Actually, dropping this special case, and dropping the other special case with fmt-merge-msg, we can do without the notion of the "primary" branch.
That leaves us in the interim with a "fast-export --anonymize" that is a little harder to use (you have no way to know which branch was which).
But I don't mind at all implementing the map-dumping feature to help move this along. As long as both make it into the same release, then fast-export only gets better, and never regresses. :)
-Peff
Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
Quoted 13 lines · Jeff King
Quoted 10 lines · Junio C Hamano
Quoted 7 lines · Jeff King
Of course that only helps you for _one_ branch. A more generally useful mechanism would be to teach fast-export to write the ref mapping (and perhaps file mappings, etc) to a separate file. Then you could convert any reproduction recipe to use the anonymized names, and share only that recipe along with the anonymized dump. But that's _way_ outside the scope of your series. This seems like a good interim step to retain the status quo.
Quoted 6 lines
Quoted 3 lines
Actually, dropping this special case, and dropping the other special case with fmt-merge-msg, we can do without the notion of the "primary" branch.
That leaves us in the interim with a "fast-export --anonymize" that is a little harder to use (you have no way to know which branch was which).
Why does fast-export special case on "master" rather than on HEAD? Isn't it more relevant to know the active branch than what _might_ have been the initial branch? It kind of feels like a bug to me that HEAD isn't the special case construct.
(Speaking as someone whose company a number of years ago had most their big repos and lots of little repos switch their main branch to be named "develop", and in some of those repos deleted "master" but didn't in others. If I had needed some steps to reproduce a problem, and hadn't been on the inside, any special casing from fast-export would make more sense to me to apply to "develop" than to "master".)
Quoted 3 lines
But I don't mind at all implementing the map-dumping feature to help move this along. As long as both make it into the same release, then fast-export only gets better, and never regresses. :)
Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
Quoted 7 lines · Elijah Newren
Quoted 2 lines
That leaves us in the interim with a "fast-export --anonymize" that is a little harder to use (you have no way to know which branch was which).
Why does fast-export special case on "master" rather than on HEAD? Isn't it more relevant to know the active branch than what _might_ have been the initial branch? It kind of feels like a bug to me that HEAD isn't the special case construct.
I am torn on that one. Surely HEAD is often the branch that has our current attention. It may well be what we are exporting and we may want to see the topology formed by other refs relative to it.
On the other hand, the current branch may not necessarily be what we are exporting. Historically a project has a single branch that is the focus of most users' attention when they talk about the general state of the project's progress, so it is understandable to expect that the topology may want to be seen relative to that one central line of development.
Quoted 6 lines
(Speaking as someone whose company a number of years ago had most their big repos and lots of little repos switch their main branch to be named "develop", and in some of those repos deleted "master" but didn't in others. If I had needed some steps to reproduce a problem, and hadn't been on the inside, any special casing from fast-export would make more sense to me to apply to "develop" than to "master".)
Yes, absolutely. You either check "develop" out temporarily just to take anonymized export to make "develop" discoverable in the output, or you would have set core.primaryBranch to "develop" once sometime in the past to tell Git that "develop" is that special one, not "master", so you can take such an export from any branch. As the anonymized export is primarily/solely a debugging aid, convenience would not be of much value, but the latter feels more convenient to me.
Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
Hi Junio,
Quoted 15 lines · Junio C Hamano
Quoted 7 lines · Elijah Newren
Quoted 2 lines
That leaves us in the interim with a "fast-export --anonymize" that is a little harder to use (you have no way to know which branch was which).
Why does fast-export special case on "master" rather than on HEAD? Isn't it more relevant to know the active branch than what _might_ have been the initial branch? It kind of feels like a bug to me that HEAD isn't the special case construct.
I am torn on that one. Surely HEAD is often the branch that has our current attention. It may well be what we are exporting and we may want to see the topology formed by other refs relative to it.
Quoted 6 lines
On the other hand, the current branch may not necessarily be what we are exporting. Historically a project has a single branch that is the focus of most users' attention when they talk about the general state of the project's progress, so it is understandable to expect that the topology may want to be seen relative to that one central line of development.
I'm trying to understand here, but I feel like I'm missing something. Let me try to explain what I understand and hopefully you can figure out what I'm not seeing...
Regardless of what is mainline and whether or not it is important, users probably trigger their bug when a certain branch is checked out. Their bug may also trigger on other branches, but it at least triggers on one, and some bugs will only trigger on one branch. It seems logical to me that we would want to have the same branch checked out (it's the one most likely to trigger the same issue), and thus identifying the HEAD branch is generally important. (Mainline may be too, I'm merely asserting that HEAD is important at this point.)
If users trigger their bug by providing various revision specifications on the command line that compare multiple branches or something, then we're already in the situation of needing to know how to map more than one reference to anonymized ones in order to be able to replicate their issue. However, knowing the mainline might not even help in this case; we instead need to know the anonymized form of the references they are using, whatever those are, and mainline is only useful if it happens to be one of them.
So, I think HEAD is always useful. Additional references would sometimes be useful, but it's not clear to me that mainline is one of those additional references. Maybe I'm just being dense, and I apologize if so, but under what circumstances does knowing the mainline help with debugging a user issue where an anonymized fast-export is provided?
Quoted 9 lines
Quoted 6 lines
(Speaking as someone whose company a number of years ago had most their big repos and lots of little repos switch their main branch to be named "develop", and in some of those repos deleted "master" but didn't in others. If I had needed some steps to reproduce a problem, and hadn't been on the inside, any special casing from fast-export would make more sense to me to apply to "develop" than to "master".)
Yes, absolutely. You either check "develop" out temporarily just to take anonymized export to make "develop" discoverable in the output,
That makes sense; if the bug triggers while they are on develop then I'd expect them to be on develop when they export. If it triggers on some other branch, I'd expect them to stay on that other branch when they export even if "develop" is the mainline.
Quoted 3 lines
or you would have set core.primaryBranch to "develop" once sometime in the past to tell Git that "develop" is that special one, not "master", so you can take such an export from any branch.
This doesn't make sense to me. The person who changed the primary branch to "develop" for some repository did so years ago. That individual might not even still be at the company, and even if they are, may well be working on a totally different project (and repository) today. Perhaps that individual set core.primaryBranch at the time, but git-config settings aren't copied by fetch/clone/push, so I don't see how this one helps at all. We could tell all future developers who clone any of these repositories that they also need to set core.primaryBranch when they clone the repo, but that seems super lame to me especially since the odds that any one of them will ever need or benefit from it are approximately 0. And yet, it'll be one of these developers who joined the project long after the switchover who runs into problems and provides fast-export dumps.
It feels like I'm probably just missing something obvious, but I really don't see how the mainline is special here. Please do point out what I'm missing.
Thanks,
Elijah
Re: [PATCH v2 01/12] fast-export: do anonymize the primary branch name
In reply to Elijah NewrenQuoted 7 lines · Elijah Newren
Quoted 2 lines
That leaves us in the interim with a "fast-export --anonymize" that is a little harder to use (you have no way to know which branch was which).
Why does fast-export special case on "master" rather than on HEAD? Isn't it more relevant to know the active branch than what _might_ have been the initial branch? It kind of feels like a bug to me that HEAD isn't the special case construct.
I don't really remember my exact thought at the time, but it was probably along the lines of: "master" is special not because it's inherently special, but because revealing it doesn't compromise the anonymity, since it's not a user-selected name.
That's not true of other names we might see in HEAD. But if we're turning it into "ref0" or some other special name anyway, then we haven't revealed anything.
That said, I still lean towards just being able to dump the whole mapping by request. That solves this problem and many more.
-Peff
PATCH v2 2/12 fmt-merge-msg: introduce a way to override the main branch name
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).
However, there are a couple of hard-coded spots in Git's source code that make this endeavor harder than necessary. For example, when formatting the commit message for merge commits, Git appends "into <branch-name>" unless the current branch is the master branch.
Clearly, this is not what one wants when already having gone through all the steps to manually rename the main branch (and taking care of all the fall-out such as re-targeting existing Pull Requests).
Let's introduce a way to override Git's hard-coded default:core.mainBranch.
We will start supporting this config option in the git fmt-merge-msg command and successively adjust all other places where the main branch name is hard-coded.
--- Documentation/config/core.txt | 5 +++++ fmt-merge-msg.c | 6 ++++-- refs.c | 27 +++++++++++++++++++++++++++ refs.h | 7 +++++++ t/t6200-fmt-merge-msg.sh | 7 +++++++ 5 files changed, 50 insertions(+), 2 deletions(-)
Documentation/config/core.txt +5 -0
@@ -626,3 +626,8 @@ core.abbrev:: in your repository, which hopefully is enough for abbreviated object names to stay unique for some time. The minimum length is 4. + +core.mainBranch:: + The name of the main (or: primary) branch in the current repository. + For historical reasons, `master` is used as the fall-back for this + setting.
fmt-merge-msg.c +4 -2
@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out, const char *current_branch) {int i =0 ; -char *sep ="" ; +char *sep ="" , *main_branch;strbuf_addstr (out,"Merge " );for (i =0 ; i < srcs.nr; i++) {
@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } -if (!strcmp ("master" , current_branch)) + main_branch =git_main_branch_name (); +if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (main_branch); } static void fmt_tag_signature(struct strbuf *tagbuf,
refs.c +27 -0
@@ -560,6 +560,33 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)argv_array_pushf (prefixes, *p, len, prefix); } +char *repo_main_branch_name (struct repository *r) +{ +const char *config_key ="core.mainbranch" ; +const char *config_display_key ="core.mainBranch" ; +const char *fall_back ="master" ; +char *name =NULL , *ret; + +if (repo_config_get_string (r, config_key, &name) <0 ) +die (_ ("could not retrieve `%s`" ), config_display_key); + + ret = name ? name :xstrdup (fall_back); + +if (check_refname_format (ret,REFNAME_ALLOW_ONELEVEL )) +die (_ ("invalid branch name: %s = %s" ), + config_display_key, name); + +if (name != ret) +free (name); + +return ret; +} + +char *git_main_branch_name (void ) +{ +return repo_main_branch_name (the_repository); +} +/* * *string and *len will only be substituted, and *string returned (for * later free()ing) if the string passed in is a magic short-hand form
refs.h +7 -0
@@ -154,6 +154,13 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_int dwim_ref (const char *str,int len,struct object_id *oid,char **ref);int dwim_log (const char *str,int len,struct object_id *oid,char **ref); +/* +* Retrieves the name of the main (or: primary) branch of the given +* repository. +*/ +char *git_main_branch_name (void ); +char *repo_main_branch_name (struct repository *r); +/* * A ref_transaction represents a collection of reference updates that * should succeed or fail together.
t/t6200-fmt-merge-msg.sh +7 -0
@@ -158,6 +158,13 @@ test_expect_success 'setup FETCH_HEAD' ' git fetch . left ' +test_expect_success 'with overridden default branch name' ' + test_when_finished "git switch master" && + git switch -c default && + git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual && + ! grep "into default" actual +' + test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && Merge branch ${apos}left${apos}
Signature · 1 line
gitgitgadget
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
Hi dscho
Quoted 6 lines · Johannes Schindelin via GitGitGadget
From: 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).
I think this is a good way of phrasing the rationale for the change
Quoted 7 lines
However, there are a couple of hard-coded spots in Git's source code that make this endeavor harder than necessary. For example, when formatting the commit message for merge commits, Git appends "into <branch-name>" unless the current branch is the
masterbranch.Clearly, this is not what one wants when already having gone through all the steps to manually rename the main branch
This didn't quite scan for me maybe s/already having/one has already/ ?
Quoted 75 lines
(and taking care of all the
fall-out such as re-targeting existing Pull Requests).Let's introduce a way to override Git's hard-coded default:
core.mainBranch.We will start supporting this config option in the
git fmt-merge-msgcommand and successively adjust all other places where the main branch name is hard-coded.Signed-off-by Johannes Schindelin <[email protected]>--- Documentation/config/core.txt | 5 +++++ fmt-merge-msg.c | 6 ++++-- refs.c | 27 +++++++++++++++++++++++++++ refs.h | 7 +++++++ t/t6200-fmt-merge-msg.sh | 7 +++++++ 5 files changed, 50 insertions(+), 2 deletions(-)Documentation/config/core.txt +5
-0@@ -626,3 +626,8 @@ core.abbrev:: in your repository, which hopefully is enough for abbreviated object names to stay unique for some time. The minimum length is 4. + +core.mainBranch:: + The name of the main (or: primary) branch in the current repository. + For historical reasons, `master` is used as the fall-back for this + setting.fmt-merge-msg.c +4
-2@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out, const char *current_branch) {int i =0 ; -char *sep ="" ; +char *sep ="" , *main_branch;strbuf_addstr (out,"Merge " );for (i =0 ; i < srcs.nr; i++) {@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } -if (!strcmp ("master" , current_branch)) + main_branch =git_main_branch_name (); +if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (main_branch); } static void fmt_tag_signature(struct strbuf *tagbuf,refs.c +8
-0@@ -560,6 +560,33 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)argv_array_pushf (prefixes, *p, len, prefix); } +char *repo_main_branch_name (struct repository *r) +{ +const char *config_key ="core.mainbranch" ; +const char *config_display_key ="core.mainBranch" ; +const char *fall_back ="master" ; +char *name =NULL , *ret; + +if (repo_config_get_string (r, config_key, &name) <0 )
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 580
Quoted 10 lines
refs.c +10
-0+die (_ ("could not retrieve `%s`" ), config_display_key); + + ret = name ? name :xstrdup (fall_back); + +if (check_refname_format (ret,REFNAME_ALLOW_ONELEVEL )) +die (_ ("invalid branch name: %s = %s" ), + config_display_key, name); + +if (name != ret) +free (name);
I'm struggling to come up with a scenario where name != NULL && name != ret here, however once we get to patch 4 that scenario definitely does exist.
Quoted 17 lines
refs.c +9
-0+ +return ret; +} + +char *git_main_branch_name (void ) +{ +return repo_main_branch_name (the_repository); +} +/* * *string and *len will only be substituted, and *string returned (for * later free()ing) if the string passed in is a magic short-hand form refs.h +0
-0
refs.h int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ · line 158
Quoted 5 lines
refs.h +2
-0@@ -154,6 +154,13 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_int dwim_ref (const char *str,int len,struct object_id *oid,char **ref);int dwim_log (const char *str,int len,struct object_id *oid,char **ref); +/* +* Retrieves the name of the main (or: primary) branch of the given
nit pick, I'm confused by the ':'
Best Wishes
Phillip
Quoted 27 lines
refs.h +5
-0+* repository. +*/ +char *git_main_branch_name (void ); +char *repo_main_branch_name (struct repository *r); +/* * A ref_transaction represents a collection of reference updates that * should succeed or fail together. t/t6200-fmt-merge-msg.sh +7
-0@@ -158,6 +158,13 @@ test_expect_success 'setup FETCH_HEAD' ' git fetch . left ' +test_expect_success 'with overridden default branch name' ' + test_when_finished "git switch master" && + git switch -c default && + git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual && + ! grep "into default" actual +' + test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && Merge branch ${apos}left${apos}
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
Hi Phillip,
Quoted 9 lines · Phillip Wood
Quoted 6 lines · Johannes Schindelin via GitGitGadget
From: 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).I think this is a good way of phrasing the rationale for the change
As I am replacing this patch in v3 with a version that simply drops the special handling of the master branch, I moved that rationale into the patch introducing support for git init --initial-branch=<name>.
Quoted 9 lines
Quoted 7 lines
However, there are a couple of hard-coded spots in Git's source code that make this endeavor harder than necessary. For example, when formatting the commit message for merge commits, Git appends "into <branch-name>" unless the current branch is the
masterbranch.Clearly, this is not what one wants when already having gone through all the steps to manually rename the main branch
This didn't quite scan for me maybe s/already having/one has already/ ?
Thank you! If I had not dropped that part of the commit message, I would have taken your suggested fix.
Quoted 80 lines
Quoted 80 lines
(and taking care of all the
fall-out such as re-targeting existing Pull Requests).Let's introduce a way to override Git's hard-coded default:
core.mainBranch.We will start supporting this config option in the
git fmt-merge-msgcommand and successively adjust all other places where the main branch name is hard-coded.Signed-off-by Johannes Schindelin <[email protected]>--- Documentation/config/core.txt | 5 +++++ fmt-merge-msg.c | 6 ++++-- refs.c | 27 +++++++++++++++++++++++++++ refs.h | 7 +++++++ t/t6200-fmt-merge-msg.sh | 7 +++++++ 5 files changed, 50 insertions(+), 2 deletions(-)Documentation/config/core.txt +5
-0@@ -626,3 +626,8 @@ core.abbrev:: in your repository, which hopefully is enough for abbreviated object names to stay unique for some time. The minimum length is 4. + +core.mainBranch:: + The name of the main (or: primary) branch in the current repository. + For historical reasons, `master` is used as the fall-back for this + setting.fmt-merge-msg.c +4
-1@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out, const char *current_branch) {int i =0 ; -char *sep ="" ; +char *sep ="" , *main_branch;strbuf_addstr (out,"Merge " );for (i =0 ; i < srcs.nr; i++) {@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } - if (!strcmp("master", current_branch)) + main_branch =git_main_branch_name (); +if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (main_branch); } static void fmt_tag_signature(struct strbuf *tagbuf,refs.c +13
-0@@ -560,6 +560,33 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) argv_array_pushf(prefixes, *p, len, prefix); } +char *repo_main_branch_name (struct repository *r) +{ +const char *config_key ="core.mainbranch" ; +const char *config_display_key ="core.mainBranch" ; +const char *fall_back ="master" ; +char *name =NULL , *ret; + +if (repo_config_get_string (r, config_key, &name) <0 ) +die (_ ("could not retrieve `%s`" ), config_display_key); + + ret = name ? name :xstrdup (fall_back); + +if (check_refname_format (ret,REFNAME_ALLOW_ONELEVEL ))
Quoted 8 lines
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 580
Quoted 5 lines
refs.c +5
-0+die (_ ("invalid branch name: %s = %s" ), + config_display_key, name); + +if (name != ret) +free (name);I'm struggling to come up with a scenario where name != NULL && name != ret here, however once we get to patch 4 that scenario definitely does exist.
Right.
But as I am dropping the concept of core.mainBranch from v3, this won't apply anymore.
Quoted 22 lines
Quoted 22 lines
refs.c +9
-0+ +return ret; +} + +char *git_main_branch_name (void ) +{ +return repo_main_branch_name (the_repository); +} +/* * *string and *len will only be substituted, and *string returned (for * later free()ing) if the string passed in is a magic short-hand form
refs.h +0
-0@@ -154,6 +154,13 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_int dwim_ref (const char *str,int len,struct object_id *oid,char **ref);int dwim_log (const char *str,int len,struct object_id *oid,char **ref);
Quoted 4 lines
refs.h int repo_dwim_log(struct repository *r, const char *str, int len, struct object_ · line 158
Quoted 2 lines
refs.h +2
-0+/* +* Retrieves the name of the main (or: primary) branch of the given nit pick, I'm confused by the ':'
Right, v3 won't have that peculiar construct.
Thank you for your review!
Dscho
Quoted 35 lines
Best Wishes
Phillip
Quoted 28 lines
refs.h +5
-0+* repository. +*/ +char *git_main_branch_name (void ); +char *repo_main_branch_name (struct repository *r); +/* * A ref_transaction represents a collection of reference updates that * should succeed or fail together.
t/t6200-fmt-merge-msg.sh +4
-0@@ -158,6 +158,13 @@ test_expect_success 'setup FETCH_HEAD' ' git fetch . left ' +test_expect_success 'with overridden default branch name' ' + test_when_finished "git switch master" && + git switch -c default && + git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual&&
t/t6200-fmt-merge-msg.sh +3
-0+ ! grep "into default" actual +' + test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && Merge branch ${apos}left${apos}
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
In reply to Johannes Schindelin via GitGitGadget"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 14 lines · writes:
fmt-merge-msg.c +1
-1@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out, const char *current_branch) {int i =0 ; -char *sep ="" ; +char *sep ="" , *main_branch;strbuf_addstr (out,"Merge " );for (i =0 ; i < srcs.nr; i++) {
fmt-merge-msg.c static void fmt_merge_msg_title(struct strbuf *out, · line 459
Quoted 10 lines
fmt-merge-msg.c +3
-1@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } -if (!strcmp ("master" , current_branch)) + main_branch =git_main_branch_name (); +if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (main_branch);
While you are at it, taking
https://lore.kernel.org/git/20200614211500.GA22505@dcvr/
and the response to it into consideration, I'd suggest we should support the case where the user says "no single branch is special here" by configuring it to an empty string.
fmt-merge-msg.c static void fmt_merge_msg_title(struct strbuf *out,
Quoted 4 lines
fmt-merge-msg.c +4
-0+core.mainBranch:: + The name of the main (or: primary) branch in the current repository. + For historical reasons, `master` is used as the fall-back for this + setting.
As to the naming of the configuration variable and the actual fall-back value, I would strongly suggest making them DIFFERNT (i.e. separate the concept from an actual value).
An instruction
... oh, if you want to do so, you can set the core.mainBranch configuration variable to 'main'
sounds strange than
... oh, if you want to do so, you can set the core.primaryBranch configuration variable to 'main'
at least to me, and since I am OK with your choice of 'main' as the replacement for 'master', a separate word would be more appropriate for the variable name.
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
Hi Junio,
Quoted 30 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 14 lines · writes:
fmt-merge-msg.c +1
-1@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out, const char *current_branch) {int i =0 ; -char *sep ="" ; +char *sep ="" , *main_branch;strbuf_addstr (out,"Merge " );for (i =0 ; i < srcs.nr; i++) {fmt-merge-msg.c static void fmt_merge_msg_title(struct strbuf *out, · line 459
Quoted 10 lines
fmt-merge-msg.c +3
-1@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } -if (!strcmp ("master" , current_branch)) + main_branch =git_main_branch_name (); +if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (main_branch);While you are at it, taking
Quoted 5 lines
https://lore.kernel.org/git/20200614211500.GA22505@dcvr/
and the response to it into consideration, I'd suggest we should support the case where the user says "no single branch is special here" by configuring it to an empty string.
Together with Peff's comments, I think we're even further than that: v3 of this patch series will completely drop core.mainBranch and not special-case *any* branch in fmt-merge-msg.
There is still merit in Hannes Sixt's wish to be able to turn off the into <branch> suffix, but that is orthogonal to the purpose of this here patch series.
Ciao,
Dscho
Quoted 25 lines
fmt-merge-msg.c static void fmt_merge_msg_title(struct strbuf *out,
Quoted 5 lines
fmt-merge-msg.c +4
-0+core.mainBranch:: + The name of the main (or: primary) branch in the current repository. + For historical reasons, `master` is used as the fall-back for this + setting.As to the naming of the configuration variable and the actual fall-back value, I would strongly suggest making them DIFFERNT (i.e. separate the concept from an actual value).
An instruction
... oh, if you want to do so, you can set the core.mainBranch configuration variable to 'main'
sounds strange than
... oh, if you want to do so, you can set the core.primaryBranch configuration variable to 'main'
at least to me, and since I am OK with your choice of 'main' as the replacement for 'master', a separate word would be more appropriate for the variable name.
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
In reply to Johannes Schindelin via GitGitGadgetDocumentation/config/core.txt core.abbrev:: · line 633
Quoted 6 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
Documentation/config/core.txt +4
-0+core.mainBranch:: + The name of the main (or: primary) branch in the current repository. + For historical reasons, `master` is used as the fall-back for this + setting.
Everywhere else in git-config(1) we just say something to the effect of the more brief:
The name of the main (or: primary) branch in the current repository (master by default).
I think we should do the same here for consistency & ease of reading.
As you note at the start of this series we're not changing the default yet, so referring to the current default as historical is putting the cart before the horse as far as producing self-contained patch serieses goes.
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
Quoted 15 lines · Ævar Arnfjörð Bjarmason
Documentation/config/core.txt core.abbrev:: · line 633
Quoted 6 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
Documentation/config/core.txt +4
-0+core.mainBranch:: + The name of the main (or: primary) branch in the current repository. + For historical reasons, `master` is used as the fall-back for this + setting.Everywhere else in git-config(1) we just say something to the effect of the more brief:
The name of the main (or: primary) branch in the current repository (
masterby default).
Quoted 6 lines
I think we should do the same here for consistency & ease of reading.
As you note at the start of this series we're not changing the default yet, so referring to the current default as historical is putting the cart before the horse as far as producing self-contained patch serieses goes.
Very good point.
In [*1*], I gave a potential outline of how a transition plan might look like (if we were to transition, that is), but what is written as step 1. in there should be split into two: step 0, in which the mechanisms (1) to change the default name used for the first branch and (2) to specify the primary branch that is special-cased by a few commands are introduced, without any future plan, and step 1, in which warning and/or advice messages knudge the users and hint the future direction.
Thanks.
[Reference]
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
In reply to Johannes Schindelin via GitGitGadgetQuoted 5 lines · Johannes Schindelin via GitGitGadget
refs.c +5
-0+char *repo_main_branch_name (struct repository *r) +{ +const char *config_key ="core.mainbranch" ; +const char *config_display_key ="core.mainBranch" ; +const char *fall_back ="master" ;
refs.c void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) · line 577
Quoted 10 lines
refs.c +10
-0+char *name =NULL , *ret; + +if (repo_config_get_string (r, config_key, &name) <0 ) +die (_ ("could not retrieve `%s`" ), config_display_key); + + ret = name ? name :xstrdup (fall_back); + +if (check_refname_format (ret,REFNAME_ALLOW_ONELEVEL )) +die (_ ("invalid branch name: %s = %s" ), + config_display_key, name);
Ah, this fixes the "we do not check the format of the short name" issue I pointed out in v1 (sorry, I just realized that v2 existed so I'll resume reviewing from there; I do still think this might make life easier for callers by returning a const pointer).
I'm not sure if this check_refname_format() is valid, though. IIRC we've had issues where "ONELEVEL" was used to check a branch name, but misses some cases. The more full check done by strbuf_check_branch_ref() actually creates the full refname and checks that. It also catches stuff like refs/heads/HEAD.
I doubt that it matters too much for us to be completely thorough here (unlike some other spots, we are not enforcing rules against potentially malicious names, but rather just helping the user realize early that their config is bogus). So I'm not sure how careful we want to be.
-Peff
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
Quoted 5 lines · Jeff King
I'm not sure if this
check_refname_format()is valid, though. IIRC we've had issues where "ONELEVEL" was used to check a branch name, but misses some cases. The more full check done bystrbuf_check_branch_ref()actually creates the full refname and checks that. It also catches stuff like refs/heads/HEAD.
Yup.
I actually am in favor of removing special casing of a single branch done by fmt-merge-msg and fast-export --anonymize, so this may not matter.
We still need a mechanism to allow users specify the default name to be given to the first branch "git init" creates and used by "git clone" as a fallback name when it cannot infer what the other side uses, though.
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
Hi,
Quoted 10 lines · Junio C Hamano
Quoted 5 lines · Jeff King
I'm not sure if this
check_refname_format()is valid, though. IIRC we've had issues where "ONELEVEL" was used to check a branch name, but misses some cases. The more full check done bystrbuf_check_branch_ref()actually creates the full refname and checks that. It also catches stuff like refs/heads/HEAD.Yup.
Quoted 7 lines
I actually am in favor of removing special casing of a single branch done by fmt-merge-msg and fast-export --anonymize, so this may not matter.
We still need a mechanism to allow users specify the default name to be given to the first branch "git init" creates and used by "git clone" as a fallback name when it cannot infer what the other side uses, though.
All right, core.mainBranch will go, then, and init.defaultBranch will stay and I will check the full ref.
Thank you for your help improving the patch series, Dscho
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
In reply to Johannes Schindelin via GitGitGadgetAm 15.06.20 um 14:50 schrieb Johannes Schindelin via GitGitGadget:
fmt-merge-msg.c static void fmt_merge_msg_title(struct strbuf *out, · line 460
Quoted 12 lines
fmt-merge-msg.c +3
-1@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } -if (!strcmp ("master" , current_branch)) + main_branch =git_main_branch_name (); +if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (main_branch); }
Now that the removal of this special case is on the plate, I would prefer that the phrase "into foo" is never appended instead of always appended.
For me, it was a always more of a hindrance than a help. The story goes like this: A branch that I'm working on was named "edit-box-fix" yesterday, but today it was renamed to "layout-fix" because the scope changed. I had merged a topic "rename-buttons" yesterday, and now I have to go back and rename that "into edit-box-fix" thing! Argh! And tomorrow I'm going to branch off yet another feature "optional-reset" from today's state that will be merged into upstream soon; "Merge branch 'rename-buttons' into layout-fix" will read strange in a history that ends in "Merge branch 'optional-reset'".
And I haven't even mentioned this horrid "into HEAD", which you get during a rebase operation.
To be clear, the branch name in "Merge branch 'option-reset'" is very important and invaluable. But the "into foo" part is mostly noise.
-- Hannes
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
Quoted 5 lines · Johannes Sixt
Am 15.06.20 um 14:50 schrieb Johannes Schindelin via GitGitGadget:
Quoted 4 lines
fmt-merge-msg.c +0
-0@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); }
Quoted 12 lines
fmt-merge-msg.c static void fmt_merge_msg_title(struct strbuf *out, · line 460
Quoted 8 lines
fmt-merge-msg.c +3
-1-if (!strcmp ("master" , current_branch)) + main_branch =git_main_branch_name (); +if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (main_branch); }Now that the removal of this special case is on the plate, I would prefer that the phrase "into foo" is never appended instead of always appended.
I do not mind such an optional feature. I always find it useful whenever I read "git log --oneline --first-parent master..pu" (of course I have an alias for that) to see which topics are already in my private "to be used in real life" edition, so I would oppose to an unconditional removal, though.
Re: [PATCH v2 02/12] fmt-merge-msg: introduce a way to override the main branch name
Hi Junio & Hannes,
Quoted 20 lines · Junio C Hamano
Quoted 5 lines · Johannes Sixt
Am 15.06.20 um 14:50 schrieb Johannes Schindelin via GitGitGadget:
Quoted 4 lines
fmt-merge-msg.c +0
-0@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); }Quoted 12 lines
fmt-merge-msg.c static void fmt_merge_msg_title(struct strbuf *out, · line 460
Quoted 8 lines
fmt-merge-msg.c +3
-1-if (!strcmp ("master" , current_branch)) + main_branch =git_main_branch_name (); +if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else strbuf_addf (out," into %s\n" , current_branch); +free (main_branch); }Now that the removal of this special case is on the plate, I would prefer that the phrase "into foo" is never appended instead of always appended.
Quoted 5 lines
I do not mind such an optional feature. I always find it useful whenever I read "git log --oneline --first-parent master..pu" (of course I have an alias for that) to see which topics are already in my private "to be used in real life" edition, so I would oppose to an unconditional removal, though.
I concur that this would make for a fine optional feature. Of course, that is an issue that is separate from the goal to make the default branch name used by git init configurable, so I will leave that feature to be implemented later (and by somebody else).
Ciao,
Dscho
PATCH v2 3/12 send-pack/transport-helper: respect `core.mainBranch`
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When mentioning the main branch name in an error message, we want to go with the preference specified by the user, only falling back to Git's own, hard-coded default when none was configured explicitly.
--- send-pack.c | 6 +++++- t/t5528-push-default.sh | 7 +++++++ transport-helper.c | 6 +++++- 3 files changed, 17 insertions(+), 2 deletions(-)
send-pack.c +5 -1
@@ -405,8 +405,12 @@ int send_pack(struct send_pack_args *args, }if (!remote_refs) { +char *branch_name =git_main_branch_name (); +fprintf (stderr,"No refs in common and none specified; doing nothing.\n" -"Perhaps you should specify a branch such as 'master'.\n" ); +"Perhaps you should specify a branch such as '%s'.\n" , + branch_name); +free (branch_name);return 0 ; }if (args->atomic && !atomic_supported)
t/t5528-push-default.sh +7 -0
@@ -98,6 +98,13 @@ test_expect_success 'push from/to new branch with upstream, matching and simple' test_push_failure upstream ' +test_expect_success '"matching" fails if none match' ' + git init --bare empty && + test_must_fail git -c core.mainBranch=unmatch push empty : 2>actual && + needle="Perhaps you should specify a branch such as '\''unmatch'\''" && + test_i18ngrep "$needle" actual +' + test_expect_success 'push ambiguously named branch with upstream, matching and simple' ' git checkout -b ambiguous && test_config branch.ambiguous.remote parent1 &&
transport-helper.c +5 -1
@@ -1044,9 +1044,13 @@ static int push_refs(struct transport *transport, }if (!remote_refs) { +char *branch_name =git_main_branch_name (); +fprintf (stderr,_ ("No refs in common and none specified; doing nothing.\n" -"Perhaps you should specify a branch such as 'master'.\n" )); +"Perhaps you should specify a branch such as '%s'.\n" ), + branch_name); +free (branch_name);return 0 ; }
Signature · 1 line
gitgitgadget
PATCH v2 4/12 git_main_branch_name(): optionally report the full ref name
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
We are about to introduce the first caller of that function (git fast-export) that wants a full ref name instead of the short branch name.
To make this change easier to review, let's refactor the function accordingly without mixing in the actual first call using the new flag.
--- fmt-merge-msg.c | 2 +- refs.c | 12 ++++++++---- refs.h | 8 ++++++-- send-pack.c | 2 +- transport-helper.c | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-)
fmt-merge-msg.c +1 -1
@@ -451,7 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } - main_branch =git_main_branch_name (); + main_branch =git_main_branch_name (0 );if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else
refs.c +8 -4
@@ -560,8 +560,9 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)argv_array_pushf (prefixes, *p, len, prefix); } -char *repo_main_branch_name (struct repository *r) +char *repo_main_branch_name (struct repository *r,int flags) { +int full_name = flags &MAIN_BRANCH_FULL_NAME ;const char *config_key ="core.mainbranch" ;const char *config_display_key ="core.mainBranch" ;const char *fall_back ="master" ;
@@ -570,7 +571,10 @@ char *repo_main_branch_name(struct repository *r)if (repo_config_get_string (r, config_key, &name) <0 )die (_ ("could not retrieve `%s`" ), config_display_key); - ret = name ? name :xstrdup (fall_back); +if (full_name) + ret =xstrfmt ("refs/heads/%s" , name ? name : fall_back); +else + ret = name ? name :xstrdup (fall_back);if (check_refname_format (ret,REFNAME_ALLOW_ONELEVEL )) die(_("invalid branch name: %s = %s"),
@@ -582,9 +586,9 @@ char *repo_main_branch_name(struct repository *r)return ret; } -char *git_main_branch_name (void ) +char *git_main_branch_name (int flags) { -return repo_main_branch_name (the_repository); +return repo_main_branch_name (the_repository, flags); }/*
refs.h +6 -2
@@ -157,9 +157,13 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);/* * Retrieves the name of the main (or: primary) branch of the given * repository. +* +* The result is an allocated string. Unless the flags ask for a short name, it +* will be prefixed with "refs/heads/". */ -char *git_main_branch_name (void ); -char *repo_main_branch_name (struct repository *r); +#define MAIN_BRANCH_FULL_NAME (1<<0) +char *git_main_branch_name (int flags); +char *repo_main_branch_name (struct repository *r,int flags);/* * A ref_transaction represents a collection of reference updates that
send-pack.c +1 -1
@@ -405,7 +405,7 @@ int send_pack(struct send_pack_args *args, }if (!remote_refs) { -char *branch_name =git_main_branch_name (); +char *branch_name =git_main_branch_name (0 ); fprintf(stderr, "No refs in common and none specified; doing nothing.\n" "Perhaps you should specify a branch such as '%s'.\n",
transport-helper.c +1 -1
@@ -1044,7 +1044,7 @@ static int push_refs(struct transport *transport, }if (!remote_refs) { -char *branch_name =git_main_branch_name (); +char *branch_name =git_main_branch_name (0 ); fprintf(stderr, _("No refs in common and none specified; doing nothing.\n"
Signature · 1 line
gitgitgadget
Re: [PATCH v2 04/12] git_main_branch_name(): optionally report the full ref name
Hi dscho
Quoted 47 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
We are about to introduce the first caller of that function (
git fast-export) that wants a full ref name instead of the short branch name.To make this change easier to review, let's refactor the function accordingly without mixing in the actual first call using the new flag.
Signed-off-by Johannes Schindelin <[email protected]>--- fmt-merge-msg.c | 2 +- refs.c | 12 ++++++++---- refs.h | 8 ++++++-- send-pack.c | 2 +- transport-helper.c | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-)fmt-merge-msg.c +1
-1@@ -451,7 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } - main_branch =git_main_branch_name (); + main_branch =git_main_branch_name (0 );if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else refs.c +2
-1@@ -560,8 +560,9 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)argv_array_pushf (prefixes, *p, len, prefix); } -char *repo_main_branch_name (struct repository *r) +char *repo_main_branch_name (struct repository *r,int flags) { +int full_name = flags &MAIN_BRANCH_FULL_NAME ;const char *config_key ="core.mainbranch" ;const char *config_display_key ="core.mainBranch" ;const char *fall_back ="master" ;
refs.c char *repo_main_branch_name(struct repository *r) · line 577
Quoted 8 lines
refs.c +4
-1@@ -570,7 +571,10 @@ char *repo_main_branch_name(struct repository *r)if (repo_config_get_string (r, config_key, &name) <0 )die (_ ("could not retrieve `%s`" ), config_display_key); - ret = name ? name :xstrdup (fall_back); +if (full_name) + ret =xstrfmt ("refs/heads/%s" , name ? name : fall_back); +else + ret = name ? name :xstrdup (fall_back);
This looks good, we always check the name before returning it and free name if we're returning refs/heads/<name>
Quoted 19 lines
refs.c +2
-2if (check_refname_format (ret,REFNAME_ALLOW_ONELEVEL )) die(_("invalid branch name: %s = %s"),@@ -582,9 +586,9 @@ char *repo_main_branch_name(struct repository *r)return ret; } -char *git_main_branch_name (void ) +char *git_main_branch_name (int flags) { -return repo_main_branch_name (the_repository); +return repo_main_branch_name (the_repository, flags); }/* refs.h +0
-0
refs.h int dwim_log(const char *str, int len, struct object_id *oid, char **ref); · line 163
Quoted 7 lines
refs.h +3
-0@@ -157,9 +157,13 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);/* * Retrieves the name of the main (or: primary) branch of the given * repository. +* +* The result is an allocated string. Unless the flags ask for a short name, it +* will be prefixed with "refs/heads/". */
nit pick: the flag is defined to give the fullname, to get the short name you just pass 0.
Best Wishes
Phillip
Quoted 35 lines
refs.h +3
-2-char *git_main_branch_name (void ); -char *repo_main_branch_name (struct repository *r); +#define MAIN_BRANCH_FULL_NAME (1<<0) +char *git_main_branch_name (int flags); +char *repo_main_branch_name (struct repository *r,int flags);/* * A ref_transaction represents a collection of reference updates that send-pack.c +1
-1@@ -405,7 +405,7 @@ int send_pack(struct send_pack_args *args, }if (!remote_refs) { -char *branch_name =git_main_branch_name (); +char *branch_name =git_main_branch_name (0 ); fprintf(stderr, "No refs in common and none specified; doing nothing.\n" "Perhaps you should specify a branch such as '%s'.\n",transport-helper.c +1
-1@@ -1044,7 +1044,7 @@ static int push_refs(struct transport *transport, }if (!remote_refs) { -char *branch_name =git_main_branch_name (); +char *branch_name =git_main_branch_name (0 ); fprintf(stderr, _("No refs in common and none specified; doing nothing.\n"
Re: [PATCH v2 04/12] git_main_branch_name(): optionally report the full ref name
Hi Phillip,
Quoted 82 lines · Phillip Wood
Quoted 47 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
We are about to introduce the first caller of that function (
git fast-export) that wants a full ref name instead of the short branch name.To make this change easier to review, let's refactor the function accordingly without mixing in the actual first call using the new flag.
Signed-off-by Johannes Schindelin <[email protected]>--- fmt-merge-msg.c | 2 +- refs.c | 12 ++++++++---- refs.h | 8 ++++++-- send-pack.c | 2 +- transport-helper.c | 2 +- 5 files changed, 17 insertions(+), 9 deletions(-)fmt-merge-msg.c +1
-0@@ -451,7 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } - main_branch =git_main_branch_name (); + main_branch =git_main_branch_name (0 );if (!strcmp (main_branch, current_branch))strbuf_addch (out,'\n' );else refs.c +2
-1@@ -560,8 +560,9 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix) argv_array_pushf(prefixes, *p, len, prefix); } -char *repo_main_branch_name (struct repository *r) +char *repo_main_branch_name (struct repository *r,int flags) { +int full_name = flags &MAIN_BRANCH_FULL_NAME ;const char *config_key ="core.mainbranch" ;const char *config_display_key ="core.mainBranch" ;const char *fall_back = "master";refs.c char *repo_main_branch_name(struct repository *r) · line 577
Quoted 7 lines
refs.c +4
-0@@ -570,7 +571,10 @@ char *repo_main_branch_name(struct repository *r)if (repo_config_get_string (r, config_key, &name) <0 )die (_ ("could not retrieve `%s`" ), config_display_key); - ret = name ? name :xstrdup (fall_back); +if (full_name) + ret =xstrfmt ("refs/heads/%s" , name ? name : fall_back); +else + ret = name ? name :xstrdup (fall_back);This looks good, we always check the name before returning it and free name if we're returning refs/heads/<name>
Quoted 23 lines
refs.c +2
-2if (check_refname_format (ret,REFNAME_ALLOW_ONELEVEL )) die(_("invalid branch name: %s = %s"),@@ -582,9 +586,9 @@ char *repo_main_branch_name(struct repository *r)return ret; } -char *git_main_branch_name (void ) +char *git_main_branch_name (int flags) { -return repo_main_branch_name (the_repository); +return repo_main_branch_name (the_repository, flags); }/* refs.h +0
-0@@ -157,9 +157,13 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);/* * Retrieves the name of the main (or: primary) branch of the given * repository.
Quoted 8 lines
Quoted 5 lines
refs.h +2
-0+* +* The result is an allocated string. Unless the flags ask for a short name, it
+ * will be prefixed with "refs/heads/".
*/nit pick: the flag is defined to give the fullname, to get the short name you just pass 0.
I decided to drop the flag and always return the name, not the full ref. It makes the code _slightly_ less efficient, but easier to follow.
Ciao,
Dscho
Quoted 41 lines
Best Wishes
Phillip
Quoted 35 lines
refs.h +3
-2-char *git_main_branch_name (void ); -char *repo_main_branch_name (struct repository *r); +#define MAIN_BRANCH_FULL_NAME (1<<0) +char *git_main_branch_name (int flags); +char *repo_main_branch_name (struct repository *r,int flags);/* * A ref_transaction represents a collection of reference updates that send-pack.c +1
-1@@ -405,7 +405,7 @@ int send_pack(struct send_pack_args *args, }if (!remote_refs) { -char *branch_name =git_main_branch_name (); +char *branch_name =git_main_branch_name (0 ); fprintf(stderr, "No refs in common and none specified; doing nothing.\n" "Perhaps you should specify a branch such as '%s'.\n",transport-helper.c +1
-1@@ -1044,7 +1044,7 @@ static int push_refs(struct transport *transport, }if (!remote_refs) { -char *branch_name =git_main_branch_name (); +char *branch_name =git_main_branch_name (0 ); fprintf(stderr, _("No refs in common and none specified; doing nothing.\n"
PATCH v2 5/12 fast-export: handle overridden main branch names correctly
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When anonymizing commit history, we are careful to translate the main branch name to ref0.
When the main branch name is overridden via the config, we will want git fast-export to use that overridden name instead.
--- builtin/fast-export.c | 11 ++++++++++- t/t9351-fast-export-anonymize.sh | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-)
builtin/fast-export.c +10 -1
@@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname) };static struct hashmap refs;static struct strbuf anon =STRBUF_INIT ; +static char *main_branch;int i;/* * In certain circumstances, it might be interesting to be able to * identify the main branch. For that reason, let's force its name to * be anonymized to `ref0`. +* +* While the main branch name might often be `main` for new +* repositories (and `master` for aged ones), and such well-known names +* may not necessarily need anonymizing, it could be configured to use +* a secret word that the user may not want to reveal. */ -if (!strcmp (refname,"refs/heads/master" )) +if (!main_branch) + main_branch =git_main_branch_name (MAIN_BRANCH_FULL_NAME ); + +if (!strcmp (refname, main_branch))return "refs/heads/ref0" ;strbuf_reset (&anon);
t/t9351-fast-export-anonymize.sh +6 -0
@@ -31,6 +31,12 @@ test_expect_success 'stream translates master to ref0' ' ! grep master stream ' +test_expect_success 'respects configured main branch' ' + git -c core.mainBranch=does-not-exist \ + fast-export --anonymize --all >stream-without-ref0 && + ! grep ref0 stream-without-ref0 +' + test_expect_success 'stream omits other refnames' ' ! grep other stream && ! grep mytag stream
Signature · 1 line
gitgitgadget
Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
Hi dscho
Quoted 31 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
When anonymizing commit history, we are careful to translate the main branch name to
ref0.When the main branch name is overridden via the config, we will want
git fast-exportto use that overridden name instead.Signed-off-by Johannes Schindelin <[email protected]>--- builtin/fast-export.c | 11 ++++++++++- t/t9351-fast-export-anonymize.sh | 6 ++++++ 2 files changed, 16 insertions(+), 1 deletion(-)builtin/fast-export.c +3
-0@@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname) };static struct hashmap refs;static struct strbuf anon =STRBUF_INIT ; +static char *main_branch;int i;/* * In certain circumstances, it might be interesting to be able to * identify the main branch. For that reason, let's force its name to * be anonymized to `ref0`. +* +* While the main branch name might often be `main` for new
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 535
Quoted 10 lines
builtin/fast-export.c +7
-1+* repositories (and `master` for aged ones), and such well-known names +* may not necessarily need anonymizing, it could be configured to use +* a secret word that the user may not want to reveal. */ -if (!strcmp (refname,"refs/heads/master" )) +if (!main_branch) + main_branch =git_main_branch_name (MAIN_BRANCH_FULL_NAME ); + +if (!strcmp (refname, main_branch))return "refs/heads/ref0" ;
This leaks main_branch if it came from git_main_branch_name()
Best Wishes
Phillip
Quoted 19 lines
builtin/fast-export.c +0
-0strbuf_reset (&anon);t/t9351-fast-export-anonymize.sh +6
-0@@ -31,6 +31,12 @@ test_expect_success 'stream translates master to ref0' ' ! grep master stream ' +test_expect_success 'respects configured main branch' ' + git -c core.mainBranch=does-not-exist \ + fast-export --anonymize --all >stream-without-ref0 && + ! grep ref0 stream-without-ref0 +' + test_expect_success 'stream omits other refnames' ' ! grep other stream && ! grep mytag stream
Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
Quoted 6 lines · Phillip Wood
Quoted 5 lines
builtin/fast-export.c +1
-0@@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname) };static struct hashmap refs;static struct strbuf anon =STRBUF_INIT ; +static char *main_branch;[...]
Quoted 8 lines
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 535
Quoted 6 lines
builtin/fast-export.c +4
-1-if (!strcmp (refname,"refs/heads/master" )) +if (!main_branch) + main_branch =git_main_branch_name (MAIN_BRANCH_FULL_NAME ); + +if (!strcmp (refname, main_branch))return "refs/heads/ref0" ;This leaks
main_branchif it came fromgit_main_branch_name()
It's a static that's used over and over, so I think it's intentional to essentially memoize it for the life of the program (at which point we could free it, but don't bother to do so, letting the process exit take care of it, and trusting in leak detectors to be aware that it's still reachable, as we do for lots of other process-lifetime allocations).
-Peff
Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
Hi Peff
Quoted 17 lines · Jeff King
Quoted 6 lines · Phillip Wood
Quoted 5 lines
builtin/fast-export.c +1
-0@@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname) };static struct hashmap refs;static struct strbuf anon =STRBUF_INIT ; +static char *main_branch;[...]
Quoted 8 lines
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 535
Quoted 6 lines
builtin/fast-export.c +4
-1-if (!strcmp (refname,"refs/heads/master" )) +if (!main_branch) + main_branch =git_main_branch_name (MAIN_BRANCH_FULL_NAME ); + +if (!strcmp (refname, main_branch))return "refs/heads/ref0" ;This leaks
main_branchif it came fromgit_main_branch_name()
Quoted 2 lines
It's a static that's used over and over, so I think it's intentional to essentially memoize it for the life of the program
Oh you're right, I completely misread the patch
Thanks
Phillip
Quoted 7 lines
(at which point we
could free it, but don't bother to do so, letting the process exit take care of it, and trusting in leak detectors to be aware that it's still reachable, as we do for lots of other process-lifetime allocations).-Peff
Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
In reply to Jeff KingHi Peff,
Quoted 17 lines · Jeff King
Quoted 6 lines · Phillip Wood
Quoted 5 lines
builtin/fast-export.c +1
-0@@ -515,14 +515,23 @@ static const char *anonymize_refname(const char *refname) };static struct hashmap refs;static struct strbuf anon =STRBUF_INIT ; +static char *main_branch;[...]
Quoted 8 lines
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 535
Quoted 6 lines
builtin/fast-export.c +4
-1-if (!strcmp (refname,"refs/heads/master" )) +if (!main_branch) + main_branch =git_main_branch_name (MAIN_BRANCH_FULL_NAME ); + +if (!strcmp (refname, main_branch))return "refs/heads/ref0" ;This leaks
main_branchif it came fromgit_main_branch_name()
Quoted 5 lines
It's a static that's used over and over, so I think it's intentional to essentially memoize it for the life of the program (at which point we could free it, but don't bother to do so, letting the process exit take care of it, and trusting in leak detectors to be aware that it's still reachable, as we do for lots of other process-lifetime allocations).
That is indeed the intention, and I will edit the commit message accordingly.
Thanks,
Dscho
Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
In reply to Johannes Schindelin via GitGitGadget"Johannes Schindelin via GitGitGadget" <[email protected]>
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 527
Quoted 2 lines · writes:
builtin/fast-export.c +2
-0+* While the main branch name might often be `main` for new +* repositories (and `master` for aged ones), and such well-known names
As I said, if you used a different word for the first 'main' in the sentence, it reads much better.
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 535
Quoted 9 lines
builtin/fast-export.c +6
-1+* may not necessarily need anonymizing, it could be configured to use +* a secret word that the user may not want to reveal. */ -if (!strcmp (refname,"refs/heads/master" )) +if (!main_branch) + main_branch =git_main_branch_name (MAIN_BRANCH_FULL_NAME ); + +if (!strcmp (refname, main_branch))return "refs/heads/ref0" ;
The same comment as 02/12 applies here. If the helper function returns "" when the user says that no branch is more special than others in the repository, the code would automatically do the right thing.
In any case, thanks for working on it. I am on "vacation" so will be commenting on the rest of the series later in the week.
Re: [PATCH v2 05/12] fast-export: handle overridden main branch names correctly
Hi Junio,
Quoted 9 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 527
Quoted 2 lines · writes:
builtin/fast-export.c +2
-0+* While the main branch name might often be `main` for new +* repositories (and `master` for aged ones), and such well-known names As I said, if you used a different word for the first 'main' in the sentence, it reads much better.
Quoted 14 lines
builtin/fast-export.c static const char *anonymize_refname(const char *refname) · line 535
Quoted 9 lines
builtin/fast-export.c +6
-1+* may not necessarily need anonymizing, it could be configured to use +* a secret word that the user may not want to reveal. */ -if (!strcmp (refname,"refs/heads/master" )) +if (!main_branch) + main_branch =git_main_branch_name (MAIN_BRANCH_FULL_NAME ); + +if (!strcmp (refname, main_branch))return "refs/heads/ref0" ;The same comment as 02/12 applies here. If the helper function returns "" when the user says that no branch is more special than others in the repository, the code would automatically do the right thing.
Seeing as the fast-export patches in this here patch series will be dropped from v3, in favor of Peff's patches, this does no longer need to be addressed.
Quoted 2 lines
In any case, thanks for working on it. I am on "vacation" so will be commenting on the rest of the series later in the week.
Welcome back! I hope you were able to rest.
Ciao,
Dscho
PATCH v2 6/12 branch -m: adjust `core.mainBranch` if necessary
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
When renaming the main branch (as possibly identified by the core.mainBranch setting), we will want to record that the main branch now has a different name.
--- builtin/branch.c | 9 +++++++++ t/t3200-branch.sh | 9 +++++++++ 2 files changed, 18 insertions(+)
builtin/branch.c +9 -0
@@ -556,6 +556,15 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int replace_each_worktree_head_symref(oldref.buf, newref.buf, logmsg.buf))die (_ ("Branch renamed to %s, but HEAD is not updated!" ), newname); +if (!copy) { +char *main_branch =git_main_branch_name (0 ); + +if (!strcmp (interpreted_oldname, main_branch)) +git_config_set ("core.mainbranch" , interpreted_newname); + +free (main_branch); + } +strbuf_release (&logmsg);strbuf_addf (&oldsection,"branch.%s" , interpreted_oldname);
t/t3200-branch.sh +9 -0
@@ -467,6 +467,15 @@ EOF test_cmp expect actual ' +test_expect_success 'renaming the main branch modifies core.mainBranch' ' + git init rename-main && + test_commit -C rename-main initial && + git -C rename-main branch -m trunk && + git -C rename-main config core.mainBranch >actual && + echo trunk >expect && + test_cmp expect actual +' + test_expect_success 'git branch -c dumps usage' ' test_expect_code 128 git branch -c 2>err && test_i18ngrep "branch name required" err
Signature · 1 line
gitgitgadget
PATCH v2 7/12 init: allow specifying the main branch name for the new repository
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
There is a growing number of projects trying to avoid the non-inclusive name master in their repositories: The master/slave terminology is insensitive and perpetuates injustice. This master/slave idea is actually where Git's naming comes from, as it was inherited from BitKeeper which uses the term in exactly this way, see
https://mail.gnome.org/archives/desktop-devel-list/2019-May/msg00066.html
To change that branch name for new repositories, currently the only way to do that automatically is by copying all of Git's template directory, then hard-coding the desired default branch name into the .git/HEAD file, and then configuring init.templateDir to point to those copied template files.
To make this process much less cumbersome, let's introduce a new option:--main-branch=<branch-name>.
This will not only initialize the repository with the specified initial branch; It will also record that branch name in core.mainBranch.
--- Documentation/git-init.txt | 7 +++++++ builtin/clone.c | 3 ++- builtin/init-db.c | 34 +++++++++++++++++++++++++++------- cache.h | 2 +- t/t0001-init.sh | 15 +++++++++++++++ 5 files changed, 52 insertions(+), 9 deletions(-)
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> | --main-branch=<branch-name>] [--shared[=<permissions>]] [directory]
@@ -67,6 +68,12 @@ repository. + If this is reinitialization, the repository will be moved to the specified path. +-b <branch-name:: +--main-branch=<branch-name>:: + +Use the specified name for the main (or: initial) branch in the newly created +repository. If not specified, fall back to the default name: `master`. + --shared[=(false|true|umask|group|all|world|everybody|0xxx)]:: Specify that the Git repository is to be shared amongst several users. This
builtin/clone.c +2 -1
@@ -1108,7 +1108,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix) } } -init_db (git_dir, real_git_dir, option_template,GIT_HASH_UNKNOWN ,INIT_DB_QUIET ); +init_db (git_dir, real_git_dir, option_template,GIT_HASH_UNKNOWN ,NULL , +INIT_DB_QUIET );if (real_git_dir) git_dir = real_git_dir;
builtin/init-db.c +27 -7
@@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)static int create_default_files (const char *template_path,const char *original_git_dir, +const char *main_branch,const struct repository_format *fmt) {struct stat st1;
@@ -258,16 +259,29 @@ static int create_default_files(const char *template_path,die ("failed to set up refs db: %s" , err.buf);/* -* Create the default symlink from ".git/HEAD" to the "master" -* branch, if it does not exist yet. +* Create the default symlink from ".git/HEAD" to the default +* branch name, if it does not exist yet. */ path =git_path_buf (&buf,"HEAD" ); reinit = (!access (path,R_OK ) ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) { -if (create_symref ("HEAD" ,"refs/heads/master" ,NULL ) <0 ) +char *ref; + +if (!main_branch) + main_branch ="master" ; + + ref =xstrfmt ("refs/heads/%s" , main_branch); +if (check_refname_format (ref,0 ) <0 ) +die (_ ("invalid main branch name: '%s'" ), main_branch); + +if (create_symref ("HEAD" , ref,NULL ) <0 )exit (1 ); - } +free (ref); + +git_config_set ("core.mainbranch" , main_branch); + }else if (main_branch) +warning (_ ("re-init: ignoring --main-branch=%s" ), main_branch);initialize_repository_version (fmt->hash_algo);
@@ -383,7 +397,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash }int init_db (const char *git_dir,const char *real_git_dir, -const char *template_dir,int hash,unsigned int flags) +const char *template_dir,int hash,const char *main_branch, +unsigned int flags) {int reinit;int exist_ok = flags &INIT_DB_EXIST_OK ;
@@ -425,7 +440,8 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); - reinit =create_default_files (template_dir, original_git_dir, &repo_fmt); + reinit =create_default_files (template_dir, original_git_dir, + main_branch, &repo_fmt);create_object_directory ();
@@ -528,6 +544,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)const char *template_dir =NULL ;unsigned int flags =0 ;const char *object_format =NULL ; +const char *main_branch =NULL ;int hash_algo =GIT_HASH_UNKNOWN ;const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ -541,6 +558,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)OPT_BIT ('q' ,"quiet" , &flags,N_ ("be quiet" ),INIT_DB_QUIET ),OPT_STRING (0 ,"separate-git-dir" , &real_git_dir,N_ ("gitdir" ),N_ ("separate git dir from working tree" )), +OPT_STRING ('b' ,"main-branch" , &main_branch,N_ ("name" ), +N_ ("override the name of the main branch" )),OPT_STRING (0 ,"object-format" , &object_format,N_ ("hash" ),N_ ("specify the hash algorithm to use" )),OPT_END ()
@@ -652,5 +671,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)UNLEAK (work_tree); flags |=INIT_DB_EXIST_OK ; -return init_db (git_dir, real_git_dir, template_dir, hash_algo, flags); +return init_db (git_dir, real_git_dir, template_dir, hash_algo, + main_branch, flags); }
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 *main_branch,unsigned int flags);void initialize_repository_version (int hash_algo);void sanitize_stdfds (void );
t/t0001-init.sh +15 -0
@@ -464,4 +464,19 @@ test_expect_success MINGW 'redirect std handles' ' grep "Needed a single revision" output.txt ' +test_expect_success '--main-branch' ' + git init --main-branch=hello main-branch-option && + git -C main-branch-option symbolic-ref HEAD >actual && + echo refs/heads/hello >expect && + test_cmp expect actual && + + : re-initializing should not change the main branch name && + git init --main-branch=ignore main-branch-option 2>err && + test_i18ngrep "ignoring --main-branch" err && + git -C main-branch-option symbolic-ref HEAD >actual && + grep hello actual && + git -C main-branch-option config core.mainBranch >actual && + grep hello actual +' + test_done
Signature · 1 line
gitgitgadget
PATCH v2 8/12 init: allow overriding the default main branch name via the config
In reply to Johannes Schindelin via GitGitGadgetFrom: Don Goodman-Wilson <[email protected]>
We just introduced the command-line option --main-branch=<branch-name> to allow initializing a new repository with a different initial branch than the hard-coded one.
To allow users to override the default main branch name more permanently (i.e. without having to specify the name manually for each and every git init invocation), let's introduce the init.defaultBranch config setting.
--- Documentation/config/init.txt | 4 ++++ builtin/init-db.c | 6 ++++-- refs.c | 7 +++++-- refs.h | 4 ++++ t/t0001-init.sh | 16 ++++++++++++++++ 5 files changed, 33 insertions(+), 4 deletions(-)
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 +4 -2
@@ -266,10 +266,11 @@ static int create_default_files(const char *template_path, reinit = (!access (path,R_OK ) ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) { -char *ref; +char *ref, *fall_back =NULL ;if (!main_branch) - main_branch ="master" ; + main_branch = fall_back = +git_main_branch_name (MAIN_BRANCH_FOR_INIT ); ref =xstrfmt ("refs/heads/%s" , main_branch);if (check_refname_format (ref,0 ) <0 )
@@ -280,6 +281,7 @@ static int create_default_files(const char *template_path,free (ref);git_config_set ("core.mainbranch" , main_branch); +free (fall_back); }else if (main_branch)warning (_ ("re-init: ignoring --main-branch=%s" ), main_branch);
refs.c +5 -2
@@ -563,8 +563,11 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)char *repo_main_branch_name (struct repository *r,int flags) {int full_name = flags &MAIN_BRANCH_FULL_NAME ; -const char *config_key ="core.mainbranch" ; -const char *config_display_key ="core.mainBranch" ; +int for_init = flags &MAIN_BRANCH_FOR_INIT ; +const char *config_key = for_init ? +"init.defaultbranch" :"core.mainbranch" ; +const char *config_display_key = for_init ? +"init.defaultBranch" :"core.mainBranch" ;const char *fall_back ="master" ;char *name =NULL , *ret;
refs.h +4 -0
@@ -158,10 +158,14 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **ref);* Retrieves the name of the main (or: primary) branch of the given * repository. * +* To obtain the default for newly-initialized repositories, pass the flag +* `MAIN_BRANCH_FOR_INIT`. +* * The result is an allocated string. Unless the flags ask for a short name, it * will be prefixed with "refs/heads/". */ #define MAIN_BRANCH_FULL_NAME (1<<0) +#define MAIN_BRANCH_FOR_INIT (1<<1)char *git_main_branch_name (int flags);char *repo_main_branch_name (struct repository *r,int flags);
t/t0001-init.sh +16 -0
@@ -479,4 +479,20 @@ test_expect_success '--main-branch' ' grep hello actual ' +test_expect_success 'overridden default main branch name (config)' ' + test_config_global init.defaultBranch nmb && + git init main-branch-config && + git -C main-branch-config symbolic-ref HEAD >actual && + grep nmb actual && + git -C main-branch-config config core.mainBranch >actual && + echo nmb >expect && + test_cmp expect actual +' + +test_expect_success 'invalid default branch name' ' + test_config_global init.defaultBranch "with space" && + test_must_fail git init main-branch-invalid 2>err && + test_i18ngrep "invalid branch name" err +' + test_done
Signature · 1 line
gitgitgadget
PATCH v2 9/12 clone: handle overridden main branch names
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 main branch name. We now really want that branch name to be used as a fall-back.
At the same time, we also want to make sure that core.mainBranch is set correctly, reflecting the name of the main branch. In case we detect a main branch, we do have to do that explicitly, otherwise init_db() will already have done that for us.
--- Documentation/config/init.txt | 4 ++-- builtin/clone.c | 16 +++++++++++++--- t/t5606-clone-options.sh | 17 +++++++++++++++++ 3 files changed, 32 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 +13 -3
@@ -718,6 +718,7 @@ static void update_head(const struct ref *our, const struct ref *remote,/* Local default branch link */ if (create_symref ("HEAD" , our->name,NULL ) <0 )die (_ ("unable to update HEAD" )); +git_config_set ("core.mainbranch" , head);if (!option_bare) {update_ref (msg,"HEAD" , &our->old_oid,NULL ,0 ,UPDATE_REFS_DIE_ON_ERR );
@@ -1264,9 +1265,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix) remote_head_points_at =NULL ; remote_head =NULL ; option_no_checkout =1 ; -if (!option_bare) -install_branch_config (0 ,"master" , option_origin, -"refs/heads/master" ); +if (!option_bare) { +char *main_branch = +git_main_branch_name (MAIN_BRANCH_FULL_NAME ); +const char *nick; + +if (!skip_prefix (main_branch,"refs/heads/" , &nick)) +BUG ("unexpected default branch '%s'" , + main_branch); +install_branch_config (0 , nick, option_origin, + main_branch); +free (main_branch); + } } write_refspec_config(src_ref_prefix, our_head_points_at,
t/t5606-clone-options.sh +17 -0
@@ -35,4 +35,21 @@ test_expect_success 'redirected clone -v does show progress' ' ' +test_expect_success 'chooses correct default main branch name' ' + git init --bare empty && + git -c init.defaultBranch=up clone empty whats-up && + test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) && + test up = $(git -C whats-up config core.mainBranch) && + test refs/heads/up = $(git -C whats-up config branch.up.merge) +' + +test_expect_success 'guesses main branch name correctly' ' + git init --main-branch=guess main-branch && + test_commit -C main-branch no-spoilers && + git -C main-branch branch abc guess && + git clone main-branch is-it && + test guess = $(git -C is-it config core.mainBranch) && + test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) +' + test_done
Signature · 1 line
gitgitgadget
Re: [PATCH v2 09/12] clone: handle overridden main branch names
builtin/clone.c static void update_head(const struct ref *our, const struct ref *remote, · line 724
Quoted 12 lines · Johannes Schindelin via GitGitGadget
builtin/clone.c +1
-0@@ -718,6 +718,7 @@ static void update_head(const struct ref *our, const struct ref *remote,/* Local default branch link */ if (create_symref ("HEAD" , our->name,NULL ) <0 )die (_ ("unable to update HEAD" )); +git_config_set ("core.mainbranch" , head);if (!option_bare) {update_ref (msg,"HEAD" , &our->old_oid,NULL ,0 ,UPDATE_REFS_DIE_ON_ERR );
Just making sure I understand what's going on here...
This covers the case that we've run "clone -b foo" or similar, but there are two other case arms when "foo" is a tag, or the remote HEAD is unreachable. And there we don't set core.mainbranch at all.
But we would not want it to be missing, because that will likely need to stay a default for "master" indefinitely (to keep behavior for existing repositories). However, it won't be missing. We'll always have set it during the init_db() call, and this is just overriding that. So we'd end update_head() with either:
- core.mainbranch set to the same branch we point HEAD to, whether we got it from the remote side or from "-b foo"
- if we write a detached HEAD, then core.mainbranch remains at init.mainbranch (or defaulting to "master" now, and probably "main" later). We have no better option.
If so, then that makes sense to me.
-Peff
Re: [PATCH v2 09/12] clone: handle overridden main branch names
Hi Peff,
Quoted 17 lines · Jeff King
builtin/clone.c static void update_head(const struct ref *our, const struct ref *remote, · line 724
Quoted 12 lines · Johannes Schindelin via GitGitGadget
builtin/clone.c +1
-0@@ -718,6 +718,7 @@ static void update_head(const struct ref *our, const struct ref *remote,/* Local default branch link */ if (create_symref ("HEAD" , our->name,NULL ) <0 )die (_ ("unable to update HEAD" )); +git_config_set ("core.mainbranch" , head);if (!option_bare) {update_ref (msg,"HEAD" , &our->old_oid,NULL ,0 ,UPDATE_REFS_DIE_ON_ERR );Just making sure I understand what's going on here...
Quoted 3 lines
This covers the case that we've run "clone -b foo" or similar, but there are two other case arms when "foo" is a tag, or the remote HEAD is unreachable. And there we don't set core.mainbranch at all.
It was actually meant to catch the case where the remote repository has a default branch other than master.
Quoted 6 lines
But we would not want it to be missing, because that will likely need to stay a default for "master" indefinitely (to keep behavior for existing repositories). However, it won't be missing. We'll always have set it during the
init_db()call, and this is just overriding that. So we'd endupdate_head()with either:
Quoted 8 lines
- core.mainbranch set to the same branch we point HEAD to, whether we got it from the remote side or from "-b foo"
- if we write a detached HEAD, then core.mainbranch remains at init.mainbranch (or defaulting to "master" now, and probably "main" later). We have no better option.
If so, then that makes sense to me.
In any case, this does not matter anymore, as I am dropping core.mainBranch from v3, as you had suggested elsewhere in this thread.
Ciao,
Dscho
PATCH v2 10/12 remote: learn about the possibly-overridden default main branch name
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 main branch of new repositories (because as far as the user is concerned, a remote that has no branches yet is a new repository).
--- remote.c | 15 ++++++++++----- t/t5606-clone-options.sh | 11 ++++++++++- 2 files changed, 20 insertions(+), 6 deletions(-)
remote.c +10 -5
@@ -256,7 +256,7 @@ static void read_remotes_file(struct remote *remote)static void read_branches_file (struct remote *remote) { -char *frag; +char *frag, *main_branch =NULL ;struct strbuf buf =STRBUF_INIT ;FILE *f =fopen_or_warn (git_path ("branches/%s" , remote->name),"r" );
@@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)/* * The branches file would have URL and optionally -* #branch specified. The "master" (or specified) branch is +* #branch specified. The main (or specified) branch is * fetched and stored in the local branch matching the * remote name. */
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)if (frag) *(frag++) ='\0' ;else - frag ="master" ; + frag = main_branch =git_main_branch_name (MAIN_BRANCH_FOR_INIT );add_url_alias (remote,strbuf_detach (&buf,NULL )); strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ -299,6 +299,7 @@ static void read_branches_file(struct remote *remote)strbuf_addf (&buf,"HEAD:refs/heads/%s" , frag);refspec_append (&remote->push, buf.buf); remote->fetch_tags =1 ;/* always auto-follow */ +free (main_branch);strbuf_release (&buf); }
@@ -2097,9 +2098,13 @@ struct ref *guess_remote_head(const struct ref *head,if (head->symref)return copy_ref (find_ref_by_name (refs, head->symref)); -/* If refs/heads/master could be right, it is. */ +/* If a remote branch exists with the main branch name, let's use it. */ if (!all) { - r =find_ref_by_name (refs,"refs/heads/master" ); +char *name =git_main_branch_name (MAIN_BRANCH_FULL_NAME | +MAIN_BRANCH_FOR_INIT ); + + r =find_ref_by_name (refs, name); +free (name);if (r &&oideq (&r->old_oid, &head->old_oid))return copy_ref (r); }
t/t5606-clone-options.sh +10 -1
@@ -49,7 +49,16 @@ test_expect_success 'guesses main branch name correctly' ' git -C main-branch branch abc guess && git clone main-branch is-it && test guess = $(git -C is-it config core.mainBranch) && - test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) + test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) && + + git -c init.defaultBranch=none init --bare no-head && + git -C main-branch push ../no-head guess abc && + git clone no-head is-it2 && + test_must_fail git -C is-it2 symbolic-ref refs/remotes/origin/HEAD && + git -C no-head update-ref --no-deref HEAD refs/heads/guess && + git -c init.defaultBranch=guess clone no-head is-it3 && + test refs/remotes/origin/guess = \ + $(git -C is-it3 symbolic-ref refs/remotes/origin/HEAD) ' test_done
Signature · 1 line
gitgitgadget
PATCH v2 11/12 submodule: use the correct default for the main branch name
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
To allow for overriding the default branch name, we have introduced a config setting. With this patch, the git submodule command learns about this, too.
--- builtin/submodule--helper.c | 10 ++++++++-- t/t7406-submodule-update.sh | 7 +++++++ 2 files changed, 15 insertions(+), 2 deletions(-)
builtin/submodule--helper.c +8 -2
@@ -1980,8 +1980,14 @@ static const char *remote_submodule_branch(const char *path) branch = sub->branch;free (key); -if (!branch) -return "master" ; +if (!branch) { +static char *fall_back; + +if (!fall_back) + fall_back =git_main_branch_name (MAIN_BRANCH_FOR_INIT ); + +return fall_back; + }if (!strcmp (branch,"." )) {const char *refname =resolve_ref_unsafe ("HEAD" ,0 ,NULL ,NULL );
t/t7406-submodule-update.sh +7 -0
@@ -70,6 +70,13 @@ test_expect_success 'setup a submodule tree' ' ) ' +test_expect_success 'update --remote uses configured default main branch' ' + git clone super main-branch && + test_must_fail git -C main-branch -c init.defaultBranch=hello \ + submodule update --init --remote submodule 2>err && + test_i18ngrep origin/hello err +' + test_expect_success 'submodule update detaching the HEAD ' ' (cd super/submodule && git reset --hard HEAD~1
Signature · 1 line
gitgitgadget
Re: [PATCH v2 11/12] submodule: use the correct default for the main branch name
Quoted 5 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
To allow for overriding the default branch name, we have introduced a config setting. With this patch, the
git submodulecommand learns about this, too.
This was the other reading case (besides guess_remote_head()) that I'm most concerned with causing regressions in a world where some repos are on "master" and some are on "main".
This value ends up as the output of "submodule--helper remote-branch".
I was initially worried that we used this branch name for the fallback when the server doesn't allow us to fetch the sha1 directly, but it doesn't look like it. That's good, because handling fallbacks there would be tricky.
Instead, we seem to use this only after fetching all of the refs for a submodule:
$ git grep -h -B2 -A11 remote-branch git-submodule.sh
if test -n "$remote"
then
branch=$(git submodule--helper remote-branch "$sm_path")
if test -z "$nofetch"
then
# Fetch remote before determining tracking $sha1
fetch_in_submodule "$sm_path" $depth ||
die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
fi
remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote)
sha1=$(sanitize_submodule_env; cd "$sm_path" &&
git rev-parse --verify "${remote_name}/${branch}") ||
die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
fiand then we just use that branch name to resolve a sha1. So this will break cases where you've set init.mainBranch, the submodule repo is still on "master", and you haven't configured a branch in .gitmodules.
It seems like, independent of any change in the default branch names, we ought to be using $remote_name/HEAD for this case anyway. I suspect that would be a behavior improvement by itself, as it means more cases could avoid having to specify the branch name in .gitmodules manually. Probably nobody noticed so far because "HEAD" is almost always "master" in the current world. It technically breaks the case that you truly did want to use "master" in the submodule, but they set HEAD to something else, and you couldn't be bothered to put it into your .gitmodules file. That seems rather unlikely to me.
And then everything would Just Work without having to worry about the local mainbranch value at all.
Alternatively, submodule--helper could pass back the empty string for "no, we don't have a configured branch name" and this shell code could actually try a sequence of reasonable guesses: init.mainbranch, then "master" (and between the two, "main" if that later becomes the default).
-Peff
Re: [PATCH v2 11/12] submodule: use the correct default for the main branch name
Hi Peff,
Quoted 52 lines · Jeff King
Quoted 5 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
To allow for overriding the default branch name, we have introduced a config setting. With this patch, the
git submodulecommand learns about this, too.This was the other reading case (besides
guess_remote_head()) that I'm most concerned with causing regressions in a world where some repos are on "master" and some are on "main".This value ends up as the output of "submodule--helper remote-branch".
I was initially worried that we used this branch name for the fallback when the server doesn't allow us to fetch the sha1 directly, but it doesn't look like it. That's good, because handling fallbacks there would be tricky.
Instead, we seem to use this only after fetching all of the refs for a submodule:
$ git grep -h -B2 -A11 remote-branch git-submodule.sh if test -n "$remote" then branch=$(git submodule--helper remote-branch "$sm_path") if test -z "$nofetch" then # Fetch remote before determining tracking $sha1 fetch_in_submodule "$sm_path" $depth || die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")" fi remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote) sha1=$(sanitize_submodule_env; cd "$sm_path" && git rev-parse --verify "${remote_name}/${branch}") || die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")" fiand then we just use that branch name to resolve a sha1. So this will break cases where you've set init.mainBranch, the submodule repo is still on "master", and you haven't configured a branch in .gitmodules.
It seems like, independent of any change in the default branch names, we ought to be using $remote_name/HEAD for this case anyway. I suspect that would be a behavior improvement by itself, as it means more cases could avoid having to specify the branch name in .gitmodules manually. Probably nobody noticed so far because "HEAD" is almost always "master" in the current world. It technically breaks the case that you truly did want to use "master" in the submodule, but they set HEAD to something else, and you couldn't be bothered to put it into your .gitmodules file. That seems rather unlikely to me.
Quoted 2 lines
And then everything would Just Work without having to worry about the local mainbranch value at all.
This is the route that I am taking.
Please note that t7519 contains a few test cases that rely on the current confusing behavior where git submodule update --remote fetches the remote master even if that is not the remote repository's current branch!
I did adjust t7519 to stop verifying this confusing behavior, and to verify the saner behavior instead.
This is of course a bit worrisome, as there might actually be users out there relying on the confusing behavior.
However, I think it is okay to fix this:
- The git submodule update --remote command does not strike me as awfully common. In fact, I had never heard of it before I worked on this here patch.
- Current Git's behavior when running this command is outright confusing, unless the remote repository's current branch _is_ master (in which case the proposed behavior matches the old behavior).
- It is actually easily fixed by setting submodule.<name>.branch to master _iff_ users want to reinstate the old behavior.
Quoted 5 lines
Alternatively, submodule--helper could pass back the empty string for "no, we don't have a configured branch name" and this shell code could actually try a sequence of reasonable guesses: init.mainbranch, then "master" (and between the two, "main" if that later becomes the default).
Quite honestly: I'd rather not.
Thank you,
Dscho
Re: [PATCH v2 11/12] submodule: use the correct default for the main branch name
Quoted 12 lines · Johannes Schindelin
Quoted 1 line
[use HEAD instead of master]
This is the route that I am taking.
[...]
This is of course a bit worrisome, as there might actually be users out there relying on the confusing behavior.However, I think it is okay to fix this:
- The
git submodule update --remotecommand does not strike me as awfully common. In fact, I had never heard of it before I worked on this here patch.
Quoted 6 lines
- Current Git's behavior when running this command is outright confusing, unless the remote repository's current branch _is_
master(in which case the proposed behavior matches the old behavior).- It is actually easily fixed by setting
submodule.<name>.branchtomaster_iff_ users want to reinstate the old behavior.
Thanks, I agree that this is the best way forward, and that the current confusing behavior is as likely to be doing the wrong thing as the right (when it even differs).
-Peff
PATCH v2 12/12 testsvn: respect `init.defaultBranch`
In reply to Johannes Schindelin via GitGitGadgetFrom: Johannes Schindelin <[email protected]>
The default name of the main branch in new repositories can now be configured. The testsvn remote helper translates the remote Subversion repository's branch name trunk to the hard-coded name master. Clearly, the intention was to make the name align with Git's detaults.
So while we are not talking about a newly-created repository in the testsvn context, it _still_ makes sense to use the overridden default name for the main branch whenever users configured it.
--- remote-testsvn.c | 12 +++++++++--- t/t9020-remote-svn.sh | 6 ++++++ 2 files changed, 15 insertions(+), 3 deletions(-)
remote-testsvn.c +9 -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,11 @@ int cmd_main(int argc, const char **argv)return 1 ; } + remote_ref =git_main_branch_name (MAIN_BRANCH_FULL_NAME | +MAIN_BRANCH_FOR_INIT ); +if (!skip_prefix (remote_ref,"refs/heads/" , &remote_ref_short)) +BUG ("unexpected remote_ref '%s'" , remote_ref); + remote =remote_get (argv[1 ]); url_in = (argc ==3 ) ? argv[2 ] : remote->url[0 ];
@@ -306,7 +311,8 @@ int cmd_main(int argc, const char **argv) url = url_sb.buf; } -strbuf_addf (&private_ref_sb,"refs/svn/%s/master" , remote->name); +strbuf_addf (&private_ref_sb,"refs/svn/%s/%s" , + remote->name, remote_ref_short); private_ref = private_ref_sb.buf;strbuf_addf (¬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 main branch' ' + git -c init.defaultBranch=trunk remote add -f trunk \ + "testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" && + git rev-parse --verify refs/remotes/trunk/trunk +' + test_debug 'git branch -a' test_done
Signature · 1 line
gitgitgadget
Re: [PATCH v2 12/12] testsvn: respect `init.defaultBranch`
Quoted 6 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
The default name of the main branch in new repositories can now be configured. The
testsvnremote helper translates the remote Subversion repository's branch nametrunkto the hard-coded namemaster. Clearly, the intention was to make the name align with Git's detaults.
s/detaults/defaults/ :)
I'd agree that moving this to Git's default name makes sense.
Though my overall preference is still to delete this whole testsvn thing entirely (I have some other pending tree-wide changes that are being held up by it, too). After getting "would you mind holding off until..." from Jonathan in [1], I've been waiting almost 2 years. Maybe now is the time?
-Peff
Re: [PATCH v2 12/12] testsvn: respect `init.defaultBranch`
Hi Peff,
Quoted 10 lines · Jeff King
Quoted 6 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
The default name of the main branch in new repositories can now be configured. The
testsvnremote helper translates the remote Subversion repository's branch nametrunkto the hard-coded namemaster. Clearly, the intention was to make the name align with Git's detaults.s/detaults/defaults/ :)
:-)
Will fix.
Quoted 1 line
I'd agree that moving this to Git's default name makes sense.
Okay.
Quoted 5 lines
Though my overall preference is still to delete this whole testsvn thing entirely (I have some other pending tree-wide changes that are being held up by it, too). After getting "would you mind holding off until..." from Jonathan in [1], I've been waiting almost 2 years. Maybe now is the time?
I wouldn't mind dropping testsvn, seeing as there are fewer and fewer users of git svn (and even those are unlikely to switch to testsvn, should that ever become production-ready).
Having said that, this is an orthogonal issue to the purpose of this patch series. And I would really like to get this patch series into a shape that can be merged down to next soon.
Thank you,
Dscho
Quoted 5 lines
-Peff
v3 cover Allow overriding the default name of the default branch
In reply to Johannes Schindelin via GitGitGadgetA growing number of open source projects aims to avoid the branch name master due to its negative connotation. See [1] for an existing discussion on this. The links [2], [3], and [4] describe community-driven ways for users to rename their default branches or use template edits to set a new default branch name.
[1]
https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/
[2] https://twitter.com/mislav/status/1270388510684598272
[3]
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx
[4] https://github.com/ethomson/retarget_prs
By necessity, existing repositories require a lot of manual work to move away from that branch name, but it should be much easier for new repositories.
This patch series allows overriding the branch name being used for new repositories' main branch. This can be configured via init.defaultBranch.
The initial patch was started by newcomer Don Goodman-Wilson, as well as the bigger change that morphed into #655, where we demonstrate how to change Git's hard-coded default branch name for new repositories to main based on this here patch series, verifying the approach. Thanks for the contribution!
This series DOES NOT change the default automatically, but only provides an opt-in mechanism for interested users. The plan for that is to convert the test scripts incrementally (by introducing GIT_TEST_DEFAULT_MAIN_BRANCH_NAME , which overrides init.defaultBranch, and then converting the tricky test scripts first, one by one, using that environment variable).
Changes since v2:
* Dropped the fast-export patches, as they have been superseded by Peff's jk/fast-export-anonym
[https://github.com/gitgitgadget/git/commits/jk/fast-export-anonym].
* Adjusted the fmt-merge-msg patch so as to not special-case master anymore (instead of special-casing a specific "main" branch).
* Modified the git submodule patch so that it uses origin/HEAD instead of trying to look for a remote branch with the name indicated by init.defaultBranch.
Changes since v1:
* The modifications to respect GIT_TEST_DEFAULT_BRANCH_NAME have been backed out from this patch series, as they are only relevant once we start converting the test suite to accommodate for a new default main branch name.
* An error message that started with an upper-case letter was downcased.
* git_default_branch_name()'s logic was simplified by replacing an if ... else ... by a ternary assignment.
* The git_default_branch_name() function was renamed to git_main_branch_name() and a corresponding repo_main_branch_name() was introduced.
* The "init" commit message's first paragraph now elaborates a little bit on the reasoning why projects want to move away from the current default branch name.
* The "init" commit was split into two.
* There are now two config settings: init.defaultBranch (defining the branch name to use when initializing new repositories) and core.mainBranch (which is now configured by init_db(), declaring what the name of the main branch is in this repository).
* The commits were re-ordered to introduce the concept of core.mainBranch first because technically, this is something that we could do even without changing git init at all.
* git fast-export --anonymize now always uses the ref name ref0 for the main branch, no matter whether it was overridden or whether the fall-back is in effect.
* The code comment regarding anonymizing the main branch to ref0 in git fast-export --anonymize was enhanced.
* A new patch was added to rename core.mainBranch if the main branch is renamed via git branch -m.
* Added a patch that introduces support for git init --main-branch=<branch-name>.
* Where possible, I added tests (although I did not try to extend test coverage to all changes: the send-pack.c/transport-helper.c patch only adds a test for the send-pack.c adjustment, for example).
Don Goodman-Wilson (1):
init: allow setting the default for the initial branch name via the
config
Johannes Schindelin (7):
fmt-merge-msg: stop treating master specially send-pack/transport-helper: avoid mentioning a particular branch
submodule: use a better fall-back for missing remote.<name>.branch
init: allow specifying the initial branch name for the new repository
clone: use configured default branch name when appropriate
remote: use the configured default branch name when appropriate
testsvn: respect init.defaultBranch
Documentation/config/init.txt | 4 ++ Documentation/git-init.txt | 7 ++ Documentation/git-submodule.txt | 4 +- builtin/clone.c | 13 ++-- builtin/init-db.c | 34 +++++++-- builtin/submodule--helper.c | 2 +- cache.h | 2 +- fmt-merge-msg.c | 5 +- refs.c | 30 ++++++++ refs.h | 9 +++ remote-testsvn.c | 10 ++- remote.c | 14 +++- send-pack.c | 2 +- t/t0001-init.sh | 26 +++++++ t/t1507-rev-parse-upstream.sh | 2 +- t/t4013-diff-various.sh | 4 +- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- ...--patch-with-stat_--summary_master_--_dir_ | 2 +- t/t4013/diff.log_--patch-with-stat_master | 2 +- .../diff.log_--patch-with-stat_master_--_dir_ | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ..._--root_--patch-with-stat_--summary_master | 2 +- .../diff.log_--root_--patch-with-stat_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4013/diff.log_--root_-p_master | 2 +- t/t4013/diff.log_--root_master | 2 +- t/t4013/diff.log_-m_-p_--first-parent_master | 2 +- t/t4013/diff.log_-m_-p_master | 4 +- t/t4013/diff.log_-p_--first-parent_master | 2 +- t/t4013/diff.log_-p_master | 2 +- t/t4013/diff.log_master | 2 +- t/t4013/diff.show_--first-parent_master | 2 +- t/t4013/diff.show_-c_master | 2 +- t/t4013/diff.show_-m_master | 4 +- t/t4013/diff.show_master | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4202-log.sh | 72 +++++++++---------- t/t5528-push-default.sh | 6 ++ t/t5606-clone-options.sh | 24 +++++++ t/t6200-fmt-merge-msg.sh | 36 +++++----- t/t7406-submodule-update.sh | 16 +++++ t/t7419-submodule-set-branch.sh | 7 +- t/t7600-merge.sh | 14 ++-- t/t7608-merge-messages.sh | 10 +-- t/t9020-remote-svn.sh | 6 ++ transport-helper.c | 2 +- 48 files changed, 287 insertions(+), 122 deletions(-)
base-commit: c9c318d6bf26bcecdca5b6f31683b9d5887a83ee
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-656%2Fdscho%2Fdefault-branch-name-option-v3
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-656/dscho/default-branch-name-option-v3
Pull-Request: https://github.com/gitgitgadget/git/pull/656
Range-diff vs v2:
1: ebd10f73cd < -: ---------- fast-export: do anonymize the primary branch name
-: ---------- > 1: fffdb9944f fmt-merge-msg: stop treating `master` specially
3: bd8af3755a ! 2: a29943d7bb send-pack/transport-helper: respect `core.mainBranch`
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- send-pack/transport-helper: respect `core.mainBranch`
+ send-pack/transport-helper: avoid mentioning a particular branch
- When mentioning the main branch name in an error message, we want to go
- with the preference specified by the user, only falling back to Git's
- own, hard-coded default when none was configured explicitly.
+ When trying to push all matching branches, but none match, we offer a
+ message suggesting to push the `master` branch.
+
+ However, we want to step away from making that branch any more special
+ than any other branch, so let's reword that message to mention no branch
+ in particular.
Signed-off-by: Johannes Schindelin <[email protected]>
## send-pack.c ##
@@ send-pack.c: int send_pack(struct send_pack_args *args,
- }
if (!remote_refs) {
-+ char *branch_name = git_main_branch_name();
-+
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
- "Perhaps you should specify a branch such as 'master'.\n");
-+ "Perhaps you should specify a branch such as '%s'.\n",
-+ branch_name);
-+ free(branch_name);
++ "Perhaps you should specify a specific branch.\n");
return 0;
}
if (args->atomic && !atomic_supported)
@@ t/t5528-push-default.sh: test_expect_success 'push from/to new branch with upstr
+test_expect_success '"matching" fails if none match' '
+ git init --bare empty &&
-+ test_must_fail git -c core.mainBranch=unmatch push empty : 2>actual &&
-+ needle="Perhaps you should specify a branch such as '\''unmatch'\''" &&
-+ test_i18ngrep "$needle" actual
++ test_must_fail git push empty : 2>actual &&
++ test_i18ngrep "Perhaps you should specify a specific branch" actual
+'
+
test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
@@ t/t5528-push-default.sh: test_expect_success 'push from/to new branch with upstr
## transport-helper.c ##
@@ transport-helper.c: static int push_refs(struct transport *transport,
- }
-
if (!remote_refs) {
-+ char *branch_name = git_main_branch_name();
-+
fprintf(stderr,
_("No refs in common and none specified; doing nothing.\n"
- "Perhaps you should specify a branch such as 'master'.\n"));
-+ "Perhaps you should specify a branch such as '%s'.\n"),
-+ branch_name);
-+ free(branch_name);
++ "Perhaps you should specify a specific branch.\n"));
return 0;
} 11: 59d6267f09 ! 3: 6bda69541b submodule: use the correct default for the main branch name
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- submodule: use the correct default for the main branch name
+ submodule: use a better fall-back for missing remote.<name>.branch
- To allow for overriding the default branch name, we have introduced a
- config setting. With this patch, the git submodule command learns
- about this, too.
+ When remote.<name>.branch is not configured, git submodule update
+ currently falls back to using the branch name master. A much better
+ idea, however, is to use HEAD: on all Git servers running reasonably
+ recent Git versions, the symref HEAD points to the main branch.
+
+ Note: t7419 demonstrates that there _might_ be use cases out there that
+ _expect_ git submodule update --remote to update submodules to the
+ remote master branch even if the remote HEAD points to another
+ branch. Arguably, this patch makes the behavior more intuitive, but
+ there is a slight possibility that this might cause regressions in
+ obscure setups.
+ ## Documentation/git-submodule.txt ##
+@@ Documentation/git-submodule.txt: OPTIONS
+ .gitmodules for update --remote. A special value of . is used to
+ indicate that the name of the branch in the submodule should be the
+ same name as the current branch in the current repository. If the
+- option is not specified, it defaults to 'master'.
++ option is not specified, it defaults to 'HEAD'.
+
+ -f::
+ --force::
+@@ Documentation/git-submodule.txt: OPTIONS
+ the superproject's recorded SHA-1 to update the submodule, use the
+ status of the submodule's remote-tracking branch. The remote used
+ is branch's remote (branch.<name>.remote), defaulting to origin.
+- The remote branch used defaults to master, but the branch name may
++ The remote branch used defaults to HEAD, but the branch name may
+ be overridden by setting the submodule.<name>.branch option in
+ either .gitmodules or .git/config (with .git/config taking
+ precedence).
+
## builtin/submodule--helper.c ##
@@ builtin/submodule--helper.c: static const char *remote_submodule_branch(const char *path)
- branch = sub->branch;
free(key);
-- if (!branch)
+ if (!branch)
- return "master";
-+ if (!branch) {
-+ static char *fall_back;
-+
-+ if (!fall_back)
-+ fall_back = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
-+
-+ return fall_back;
-+ }
++ return "HEAD";
if (!strcmp(branch, ".")) {
const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
@@ t/t7406-submodule-update.sh: test_expect_success 'setup a submodule tree' '
)
'
-+test_expect_success 'update --remote uses configured default main branch' '
-+ git clone super main-branch &&
-+ test_must_fail git -C main-branch -c init.defaultBranch=hello \
-+ submodule update --init --remote submodule 2>err &&
-+ test_i18ngrep origin/hello err
++test_expect_success 'update --remote falls back to using HEAD' '
++ test_create_repo main-branch-submodule &&
++ test_commit -C main-branch-submodule initial &&
++
++ test_create_repo main-branch &&
++ git -C main-branch submodule add ../main-branch-submodule &&
++ git -C main-branch commit -m add-submodule &&
++
++ git -C main-branch-submodule switch -c hello &&
++ test_commit -C main-branch-submodule world &&
++
++ git clone --recursive main-branch main-branch-clone &&
++ git -C main-branch-clone submodule update --remote main-branch-submodule &&
++ test_path_exists main-branch-clone/main-branch-submodule/world.t
+'
+
test_expect_success 'submodule update detaching the HEAD ' '
(cd super/submodule &&
git reset --hard HEAD~1
+
+ ## t/t7419-submodule-set-branch.sh ##
+@@ t/t7419-submodule-set-branch.sh: test_expect_success 'test submodule set-branch --branch' '
+ '
+
+ test_expect_success 'test submodule set-branch --default' '
++ test_commit -C submodule c &&
+ (cd super &&
+ git submodule set-branch --default submodule &&
+ ! grep branch .gitmodules &&
+ git submodule update --remote &&
+ cat <<-\EOF >expect &&
+- a
++ c
+ EOF
+ git -C submodule show -s --pretty=%s >actual &&
+ test_cmp expect actual
+@@ t/t7419-submodule-set-branch.sh: test_expect_success 'test submodule set-branch --default' '
+ '
+
+ test_expect_success 'test submodule set-branch -b' '
++ test_commit -C submodule b &&
+ (cd super &&
+ git submodule set-branch -b topic submodule &&
+ grep "branch = topic" .gitmodules &&
+@@ t/t7419-submodule-set-branch.sh: test_expect_success 'test submodule set-branch -b' '
+ '
+
+ test_expect_success 'test submodule set-branch -d' '
++ test_commit -C submodule d &&
+ (cd super &&
+ git submodule set-branch -d submodule &&
+ ! grep branch .gitmodules &&
+ git submodule update --remote &&
+ cat <<-\EOF >expect &&
+- a
++ d
+ EOF
+ git -C submodule show -s --pretty=%s >actual &&
+ test_cmp expect actual
7: 0ec04b2086 ! 4: e8a6587c1a init: allow specifying the main branch name for the new repository
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- init: allow specifying the main branch name for the new repository
+ init: allow specifying the initial branch name for the new repository
- There is a growing number of projects trying to avoid the non-inclusive
- name `master` in their repositories: The `master`/`slave` terminology is
- insensitive and perpetuates injustice. This `master`/`slave` idea is
- actually where Git's naming comes from, as it was inherited from
- BitKeeper which uses the term in exactly this way, see
- https://mail.gnome.org/archives/desktop-devel-list/2019-May/msg00066.html
+ There is a growing number of projects and companies desiring to change
+ the main branch name of their repositories (see e.g.
+ https://twitter.com/mislav/status/1270388510684598272 for background on
+ this).
To change that branch name for new repositories, currently the only way
to do that automatically is by copying all of Git's template directory,
@@ Commit message
template files.
To make this process much less cumbersome, let's introduce a new option:
- `--main-branch=<branch-name>`.
-
- This will not only initialize the repository with the specified initial
- branch; It will also record that branch name in `core.mainBranch`.
+ `--initial-branch=<branch-name>`.
Signed-off-by: Johannes Schindelin <[email protected]>
@@ Documentation/git-init.txt: SYNOPSIS
[verse]
'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
[--separate-git-dir <git dir>] [--object-format=<format]
-+ [-b <branch-name> | --main-branch=<branch-name>]
++ [-b <branch-name> | --initial-branch=<branch-name>]
[--shared[=<permissions>]] [directory]
@@ Documentation/git-init.txt: repository.
If this is reinitialization, the repository will be moved to the specified path.
+-b <branch-name::
-+--main-branch=<branch-name>::
++--initial-branch=<branch-name>::
+
-+Use the specified name for the main (or: initial) branch in the newly created
-+repository. If not specified, fall back to the default name: `master`.
++Use the specified name for the initial branch in the newly created repository.
++If not specified, fall back to the default name: `master`.
+
--shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
@@ builtin/init-db.c: void initialize_repository_version(int hash_algo)
static int create_default_files(const char *template_path,
const char *original_git_dir,
-+ const char *main_branch,
++ const char *initial_branch,
const struct repository_format *fmt)
{
struct stat st1;
@@ builtin/init-db.c: static int create_default_files(const char *template_path,
- if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
+ char *ref;
+
-+ if (!main_branch)
-+ main_branch = "master";
++ if (!initial_branch)
++ initial_branch = "master";
+
-+ ref = xstrfmt("refs/heads/%s", main_branch);
++ ref = xstrfmt("refs/heads/%s", initial_branch);
+ if (check_refname_format(ref, 0) < 0)
-+ die(_("invalid main branch name: '%s'"), main_branch);
++ die(_("invalid initial branch name: '%s'"),
++ initial_branch);
+
+ if (create_symref("HEAD", ref, NULL) < 0)
exit(1);
- }
+ free(ref);
-+
-+ git_config_set("core.mainbranch", main_branch);
-+ } else if (main_branch)
-+ warning(_("re-init: ignoring --main-branch=%s"), main_branch);
++ } else if (initial_branch)
++ warning(_("re-init: ignoring --initial-branch=%s"),
++ initial_branch);
initialize_repository_version(fmt->hash_algo);
@@ builtin/init-db.c: static void validate_hash_algorithm(struct repository_format
int init_db(const char *git_dir, const char *real_git_dir,
- const char *template_dir, int hash, unsigned int flags)
-+ const char *template_dir, int hash, const char *main_branch,
++ const char *template_dir, int hash, const char *initial_branch,
+ unsigned int flags)
{
int reinit;
@@ builtin/init-db.c: int init_db(const char *git_dir, const char *real_git_dir,
- reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
+ reinit = create_default_files(template_dir, original_git_dir,
-+ main_branch, &repo_fmt);
++ initial_branch, &repo_fmt);
create_object_directory();
@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
const char *template_dir = NULL;
unsigned int flags = 0;
const char *object_format = NULL;
-+ const char *main_branch = NULL;
++ const char *initial_branch = NULL;
int hash_algo = GIT_HASH_UNKNOWN;
const struct option init_db_options[] = {
OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
N_("separate git dir from working tree")),
-+ OPT_STRING('b', "main-branch", &main_branch, N_("name"),
-+ N_("override the name of the main branch")),
++ OPT_STRING('b', "initial-branch", &initial_branch, N_("name"),
++ N_("override the name of the initial branch")),
OPT_STRING(0, "object-format", &object_format, N_("hash"),
N_("specify the hash algorithm to use")),
OPT_END()
@@ builtin/init-db.c: int cmd_init_db(int argc, const char **argv, const char *pref
flags |= INIT_DB_EXIST_OK;
- return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
+ return init_db(git_dir, real_git_dir, template_dir, hash_algo,
-+ main_branch, flags);
++ initial_branch, flags);
}
## cache.h ##
@@ cache.h: int path_inside_repo(const char *prefix, const char *path);
int init_db(const char *git_dir, const char *real_git_dir,
const char *template_dir, int hash_algo,
- unsigned int flags);
-+ const char *main_branch, unsigned int flags);
++ const char *initial_branch, unsigned int flags);
void initialize_repository_version(int hash_algo);
void sanitize_stdfds(void);
@@ t/t0001-init.sh: test_expect_success MINGW 'redirect std handles' '
grep "Needed a single revision" output.txt
'
-+test_expect_success '--main-branch' '
-+ git init --main-branch=hello main-branch-option &&
-+ git -C main-branch-option symbolic-ref HEAD >actual &&
++test_expect_success '--initial-branch' '
++ git init --initial-branch=hello initial-branch-option &&
++ git -C initial-branch-option symbolic-ref HEAD >actual &&
+ echo refs/heads/hello >expect &&
+ test_cmp expect actual &&
+
-+ : re-initializing should not change the main branch name &&
-+ git init --main-branch=ignore main-branch-option 2>err &&
-+ test_i18ngrep "ignoring --main-branch" err &&
-+ git -C main-branch-option symbolic-ref HEAD >actual &&
-+ grep hello actual &&
-+ git -C main-branch-option config core.mainBranch >actual &&
++ : re-initializing should not change the branch name &&
++ git init --initial-branch=ignore initial-branch-option 2>err &&
++ test_i18ngrep "ignoring --initial-branch" err &&
++ git -C initial-branch-option symbolic-ref HEAD >actual &&
+ grep hello actual
+'
+ 2: f4d5473915 ! 5: a500e0f214 fmt-merge-msg: introduce a way to override the main branch name
@@
## Metadata ##
-Author: Johannes Schindelin <[email protected]>
+Author: Don Goodman-Wilson <[email protected]>
## Commit message ##
- fmt-merge-msg: introduce a way to override the main branch name
+ init: allow setting the default for the initial branch name via the config
- There is a growing number of projects and companies desiring to change
- the main branch name of their repositories (see e.g.
- https://twitter.com/mislav/status/1270388510684598272 for background on
- this).
+ We just introduced the command-line option
+ --initial-branch=<branch-name> to allow initializing a new repository
+ with a different initial branch than the hard-coded one.
- However, there are a couple of hard-coded spots in Git's source code
- that make this endeavor harder than necessary. For example, when
- formatting the commit message for merge commits, Git appends "into
- <branch-name>" unless the current branch is the master branch.
+ To allow users to override the initial branch name more permanently
+ (i.e. without having to specify the name manually for each and every
+ git init invocation), let's introduce the init.defaultBranch config
+ setting.
- Clearly, this is not what one wants when already having gone through all
- the steps to manually rename the main branch (and taking care of all the
- fall-out such as re-targeting existing Pull Requests).
+ Helped-by: Johannes Schindelin <[email protected]>
+ Helped-by: Derrick Stolee <[email protected]>
+ Signed-off-by: Don Goodman-Wilson <[email protected]>
- Let's introduce a way to override Git's hard-coded default:
- core.mainBranch.
-
- We will start supporting this config option in the git fmt-merge-msg
- command and successively adjust all other places where the main branch
- name is hard-coded.
-
- Signed-off-by: Johannes Schindelin <[email protected]>
-
- ## Documentation/config/core.txt ## -@@ Documentation/config/core.txt: core.abbrev::
- in your repository, which hopefully is enough for
- abbreviated object names to stay unique for some time.
- The minimum length is 4.
+ ## Documentation/config/init.txt ## +@@
+ init.templateDir::
+ Specify the directory from which templates will be copied.
+ (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+
-+core.mainBranch::
-+ The name of the main (or: primary) branch in the current repository.
-+ For historical reasons, master is used as the fall-back for this
-+ setting.
++init.defaultBranch::
++ Allows overriding the default branch name when initializing
++ a new repository.
- ## fmt-merge-msg.c ##
-@@ fmt-merge-msg.c: static void fmt_merge_msg_title(struct strbuf *out,
- const char *current_branch)
- {
- int i = 0;
-- char *sep = "";
-+ char *sep = "", *main_branch;
+ ## builtin/init-db.c ##
+@@ builtin/init-db.c: static int create_default_files(const char *template_path,
+ char *ref;
- strbuf_addstr(out, "Merge ");
- for (i = 0; i < srcs.nr; i++) {
-@@ fmt-merge-msg.c: static void fmt_merge_msg_title(struct strbuf *out,
- strbuf_addf(out, " of %s", srcs.items[i].string);
- }
+ if (!initial_branch)
+- initial_branch = "master";
++ initial_branch = git_default_branch_name();
-- if (!strcmp("master", current_branch))
-+ main_branch = git_main_branch_name();
-+ if (!strcmp(main_branch, current_branch))
- strbuf_addch(out, '\n');
- else
- strbuf_addf(out, " into %s\n", current_branch);
-+ free(main_branch);
- }
-
- static void fmt_tag_signature(struct strbuf *tagbuf,
+ ref = xstrfmt("refs/heads/%s", initial_branch);
+ if (check_refname_format(ref, 0) < 0)
## refs.c ##
@@ refs.c: void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
argv_array_pushf(prefixes, *p, len, prefix);
}
-+char *repo_main_branch_name(struct repository *r)
++char *repo_default_branch_name(struct repository *r)
+{
-+ const char *config_key = "core.mainbranch";
-+ const char *config_display_key = "core.mainBranch";
-+ const char *fall_back = "master";
-+ char *name = NULL, *ret;
++ const char *config_key = "init.defaultbranch";
++ const char *config_display_key = "init.defaultBranch";
++ char *ret = NULL, *full_ref;
+
-+ if (repo_config_get_string(r, config_key, &name) < 0)
++ if (repo_config_get_string(r, config_key, &ret) < 0)
+ die(_("could not retrieve %s"), config_display_key);
+
-+ ret = name ? name : xstrdup(fall_back);
-+
-+ if (check_refname_format(ret, REFNAME_ALLOW_ONELEVEL))
-+ die(_("invalid branch name: %s = %s"),
-+ config_display_key, name);
++ if (!ret)
++ ret = xstrdup("master");
+
-+ if (name != ret)
-+ free(name);
++ full_ref = xstrfmt("refs/heads/%s", ret);
++ if (check_refname_format(full_ref, 0))
++ die(_("invalid branch name: %s = %s"), config_display_key, ret);
++ free(full_ref);
+
+ return ret;
+}
+
-+char *git_main_branch_name(void)
++const char *git_default_branch_name(void)
+{
-+ return repo_main_branch_name(the_repository);
++ static char *ret;
++
++ if (!ret)
++ ret = repo_default_branch_name(the_repository);
++
++ return ret;
+}
+
/*
@@ refs.h: int repo_dwim_log(struct repository *r, const char *str, int len, struct
int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
+/*
-+ * Retrieves the name of the main (or: primary) branch of the given -+ * repository.
++ * Retrieves the default branch name for newly-initialized repositories. ++ *
++ * The return value of repo_default_branch_name() is an allocated string. The ++ * return value of git_default_branch_name() is a singleton.
+ */
-+char *git_main_branch_name(void);
-+char *repo_main_branch_name(struct repository *r);
++const char *git_default_branch_name(void);
++char *repo_default_branch_name(struct repository *r);
+
/*
* A ref_transaction represents a collection of reference updates that
* should succeed or fail together.
- ## t/t6200-fmt-merge-msg.sh ##
-@@ t/t6200-fmt-merge-msg.sh: test_expect_success 'setup FETCH_HEAD' '
- git fetch . left
+ ## t/t0001-init.sh ##
+@@ t/t0001-init.sh: test_expect_success '--initial-branch' '
+ grep hello actual
'
-+test_expect_success 'with overridden default branch name' '
-+ test_when_finished "git switch master" &&
-+ git switch -c default &&
-+ git -c core.mainBranch=default fmt-merge-msg <.git/FETCH_HEAD >actual &&
-+ ! grep "into default" actual
++test_expect_success 'overridden default initial branch name (config)' '
++ test_config_global init.defaultBranch nmb &&
++ git init initial-branch-config &&
++ git -C initial-branch-config symbolic-ref HEAD >actual &&
++ grep nmb actual
++'
++
++test_expect_success 'invalid default branch name' '
++ test_config_global init.defaultBranch "with space" &&
++ test_must_fail git init initial-branch-invalid 2>err &&
++ test_i18ngrep "invalid branch name" err
+'
+
- test_expect_success 'merge.log=3 limits shortlog length' '
- cat >expected <<-EOF &&
- Merge branch ${apos}left${apos}
+ test_done
4: ca1c63c3e0 < -: ---------- git_main_branch_name(): optionally report the full ref name
5: a3be4f39aa < -: ---------- fast-export: handle overridden main branch names correctly
6: 933e314813 < -: ---------- branch -m: adjust `core.mainBranch` if necessary
8: c711eba7e7 < -: ---------- init: allow overriding the default main branch name via the config
9: 0e59b61816 ! 6: c0d74cedd1 clone: handle overridden main branch names
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- clone: handle overridden main branch names
+ clone: use configured default branch name when appropriate
When cloning a repository without any branches, Git chooses a default
branch name for the as-yet unborn branch.
- As part of the implicit initialization of the local repository, Git
- just learned to respect `init.defaultBranch` to choose a different main
+ As part of the implicit initialization of the local repository, Git just
+ learned to respect `init.defaultBranch` to choose a different initial
branch name. We now really want that branch name to be used as a
fall-back.
- At the same time, we also want to make sure that `core.mainBranch` is
- set correctly, reflecting the name of the main branch. In case we detect
- a main branch, we do have to do that explicitly, otherwise `init_db()`
- will already have done that for us.
-
Signed-off-by: Johannes Schindelin <[email protected]>
## Documentation/config/init.txt ##
@@ Documentation/config/init.txt: init.templateDir::
+ a new repository or when cloning an empty repository.
## builtin/clone.c ##
-@@ builtin/clone.c: static void update_head(const struct ref *our, const struct ref *remote,
- /* Local default branch link */
- if (create_symref("HEAD", our->name, NULL) < 0)
- die(_("unable to update HEAD"));
-+ git_config_set("core.mainbranch", head);
- if (!option_bare) {
- update_ref(msg, "HEAD", &our->old_oid, NULL, 0,
- UPDATE_REFS_DIE_ON_ERR);
@@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
remote_head_points_at = NULL;
remote_head = NULL;
@@ builtin/clone.c: int cmd_clone(int argc, const char **argv, const char *prefix)
- install_branch_config(0, "master", option_origin,
- "refs/heads/master");
+ if (!option_bare) {
-+ char *main_branch =
-+ git_main_branch_name(MAIN_BRANCH_FULL_NAME);
-+ const char *nick;
++ const char *branch = git_default_branch_name();
++ char *ref = xstrfmt("refs/heads/%s", branch);
+
-+ if (!skip_prefix(main_branch, "refs/heads/", &nick))
-+ BUG("unexpected default branch '%s'",
-+ main_branch);
-+ install_branch_config(0, nick, option_origin,
-+ main_branch);
-+ free(main_branch);
++ install_branch_config(0, branch, option_origin, ref);
++ free(ref);
+ }
}
@@ t/t5606-clone-options.sh: test_expect_success 'redirected clone -v does show pro
'
-+test_expect_success 'chooses correct default main branch name' '
++test_expect_success 'chooses correct default initial branch name' '
+ git init --bare empty &&
+ git -c init.defaultBranch=up clone empty whats-up &&
+ test refs/heads/up = $(git -C whats-up symbolic-ref HEAD) &&
-+ test up = $(git -C whats-up config core.mainBranch) &&
+ test refs/heads/up = $(git -C whats-up config branch.up.merge)
+'
+
-+test_expect_success 'guesses main branch name correctly' '
-+ git init --main-branch=guess main-branch &&
-+ test_commit -C main-branch no-spoilers &&
-+ git -C main-branch branch abc guess &&
-+ git clone main-branch is-it &&
-+ test guess = $(git -C is-it config core.mainBranch) &&
++test_expect_success 'guesses initial branch name correctly' '
++ git init --initial-branch=guess initial-branch &&
++ test_commit -C initial-branch no-spoilers &&
++ git -C initial-branch branch abc guess &&
++ git clone initial-branch is-it &&
+ test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
+'
+ 10: 59b8f4cfbb ! 7: 00a1b281e5 remote: learn about the possibly-overridden default main branch name
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- remote: learn about the possibly-overridden default main branch name
+ remote: use the configured default branch name when appropriate
When guessing the default branch name of a remote, and there are no refs to guess from, we want to go with the preference specified by the user
- for the fall-back, i.e. the default name to be used for the main branch
- of new repositories (because as far as the user is concerned, a remote
- that has no branches yet is a new repository).
+ for the fall-back, i.e. the default name to be used for the initial
+ branch of new repositories (because as far as the user is concerned, a
+ remote that has no branches yet is a new repository).
+
+ At the same time, when talking to an older Git server that does not
+ report a symref for HEAD (but instead reports a commit hash), let's
+ try to guess the configured default branch name first. If it does not
+ match the reported commit hash, let's fall back to master as before.
## remote.c ##
-@@ remote.c: static void read_remotes_file(struct remote *remote) -
- static void read_branches_file(struct remote *remote)
- {
-- char *frag;
-+ char *frag, *main_branch = NULL;
- struct strbuf buf = STRBUF_INIT;
- FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r");
-
@@ remote.c: static void read_branches_file(struct remote *remote)
/*
@@ remote.c: static void read_branches_file(struct remote *remote)
*(frag++) = '\0';
else
- frag = "master";
-+ frag = main_branch = git_main_branch_name(MAIN_BRANCH_FOR_INIT);
++ frag = (char *)git_default_branch_name();
add_url_alias(remote, strbuf_detach(&buf, NULL)); strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
-@@ remote.c: static void read_branches_file(struct remote *remote)
- strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
- refspec_append(&remote->push, buf.buf);
- remote->fetch_tags = 1; /* always auto-follow */
-+ free(main_branch);
- strbuf_release(&buf);
- }
-
@@ remote.c: struct ref *guess_remote_head(const struct ref *head,
if (head->symref)
return copy_ref(find_ref_by_name(refs, head->symref));
- /* If refs/heads/master could be right, it is. */
-+ /* If a remote branch exists with the main branch name, let's use it. */
++ /* If a remote branch exists with the default branch name, let's use it. */
if (!all) {
-- r = find_ref_by_name(refs, "refs/heads/master");
-+ char *name = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
-+ MAIN_BRANCH_FOR_INIT);
++ char *ref = xstrfmt("refs/heads/%s", git_default_branch_name());
++
++ r = find_ref_by_name(refs, ref);
++ free(ref);
++ if (r && oideq(&r->old_oid, &head->old_oid))
++ return copy_ref(r);
+
-+ r = find_ref_by_name(refs, name);
-+ free(name);
++ /* Fall back to the hard-coded historical default */
+ r = find_ref_by_name(refs, "refs/heads/master");
if (r && oideq(&r->old_oid, &head->old_oid))
return copy_ref(r);
- }
## t/t5606-clone-options.sh ##
-@@ t/t5606-clone-options.sh: test_expect_success 'guesses main branch name correctly' '
- git -C main-branch branch abc guess &&
- git clone main-branch is-it &&
- test guess = $(git -C is-it config core.mainBranch) &&
+@@ t/t5606-clone-options.sh: test_expect_success 'guesses initial branch name correctly' '
+ test_commit -C initial-branch no-spoilers &&
+ git -C initial-branch branch abc guess &&
+ git clone initial-branch is-it &&
- test refs/heads/guess = $(git -C is-it symbolic-ref HEAD)
+ test refs/heads/guess = $(git -C is-it symbolic-ref HEAD) &&
+
+ git -c init.defaultBranch=none init --bare no-head &&
-+ git -C main-branch push ../no-head guess abc &&
++ git -C initial-branch push ../no-head guess abc &&
+ git clone no-head is-it2 &&
+ test_must_fail git -C is-it2 symbolic-ref refs/remotes/origin/HEAD &&
+ git -C no-head update-ref --no-deref HEAD refs/heads/guess &&
12: e09f857f06 ! 8: 1aa0e63785 testsvn: respect init.defaultBranch
@@ Metadata
## Commit message ##
testsvn: respect init.defaultBranch
- The default name of the main branch in new repositories can now be
+ The default name of the initial branch in new repositories can now be
configured. The testsvn remote helper translates the remote Subversion repository's branch name trunk to the hard-coded name master.
- Clearly, the intention was to make the name align with Git's detaults.
+ Clearly, the intention was to make the name align with Git's defaults.
So while we are not talking about a newly-created repository in the
- testsvn context, it _still_ makes sense to use the overridden default
- name for the main branch whenever users configured it.
+ testsvn context, it is a newly-created _Git_ repository, si it _still_
+ makes sense to use the overridden default name for the initial branch
+ whenever users configured it.
@@ remote-testsvn.c: int cmd_main(int argc, const char **argv)
return 1;
}
-+ remote_ref = git_main_branch_name(MAIN_BRANCH_FULL_NAME |
-+ MAIN_BRANCH_FOR_INIT);
-+ if (!skip_prefix(remote_ref, "refs/heads/", &remote_ref_short))
-+ BUG("unexpected remote_ref '%s'", remote_ref);
++ remote_ref_short = git_default_branch_name();
++ remote_ref = xstrfmt("refs/heads/%s", remote_ref_short);
+
remote = remote_get(argv[1]);
url_in = (argc == 3) ? argv[2] : remote->url[0];
@@ t/t9020-remote-svn.sh: test_expect_success REMOTE_SVN 'incremental imports must
test_cmp master.good .git/refs/remotes/svnsim/master
'
-+test_expect_success REMOTE_SVN 'respects configured default main branch' ' ++test_expect_success REMOTE_SVN 'respects configured default initial branch' '
+ git -c init.defaultBranch=trunk remote add -f trunk \
+ "testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" &&
+ git rev-parse --verify refs/remotes/trunk/trunk
Signature · 1 line
gitgitgadget
PATCH v3 1/8 fmt-merge-msg: stop treating `master` specially
From: Johannes Schindelin <[email protected]>
In the context of many projects renaming their primary branch names away from master, Git wants to stop treating the master branch specially.
Let's start with git fmt-merge-msg.
--- fmt-merge-msg.c | 5 +- t/t1507-rev-parse-upstream.sh | 2 +- t/t4013-diff-various.sh | 4 +- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- ...--patch-with-stat_--summary_master_--_dir_ | 2 +- t/t4013/diff.log_--patch-with-stat_master | 2 +- .../diff.log_--patch-with-stat_master_--_dir_ | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ..._--root_--patch-with-stat_--summary_master | 2 +- .../diff.log_--root_--patch-with-stat_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4013/diff.log_--root_-p_master | 2 +- t/t4013/diff.log_--root_master | 2 +- t/t4013/diff.log_-m_-p_--first-parent_master | 2 +- t/t4013/diff.log_-m_-p_master | 4 +- t/t4013/diff.log_-p_--first-parent_master | 2 +- t/t4013/diff.log_-p_master | 2 +- t/t4013/diff.log_master | 2 +- t/t4013/diff.show_--first-parent_master | 2 +- t/t4013/diff.show_-c_master | 2 +- t/t4013/diff.show_-m_master | 4 +- t/t4013/diff.show_master | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4202-log.sh | 72 +++++++++---------- t/t6200-fmt-merge-msg.sh | 36 +++++----- t/t7600-merge.sh | 14 ++-- t/t7608-merge-messages.sh | 10 +-- 29 files changed, 94 insertions(+), 97 deletions(-)
fmt-merge-msg.c +1 -4
@@ -451,10 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } -if (!strcmp ("master" , current_branch)) -strbuf_addch (out,'\n' ); -else -strbuf_addf (out," into %s\n" , current_branch); +strbuf_addf (out," into %s\n" , current_branch); } static void fmt_tag_signature(struct strbuf *tagbuf,
t/t1507-rev-parse-upstream.sh +1 -1
@@ -137,7 +137,7 @@ test_expect_success 'merge my-side@{u} records the correct name' ' git branch -t new my-side@{u} && git merge -s ours new@{u} && git show -s --pretty=tformat:%s >actual && - echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect && + echo "Merge remote-tracking branch ${SQ}origin/side${SQ} into master" >expect && test_cmp expect actual ) '
t/t4013-diff-various.sh +2 -2
@@ -117,12 +117,12 @@ test_expect_success setup ' : <<\EOF ! [initial] Initial - * [master] Merge branch 'side' + * [master] Merge branch 'side' into master ! [rearrange] Rearranged lines in dir/sub ! [side] Side ---- + [rearrange] Rearranged lines in dir/sub - - [master] Merge branch 'side' + - [master] Merge branch 'side' into master * + [side] Side * [master^] Third * [master~2] Second
t/t4013/diff.log_--decorate=full_--all +1 -1
@@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (refs/heads/side) Author: A U Thor <[email protected]>
t/t4013/diff.log_--decorate_--all +1 -1
@@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (side) Author: A U Thor <[email protected]>
t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--patch-with-stat_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--patch-with-stat_master_--_dir_ +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master dir/sub | 2 ++ file0 | 3 +++
t/t4013/diff.log_--root_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--root_--patch-with-stat_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master dir/sub | 2 ++ file0 | 3 +++
t/t4013/diff.log_--root_-p_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--root_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_-m_-p_--first-parent_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644
t/t4013/diff.log_-m_-p_master +2 -2
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644
@@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index 7289e35..992913c 100644
t/t4013/diff.log_-p_--first-parent_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Author: A U Thor <[email protected]>
t/t4013/diff.log_-p_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.show_--first-parent_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644
t/t4013/diff.show_-c_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --combined dir/sub index cead32e,7289e35..992913c
t/t4013/diff.show_-m_master +2 -2
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644
@@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index 7289e35..992913c 100644
t/t4013/diff.show_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --cc dir/sub index cead32e,7289e35..992913c
t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master dir/sub | 2 ++ file0 | 3 +++
t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master dir/sub | 2 ++ file0 | 3 +++
t/t4202-log.sh +36 -36
215 lines not on this page · raw message
t/t6200-fmt-merge-msg.sh +18 -18
@@ -79,7 +79,7 @@ test_expect_success GPG 'set up a signed tag' ' ' test_expect_success 'message for merging local branch' ' - echo "Merge branch ${apos}left${apos}" >expected && + echo "Merge branch ${apos}left${apos} into master" >expected && git checkout master && git fetch . left &&
@@ -107,7 +107,7 @@ test_expect_success GPG 'message for merging local tag signed by unknown key' ' ' test_expect_success 'message for merging external branch' ' - echo "Merge branch ${apos}left${apos} of $(pwd)" >expected && + echo "Merge branch ${apos}left${apos} of $(pwd) into master" >expected && git checkout master && git fetch "$(pwd)" left &&
@@ -118,7 +118,7 @@ test_expect_success 'message for merging external branch' ' test_expect_success '[merge] summary/log configuration' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -160,7 +160,7 @@ test_expect_success 'setup FETCH_HEAD' ' test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -177,7 +177,7 @@ test_expect_success 'merge.log=3 limits shortlog length' ' test_expect_success 'merge.log=5 shows all 5 commits' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -195,7 +195,7 @@ test_expect_success 'merge.log=5 shows all 5 commits' ' test_expect_success '--log=5 with custom comment character' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master x By Another Author (3) and A U Thor (2) x Via Another Committer
@@ -212,14 +212,14 @@ test_expect_success '--log=5 with custom comment character' ' ' test_expect_success 'merge.log=0 disables shortlog' ' - echo "Merge branch ${apos}left${apos}" >expected && + echo "Merge branch ${apos}left${apos} into master" >expected && git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success '--log=3 limits shortlog length' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -236,7 +236,7 @@ test_expect_success '--log=3 limits shortlog length' ' test_expect_success '--log=5 shows all 5 commits' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -253,13 +253,13 @@ test_expect_success '--log=5 shows all 5 commits' ' ' test_expect_success '--no-log disables shortlog' ' - echo "Merge branch ${apos}left${apos}" >expected && + echo "Merge branch ${apos}left${apos} into master" >expected && git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success '--log=0 disables shortlog' ' - echo "Merge branch ${apos}left${apos}" >expected && + echo "Merge branch ${apos}left${apos} into master" >expected && git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual '
@@ -300,7 +300,7 @@ test_expect_success 'fmt-merge-msg -m' ' test_expect_success 'setup: expected shortlog for two branches' ' cat >expected <<-EOF - Merge branches ${apos}left${apos} and ${apos}right${apos} + Merge branches ${apos}left${apos} and ${apos}right${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -397,7 +397,7 @@ test_expect_success 'merge-msg with nothing to merge' ' test_expect_success 'merge-msg tag' ' cat >expected <<-EOF && - Merge tag ${apos}tag-r3${apos} + Merge tag ${apos}tag-r3${apos} into master * tag ${apos}tag-r3${apos}: Right #3
@@ -418,7 +418,7 @@ test_expect_success 'merge-msg tag' ' test_expect_success 'merge-msg two tags' ' cat >expected <<-EOF && - Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} + Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} into master * tag ${apos}tag-r3${apos}: Right #3
@@ -448,7 +448,7 @@ test_expect_success 'merge-msg two tags' ' test_expect_success 'merge-msg tag and branch' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} + Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} into master * tag ${apos}tag-r3${apos}: Right #3
@@ -479,7 +479,7 @@ test_expect_success 'merge-msg tag and branch' ' test_expect_success 'merge-msg lots of commits' ' { cat <<-EOF && - Merge branch ${apos}long${apos} + Merge branch ${apos}long${apos} into master * long: (35 commits) EOF
@@ -516,7 +516,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git fmt-merge-msg <.git/FETCH_HEAD >actual && { cat <<-\EOF - Merge tag '\''annote'\'' + Merge tag '\''annote'\'' into master An annotated one
@@ -531,7 +531,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git merge --no-commit --no-ff $annote && { cat <<-EOF - Merge tag '\''$annote'\'' + Merge tag '\''$annote'\'' into master An annotated one
t/t7600-merge.sh +7 -7
@@ -14,9 +14,9 @@ Testing basic merge operations/option parsing. ! [c4] c4 ! [c5] c5 ! [c6] c6 - * [master] Merge commit 'c1' + * [master] Merge commit 'c1' into master -------- - - [master] Merge commit 'c1' + - [master] Merge commit 'c1' into master + * [c1] commit 1 + [c6] c6 + [c5] c5
@@ -44,8 +44,8 @@ test_write_lines '1 X' 2 '3 X' 4 '5 X' 6 7 8 '9 X' >result.1-3-5-9 test_write_lines 1 2 3 4 5 6 7 8 '9 Z' >result.9z create_merge_msgs () { - echo "Merge tag 'c2'" >msg.1-5 && - echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 && + echo "Merge tag 'c2' into master" >msg.1-5 && + echo "Merge tags 'c2' and 'c3' into master" >msg.1-5-9 && { echo "Squashed commit of the following:" && echo &&
@@ -258,7 +258,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' ' git commit --no-edit -a && cat >expect <<-\EOF && - Merge tag '"'"'c7'"'"' + Merge tag '"'"'c7'"'"' into master # ------------------------ >8 ------------------------ # Do not modify or remove the line above.
@@ -808,10 +808,10 @@ test_expect_success 'merge with conflicted --autostash changes' ' ' cat >expected.branch <<\EOF -Merge branch 'c5-branch' (early part) +Merge branch 'c5-branch' (early part) into master EOF cat >expected.tag <<\EOF -Merge commit 'c5~1' +Merge commit 'c5~1' into master EOF test_expect_success 'merge early part of c2' '
t/t7608-merge-messages.sh +5 -5
@@ -16,7 +16,7 @@ test_expect_success 'merge local branch' ' git checkout master && test_commit master-2 && git merge local-branch && - check_oneline "Merge branch Qlocal-branchQ" + check_oneline "Merge branch Qlocal-branchQ into master" ' test_expect_success 'merge octopus branches' '
@@ -26,7 +26,7 @@ test_expect_success 'merge octopus branches' ' test_commit octopus-2 && git checkout master && git merge octopus-a octopus-b && - check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ" + check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ into master" ' test_expect_success 'merge tag' '
@@ -35,7 +35,7 @@ test_expect_success 'merge tag' ' git checkout master && test_commit master-3 && git merge tag-1 && - check_oneline "Merge tag Qtag-1Q" + check_oneline "Merge tag Qtag-1Q into master" ' test_expect_success 'ambiguous tag' '
@@ -44,7 +44,7 @@ test_expect_success 'ambiguous tag' ' git checkout master && test_commit master-4 && git merge ambiguous && - check_oneline "Merge tag QambiguousQ" + check_oneline "Merge tag QambiguousQ into master" ' test_expect_success 'remote-tracking branch' '
@@ -54,7 +54,7 @@ test_expect_success 'remote-tracking branch' ' git checkout master && test_commit master-5 && git merge origin/master && - check_oneline "Merge remote-tracking branch Qorigin/masterQ" + check_oneline "Merge remote-tracking branch Qorigin/masterQ into master" ' test_done
Signature · 1 line
gitgitgadget
Re: [PATCH v3 1/8] fmt-merge-msg: stop treating `master` specially
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 31 lines · writes:
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.Let's start with
git fmt-merge-msg.Signed-off-by Johannes Schindelin <[email protected]>--- fmt-merge-msg.c | 5 +- t/t1507-rev-parse-upstream.sh | 2 +- t/t4013-diff-various.sh | 4 +- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- ...--patch-with-stat_--summary_master_--_dir_ | 2 +- t/t4013/diff.log_--patch-with-stat_master | 2 +- .../diff.log_--patch-with-stat_master_--_dir_ | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ..._--root_--patch-with-stat_--summary_master | 2 +- .../diff.log_--root_--patch-with-stat_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4013/diff.log_--root_-p_master | 2 +- t/t4013/diff.log_--root_master | 2 +- t/t4013/diff.log_-m_-p_--first-parent_master | 2 +- t/t4013/diff.log_-m_-p_master | 4 +- t/t4013/diff.log_-p_--first-parent_master | 2 +- t/t4013/diff.log_-p_master | 2 +- t/t4013/diff.log_master | 2 +- t/t4013/diff.show_--first-parent_master | 2 +- t/t4013/diff.show_-c_master | 2 +- t/t4013/diff.show_-m_master | 4 +-
Quoted 8 lines
t/t4013/diff.show_master | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4202-log.sh | 72 +++++++++---------- t/t6200-fmt-merge-msg.sh | 36 +++++----- t/t7600-merge.sh | 14 ++-- t/t7608-merge-messages.sh | 10 +-- 29 files changed, 94 insertions(+), 97 deletions(-)
This must have been tedious as the tests with merge commits are all over the place (I know updating t4013 would not have been too much of the work as it has its own self-update knob, but it still is a lot of work to verify that the changes make sense).
Thanks.
Re: [PATCH v3 1/8] fmt-merge-msg: stop treating `master` specially
Hi Junio,
Quoted 43 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 31 lines · writes:
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.Let's start with
git fmt-merge-msg.Signed-off-by Johannes Schindelin <[email protected]>--- fmt-merge-msg.c | 5 +- t/t1507-rev-parse-upstream.sh | 2 +- t/t4013-diff-various.sh | 4 +- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- ...--patch-with-stat_--summary_master_--_dir_ | 2 +- t/t4013/diff.log_--patch-with-stat_master | 2 +- .../diff.log_--patch-with-stat_master_--_dir_ | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ..._--root_--patch-with-stat_--summary_master | 2 +- .../diff.log_--root_--patch-with-stat_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4013/diff.log_--root_-p_master | 2 +- t/t4013/diff.log_--root_master | 2 +- t/t4013/diff.log_-m_-p_--first-parent_master | 2 +- t/t4013/diff.log_-m_-p_master | 4 +- t/t4013/diff.log_-p_--first-parent_master | 2 +- t/t4013/diff.log_-p_master | 2 +- t/t4013/diff.log_master | 2 +- t/t4013/diff.show_--first-parent_master | 2 +- t/t4013/diff.show_-c_master | 2 +- t/t4013/diff.show_-m_master | 4 +-Quoted 8 lines
t/t4013/diff.show_master | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4202-log.sh | 72 +++++++++---------- t/t6200-fmt-merge-msg.sh | 36 +++++----- t/t7600-merge.sh | 14 ++-- t/t7608-merge-messages.sh | 10 +-- 29 files changed, 94 insertions(+), 97 deletions(-)
Quoted 4 lines
This must have been tedious as the tests with merge commits are all over the place (I know updating t4013 would not have been too much of the work as it has its own self-update knob, but it still is a lot of work to verify that the changes make sense).
I missed the self-update knob, but in any case, I would not have used it, anyway, to make sure that I do look closely at all the sites.
Ciao,
Dscho
PATCH v3 2/8 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 specific 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 specific branch" actual +' + test_expect_success 'push ambiguously named branch with upstream, matching and simple' ' git checkout -b ambiguous && test_config branch.ambiguous.remote parent1 &&
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 specific branch.\n" ));return 0 ; }
Signature · 1 line
gitgitgadget
Re: [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch
"Johannes Schindelin via GitGitGadget" <[email protected]>
transport-helper.c static int push_refs(struct transport *transport, · line 1049
Quoted 6 lines · writes:
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 specific branch.\n" ));
Hmph, not just "specify a branch."? Maybe it is just me, but "specify a specific branch" did not roll well on my tongue.
Re: [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch
Hi Junio,
Quoted 12 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
transport-helper.c static int push_refs(struct transport *transport, · line 1049
Quoted 6 lines · writes:
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 specific branch.\n" ));Hmph, not just "specify a branch."? Maybe it is just me, but "specify a specific branch" did not roll well on my tongue.
Oh well. "Perhaps you should specify a branch" sounded too judgmental to me, but I'm not a native speaker, so I simply removed the word "specific".
Ciao,
Dscho
Re: [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch
Quoted 17 lines · Johannes Schindelin
Hi Junio,
Quoted 12 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
transport-helper.c static int push_refs(struct transport *transport, · line 1049
Quoted 6 lines · writes:
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 specific branch.\n" ));Hmph, not just "specify a branch."? Maybe it is just me, but "specify a specific branch" did not roll well on my tongue.
Quoted 2 lines
Oh well. "Perhaps you should specify a branch" sounded too judgmental to me, but I'm not a native speaker, so I simply removed the word "specific".
I'm not either. Note that when I say "maybe it is just me", I usually am not asking to change anything.
Re: [PATCH v3 2/8] send-pack/transport-helper: avoid mentioning a particular branch
Hi Junio,
Quoted 17 lines · Junio C Hamano
Quoted 15 lines · Johannes Schindelin
Quoted 12 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
transport-helper.c static int push_refs(struct transport *transport, · line 1049
Quoted 6 lines · writes:
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 specific branch.\n" ));Hmph, not just "specify a branch."? Maybe it is just me, but "specify a specific branch" did not roll well on my tongue.
Quoted 4 lines
Quoted 2 lines
Oh well. "Perhaps you should specify a branch" sounded too judgmental to me, but I'm not a native speaker, so I simply removed the word "specific".
I'm not either.
We should start a society or something ;-)
Quoted 2 lines
Note that when I say "maybe it is just me", I usually am not asking to change anything.
Of course! In this instance, your suggestion made me think and prefer the non-repetitive version (because let's face it, taking out that word did not make it any more or less judgemental).
Ciao,
Dscho
PATCH v3 3/8 submodule: use a better fall-back 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 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.
--- Documentation/git-submodule.txt | 4 ++-- builtin/submodule--helper.c | 2 +- t/t7406-submodule-update.sh | 16 ++++++++++++++++ t/t7419-submodule-set-branch.sh | 7 +++++-- 4 files changed, 24 insertions(+), 5 deletions(-)
Documentation/git-submodule.txt +2 -2
@@ -284,7 +284,7 @@ OPTIONS `.gitmodules` for `update --remote`. A special value of `.` is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository. If the - option is not specified, it defaults to 'master'. + option is not specified, it defaults to 'HEAD'. -f:: --force::
@@ -322,7 +322,7 @@ OPTIONS the superproject's recorded SHA-1 to update the submodule, use the status of the submodule's remote-tracking branch. The remote used is branch's remote (`branch.<name>.remote`), defaulting to `origin`. - The remote branch used defaults to `master`, but the branch name may + The remote branch used defaults to `HEAD`, but the branch name may be overridden by setting the `submodule.<name>.branch` option in either `.gitmodules` or `.git/config` (with `.git/config` taking precedence).
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 v3 3/8] submodule: use a better fall-back for missing remote.<name>.branch
Hi Dscho,
Quoted 8 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
When
remote.<name>.branchis not configured,git submodule updatecurrently falls back to using the branch namemaster. A much better idea, however, is to useHEAD: on all Git servers running reasonably recent Git versions, the symrefHEADpoints to the main branch.
To be pedantic, it is up to the maintainer/developers to make sure that HEAD on the canonic repository indeed points to the branch that is considered the 'main' branch of the project; the Git version does not really matter IMO... I've seen plenty of repos at work that have HEAD pointing to master but master is not used, or not anymore...
Quoted 8 lines
Note: t7419 demonstrates that there _might_ be use cases out there that _expect_
git submodule update --remoteto update submodules to the remotemasterbranch even if the remoteHEADpoints to another branch. Arguably, this patch makes the behavior more intuitive, but there is a slight possibility that this might cause regressions in obscure setups.Signed-off-by Johannes Schindelin <[email protected]>
I think that's an excellent idea. However I'd be more explicit in the commit message title:
submodule: fall back to remote's HEAD for missing remote.<name>.branch
meta comment: I never know where is the best place to make suggestions about changing the commit message title, since I can't quote it in my replies!
Quoted 6 lines
---
Documentation/git-submodule.txt | 4 ++-- builtin/submodule--helper.c | 2 +- t/t7406-submodule-update.sh | 16 ++++++++++++++++ t/t7419-submodule-set-branch.sh | 7 +++++-- 4 files changed, 24 insertions(+), 5 deletions(-)
I think Documentation/gitmodules.txt (submodule.<name>.branch header)
should also be changed to reflect the behaviour change:
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.
Documentation/git-submodule.txt OPTIONS · line 287
Quoted 10 lines
Documentation/git-submodule.txt +1
-1@@ -284,7 +284,7 @@ OPTIONS `.gitmodules` for `update --remote`. A special value of `.` is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository. If the - option is not specified, it defaults to 'master'. + option is not specified, it defaults to 'HEAD'.
Just to be extra clear (it's easy to get confused with submodules!) I'd say explicitly:
If the option is not specified, it defaults to the remote 'HEAD'.
Documentation/git-submodule.txt OPTIONS · line 325
Quoted 9 lines
Documentation/git-submodule.txt +1
-3-f:: --force::@@ -322,7 +322,7 @@ OPTIONS the superproject's recorded SHA-1 to update the submodule, use the status of the submodule's remote-tracking branch. The remote used is branch's remote (`branch.<name>.remote`), defaulting to `origin`. - The remote branch used defaults to `master`, but the branch name may + The remote branch used defaults to `HEAD`, but the branch name may
Same thing here:
The remote branch used defaults to the remote HEAD.
Documentation/git-submodule.txt OPTIONS · line 328
Quoted 3 lines
Documentation/git-submodule.txt +0
-0be overridden by setting the `submodule.<name>.branch` option in either `.gitmodules` or `.git/config` (with `.git/config` taking precedence).
Also, you seem to have missed the master reference in the description of the 'set-branch' subcommand. Something like this would do, I think:
Documentation/git-submodule.txt +1 -1
@@ -183,7 +183,7 @@ set-branch (-d|--default) [--] <path>:: Sets the default remote tracking branch for the submodule. The `--branch` option allows the remote branch to be specified. The `--default` option removes the submodule.<name>.branch configuration - key, which causes the tracking branch to default to 'master'. + key, which causes the tracking branch to default to the remote 'HEAD'. set-url [--] <path> <newurl>:: Sets the URL of the specified submodule to <newurl>. Then, it will
The rest of the patch looks good.
Cheers,
Philippe.
Re: [PATCH v3 3/8] submodule: use a better fall-back for missing remote.<name>.branch
Hi Philippe,
Quoted 9 lines · Philippe Blain
Quoted 8 lines · Johannes Schindelin via GitGitGadget
From: Johannes Schindelin <[email protected]>
When
remote.<name>.branchis not configured,git submodule updatecurrently falls back to using the branch namemaster. A much better idea, however, is to useHEAD: on all Git servers running reasonably recent Git versions, the symrefHEADpoints to the main branch.
Quoted 5 lines
To be pedantic, it is up to the maintainer/developers to make sure that HEAD on the canonic repository indeed points to the branch that is considered the 'main' branch of the project; the Git version does not really matter IMO... I've seen plenty of repos at work that have HEAD pointing to
masterbutmasteris not used, or not anymore...
Oh, but in this case, my main concern was servers that are so old that HEAD is not a symref, in which case it can be a bit tricky to figure out the default branch.
In any case, I feel this is such a minor point that I don't really want to spend a lot of time on this paragraph.
Quoted 7 lines
Quoted 7 lines
Note: t7419 demonstrates that there _might_ be use cases out there that _expect_
git submodule update --remoteto update submodules to the remotemasterbranch even if the remoteHEADpoints 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.
Quoted 6 lines
Quoted 1 line
Signed-off-by Johannes Schindelin <[email protected]>I think that's an excellent idea. However I'd be more explicit in the commit message title:
submodule: fall back to remote's HEAD for missing remote.<name>.branch
Great!
Quoted 3 lines
meta comment: I never know where is the best place to make suggestions about changing the commit message title, since I can't quote it in my replies!
True. You could copy it, but that's not the same.
Quoted 16 lines
Quoted 6 lines
---
Documentation/git-submodule.txt | 4 ++-- builtin/submodule--helper.c | 2 +- t/t7406-submodule-update.sh | 16 ++++++++++++++++ t/t7419-submodule-set-branch.sh | 7 +++++-- 4 files changed, 24 insertions(+), 5 deletions(-)I think
Documentation/gitmodules.txt(submodule.<name>.branchheader)
should also be changed to reflect the behaviour change:Documentation/gitmodules.txt +0
-0@@ -49,9 +49,9 @@ submodule.<name>.update::
Documentation/gitmodules.txt submodule.<name>.update:: · line 56
Quoted 10 lines
Documentation/gitmodules.txt +3
-3submodule.<name>.branch:: A remote branch name for tracking updates in the upstream submodule. - If the option is not specified, it defaults to 'master'. A special - value of `.` is used to indicate that the name of the branch in the - submodule should be the same name as the current branch in the + If the option is not specified, it defaults to the remote 'HEAD'. + A special value of `.` is used to indicate that the name of the branch + in the submodule should be the same name as the current branch in the current repository. See the `--remote` documentation in linkgit:git-submodule[1] for details.
Excellent, I used that verbatim. Thank you!
Quoted 14 lines
Documentation/git-submodule.txt OPTIONS · line 287
Quoted 10 lines
Documentation/git-submodule.txt +1
-1@@ -284,7 +284,7 @@ OPTIONS `.gitmodules` for `update --remote`. A special value of `.` is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository. If the - option is not specified, it defaults to 'master'. + option is not specified, it defaults to 'HEAD'.Just to be extra clear (it's easy to get confused with submodules!) I'd say explicitly:
Quoted 1 line
If the option is not specified, it defaults to the remote 'HEAD'.
Good idea. I incorporated that, too.
Quoted 11 lines
Documentation/git-submodule.txt OPTIONS · line 325
Quoted 8 lines
Documentation/git-submodule.txt +1
-3-f:: --force::@@ -322,7 +322,7 @@ OPTIONS the superproject's recorded SHA-1 to update the submodule, use the status of the submodule's remote-tracking branch. The remote used is branch's remote (`branch.<name>.remote`), defaulting to `origin`. - The remote branch used defaults to `master`, but the branch name may + The remote branch used defaults to `HEAD`, but the branch name maySame thing here:
Quoted 1 line
The remote branch used defaults to the remote
HEAD.
And that.
Quoted 12 lines
Documentation/git-submodule.txt OPTIONS · line 328
Quoted 3 lines
Documentation/git-submodule.txt +0
-0be overridden by setting the `submodule.<name>.branch` option in either `.gitmodules` or `.git/config` (with `.git/config` taking precedence).Also, you seem to have missed the
masterreference in the description of the 'set-branch' subcommand. Something like this would do, I think:Documentation/git-submodule.txt +0
-0
Documentation/git-submodule.txt set-branch (-d|--default) [--] <path>:: · line 189
Quoted 8 lines
Documentation/git-submodule.txt +1
-1@@ -183,7 +183,7 @@ set-branch (-d|--default) [--] <path>:: Sets the default remote tracking branch for the submodule. The `--branch` option allows the remote branch to be specified. The `--default` option removes the submodule.<name>.branch configuration - key, which causes the tracking branch to default to 'master'. + key, which causes the tracking branch to default to the remote 'HEAD'. set-url [--] <path> <newurl>:: Sets the URL of the specified submodule to <newurl>. Then, it will
And that.
Quoted 1 line
The rest of the patch looks good.
Awesome. Thank you for helping me improve this patch series!
Ciao,
Dscho
PATCH v3 4/8 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 | 34 +++++++++++++++++++++++++++------- cache.h | 2 +- t/t0001-init.sh | 13 +++++++++++++ 5 files changed, 50 insertions(+), 9 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 -7
@@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)static int create_default_files (const char *template_path,const char *original_git_dir, +const char *initial_branch,const struct repository_format *fmt) {struct stat st1;
@@ -258,16 +259,29 @@ static int create_default_files(const char *template_path,die ("failed to set up refs db: %s" , err.buf);/* -* Create the default symlink from ".git/HEAD" to the "master" -* branch, if it does not exist yet. +* Create the default symlink from ".git/HEAD" to the default +* branch name, if it does not exist yet. */ path =git_path_buf (&buf,"HEAD" ); reinit = (!access (path,R_OK ) ||readlink (path, junk,sizeof (junk)-1 ) !=-1 );if (!reinit) { -if (create_symref ("HEAD" ,"refs/heads/master" ,NULL ) <0 ) +char *ref; + +if (!initial_branch) + initial_branch ="master" ; + + ref =xstrfmt ("refs/heads/%s" , initial_branch); +if (check_refname_format (ref,0 ) <0 ) +die (_ ("invalid initial branch name: '%s'" ), + initial_branch); + +if (create_symref ("HEAD" , ref,NULL ) <0 )exit (1 ); - } +free (ref); + }else if (initial_branch) +warning (_ ("re-init: ignoring --initial-branch=%s" ), + initial_branch);initialize_repository_version (fmt->hash_algo);
@@ -383,7 +397,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash }int init_db (const char *git_dir,const char *real_git_dir, -const char *template_dir,int hash,unsigned int flags) +const char *template_dir,int hash,const char *initial_branch, +unsigned int flags) {int reinit;int exist_ok = flags &INIT_DB_EXIST_OK ;
@@ -425,7 +440,8 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); - reinit =create_default_files (template_dir, original_git_dir, &repo_fmt); + reinit =create_default_files (template_dir, original_git_dir, + initial_branch, &repo_fmt);create_object_directory ();
@@ -528,6 +544,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)const char *template_dir =NULL ;unsigned int flags =0 ;const char *object_format =NULL ; +const char *initial_branch =NULL ;int hash_algo =GIT_HASH_UNKNOWN ;const struct option init_db_options[] = { OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ -541,6 +558,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)OPT_BIT ('q' ,"quiet" , &flags,N_ ("be quiet" ),INIT_DB_QUIET ),OPT_STRING (0 ,"separate-git-dir" , &real_git_dir,N_ ("gitdir" ),N_ ("separate git dir from working tree" )), +OPT_STRING ('b' ,"initial-branch" , &initial_branch,N_ ("name" ), +N_ ("override the name of the initial branch" )),OPT_STRING (0 ,"object-format" , &object_format,N_ ("hash" ),N_ ("specify the hash algorithm to use" )),OPT_END ()
@@ -652,5 +671,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)UNLEAK (work_tree); flags |=INIT_DB_EXIST_OK ; -return init_db (git_dir, real_git_dir, template_dir, hash_algo, flags); +return init_db (git_dir, real_git_dir, template_dir, hash_algo, + initial_branch, flags); }
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 "ignoring --initial-branch" err && + git -C initial-branch-option symbolic-ref HEAD >actual && + grep hello actual +' + test_done
Signature · 1 line
gitgitgadget
Re: [PATCH v3 4/8] init: allow specifying the initial branch name for the new repository
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 3 lines · writes:
[verse]
'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
[--separate-git-dir <git dir>] [--object-format=<format]
Completely offtopic. We lack the closing ket> here.
Documentation/git-init.txt repository. · line 75
Quoted 13 lines
Documentation/git-init.txt +6
-0+ [-b <branch-name> | --initial-branch=<branch-name>] [--shared[=<permissions>]] [directory]@@ -67,6 +68,12 @@ repository. + If this is reinitialization, the repository will be moved to the specified path. +-b <branch-name:: +--initial-branch=<branch-name>:: + +Use the specified name for the initial branch in the newly created repository. +If not specified, fall back to the default name: `master`.
OK.
Quoted 27 lines
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 +1
-0@@ -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;
builtin/init-db.c static int create_default_files(const char *template_path, · line 264
Quoted 8 lines
builtin/init-db.c +2
-2@@ -258,16 +259,29 @@ static int create_default_files(const char *template_path,die ("failed to set up refs db: %s" , err.buf);/* -* Create the default symlink from ".git/HEAD" to the "master" -* branch, if it does not exist yet. +* Create the default symlink from ".git/HEAD" to the default +* branch name, if it does not exist yet. */
To the caller of this helper, it may be "the default", but as far as this helper is concerned, it is not "default" but the initial branch that was given by the caller. How about...
/* * Point the initial branch with HEAD symref, if HEAD does * not exist yet. */
... to modernize the reference to symlink and replace it with symref?
builtin/init-db.c static int create_default_files(const char *template_path, · line 277
Quoted 7 lines
builtin/init-db.c +7
-0+if (!initial_branch) + initial_branch ="master" ; + + ref =xstrfmt ("refs/heads/%s" , initial_branch); +if (check_refname_format (ref,0 ) <0 ) +die (_ ("invalid initial branch name: '%s'" ), + initial_branch);
Good. We make sure to prefix with "refs/heads/" so the callers cannot abuse us to point HEAD outside the local branches.
builtin/init-db.c static int create_default_files(const char *template_path, · line 284
Quoted 7 lines
builtin/init-db.c +5
-1+if (create_symref ("HEAD" , ref,NULL ) <0 )exit (1 ); - } +free (ref); + }else if (initial_branch) +warning (_ ("re-init: ignoring --initial-branch=%s" ), + initial_branch);
Somehow the error checking convention feels uneven in this API. It is a warning-worthy offense for the caller to give initial_branch when we are re-initializing, but it is not an error for the caller not to supply the initial branch name on the other side of if/else. Worse yet, this helper function even knows the command line option name that resulted in the parameter coming to it.
That unevenness ultimately comes from the fact that the caller does not know if we are dealing with a repository that already has HEAD before calling, but at least we should be able to tell the caller if we initialized or not with our return value and allow the caller to issue this warning---that way we can lose the warning from here and get rid of the uneven feeling. Oh, and ...
Quoted 11 lines
builtin/init-db.c +2
-1@@ -383,7 +397,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash }int init_db (const char *git_dir,const char *real_git_dir, -const char *template_dir,int hash,unsigned int flags) +const char *template_dir,int hash,const char *initial_branch, +unsigned int flags) {int reinit;int exist_ok = flags &INIT_DB_EXIST_OK ;
builtin/init-db.c int init_db(const char *git_dir, const char *real_git_dir, · line 444
Quoted 6 lines
builtin/init-db.c +2
-1@@ -425,7 +440,8 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); - reinit =create_default_files (template_dir, original_git_dir, &repo_fmt); + reinit =create_default_files (template_dir, original_git_dir, + initial_branch, &repo_fmt);
... we are telling the caller if we are in reinit situation, so we can afford to do exactly that.
reinit = create_default_files...
if (reinit && initial_branch)
warning(_("re-init: ignored --initial-branch"));That's much better ;-)
Other than that, looks good to me.
Thanks.
Re: [PATCH v3 4/8] init: allow specifying the initial branch name for the new repository
Hi Junio,
Quoted 8 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 3 lines · writes:
[verse]
'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
[--separate-git-dir <git dir>] [--object-format=<format]Completely offtopic. We lack the closing ket> here.
Not so off-topic: the fix for this would cause conflicts. In the interest of avoiding merge conflicts, I incorporated a patch to fix that (git grep found two more instances, which I fixed "while at it").
Quoted 56 lines
Documentation/git-init.txt repository. · line 75
Quoted 13 lines
Documentation/git-init.txt +6
-0+ [-b <branch-name> | --initial-branch=<branch-name>] [--shared[=<permissions>]] [directory]@@ -67,6 +68,12 @@ repository. + If this is reinitialization, the repository will be moved to the specified path. +-b <branch-name:: +--initial-branch=<branch-name>:: + +Use the specified name for the initial branch in the newly created repository. +If not specified, fall back to the default name: `master`.OK.
Quoted 27 lines
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 +1
-0@@ -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;builtin/init-db.c static int create_default_files(const char *template_path, · line 264
Quoted 8 lines
builtin/init-db.c +2
-2@@ -258,16 +259,29 @@ static int create_default_files(const char *template_path,die ("failed to set up refs db: %s" , err.buf);/* -* Create the default symlink from ".git/HEAD" to the "master" -* branch, if it does not exist yet. +* Create the default symlink from ".git/HEAD" to the default +* branch name, if it does not exist yet. */ To the caller of this helper, it may be "the default", but as far as this helper is concerned, it is not "default" but the initial branch that was given by the caller. How about...
Quoted 7 lines
/* * Point the initial branch with HEAD symref, if HEAD does * not exist yet. */... to modernize the reference to symlink and replace it with symref?
Good point. I massaged your proposed comment and replaced the old one with it.
Quoted 10 lines
builtin/init-db.c static int create_default_files(const char *template_path, · line 277
Quoted 7 lines
builtin/init-db.c +7
-0+if (!initial_branch) + initial_branch ="master" ; + + ref =xstrfmt ("refs/heads/%s" , initial_branch); +if (check_refname_format (ref,0 ) <0 ) +die (_ ("invalid initial branch name: '%s'" ), + initial_branch);Good. We make sure to prefix with "refs/heads/" so the callers cannot abuse us to point HEAD outside the local branches.
Yes, Peff offered that concern, and I agree.
Quoted 43 lines
builtin/init-db.c static int create_default_files(const char *template_path, · line 284
Quoted 7 lines
builtin/init-db.c +5
-1+if (create_symref ("HEAD" , ref,NULL ) <0 )exit (1 ); - } +free (ref); + }else if (initial_branch) +warning (_ ("re-init: ignoring --initial-branch=%s" ), + initial_branch);Somehow the error checking convention feels uneven in this API. It is a warning-worthy offense for the caller to give
initial_branchwhen we are re-initializing, but it is not an error for the caller not to supply the initial branch name on the other side of if/else. Worse yet, this helper function even knows the command line option name that resulted in the parameter coming to it.That unevenness ultimately comes from the fact that the caller does not know if we are dealing with a repository that already has HEAD before calling, but at least we should be able to tell the caller if we initialized or not with our return value and allow the caller to issue this warning---that way we can lose the warning from here and get rid of the uneven feeling. Oh, and ...
Quoted 11 lines
builtin/init-db.c +2
-1@@ -383,7 +397,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash }int init_db (const char *git_dir,const char *real_git_dir, -const char *template_dir,int hash,unsigned int flags) +const char *template_dir,int hash,const char *initial_branch, +unsigned int flags) {int reinit;int exist_ok = flags &INIT_DB_EXIST_OK ;builtin/init-db.c int init_db(const char *git_dir, const char *real_git_dir, · line 444
Quoted 6 lines
builtin/init-db.c +2
-1@@ -425,7 +440,8 @@ int init_db(const char *git_dir, const char *real_git_dir,validate_hash_algorithm (&repo_fmt, hash); - reinit =create_default_files (template_dir, original_git_dir, &repo_fmt); + reinit =create_default_files (template_dir, original_git_dir, + initial_branch, &repo_fmt);... we are telling the caller if we are in reinit situation, so we can afford to do exactly that.
Quoted 3 lines
reinit =
create_default_files...
if (reinit &&initial_branch)warning(_("re-init: ignored --initial-branch"));
I changed it accordingly.
Thanks,
Dscho
Quoted 8 lines
That's much better ;-)
Other than that, looks good to me.
Thanks.
PATCH v3 5/8 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
Re: [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config
"Don Goodman-Wilson via GitGitGadget" <[email protected]>
builtin/init-db.c static int create_default_files(const char *template_path, · line 275
Quoted 13 lines · writes:
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 )
Continuing with the division of labor between this helper and its caller, I had this funny dislike of falling back here and not in the caller. But with the same idea of using "reinit", we could get rid of this "if the caller didn't give us initial_branch, fall back to..." logic from the function. The caller may do
reinit = create_default_files(... initial_branch ? initial_branch : "master", ...); if (reinit || initial_branch) warning(_(...));
in the previous step and then we can teach the caller to use the configured value instead of the hardcoded "master".
That's much better ;-)
Other than that, looks good to me.
Thanks.
Re: [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config
Hi Junio,
Quoted 23 lines · Junio C Hamano
"Don Goodman-Wilson via GitGitGadget" <[email protected]>
builtin/init-db.c static int create_default_files(const char *template_path, · line 275
Quoted 13 lines · writes:
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 )Continuing with the division of labor between this helper and its caller, I had this funny dislike of falling back here and not in the caller. But with the same idea of using "reinit", we could get rid of this "if the caller didn't give us
initial_branch, fall back to..." logic from the function. The caller may do
Quoted 8 lines
reinit = create_default_files(... initial_branch ? initial_branch : "master", ...); if (reinit || initial_branch) warning(_(...));in the previous step and then we can teach the caller to use the configured value instead of the hardcoded "master".
While that is really tempting, there is another called of init_db() (which calls create_default_files()): builtin/clone.c. And I do not wish to duplicate the logic there.
So I left this as-is.
Ciao,
Dscho
Quoted 7 lines
That's much better ;-)
Other than that, looks good to me.
Thanks.
Re: [PATCH v3 5/8] init: allow setting the default for the initial branch name via the config
Quoted 6 lines · Johannes Schindelin
Quoted 6 lines
reinit = create_default_files(... initial_branch ? initial_branch : "master", ...); if (reinit || initial_branch) warning(_(...));
Quoted 8 lines
Quoted 2 lines
in the previous step and then we can teach the caller to use the configured value instead of the hardcoded "master".
While that is really tempting, there is another called of
init_db()(which callscreate_default_files()):builtin/clone.c. And I do not wish to duplicate the logic there.So I left this as-is.
I am still on the fence after seeing v4, but let's leave it as is. The reason why I wanted to leave the "default to" logic out of the helper was to make sure it implements little or no policy, which would leave the door open to let other callers of the helper to use their own and different default, but we can revisit when we acquire the third caller. I do not see an immediate need to make the clone's fallback default configurable separately from what init uses for the default initial branch name, and with modern servers it is doubtful that the fallback default by clone is ever used anyway.
Thanks.
PATCH v3 6/8 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 v3 7/8 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 main (or specified) branch is * fetched and stored in the local branch matching the * remote name. */
@@ -284,7 +284,7 @@ static void read_branches_file(struct remote *remote)if (frag) *(frag++) ='\0' ;else - frag ="master" ; + frag = (char *)git_default_branch_name ();add_url_alias (remote,strbuf_detach (&buf,NULL )); strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ -2097,8 +2097,16 @@ struct ref *guess_remote_head(const struct ref *head,if (head->symref)return copy_ref (find_ref_by_name (refs, head->symref)); -/* If refs/heads/master could be right, it is. */ +/* If a remote branch exists with the default branch name, let's use it. */ if (!all) { +char *ref =xstrfmt ("refs/heads/%s" ,git_default_branch_name ()); + + r =find_ref_by_name (refs, ref); +free (ref); +if (r &&oideq (&r->old_oid, &head->old_oid)) +return copy_ref (r); + +/* Fall back to the hard-coded historical default */ r =find_ref_by_name (refs,"refs/heads/master" );if (r &&oideq (&r->old_oid, &head->old_oid))return copy_ref (r);
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
Re: [PATCH v3 7/8] remote: use the configured default branch name when appropriate
"Johannes Schindelin via GitGitGadget" <[email protected]>
remote.c static void read_branches_file(struct remote *remote) · line 282
Quoted 13 lines · writes:
remote.c +1
-1@@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)/* * The branches file would have URL and optionally -* #branch specified. The "master" (or specified) branch is +* #branch specified. The main (or specified) branch is * fetched and stored in the local branch matching the * remote name. */
Isn't this a bit premature here?
Re: [PATCH v3 7/8] remote: use the configured default branch name when appropriate
Hi Junio,
Quoted 9 lines · Junio C Hamano
"Johannes Schindelin via GitGitGadget" <[email protected]>
Quoted 6 lines · writes:
remote.c +0
-0@@ -276,7 +276,7 @@ static void read_branches_file(struct remote *remote)
Quoted 9 lines
remote.c static void read_branches_file(struct remote *remote) · line 282
Quoted 7 lines
remote.c +1
-1/* * The branches file would have URL and optionally -* #branch specified. The "master" (or specified) branch is +* #branch specified. The main (or specified) branch is * fetched and stored in the local branch matching the * remote name. */ Isn't this a bit premature here?
Actually, it is just wrong. It should talk about the default branch instead.
Ciao,
Dscho
PATCH v3 8/8 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
v4 cover Allow overriding the default name of the default branch
In reply to Johannes Schindelin via GitGitGadgetA growing number of open source projects aims to avoid the branch name master due to its negative connotation. See [1] for an existing discussion on this. The links [2], [3], and [4] describe community-driven ways for users to rename their default branches or use template edits to set a new default branch name.
[1]
https://lore.kernel.org/git/CAOAHyQwyXC1Z3v7BZAC+Bq6JBaM7FvBenA-1fcqeDV==apdWDg@mail.gmail.com/
[2] https://twitter.com/mislav/status/1270388510684598272
[3]
https://www.hanselman.com/blog/EasilyRenameYourGitDefaultBranchFromMasterToMain.aspx
[4] https://github.com/ethomson/retarget_prs
By necessity, existing repositories require a lot of manual work to move away from that branch name, but it should be much easier for new repositories.
This patch series allows overriding the branch name being used for new repositories' main branch. This can be configured via init.defaultBranch.
The initial patch was started by newcomer Don Goodman-Wilson, as well as the bigger change that morphed into #655, where we demonstrate how to change Git's hard-coded default branch name for new repositories to main based on this here patch series, verifying the approach. Thanks for the contribution!
This series DOES NOT change the default automatically, but only provides an opt-in mechanism for interested users. The plan for that is to convert the test scripts incrementally (by introducing GIT_TEST_DEFAULT_MAIN_BRANCH_NAME , which overrides init.defaultBranch, and then converting the tricky test scripts first, one by one, using that environment variable).
Changes since v3:
* We now avoid the phrasing "specify a specific" in the messages.
* The git submodule patch has a better commit title now, and it also adjusts the documentation more completely now (thanks, Philippe!).
* A code comment in builtin/init-db.c was updated to no longer talk about a symlink when it comes to HEAD.
* Made it the responsibility of the caller to warn about reinit && initial_branch.
Changes since v2:
* Dropped the fast-export patches, as they have been superseded by Peff's jk/fast-export-anonym
[https://github.com/gitgitgadget/git/commits/jk/fast-export-anonym].
* Adjusted the fmt-merge-msg patch so as to not special-case master anymore (instead of special-casing a specific "main" branch).
* Modified the git submodule patch so that it uses origin/HEAD instead of trying to look for a remote branch with the name indicated by init.defaultBranch.
Changes since v1:
* The modifications to respect GIT_TEST_DEFAULT_BRANCH_NAME have been backed out from this patch series, as they are only relevant once we start converting the test suite to accommodate for a new default main branch name.
* An error message that started with an upper-case letter was downcased.
* git_default_branch_name()'s logic was simplified by replacing an if ... else ... by a ternary assignment.
* The git_default_branch_name() function was renamed to git_main_branch_name() and a corresponding repo_main_branch_name() was introduced.
* The "init" commit message's first paragraph now elaborates a little bit on the reasoning why projects want to move away from the current default branch name.
* The "init" commit was split into two.
* There are now two config settings: init.defaultBranch (defining the branch name to use when initializing new repositories) and core.mainBranch (which is now configured by init_db(), declaring what the name of the main branch is in this repository).
* The commits were re-ordered to introduce the concept of core.mainBranch first because technically, this is something that we could do even without changing git init at all.
* git fast-export --anonymize now always uses the ref name ref0 for the main branch, no matter whether it was overridden or whether the fall-back is in effect.
* The code comment regarding anonymizing the main branch to ref0 in git fast-export --anonymize was enhanced.
* A new patch was added to rename core.mainBranch if the main branch is renamed via git branch -m.
* Added a patch that introduces support for git init --main-branch=<branch-name>.
* Where possible, I added tests (although I did not try to extend test coverage to all changes: the send-pack.c/transport-helper.c patch only adds a test for the send-pack.c adjustment, for example).
Don Goodman-Wilson (1):
init: allow setting the default for the initial branch name via the
config
Johannes Schindelin (8):
fmt-merge-msg: stop treating master specially send-pack/transport-helper: avoid mentioning a particular branch
submodule: fall back to remote's HEAD for missing remote.<name>.branch
docs: add missing diamond brackets
init: allow specifying the initial branch name for the new repository
clone: use configured default branch name when appropriate
remote: use the configured default branch name when appropriate
testsvn: respect init.defaultBranch
Documentation/config/init.txt | 4 ++ Documentation/git-branch.txt | 2 +- Documentation/git-clone.txt | 2 +- Documentation/git-init.txt | 9 ++- Documentation/git-submodule.txt | 12 ++-- Documentation/gitmodules.txt | 6 +- builtin/clone.c | 13 ++-- builtin/init-db.c | 33 +++++++-- builtin/submodule--helper.c | 2 +- cache.h | 2 +- fmt-merge-msg.c | 5 +- refs.c | 30 ++++++++ refs.h | 9 +++ remote-testsvn.c | 10 ++- remote.c | 14 +++- send-pack.c | 2 +- t/t0001-init.sh | 26 +++++++ t/t1507-rev-parse-upstream.sh | 2 +- t/t4013-diff-various.sh | 4 +- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- ...--patch-with-stat_--summary_master_--_dir_ | 2 +- t/t4013/diff.log_--patch-with-stat_master | 2 +- .../diff.log_--patch-with-stat_master_--_dir_ | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ..._--root_--patch-with-stat_--summary_master | 2 +- .../diff.log_--root_--patch-with-stat_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4013/diff.log_--root_-p_master | 2 +- t/t4013/diff.log_--root_master | 2 +- t/t4013/diff.log_-m_-p_--first-parent_master | 2 +- t/t4013/diff.log_-m_-p_master | 4 +- t/t4013/diff.log_-p_--first-parent_master | 2 +- t/t4013/diff.log_-p_master | 2 +- t/t4013/diff.log_master | 2 +- t/t4013/diff.show_--first-parent_master | 2 +- t/t4013/diff.show_-c_master | 2 +- t/t4013/diff.show_-m_master | 4 +- t/t4013/diff.show_master | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4202-log.sh | 72 +++++++++---------- t/t5528-push-default.sh | 6 ++ t/t5606-clone-options.sh | 24 +++++++ t/t6200-fmt-merge-msg.sh | 36 +++++----- t/t7406-submodule-update.sh | 16 +++++ t/t7419-submodule-set-branch.sh | 7 +- t/t7600-merge.sh | 14 ++-- t/t7608-merge-messages.sh | 10 +-- t/t9020-remote-svn.sh | 6 ++ transport-helper.c | 2 +- 51 files changed, 297 insertions(+), 131 deletions(-)
base-commit: c9c318d6bf26bcecdca5b6f31683b9d5887a83ee
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-656%2Fdscho%2Fdefault-branch-name-option-v4
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-656/dscho/default-branch-name-option-v4
Pull-Request: https://github.com/gitgitgadget/git/pull/656
Range-diff vs v3:
1: fffdb9944f = 1: fffdb9944f fmt-merge-msg: stop treating `master` specially
2: a29943d7bb ! 2: 1216de51ab send-pack/transport-helper: avoid mentioning a particular branch
@@ send-pack.c: int send_pack(struct send_pack_args *args,
if (!remote_refs) {
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
- "Perhaps you should specify a branch such as 'master'.\n");
-+ "Perhaps you should specify a specific branch.\n");
++ "Perhaps you should specify a branch.\n");
return 0;
}
if (args->atomic && !atomic_supported)
@@ t/t5528-push-default.sh: test_expect_success 'push from/to new branch with upstr
+test_expect_success '"matching" fails if none match' '
+ git init --bare empty &&
+ test_must_fail git push empty : 2>actual &&
-+ test_i18ngrep "Perhaps you should specify a specific branch" actual
++ test_i18ngrep "Perhaps you should specify a branch" actual
+'
+
test_expect_success 'push ambiguously named branch with upstream, matching and simple' '
@@ transport-helper.c: static int push_refs(struct transport *transport,
fprintf(stderr,
_("No refs in common and none specified; doing nothing.\n"
- "Perhaps you should specify a branch such as 'master'.\n"));
-+ "Perhaps you should specify a specific branch.\n"));
++ "Perhaps you should specify a branch.\n"));
return 0;
} 3: 6bda69541b ! 3: 54563642db submodule: use a better fall-back for missing remote.<name>.branch
@@ Metadata
Author: Johannes Schindelin <[email protected]>
## Commit message ##
- submodule: use a better fall-back for missing remote.<name>.branch
+ submodule: fall back to remote's HEAD for missing remote.<name>.branch
When remote.<name>.branch is not configured, git submodule update currently falls back to using the branch name master. A much better
- idea, however, is to use HEAD: on all Git servers running reasonably
- recent Git versions, the symref HEAD points to the main branch.
+ idea, however, is to use the remote HEAD: on all Git servers running
+ reasonably recent Git versions, the symref HEAD points to the main
+ branch.
Note: t7419 demonstrates that there _might_ be use cases out there that _expect_ git submodule update --remote to update submodules to the
@@ Commit message
there is a slight possibility that this might cause regressions in obscure setups.
+ Even so, it should be okay to fix this behavior without anything like a
+ longer transition period:
+
+ - The git submodule update --remote command is not really common.
+
+ - Current Git's behavior when running this command is outright
+ confusing, unless the remote repository's current branch _is_ master
+ (in which case the proposed behavior matches the old behavior).
+
+ - If a user encounters a regression due to the changed behavior, the fix
+ is actually trivial: setting submodule.<name>.branch to master
+ will reinstate the old behavior.
+
+ Helped-by: Philippe Blain <[email protected]>
## Documentation/git-submodule.txt ##
+@@ Documentation/git-submodule.txt: set-branch (-d|--default) [--] <path>::
+ Sets the default remote tracking branch for the submodule. The
+ --branch option allows the remote branch to be specified. The
+ --default option removes the submodule.<name>.branch configuration
+- key, which causes the tracking branch to default to 'master'.
++ key, which causes the tracking branch to default to the remote 'HEAD'.
+
+ set-url [--] <path> <newurl>::
+ Sets the URL of the specified submodule to <newurl>. Then, it will
@@ Documentation/git-submodule.txt: OPTIONS
.gitmodules for update --remote. A special value of . is used to indicate that the name of the branch in the submodule should be the same name as the current branch in the current repository. If the
- option is not specified, it defaults to 'master'.
-+ option is not specified, it defaults to 'HEAD'.
++ option is not specified, it defaults to the remote 'HEAD'.
-f::
--force::
@@ Documentation/git-submodule.txt: OPTIONS
status of the submodule's remote-tracking branch. The remote used is branch's remote (branch.<name>.remote), defaulting to origin.
- The remote branch used defaults to master, but the branch name may
-+ The remote branch used defaults to HEAD, but the branch name may
- be overridden by setting the submodule.<name>.branch option in
- either .gitmodules or .git/config (with .git/config taking
- precedence).
+- be overridden by setting the submodule.<name>.branch option in
+- either .gitmodules or .git/config (with .git/config taking
+- precedence).
++ The remote branch used defaults to the remote HEAD, but the branch
++ name may be overridden by setting the submodule.<name>.branch
++ option in either .gitmodules or .git/config (with .git/config
++ taking precedence).
+ +
+ This works for any of the supported update procedures (--checkout,
+ --rebase, etc.). The only change is the source of the target SHA-1. +
+ ## Documentation/gitmodules.txt ##
+@@ Documentation/gitmodules.txt: submodule.<name>.update::
+
+ submodule.<name>.branch::
+ A remote branch name for tracking updates in the upstream submodule.
+- If the option is not specified, it defaults to 'master'. A special
+- value of . is used to indicate that the name of the branch in the
+- submodule should be the same name as the current branch in the
++ If the option is not specified, it defaults to the remote 'HEAD'.
++ A special value of . is used to indicate that the name of the branch
++ in the submodule should be the same name as the current branch in the
+ current repository. See the --remote documentation in
+ linkgit:git-submodule[1] for details.
+
## builtin/submodule--helper.c ##
@@ builtin/submodule--helper.c: static const char *remote_submodule_branch(const char *path)
-: ---------- > 4: 1d723d35ed docs: add missing diamond brackets
4: e8a6587c1a ! 5: 9edd4fd3b2 init: allow specifying the initial branch name for the new repository
@@ Documentation/git-init.txt
@@ Documentation/git-init.txt: SYNOPSIS
[verse]
'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
- [--separate-git-dir <git dir>] [--object-format=<format]
+ [--separate-git-dir <git dir>] [--object-format=<format>]
+ [-b <branch-name> | --initial-branch=<branch-name>]
[--shared[=<permissions>]] [directory]
@@ builtin/init-db.c: static int create_default_files(const char *template_path,
/*
- * Create the default symlink from ".git/HEAD" to the "master"
- * branch, if it does not exist yet.
-+ * Create the default symlink from ".git/HEAD" to the default
-+ * branch name, if it does not exist yet.
++ * Point the HEAD symref to the initial branch with if HEAD does
++ * not yet exist.
*/
path = git_path_buf(&buf, "HEAD");
reinit = (!access(path, R_OK)
@@ builtin/init-db.c: static int create_default_files(const char *template_path,
+
+ if (create_symref("HEAD", ref, NULL) < 0)
exit(1);
-- }
+ free(ref);
-+ } else if (initial_branch)
-+ warning(_("re-init: ignoring --initial-branch=%s"),
-+ initial_branch);
+ }
initialize_repository_version(fmt->hash_algo);
-
@@ builtin/init-db.c: static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
}
@@ builtin/init-db.c: int init_db(const char *git_dir, const char *real_git_dir,
- reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
+ reinit = create_default_files(template_dir, original_git_dir,
+ initial_branch, &repo_fmt);
++ if (reinit && initial_branch)
++ warning(_("re-init: ignored --initial-branch=%s"),
++ initial_branch);
create_object_directory();
@@ t/t0001-init.sh: test_expect_success MINGW 'redirect std handles' '
+
+ : re-initializing should not change the branch name &&
+ git init --initial-branch=ignore initial-branch-option 2>err &&
-+ test_i18ngrep "ignoring --initial-branch" err &&
++ test_i18ngrep "ignored --initial-branch" err &&
+ git -C initial-branch-option symbolic-ref HEAD >actual &&
+ grep hello actual
+'
5: a500e0f214 = 6: 7747eaa57d init: allow setting the default for the initial branch name via the config
6: c0d74cedd1 = 7: 1cff7705e4 clone: use configured default branch name when appropriate
7: 00a1b281e5 ! 8: 0a7c0bdfda remote: use the configured default branch name when appropriate @@ remote.c: static void read_branches_file(struct remote *remote)
/*
* The branches file would have URL and optionally
- * #branch specified. The "master" (or specified) branch is
-+ * #branch specified. The main (or specified) branch is
++ * #branch specified. The default (or specified) branch is
* fetched and stored in the local branch matching the
* remote name.
*/
8: 1aa0e63785 = 9: 6c72abf677 testsvn: respect init.defaultBranch
Signature · 1 line
gitgitgadget
PATCH v4 1/9 fmt-merge-msg: stop treating `master` specially
From: Johannes Schindelin <[email protected]>
In the context of many projects renaming their primary branch names away from master, Git wants to stop treating the master branch specially.
Let's start with git fmt-merge-msg.
--- fmt-merge-msg.c | 5 +- t/t1507-rev-parse-upstream.sh | 2 +- t/t4013-diff-various.sh | 4 +- t/t4013/diff.log_--decorate=full_--all | 2 +- t/t4013/diff.log_--decorate_--all | 2 +- ...--patch-with-stat_--summary_master_--_dir_ | 2 +- t/t4013/diff.log_--patch-with-stat_master | 2 +- .../diff.log_--patch-with-stat_master_--_dir_ | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ..._--root_--patch-with-stat_--summary_master | 2 +- .../diff.log_--root_--patch-with-stat_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4013/diff.log_--root_-p_master | 2 +- t/t4013/diff.log_--root_master | 2 +- t/t4013/diff.log_-m_-p_--first-parent_master | 2 +- t/t4013/diff.log_-m_-p_master | 4 +- t/t4013/diff.log_-p_--first-parent_master | 2 +- t/t4013/diff.log_-p_master | 2 +- t/t4013/diff.log_master | 2 +- t/t4013/diff.show_--first-parent_master | 2 +- t/t4013/diff.show_-c_master | 2 +- t/t4013/diff.show_-m_master | 4 +- t/t4013/diff.show_master | 2 +- ...ot_--cc_--patch-with-stat_--summary_master | 2 +- ...root_-c_--patch-with-stat_--summary_master | 2 +- t/t4202-log.sh | 72 +++++++++---------- t/t6200-fmt-merge-msg.sh | 36 +++++----- t/t7600-merge.sh | 14 ++-- t/t7608-merge-messages.sh | 10 +-- 29 files changed, 94 insertions(+), 97 deletions(-)
fmt-merge-msg.c +1 -4
@@ -451,10 +451,7 @@ static void fmt_merge_msg_title(struct strbuf *out,strbuf_addf (out," of %s" , srcs.items[i].string); } -if (!strcmp ("master" , current_branch)) -strbuf_addch (out,'\n' ); -else -strbuf_addf (out," into %s\n" , current_branch); +strbuf_addf (out," into %s\n" , current_branch); } static void fmt_tag_signature(struct strbuf *tagbuf,
t/t1507-rev-parse-upstream.sh +1 -1
@@ -137,7 +137,7 @@ test_expect_success 'merge my-side@{u} records the correct name' ' git branch -t new my-side@{u} && git merge -s ours new@{u} && git show -s --pretty=tformat:%s >actual && - echo "Merge remote-tracking branch ${SQ}origin/side${SQ}" >expect && + echo "Merge remote-tracking branch ${SQ}origin/side${SQ} into master" >expect && test_cmp expect actual ) '
t/t4013-diff-various.sh +2 -2
@@ -117,12 +117,12 @@ test_expect_success setup ' : <<\EOF ! [initial] Initial - * [master] Merge branch 'side' + * [master] Merge branch 'side' into master ! [rearrange] Rearranged lines in dir/sub ! [side] Side ---- + [rearrange] Rearranged lines in dir/sub - - [master] Merge branch 'side' + - [master] Merge branch 'side' into master * + [side] Side * [master^] Third * [master~2] Second
t/t4013/diff.log_--decorate=full_--all +1 -1
@@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (refs/heads/side) Author: A U Thor <[email protected]>
t/t4013/diff.log_--decorate_--all +1 -1
@@ -31,7 +31,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a (side) Author: A U Thor <[email protected]>
t/t4013/diff.log_--patch-with-stat_--summary_master_--_dir_ +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--patch-with-stat_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--patch-with-stat_master_--_dir_ +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--root_--cc_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master dir/sub | 2 ++ file0 | 3 +++
t/t4013/diff.log_--root_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--root_--patch-with-stat_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--root_-c_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master dir/sub | 2 ++ file0 | 3 +++
t/t4013/diff.log_--root_-p_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_--root_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_-m_-p_--first-parent_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644
t/t4013/diff.log_-m_-p_master +2 -2
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644
@@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index 7289e35..992913c 100644
t/t4013/diff.log_-p_--first-parent_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit 9a6d4949b6b76956d9d5e26f2791ec2ceff5fdc0 Author: A U Thor <[email protected]>
t/t4013/diff.log_-p_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.log_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master commit c7a2ab9e8eac7b117442a607d5a9b3950ae34d5a Author: A U Thor <[email protected]>
t/t4013/diff.show_--first-parent_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644
t/t4013/diff.show_-c_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --combined dir/sub index cead32e,7289e35..992913c
t/t4013/diff.show_-m_master +2 -2
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index cead32e..992913c 100644
@@ -33,7 +33,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --git a/dir/sub b/dir/sub index 7289e35..992913c 100644
t/t4013/diff.show_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master diff --cc dir/sub index cead32e,7289e35..992913c
t/t4013/diff.whatchanged_--root_--cc_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master dir/sub | 2 ++ file0 | 3 +++
t/t4013/diff.whatchanged_--root_-c_--patch-with-stat_--summary_master +1 -1
@@ -4,7 +4,7 @@ Merge: 9a6d494 c7a2ab9 Author: A U Thor <[email protected]> Date: Mon Jun 26 00:04:00 2006 +0000 - Merge branch 'side' + Merge branch 'side' into master dir/sub | 2 ++ file0 | 3 +++
t/t4202-log.sh +36 -36
215 lines not on this page · raw message
t/t6200-fmt-merge-msg.sh +18 -18
@@ -79,7 +79,7 @@ test_expect_success GPG 'set up a signed tag' ' ' test_expect_success 'message for merging local branch' ' - echo "Merge branch ${apos}left${apos}" >expected && + echo "Merge branch ${apos}left${apos} into master" >expected && git checkout master && git fetch . left &&
@@ -107,7 +107,7 @@ test_expect_success GPG 'message for merging local tag signed by unknown key' ' ' test_expect_success 'message for merging external branch' ' - echo "Merge branch ${apos}left${apos} of $(pwd)" >expected && + echo "Merge branch ${apos}left${apos} of $(pwd) into master" >expected && git checkout master && git fetch "$(pwd)" left &&
@@ -118,7 +118,7 @@ test_expect_success 'message for merging external branch' ' test_expect_success '[merge] summary/log configuration' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -160,7 +160,7 @@ test_expect_success 'setup FETCH_HEAD' ' test_expect_success 'merge.log=3 limits shortlog length' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -177,7 +177,7 @@ test_expect_success 'merge.log=3 limits shortlog length' ' test_expect_success 'merge.log=5 shows all 5 commits' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -195,7 +195,7 @@ test_expect_success 'merge.log=5 shows all 5 commits' ' test_expect_success '--log=5 with custom comment character' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master x By Another Author (3) and A U Thor (2) x Via Another Committer
@@ -212,14 +212,14 @@ test_expect_success '--log=5 with custom comment character' ' ' test_expect_success 'merge.log=0 disables shortlog' ' - echo "Merge branch ${apos}left${apos}" >expected && + echo "Merge branch ${apos}left${apos} into master" >expected && git -c merge.log=0 fmt-merge-msg <.git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success '--log=3 limits shortlog length' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -236,7 +236,7 @@ test_expect_success '--log=3 limits shortlog length' ' test_expect_success '--log=5 shows all 5 commits' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos} + Merge branch ${apos}left${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -253,13 +253,13 @@ test_expect_success '--log=5 shows all 5 commits' ' ' test_expect_success '--no-log disables shortlog' ' - echo "Merge branch ${apos}left${apos}" >expected && + echo "Merge branch ${apos}left${apos} into master" >expected && git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual ' test_expect_success '--log=0 disables shortlog' ' - echo "Merge branch ${apos}left${apos}" >expected && + echo "Merge branch ${apos}left${apos} into master" >expected && git fmt-merge-msg --no-log <.git/FETCH_HEAD >actual && test_cmp expected actual '
@@ -300,7 +300,7 @@ test_expect_success 'fmt-merge-msg -m' ' test_expect_success 'setup: expected shortlog for two branches' ' cat >expected <<-EOF - Merge branches ${apos}left${apos} and ${apos}right${apos} + Merge branches ${apos}left${apos} and ${apos}right${apos} into master # By Another Author (3) and A U Thor (2) # Via Another Committer
@@ -397,7 +397,7 @@ test_expect_success 'merge-msg with nothing to merge' ' test_expect_success 'merge-msg tag' ' cat >expected <<-EOF && - Merge tag ${apos}tag-r3${apos} + Merge tag ${apos}tag-r3${apos} into master * tag ${apos}tag-r3${apos}: Right #3
@@ -418,7 +418,7 @@ test_expect_success 'merge-msg tag' ' test_expect_success 'merge-msg two tags' ' cat >expected <<-EOF && - Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} + Merge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos} into master * tag ${apos}tag-r3${apos}: Right #3
@@ -448,7 +448,7 @@ test_expect_success 'merge-msg two tags' ' test_expect_success 'merge-msg tag and branch' ' cat >expected <<-EOF && - Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} + Merge branch ${apos}left${apos}, tag ${apos}tag-r3${apos} into master * tag ${apos}tag-r3${apos}: Right #3
@@ -479,7 +479,7 @@ test_expect_success 'merge-msg tag and branch' ' test_expect_success 'merge-msg lots of commits' ' { cat <<-EOF && - Merge branch ${apos}long${apos} + Merge branch ${apos}long${apos} into master * long: (35 commits) EOF
@@ -516,7 +516,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git fmt-merge-msg <.git/FETCH_HEAD >actual && { cat <<-\EOF - Merge tag '\''annote'\'' + Merge tag '\''annote'\'' into master An annotated one
@@ -531,7 +531,7 @@ test_expect_success 'merge-msg with "merging" an annotated tag' ' git merge --no-commit --no-ff $annote && { cat <<-EOF - Merge tag '\''$annote'\'' + Merge tag '\''$annote'\'' into master An annotated one
t/t7600-merge.sh +7 -7
@@ -14,9 +14,9 @@ Testing basic merge operations/option parsing. ! [c4] c4 ! [c5] c5 ! [c6] c6 - * [master] Merge commit 'c1' + * [master] Merge commit 'c1' into master -------- - - [master] Merge commit 'c1' + - [master] Merge commit 'c1' into master + * [c1] commit 1 + [c6] c6 + [c5] c5
@@ -44,8 +44,8 @@ test_write_lines '1 X' 2 '3 X' 4 '5 X' 6 7 8 '9 X' >result.1-3-5-9 test_write_lines 1 2 3 4 5 6 7 8 '9 Z' >result.9z create_merge_msgs () { - echo "Merge tag 'c2'" >msg.1-5 && - echo "Merge tags 'c2' and 'c3'" >msg.1-5-9 && + echo "Merge tag 'c2' into master" >msg.1-5 && + echo "Merge tags 'c2' and 'c3' into master" >msg.1-5-9 && { echo "Squashed commit of the following:" && echo &&
@@ -258,7 +258,7 @@ test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' ' git commit --no-edit -a && cat >expect <<-\EOF && - Merge tag '"'"'c7'"'"' + Merge tag '"'"'c7'"'"' into master # ------------------------ >8 ------------------------ # Do not modify or remove the line above.
@@ -808,10 +808,10 @@ test_expect_success 'merge with conflicted --autostash changes' ' ' cat >expected.branch <<\EOF -Merge branch 'c5-branch' (early part) +Merge branch 'c5-branch' (early part) into master EOF cat >expected.tag <<\EOF -Merge commit 'c5~1' +Merge commit 'c5~1' into master EOF test_expect_success 'merge early part of c2' '
t/t7608-merge-messages.sh +5 -5
@@ -16,7 +16,7 @@ test_expect_success 'merge local branch' ' git checkout master && test_commit master-2 && git merge local-branch && - check_oneline "Merge branch Qlocal-branchQ" + check_oneline "Merge branch Qlocal-branchQ into master" ' test_expect_success 'merge octopus branches' '
@@ -26,7 +26,7 @@ test_expect_success 'merge octopus branches' ' test_commit octopus-2 && git checkout master && git merge octopus-a octopus-b && - check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ" + check_oneline "Merge branches Qoctopus-aQ and Qoctopus-bQ into master" ' test_expect_success 'merge tag' '
@@ -35,7 +35,7 @@ test_expect_success 'merge tag' ' git checkout master && test_commit master-3 && git merge tag-1 && - check_oneline "Merge tag Qtag-1Q" + check_oneline "Merge tag Qtag-1Q into master" ' test_expect_success 'ambiguous tag' '
@@ -44,7 +44,7 @@ test_expect_success 'ambiguous tag' ' git checkout master && test_commit master-4 && git merge ambiguous && - check_oneline "Merge tag QambiguousQ" + check_oneline "Merge tag QambiguousQ into master" ' test_expect_success 'remote-tracking branch' '
@@ -54,7 +54,7 @@ test_expect_success 'remote-tracking branch' ' git checkout master && test_commit master-5 && git merge origin/master && - check_oneline "Merge remote-tracking branch Qorigin/masterQ" + check_oneline "Merge remote-tracking branch Qorigin/masterQ into master" ' test_done
Signature · 1 line
gitgitgadget
Re: [PATCH v4 1/9] fmt-merge-msg: stop treating `master` specially
Quoted 9 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.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.
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: 8bit
We're starting to stop treating `master' specially in fmt-merge-msg. Adjust the test to reflect that change.
--- 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" ) '
Signature · 2 lines
2.27.0.111.gc72c7da667 Danh