]> git.ipfire.org Git - thirdparty/git.git/commitdiff
breaking-changes: switch default branch to main
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Wed, 10 Sep 2025 15:29:00 +0000 (16:29 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 10 Sep 2025 20:34:58 +0000 (13:34 -0700)
Since 1296cbe4b46 (init: document `init.defaultBranch` better,
2020-12-11) "git-init.adoc" has advertised that the default name
of the initial branch may change in the future. The name "main"
is chosen to match the default used by the big Git forge web sites.

The advice printed when init.defaultBranch is not set is updated
to say that the default will change to "main" in Git 3.0. Building
with WITH_BREAKING_CHANGES enabled removes the advice and changes
the default branch name to "main". The code in guess_remote_head()
that looks for "refs/heads/master" is left unchanged as that is only
called when the remote server does not support the symref capability
in the v0 protocol or the symref extension to the ls-refs list in the
v2 protocol. Such an old server is more likely to be using "master"
as the default branch name.

With the exception of the "git-init.adoc" the documentation is left
unchanged. I had hoped to parameterize the name of the default branch
by using an asciidoc attribute. Unfortunately attribute expansion
is inhibited by backticks and we use backticks to mark up ref names
so that idea does not work. As the changes to git-init.adoc show
inserting ifdef's around each instance of the branch name "master"
is cumbersome and makes the documentation sources harder to read.

Apart from "git-init.adoc" there are some other files where "master" is
used as the name of the initial branch rather than as an example of a
branch name such as "user-manual.adoc" and "gitcore-tutorial.adoc". The
name appears a lot in those so updating it with ifdef's is not really
practical. We can update that document in the 3.0 release cycle. The
other documentation where master is used as an example branch name
can be gradually converted over time.

Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/BreakingChanges.adoc
Documentation/git-init.adoc
advice.c
advice.h
ci/run-build-and-tests.sh
refs.c
t/t0001-init.sh
t/test-lib.sh

index f8d2eba061c82a6db04f3d2ceeb2489b53597e83..f4e11c88655392307ee5b7502738da141ac6e0b4 100644 (file)
@@ -165,6 +165,12 @@ A prerequisite for this change is that the ecosystem is ready to support the
 "reftable" format. Most importantly, alternative implementations of Git like
 JGit, libgit2 and Gitoxide need to support it.
 
+* In new repositories, the default branch name will be `main`. We have been
+  warning that the default name will change since 675704c74dd (init:
+  provide useful advice about init.defaultBranch, 2020-12-11).  The new name
+  matches the default branch name used in new repositories by many of the
+  big Git forges.
+
 === Removals
 
 * Support for grafting commits has long been superseded by git-replace(1).
index a0dffba665fed61dd90723f63083ccb7b7ac4c59..bab99b9b477ba9b03d43a72e4c48f3e9b71b284c 100644 (file)
@@ -77,9 +77,15 @@ If this is a reinitialization, the repository will be moved to the specified pat
 `-b <branch-name>`::
 `--initial-branch=<branch-name>`::
 Use _<branch-name>_ for the initial branch in the newly created
-repository.  If not specified, fall back to the default name (currently
-`master`, but this is subject to change in the future; the name can be
-customized via the `init.defaultBranch` configuration variable).
+repository.  If not specified, fall back to the default name
+ifndef::with-breaking-changes[]
+(currently `master`, but this will change to `main` when Git 3.0 is released).
+endif::with-breaking-changes[]
+ifdef::with-breaking-changes[]
+`main`.
+endif::with-breaking-changes[]
+The default name can be customized via the `init.defaultBranch` configuration
+variable.
 
 `--shared[=(false|true|umask|group|all|world|everybody|<perm>)]`::
 
index e5f0ff844917ec5927d15c10a07cad873598d545..48c49ee4145267a33d44f9d3397933d18d7dedbf 100644 (file)
--- a/advice.c
+++ b/advice.c
@@ -51,7 +51,9 @@ static struct {
        [ADVICE_AM_WORK_DIR]                            = { "amWorkDir" },
        [ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME]  = { "checkoutAmbiguousRemoteBranchName" },
        [ADVICE_COMMIT_BEFORE_MERGE]                    = { "commitBeforeMerge" },
+#ifndef WITH_BREAKING_CHANGES
        [ADVICE_DEFAULT_BRANCH_NAME]                    = { "defaultBranchName" },
+#endif /* WITH_BREAKING_CHANGES */
        [ADVICE_DETACHED_HEAD]                          = { "detachedHead" },
        [ADVICE_DIVERGING]                              = { "diverging" },
        [ADVICE_FETCH_SET_HEAD_WARN]                    = { "fetchRemoteHEADWarn" },
index 727dcecf4a3ee0d827f5efe5049479c46f3c247b..fc1dc8720493d1cc5d50eb22059c4b4b2f3d0db9 100644 (file)
--- a/advice.h
+++ b/advice.h
@@ -18,7 +18,9 @@ enum advice_type {
        ADVICE_AM_WORK_DIR,
        ADVICE_CHECKOUT_AMBIGUOUS_REMOTE_BRANCH_NAME,
        ADVICE_COMMIT_BEFORE_MERGE,
+#ifndef WITH_BREAKING_CHANGES
        ADVICE_DEFAULT_BRANCH_NAME,
+#endif /* WITH_BREAKING_CHANGES */
        ADVICE_DETACHED_HEAD,
        ADVICE_DIVERGING,
        ADVICE_FETCH_SET_HEAD_WARN,
index 01823fd0f140bb43fc94eedf47384fd6a125f728..a21834043f3b858b6220a510a3db7941a722a7d1 100755 (executable)
@@ -9,7 +9,6 @@ run_tests=t
 
 case "$jobname" in
 linux-breaking-changes)
-       export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
        export WITH_BREAKING_CHANGES=YesPlease
        ;;
 linux-TEST-vars)
diff --git a/refs.c b/refs.c
index 4ff55cf24f68ee90e73de04f823c36bf536882bd..149a8d1cec1944d5b16856eba1bbdb245d6abb6a 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -627,10 +627,12 @@ void expand_ref_prefix(struct strvec *prefixes, const char *prefix)
                strvec_pushf(prefixes, *p, len, prefix);
 }
 
