Skip to content

Commit f22be25

Browse files
committed
Merge branch 'js/default-branch-name' into pu
The name of the primary branch in existing repositories, and the default name used for the first branch in newly created repositories, is made configurable, so that we can eventually wean ourselves off of the hardcoded 'master'. * js/default-branch-name: Document how the default branch name can be overridden fmt-merge-msg: learn about the possibly-configured default branch name clone: learn about the possibly-configured default branch name submodule: use the (possibly overridden) default branch name testsvn: respect `core.defaultBranchName` send-pack/transport-helper: respect `core.defaultBranchName` remote: respect `core.defaultBranchName` init: allow overriding the default branch name for new repositories
2 parents 25996c0 + 13442e4 commit f22be25

15 files changed

+139
-19
lines changed

Documentation/config/core.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,3 +626,7 @@ core.abbrev::
626626
in your repository, which hopefully is enough for
627627
abbreviated object names to stay unique for some time.
628628
The minimum length is 4.
629+
630+
core.defaultBranchName::
631+
Allows overriding the default branch name e.g. when initializing
632+
a new repository or when cloning an empty repository.

builtin/clone.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,9 +1275,17 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12751275
remote_head_points_at = NULL;
12761276
remote_head = NULL;
12771277
option_no_checkout = 1;
1278-
if (!option_bare)
1279-
install_branch_config(0, "master", option_origin,
1280-
"refs/heads/master");
1278+
if (!option_bare) {
1279+
char *default_branch = git_default_branch_name(0);
1280+
const char *nick;
1281+
1282+
if (!skip_prefix(default_branch, "refs/heads/", &nick))
1283+
BUG("unexpected default branch '%s'",
1284+
default_branch);
1285+
install_branch_config(0, nick, option_origin,
1286+
default_branch);
1287+
free(default_branch);
1288+
}
12811289
}
12821290

