Set default branch at custom Git Server (scratch) – Solve Git’s Default ‘master’ branch issue on Git Server Side

By | 22/01/2021
Set default branch at custom Git Server (scratch) – Solve Git’s Default ‘master’ branch issue on Git Server Side

In today’s time, the IT industry can’t work without Git. If you are someone related to this industry, you must have heard about Git, GitHub, GitLab etc. Most of the industry use GitHub, some use the free, and some use the paid features.

But, if you are someone who likes to make things on your own and in a way that you like them to be, you probably have heard about having own custom Git Servers. There are some companies and/or individuals who have their own Git servers on their own Private Servers.

So, couple of weeks ago, I was trying to setup my own Git Server, where I wanted to keep my projects in a whole set along with Private Keys and Other Design and Development Files that I won’t share on a public platform. But, we all know that GitHub introduced a feature and a concept of Default Branch. You can manually set the Default Branch in GitHub. And specially, before couple of months, GitHub changed their default branch from ‘master’ to ‘main’.

Now, I tried to do the same. But guess what I found out ? Git doesn’t really have a concept of having a ‘Default Branch’!
Wait! Then how does it work ?

So when a Remote Git Repository is created on a Remote Git Server (‘Bare Repository’), it doesn’t have any default branch set from the beginning. So, if you add the repository in your local repository as a remote, and change your local repo’s branch from ‘master’ to ‘main’, and then push the code, it will all work perfectly.

But the problem is, when you try to clone the repo at a different location, you will get the master branch by default. You will have to manually check the ‘main’ or whatever branch you set as your default in local (the first time, before pushing the code) and then you can work.

Sounds confusing and a boring thing to do every time, right ? Yes! I agree!

So I tried to find a solution. Now, to set the default repo locally, there is a solution (for git 2.28 and +):

git config --global init.defaultBranch {branchName}

But that will set it for your local repo! We need to do it one the Server Side.
But wait, we create remote repositories on the server side as Bare Repositories:

git init --bare

And it doesn’t have any default branches created with it! Then ?

I found a Solution:

Well, to be very honest, there is one workaround, and one permanent solution.


git symbolic-ref HEAD refs/heads/main

If you run the above code in your server repo, it will set the HEAD to point at a branch named ‘main’. And from then on wards, on that specific repository, the default branch will be main, unless and until the user changes something.

But the problem with this is, you have to do it every time you create a repo in the server.

Permanent Solution:

To solve it, by default we don’t really have any Settings or Rules that’s provided by Git (at least, nothing that I found, If you know something, please share in the comments, we all would love to know more).

But what we can do is use some other way around. How Git Server works is, whenever we run the command ‘git init –bare’, git creates the bare repository with the necessary files and folders.
But git doesn’t generate those files. It has a template folder in it’s core folder, and from there, it just copies the default template folder into your bare repository.

So what I did, I made a copy of that template folder, into a folder named ‘git.git’ and kept it under a folder ‘templates’ in my user’s home directory.

cp -r /usr/share/git-core/templates ~/templates/git.git

PS: You have to create the ‘template’ directory first, and then you can run the above command to copy the files. It will create the ‘git.git’ directory itself.

Make ‘templates’ directory and change directory
Copy git’s default template directory into ‘~/templates/git.git’

And then, I changed the default git template on the server from git’s own default template folder to my ‘templates/git.git’ folder.


git config --global init.templateDir '~/templates/git.git'
Set the default Git Template to your custom git template folder, i.e. ‘~/templates/git.git’

Then, last step, I created a file named ‘HEAD’ and wrote the symbolic link refference to ‘main’ to set the ‘HEAD’ to point at ‘main’ branch from the begining of that repository creation.


echo 'ref: refs/heads/main' > ~/templates/git.git/HEAD
Create a file named ‘HEAD’ and set the ref to point at the branch you want, i.e. ‘main’ for me

So, now, we have the default git template set to out ‘home/user/templates/git.git’ directory, and have a file ‘HEAD’ inside it which contains a reference for the HEAD to point to main branch. So, the next time we create a bare repository on the remote server, it will end up having it’s HEAD pointing to ‘main’ branch.

I created a temporary git remote bare repo named ‘temp.git’. You can see that git log command reflected an error with the ‘current’ branch set as ‘main’.
That’s the default current branch that git made from the custom template.

Now, I used ‘main’ as my default. Because for me, it is easier to call it main rather than master. If you want, you can change it to anything you like. Make the necessary changes in the commands and replace ‘main’ with your desired branch name, and you are done!

Please write comments if you find anything incorrect, helpful, questions or you want to share more information about the topic discussed above.

Spread the love

Leave a Reply

Your email address will not be published. Required fields are marked *