+#ifndef WITH_BREAKING_CHANGES
 static const char default_branch_name_advice[] = N_(
 "Using '%s' as the name for the initial branch. This default branch name\n"
-"is subject to change. To configure the initial branch name to use in all\n"
-"of your new repositories, which will suppress this warning, call:\n"
+"will change to \"main\" in Git 3.0. To configure the initial branch name\n"
+"to use in all of your new repositories, which will suppress this warning,\n"
+"call:\n"
 "\n"
 "\tgit config --global init.defaultBranch <name>\n"
 "\n"
@@ -639,8 +641,9 @@ static const char default_branch_name_advice[] = N_(
 "\n"
 "\tgit branch -m <name>\n"
 );
+#endif /* WITH_BREAKING_CHANGES */
 
-char *repo_default_branch_name(struct repository *r, int quiet)
+char *repo_default_branch_name(struct repository *r, MAYBE_UNUSED int quiet)
 {
        const char *config_key = "init.defaultbranch";
        const char *config_display_key = "init.defaultBranch";
@@ -649,14 +652,18 @@ char *repo_default_branch_name(struct repository *r, int quiet)
 
        if (env && *env)
                ret = xstrdup(env);
-       else if (repo_config_get_string(r, config_key, &ret) < 0)
+       if (!ret && repo_config_get_string(r, config_key, &ret) < 0)
                die(_("could not retrieve `%s`"), config_display_key);
 
        if (!ret) {
+#ifdef WITH_BREAKING_CHANGES
+               ret = xstrdup("main");
+#else
                ret = xstrdup("master");
                if (!quiet)
                        advise_if_enabled(ADVICE_DEFAULT_BRANCH_NAME,
                                          _(default_branch_name_advice), ret);
+#endif /* WITH_BREAKING_CHANGES */
        }
 
        full_ref = xstrfmt("refs/heads/%s", ret);
index f593c5368746fa276154fb731a7fc3f21982e1a9..df0040b9ace1d3d47252093c31e0f188f623796f 100755 (executable)
@@ -868,7 +868,7 @@ test_expect_success 'overridden default initial branch name (config)' '
        grep nmb actual
 '
 
-test_expect_success 'advice on unconfigured init.defaultBranch' '
+test_expect_success !WITH_BREAKING_CHANGES 'advice on unconfigured init.defaultBranch' '
        GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= git -c color.advice=always \
                init unconfigured-default-branch-name 2>err &&
        test_decode_color <err >decoded &&
@@ -883,6 +883,22 @@ test_expect_success 'advice on unconfigured init.defaultBranch disabled' '
        test_grep ! "hint: " err
 '
 
+test_expect_success 'default branch name' '
+       if test_have_prereq WITH_BREAKING_CHANGES
+       then
+               expect=main
+       else
+               expect=master
+       fi &&
+       echo "refs/heads/$expect" >expect &&
+       (
+               sane_unset GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME &&
+               git init default-initial-branch-name
+       ) &&
+       git -C default-initial-branch-name symbolic-ref HEAD >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'overridden default main branch name (env)' '
        test_config_global init.defaultBranch nmb &&
        GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=env git init main-branch-env &&
index 621cd31ae1dc5143979f3563fb407ff7b943bae6..b191954c3c445df81e7183328501efa5e6ec7bf8 100644 (file)
@@ -127,10 +127,13 @@ then
        export GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS
 fi
 
-# Explicitly set the default branch name for testing, to avoid the
-# transitory "git init" warning under --verbose.
-: ${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME:=master}
-export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+if test -z "$WITH_BREAKING_CHANGES"
+then
+       # Explicitly set the default branch name for testing, to avoid the
+       # transitory "git init" warning under --verbose.
+       : ${GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME:=master}
+       export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+fi
 
 ################################################################
 # It appears that people try to run tests without building...