Read Git Default Branch from the Command Line

Jonathan Bowman Created: January 29, 2021 Updated: July 06, 2023 [Dev] #git #commandline git logo

On occasion, one needs to know the default branch for a given Git repo. Below I have compiled methods that fit a variety of use cases, and cover specific platforms (Github and Gitlab) as well as methods that work universally regardless of remote platform.

๐Ÿ”—Github API method

Given a repo username/reponame, the following script will work in Bash, Dash/Ash, or Zsh, provided you have the wget tool, and sed:

wget -q -O - "https://api.github.com/repos/username/reponame" | sed -nE 's/^\s+"default_branch": "([^"]+).+$/\1/p'

If you have jq it is even simpler:

wget -q -O - "https://api.github.com/repos/username/reponame" | jq -r '.default_branch'

Or for those who prefer curl:

curl -s "https://api.github.com/repos/username/reponame" | jq -r '.default_branch'

This is pretty easy in Powershell, as well:

iwr -useb https://api.github.com/repos/username/reponame | ConvertFrom-Json | select -exp default_branch

In summary, we first query information about the given repo, then parse the JSON that is returned, extracting the value of the default_branch key.

Is this something you might use repeatedly? Consider building a function and placing the following in your shell config (such as .bashrc):

defbranch () {
  REPO=$1
  wget -q -O - "https://api.github.com/repos/$REPO" | sed -nE 's/^\s+"default_branch": "([^"]+).+$/\1/p'
}

Feel free to use this gist

Or, for Windows Powershell, place the following in your Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:

function defbranch {
  Param ([string]$repo)
  iwr -useb https://api.github.com/repos/$repo | ConvertFrom-Json | select -exp default_branch
}

Feel free to use this gist

๐Ÿ”—Similar functionality on Gitlab

The above is specific to Github, because it is specifically a Github setting. In Github, even an empty repo can have a default branch that is different than master.

Gitlab, another popular โ€œsocial codingโ€ service, has different but similar functionality. A populated repo can have a default branch. An empty one will not.

Here is an example function that uses the Gitlab API (see gist):

gldefbranch () {
  REPO=$(echo $1 | sed "s/\//%2F/g")
  BRANCH=$(wget -q -O - "https://gitlab.com/api/v4/projects/$REPO" | sed -nE 's/.*"default_branch":"([^"]+).*/\1/p')
  [ "$BRANCH" == null ] && echo master || echo $BRANCH
}

and the Powershell equivalent:

function gldefbranch {
  Param ([string]$repo)
  $repo = $repo.replace("/","%2F")
  $branch = (iwr -useb "https://gitlab.com/api/v4/projects/$repo" | ConvertFrom-Json | select -exp default_branch)
  if ($branch) {
    echo $branch
  } else {
    echo "master"
  }
}

๐Ÿ”—A better, universal approach if repo is non-empty

My original intent was to read a Github setting on a repo, new or old, empty or not. However, if desiring to simply get the default branch on an existing repo, an API call is unnecessary. We can use git ls-remote.

Thanks to u/Cyberbeni in this Reddit discussion for these suggestions.

To query the default branch on a remote repository, try this, with your repository URL assigned to or substituted for $REPO_URL:

git ls-remote --symref "$REPO_URL" HEAD | sed -nE 's|^ref: refs/heads/(\S+)\s+HEAD|\1|p'

Or Powershell equivalent:

"$(git ls-remote --symref 'https://gitlab.com/bowmanjd/dotfiles1.git' HEAD)" -replace '.*?^ref: refs/heads/(\S+).+','$1'

๐Ÿ”—Get local origin/HEAD reference if available

If the repo was downloaded with git clone, then origin/HEAD is set automatically. In such cases, the following should work quickly, without needing to query the remote:

git symbolic-ref refs/remotes/origin/HEAD | cut -d '/' -f4

In Powershell:

(git symbolic-ref refs/remotes/origin/HEAD) -split '/' | select -Last 1

Please note the above is unreliable, as it is easily possible to work locally without origin/HEAD being set.

Again, thanks to u/Cyberbeni for the tip on Reddit.

๐Ÿ”—Get locally-set Git preference

Of course, if you just want to know the current userโ€™s preferred default branch, the following will yield the results, or blank if none has been set up:

git config init.defaultBranch

One can set this value to, for instance, main with something like

git config --global init.defaultBranch main

Happy scripting!

Back to top