42

I'm trying to figure out how to make git init use a different default branch name other than master for the first commit, but I can't find a git config for it or anything that'd allow me to do this (e.g. aliases only work for commands, not branch names).

Is there any way to change the default first branch name that git init sets up?

49

As of Git 2.28 (released 27th July 2020), you can now configure the name of the branch created when you init a new repository:

$ git config --global init.defaultBranch main

After setting this variable, running git init will produce a repository whose initial branch is main:

$ git init
Initialised empty Git repository in /home/thomas/test-git-repo/.git/
$ git status
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Release notes: https://lore.kernel.org/git/xmqq5za8hpir.fsf@gitster.c.googlers.com/

| improve this answer | |
  • Do you suppose this would work for a server-side Git management tool like GitHub or Bitbucket if executed as the user account running that software? – RCross Aug 18 at 6:01
  • @RCross I'm not totally sure I understand what you mean - do you mean if you are running the Github software on your server, would this command be sufficient to mean that users of that server would get new repos with the default name? If so, I certainly don't know. I was under the impression GH used a bespoke fork of Git anyway. If you mean can a user of github.com set the default name of new repositories, I would assume the answer is no - this command affects only local calls of git init AFAICT. – T. Kiley Aug 19 at 12:39
7

HEAD is hardcoded in git to point to refs/heads/master.

if (create_symref("HEAD", "refs/heads/master", NULL) < 0)

So there is no config setting or option that you can pass to git init to change it to something else.

What is possible though is to change what HEAD points to right after git init with the help of git symbolic-ref:

$ git init
$ git symbolic-ref HEAD refs/heads/test

This will change HEAD to point to a (not yet existing) branch called test. Then when you create your first commit, the branch will be called test instead of master.

| improve this answer | |
  • 3
    It looks like as of 19 days ago, this is no longer the case: github.com/git/git/commit/… Will see if I can work out what version of git is required for this feature and then add an answer. (Note link in this answer is now out of date). – T. Kiley Jul 13 at 13:22
  • Good spot, @T.Kiley... looks like there's a new command line option added in the release candidate for v.2.28.0. See Documentation/git-init.txt. – Quintin Willison Jul 13 at 14:56
  • I've also submitted an edit for approval that changes the "hardcoded" link in the answer to a perma-link to fix visbility for those researching in future. – Quintin Willison Jul 13 at 15:01
  • Looks like this has been now released, I've added an answer – T. Kiley Jul 27 at 21:36
6

A simple way to change the default HEAD is to create a HEAD in the git template dir. First, configure your template dir to ~/Templates/git.git (or whatever you'd prefer):

$ git config --global init.templateDir '~/Templates/git.git'
$ cp -r /usr/share/git-core/templates ~/Templates/git.git

Then, create the file HEAD in the template dir:

$ echo 'ref: refs/heads/default' > ~/Templates/git.git/HEAD

And you're good to go! Whenever you run git init, you'll now get the message:

$ git init
Reinitialized existing Git repository in [...]

For some reason, git decides whether to use this message based on the presence of the HEAD file in .git, rather than relying on whether or not .git had to be created. However, it really doesn't matter what message it shows you. From the git-init man page:

Running git init in an existing repository is safe. It will not overwrite things that are already there. The primary reason for rerunning git init is to pick up newly added templates (or to move the repository to another place if --separate-git-dir is given).

That is to say, git init is guaranteed not to overwrite the HEAD you put in the template, and it won't use the template's HEAD to overwrite an existing HEAD either. Since this is explicitly documented, you can rely on it.

Additionally, it also says:

Files and directories in the template directory whose name do not start with a dot will be copied to the $GIT_DIR after it is created.

Which means you can also rely on the template being copied immediately after the creation of .git, and not at a later point.

(Of course, this is my personal interpretation of the manual. It's entirely possible that the git developers will disagree.)

| improve this answer | |
1

As mentioned HEAD is hardcoded to point to master. However, you could create a shell alias, to make git init do what you like. If you are using bash as your shell, put something like this in your .bashrc:

function git_init_fnc () {
  default_branch="daddy"
  if [[ $1 == "init" ]] && [[ $# -eq 1 ]];then
      git init
      if [[ ! -z $(git branch -a | grep $default_branch) ]]; then
          git checkout "$default_branch"
      else
          git checkout -b "$default_branch"
      fi
  else
      /usr/bin/git "$@"
  fi
}

alias "git"=git_init_fnc

This will replace the command git with a function. This function will make the command git run exactly the same, unless you are calling git init without any other arguments. When you call git init it will init the repository. Next it will check to see if the branch "daddy" already exists. If it does, it will check out that branch, otherwise it will create the branch and move you to it.

| improve this answer | |
1

I went with a simple wrapper function in my bash profile:

git() {
    command git "$@"
    if [[ "$1" == "init" && $? -eq 0 ]]; then
        command git checkout -b default
    fi
}
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.