Skip to content

Commit 32ba12d

Browse files
dschogitster
authored andcommitted
init: allow specifying the initial branch name for the new repository
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>`. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6069ecc commit 32ba12d

File tree

5 files changed

+50
-8
lines changed

5 files changed

+50
-8
lines changed

Documentation/git-init.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ SYNOPSIS
1111
[verse]
1212
'git init' [-q | --quiet] [--bare] [--template=<template_directory>]
1313
[--separate-git-dir <git dir>] [--object-format=<format>]
14+
[-b <branch-name> | --initial-branch=<branch-name>]
1415
[--shared[=<permissions>]] [directory]
1516

1617

@@ -67,6 +68,12 @@ repository.
6768
+
6869
If this is reinitialization, the repository will be moved to the specified path.
6970

71+
-b <branch-name::
72+
--initial-branch=<branch-name>::
73+
74+
Use the specified name for the initial branch in the newly created repository.
75+
If not specified, fall back to the default name: `master`.
76+
7077
--shared[=(false|true|umask|group|all|world|everybody|0xxx)]::
7178

7279
Specify that the Git repository is to be shared amongst several users. This

builtin/clone.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1108,7 +1108,8 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
11081108
}
11091109
}
11101110

1111-
init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, INIT_DB_QUIET);
1111+
init_db(git_dir, real_git_dir, option_template, GIT_HASH_UNKNOWN, NULL,
1112+
INIT_DB_QUIET);
11121113

11131114
if (real_git_dir)
11141115
git_dir = real_git_dir;

builtin/init-db.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ void initialize_repository_version(int hash_algo)
203203

204204
static int create_default_files(const char *template_path,
205205
const char *original_git_dir,
206+
const char *initial_branch,
206207
const struct repository_format *fmt)
207208
{
208209
struct stat st1;
@@ -258,15 +259,26 @@ static int create_default_files(const char *template_path,
258259
die("failed to set up refs db: %s", err.buf);
259260

260261
/*
261-
* Create the default symlink from ".git/HEAD" to the "master"
262-
* branch, if it does not exist yet.
262+
* Point the HEAD symref to the initial branch with if HEAD does
263+
* not yet exist.
263264
*/
264265
path = git_path_buf(&buf, "HEAD");
265266
reinit = (!access(path, R_OK)
266267
|| readlink(path, junk, sizeof(junk)-1) != -1);
267268
if (!reinit) {
268-
if (create_symref("HEAD", "refs/heads/master", NULL) < 0)
269+
char *ref;
270+
271+
if (!initial_branch)
272+
initial_branch = "master";
273+
274+
ref = xstrfmt("refs/heads/%s", initial_branch);
275+
if (check_refname_format(ref, 0) < 0)
276+
die(_("invalid initial branch name: '%s'"),
277+
initial_branch);
278+
279+
if (create_symref("HEAD", ref, NULL) < 0)
269280
exit(1);
281+
free(ref);
270282
}
271283

272284
initialize_repository_version(fmt->hash_algo);
@@ -383,7 +395,8 @@ static void validate_hash_algorithm(struct repository_format *repo_fmt, int hash
383395
}
384396

385397
int init_db(const char *git_dir, const char *real_git_dir,
386-
const char *template_dir, int hash, unsigned int flags)
398+
const char *template_dir, int hash, const char *initial_branch,
399+
unsigned int flags)
387400
{
388401
int reinit;
389402
int exist_ok = flags & INIT_DB_EXIST_OK;
@@ -425,7 +438,11 @@ int init_db(const char *git_dir, const char *real_git_dir,
425438

426439
validate_hash_algorithm(&repo_fmt, hash);
427440

428-
reinit = create_default_files(template_dir, original_git_dir, &repo_fmt);
441+
reinit = create_default_files(template_dir, original_git_dir,
442+
initial_branch, &repo_fmt);
443+
if (reinit && initial_branch)
444+
warning(_("re-init: ignored --initial-branch=%s"),
445+
initial_branch);
429446

430447
create_object_directory();
431448

@@ -528,6 +545,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
528545
const char *template_dir = NULL;
529546
unsigned int flags = 0;
530547
const char *object_format = NULL;
548+
const char *initial_branch = NULL;
531549
int hash_algo = GIT_HASH_UNKNOWN;
532550
const struct option init_db_options[] = {
533551
OPT_STRING(0, "template", &template_dir, N_("template-directory"),
@@ -541,6 +559,8 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
541559
OPT_BIT('q', "quiet", &flags, N_("be quiet"), INIT_DB_QUIET),
542560
OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"),
543561
N_("separate git dir from working tree")),
562+
OPT_STRING('b', "initial-branch", &initial_branch, N_("name"),
563+
N_("override the name of the initial branch")),
544564
OPT_STRING(0, "object-format", &object_format, N_("hash"),
545565
N_("specify the hash algorithm to use")),
546566
OPT_END()
@@ -652,5 +672,6 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
652672
UNLEAK(work_tree);
653673

654674
flags |= INIT_DB_EXIST_OK;
655-
return init_db(git_dir, real_git_dir, template_dir, hash_algo, flags);
675+
return init_db(git_dir, real_git_dir, template_dir, hash_algo,
676+
initial_branch, flags);
656677
}

cache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ int path_inside_repo(const char *prefix, const char *path);
628628

629629
int init_db(const char *git_dir, const char *real_git_dir,
630630
const char *template_dir, int hash_algo,
631-
unsigned int flags);
631+
const char *initial_branch, unsigned int flags);
632632
void initialize_repository_version(int hash_algo);
633633

634634
void sanitize_stdfds(void);

t/t0001-init.sh

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

467+
test_expect_success '--initial-branch' '
468+
git init --initial-branch=hello initial-branch-option &&
469+
git -C initial-branch-option symbolic-ref HEAD >actual &&
470+
echo refs/heads/hello >expect &&
471+
test_cmp expect actual &&
472+
473+
: re-initializing should not change the branch name &&
474+
git init --initial-branch=ignore initial-branch-option 2>err &&
475+
test_i18ngrep "ignored --initial-branch" err &&
476+
git -C initial-branch-option symbolic-ref HEAD >actual &&
477+
grep hello actual
478+
'
479+
467480
test_done

0 commit comments

Comments
 (0)