DEV Community

loading...
Cover image for Get Git Default Branch from the Command Line (Powershell or Bash/Zsh)

Get Git Default Branch from the Command Line (Powershell or Bash/Zsh)

bowmanjd profile image Jonathan Bowman Updated on ・3 min read

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'
Enter fullscreen mode Exit fullscreen mode

If you have jq it is even simpler:

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

Or for those who prefer curl:

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

This is pretty easy in Powershell, as well:

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

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'
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

Or Powershell equivalent:

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

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
Enter fullscreen mode Exit fullscreen mode

In Powershell:

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

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
Enter fullscreen mode Exit fullscreen mode

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

git config --global init.defaultBranch main
Enter fullscreen mode Exit fullscreen mode

Happy scripting!

Discussion (0)

pic
Editor guide