12831291
write_refspec_config(src_ref_prefix, our_head_points_at,

builtin/init-db.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,15 +258,17 @@ static int create_default_files(const char *template_path,
258258
die("failed to set up refs db: %s", err.buf);
259259

260260
/*
261-
* Create the default symlink from ".git/HEAD" to the "master"
262-
* branch, if it does not exist yet.
261+
* Create the default symlink from ".git/HEAD" to the default
262+
* branch name, if it does not exist yet.
263263
*/
264264
path = git_path_buf(&buf, "HEAD");
265265
reinit = (!access(path, R_OK)
266266
|| readlink(path, junk, sizeof(junk)-1) != -1);
267267
if (!reinit) {
268-
if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
268+
char *default_ref = git_default_branch_name(0);
269+
if (create_symref("HEAD", default_ref, NULL) < 0)
269270
exit(1);
271+
free(default_ref);
270272
}
271273

272274
initialize_repository_version(fmt->hash_algo);

builtin/submodule--helper.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,8 +1980,14 @@ static const char *remote_submodule_branch(const char *path)
19801980
branch = sub->branch;
19811981
free(key);
19821982

1983-
if (!branch)
1984-
return "master";
1983+
if (!branch) {
1984+
static char *default_branch;
1985+
1986+
if (!default_branch)
1987+
default_branch = git_default_branch_name(1);
1988+
1989+
return default_branch;
1990+
}
19851991

19861992
if (!strcmp(branch, ".")) {
19871993
const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);

fmt-merge-msg.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ static void fmt_merge_msg_title(struct strbuf *out,
407407
const char *current_branch)
408408
{
409409
int i = 0;
410-
char *sep = "";
410+
char *sep = "", *default_branch_name;
411411

412412
strbuf_addstr(out, "Merge ");
413413
for (i = 0; i < srcs.nr; i++) {
@@ -451,10 +451,12 @@ static void fmt_merge_msg_title(struct strbuf *out,
451451
strbuf_addf(out, " of %s", srcs.items[i].string);
452452
}
453453

454-
if (!strcmp("master", current_branch))
454+
default_branch_name = git_default_branch_name(1);
455+
if (!strcmp(default_branch_name, current_branch))
455456
strbuf_addch(out, '\n');
456457
else
457458
strbuf_addf(out, " into %s\n", current_branch);
459+
free(default_branch_name);
458460
}
459461

460462
static void fmt_tag_signature(struct strbuf *tagbuf,

refs.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,40 @@ void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
562562
argv_array_pushf(prefixes, *p, len, prefix);
563563
}
564564

565+
char *git_default_branch_name(int short_name)
566+
{
567+
const char *branch_name = getenv("GIT_TEST_DEFAULT_BRANCH_NAME");
568+
char *from_config = NULL, *prefixed;
569+
570+
/*
571+
* If the default branch name was not specified via the environment
572+
* variable GIT_TEST_DEFAULT_BRANCH_NAME, retrieve it from the config
573+
* setting core.defaultBranchName. If neither are set, fall back to the
574+
* hard-coded default.
575+
*/
576+
if (!branch_name || !*branch_name) {
577+
if (git_config_get_string("core.defaultbranchname",
578+
&from_config) < 0)
579+
die(_("Could not retrieve `core.defaultBranchName`"));
580+
581+
if (from_config)
582+
branch_name = from_config;
583+
else
584+
branch_name = "master";
585+
}
586+
587+
if (short_name)
588+
return from_config ? from_config : xstrdup(branch_name);
589+
590+
/* prepend "refs/heads/" to the branch name */
591+
prefixed = xstrfmt("refs/heads/%s", branch_name);
592+
if (check_refname_format(prefixed, 0))
593+
die(_("invalid default branch name: '%s'"), branch_name);
594+
595+
free(from_config);
596+
return prefixed;
597+
}
598+
565599
/*
566600
* *string and *len will only be substituted, and *string returned (for
567601
* later free()ing) if the string passed in is a magic short-hand form

refs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ int repo_dwim_log(struct repository *r, const char *str, int len, struct object_
154154
int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
155155
int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
156156

157+
/*
158+
* Retrieves the name of the default branch. If `short_name` is non-zero, the
159+
* branch name will be prefixed with "refs/heads/".
160+
*/
161+
char *git_default_branch_name(int short_name);
162+
157163
/*
158164
* A ref_transaction represents a collection of reference updates that
159165
* should succeed or fail together.

remote-testsvn.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
static const char *url;
1414
static int dump_from_file;
1515
static const char *private_ref;
16-
static const char *remote_ref = "refs/heads/master";
16+
static char *remote_ref;
1717
static const char *marksfilename, *notes_ref;
1818
struct rev_note { unsigned int rev_nr; };
1919

@@ -286,14 +286,18 @@ int cmd_main(int argc, const char **argv)
286286
private_ref_sb = STRBUF_INIT, marksfilename_sb = STRBUF_INIT,
287287
notes_ref_sb = STRBUF_INIT;
288288
static struct remote *remote;
289-
const char *url_in;
289+
const char *url_in, *default_branch;
290290

291291
setup_git_directory();
292292
if (argc < 2 || argc > 3) {
293293
usage("git-remote-svn <remote-name> [<url>]");
294294
return 1;
295295
}
296296

297+
remote_ref = git_default_branch_name(0);
298+
if (!skip_prefix(remote_ref, "refs/heads/", &default_branch))
299+
BUG("unexpected remote_ref '%s'", remote_ref);
300+
297301
remote = remote_get(argv[1]);
298302
url_in = (argc == 3) ? argv[2] : remote->url[0];
299303

@@ -306,7 +310,8 @@ int cmd_main(int argc, const char **argv)
306310
url = url_sb.buf;
307311
}
308312

309-
strbuf_addf(&private_ref_sb, "refs/svn/%s/master", remote->name);
313+
strbuf_addf(&private_ref_sb, "refs/svn/%s/%s",
314+
remote->name, default_branch);
310315
private_ref = private_ref_sb.buf;
311316

312317
strbuf_addf(&notes_ref_sb, "refs/notes/%s/revs", remote->name);

remote.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ static void read_remotes_file(struct remote *remote)
256256

257257
static void read_branches_file(struct remote *remote)
258258
{
259-
char *frag;
259+
char *frag, *default_branch_name = NULL;
260260
struct strbuf buf = STRBUF_INIT;
261261
FILE *f = fopen_or_warn(git_path("branches/%s", remote->name), "r");
262262

@@ -276,15 +276,15 @@ static void read_branches_file(struct remote *remote)
276276

277277
/*
278278
* The branches file would have URL and optionally
279-
* #branch specified. The "master" (or specified) branch is
279+
* #branch specified. The default (or specified) branch is
280280
* fetched and stored in the local branch matching the
281281
* remote name.
282282
*/
283283
frag = strchr(buf.buf, '#');
284284
if (frag)
285285
*(frag++) = '\0';
286286
else
287-
frag = "master";
287+
frag = default_branch_name = git_default_branch_name(1);
288288

289289
add_url_alias(remote, strbuf_detach(&buf, NULL));
290290
strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
@@ -299,6 +299,7 @@ static void read_branches_file(struct remote *remote)
299299
strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
300300
refspec_append(&remote->push, buf.buf);
301301
remote->fetch_tags = 1; /* always auto-follow */
302+
free(default_branch_name);
302303
strbuf_release(&buf);
303304
}
304305

@@ -2149,7 +2150,10 @@ struct ref *guess_remote_head(const struct ref *head,
21492150

21502151
/* If refs/heads/master could be right, it is. */
21512152
if (!all) {
2152-
r = find_ref_by_name(refs, "refs/heads/master");
2153+
char *name = git_default_branch_name(0);
2154+
2155+
r = find_ref_by_name(refs, name);
2156+
free(name);
21532157
if (r && oideq(&r->old_oid, &head->old_oid))
21542158
return copy_ref(r);
21552159
}

send-pack.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,12 @@ int send_pack(struct send_pack_args *args,
470470
}
471471

472472
if (!remote_refs) {
473+
char *branch_name = git_default_branch_name(1);
474+
473475
fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
474-
"Perhaps you should specify a branch such as 'master'.\n");
476+
"Perhaps you should specify a branch such as '%s'.\n",
477+
branch_name);
478+
free(branch_name);
475479
return 0;
476480
}
477481
if (args->atomic && !atomic_supported)

t/README

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,10 @@ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is
421421
the default when running tests), errors out when an abbreviated option
422422
is used.
423423

