1

With the big move from master as the default branch name for git in many projects (e.g. to main in GitHub), some of the scripts and configurations assuming it as the default name will be broken. For example, if you have setup aliases to save time typing some of the git commands:

[alias]
    com = checkout master
    rbm = rebase master
    rbmi = rebase -i master

The same applies to shell scripts - is there any equivalent to git checkout master but where master would be any default branch of the current repository?

2

Git doesn't have a concept of a default branch. A repository may contain many independent lines of development (e.g., a maintenance and a development branch), none of which are more special than any other. The importance of branches and how they're to be merged is up to the owner of the repository.

What you think of as the default branch, on GitHub and elsewhere, is the branch to which HEAD points in a bare repository. You can see what that name was for a remote when you last updated it by running this:

$ git rev-parse --abbrev-ref origin/HEAD
origin/master

If you want to know the very latest value from the remote and are willing to make a network request to do it, then you can do this:

$ git ls-remote --symref origin | head -n1
ref: refs/heads/master  HEAD

Note that this reference is not updated automatically; you must run git remote set-head -a origin to update it.

However, that doesn't tell you the name of the local branch that you're using as the default branch. For example, the command above is from my copy of Git, where the default branch is master. However, on my local machine, the branch into which the remote repository's default branch is pulled is called dev (that's my preferred default branch name). If that's what you want to know, then this is probably the command you want (assuming origin is your remote):

$ git config -l | ruby -e '
remote = ARGV[0]
head = `git rev-parse --abbrev-ref #{remote}/HEAD`.chomp
a = {}
while line = $stdin.gets
  if line =~ /^branch\.(.*)\.remote=(.*)$/
    a[$1] ||= [nil, nil]
    a[$1][0] = $2
  elsif line =~ %r[^branch\.(.*)\.merge=refs/heads/(.*)$]
    a[$1] ||= [nil, nil]
    a[$1][1] = $2
  end
end
puts a.map { |k, (a, b)| ["#{a}/#{b}", k]}.to_h[head]' origin

Since this is Ruby, if you want make it a one-liner, you can put semicolons in place of the newlines. You can also use Perl if you like that better.

1

There is no dedicated command to get the default branch. However with a bit of workarounds you might be able to get it. If you use your own repositories you can just always choose the same name. If you are using others they will have some sort of remote and then this trick (from David Walsh) could help:

LC_ALL=C git remote show origin | sed -n '/HEAD branch:/{s/.*: //;p}'
1
  • 1
    Note that git remote show retrieves information from the remote, so it requires a network connection and may prompt for authentication information. Nov 9 '20 at 10:56

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.