424+
GIT_TEST_DEFAULT_BRANCH_NAME allows overriding the default branch name
425+
that is used for example when initializing new repositories, or when
426+
cloning a repository that has no branches yet.
427+
424428
Naming Tests
425429
------------
426430

t/t0001-init.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,4 +464,24 @@ test_expect_success MINGW 'redirect std handles' '
464464
grep "Needed a single revision" output.txt
465465
'
466466

467+
test_expect_success 'custom default branch name from config' '
468+
git config --global core.defaultbranchname nmb &&
469+
GIT_TEST_DEFAULT_BRANCH_NAME= git init custom-config &&
470+
git config --global --unset core.defaultbranchname &&
471+
git -C custom-config symbolic-ref HEAD >actual &&
472+
grep nmb actual
473+
'
474+
475+
test_expect_success 'custom default branch name from env' '
476+
GIT_TEST_DEFAULT_BRANCH_NAME=nmb git init custom-env &&
477+
git -C custom-env symbolic-ref HEAD >actual &&
478+
grep nmb actual
479+
'
480+
481+
test_expect_success 'invalid custom default branch name' '
482+
test_must_fail env GIT_TEST_DEFAULT_BRANCH_NAME="with space" \
483+
git init custom-invalid 2>err &&
484+
test_i18ngrep "invalid default branch name" err
485+
'
486+
467487
test_done

t/t5609-clone-branch.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,13 @@ test_expect_success 'clone -b not allowed with empty repos' '
6767
test_must_fail git clone -b branch empty clone-branch-empty
6868
'
6969

70+
test_expect_success 'chooses correct default branch name' '
71+
GIT_TEST_DEFAULT_BRANCH_NAME= \
72+
git -c core.defaultBranchName=up clone empty whats-up &&
73+
test_write_lines refs/heads/up refs/heads/up >expect &&
74+
git -C whats-up symbolic-ref HEAD >actual &&
75+
git -C whats-up config branch.up.merge >>actual &&
76+
test_cmp expect actual
77+
'
78+
7079
test_done

t/t6200-fmt-merge-msg.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ test_expect_success 'setup FETCH_HEAD' '
158158
git fetch . left
159159
'
160160

161+
test_expect_success 'with overridden default branch name' '
162+
test_config core.defaultBranchName default &&
163+
test_when_finished "git switch master" &&
164+
git switch -c default &&
165+
git fmt-merge-msg <.git/FETCH_HEAD >actual &&
166+
! grep "into default" actual
167+
'
168+
161169
test_expect_success 'merge.log=3 limits shortlog length' '
162170
cat >expected <<-EOF &&
163171
Merge branch ${apos}left${apos}

transport-helper.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1099,9 +1099,13 @@ static int push_refs(struct transport *transport,
10991099
}
11001100

11011101
if (!remote_refs) {
1102+
char *branch_name = git_default_branch_name(1);
1103+
11021104
fprintf(stderr,
11031105
_("No refs in common and none specified; doing nothing.\n"
1104-
"Perhaps you should specify a branch such as 'master'.\n"));
1106+
"Perhaps you should specify a branch such as '%s'.\n"),
1107+
branch_name);
1108+
free(branch_name);
11051109
return 0;
11061110
}
11071111

0 commit comments

Comments
 (0)