Is there a way to determine what the default branch is on an upstream repo when the local repo had the default branch changed to something different than the upstream repo?
-
What do you mean by default branch? – evolutionxbox Mar 20 '18 at 17:16
-
Could this question help? https://stackoverflow.com/questions/18726037/what-determines-default-branch-after-git-clone – evolutionxbox Mar 20 '18 at 18:09
-
Default branch, according to GitHub is, "The default branch is considered the “base” branch in your repository, against which all pull requests and code commits are automatically made, unless you specify a different branch." – user2569618 Mar 20 '18 at 19:26
-
Duplicate: [git - how to get default branch?](https://stackoverflow.com/questions/28666357/git-how-to-get-default-branch) – IMSoP Feb 15 '22 at 23:13
2 Answers
There is no notation of "default branch" in Git. There is only HEAD
in local and remote repository. You move HEAD
locally quite often so there almost always be difference between upstream HEAD
and local HEAD
.

- 22,873
- 4
- 61
- 112
-
@MarkAdelsberger I wouldn’t say so. Remote `HEAD` can be detached as any other `HEAD` and it will point to no branch. It is uncommon, but possible. Also remote `HEAD` only matters during first pull, after that **for Git** it doesn’t matter at all. – Hauleth Mar 20 '18 at 17:40
-
If there is no "default branch", then why does GitHub give me an option in the Settings -> Branch to set the "Default branch"? Even the verbiage states the following: "The default branch is considered the “base” branch in your repository, against which all pull requests and code commits are automatically made, unless you specify a different branch." – user2569618 Mar 20 '18 at 19:24
-
Because GitHub needs such as a “base” for all pull requests, but Git itself doesn’t have any notation of “default branch”. You are mixing GitHub ideas with Git ideas. – Hauleth Mar 20 '18 at 19:27
-
Allow me to restate my question: Is there a way to determine what the default branch in GitHub is when the local repo's default branch changed to something different than the GitHub repo? – user2569618 Mar 20 '18 at 19:52
-
Why don’t you change the default branch in github? As for the local repo, as @Hauleth has said it doesn’t have any notion of a default branch. – evolutionxbox Mar 21 '18 at 10:16
-
@user2569618 and what do you mean by “default local branch”? There is no such thing. There is only local `HEAD` and remote `HEAD`. – Hauleth Mar 21 '18 at 10:17
-
@Hauleth - Maybe you wouldn't say so, but the git documentation does. – Mark Adelsberger Mar 21 '18 at 12:56
-
@MarkAdelsberger could you provide link to such documentation because all I can Google is [GitHub's docs about GitHub's notation of "default branch](https://stackoverflow.com/questions/49390069/determine-the-default-branch-on-an-upstream-repo/49390441?noredirect=1#comment85814841_49390441) and [SO question about "default branch"](https://stackoverflow.com/questions/18726037/what-determines-default-branch-after-git-clone) which is exactly what I am saying that there is no "default branch" only couple `HEAD`s and after first clone Git sets local `HEAD` to the same value as remote `HEAD`. – Hauleth Mar 21 '18 at 13:01
-
@Hauleth - Do a text search for "default branch" at https://git-scm.com/docs/git-clone ; this reference won't define it but should clear up your belief that git doesn't have a concept of default branch. If you want the defining reference, do your own legwork. – Mark Adelsberger Mar 21 '18 at 13:15
-
@MarkAdelsberger only definition of "default branch" I have found on git-scm.com is "default branch name in Git is `master`" which is used in the same context as " default remote name in Git is `origin`". This mean that by default Git will create you `master` branch (but you can remove it later, nothing stops you). While in `git-clone` manage you can see "creates and checks out an initial branch that is forked from the cloned repository's currently active branch" which means exactly that what I have said: `HEAD` points to "currently active branch". – Hauleth Mar 21 '18 at 13:23
-
@Hauleth - No, that's the definition of "default branch name", and if you think about it you'll realize that it makes no sense to match that definition up with what the git clone reference I provided says about default branch. Sorry you're unable to find the info, but I don't have time to keep acting as your research department. If you're set on believing that git doesn't have a concept of default branch, that doesn't really matter to me. – Mark Adelsberger Mar 21 '18 at 13:34
-
Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/167265/discussion-between-hauleth-and-mark-adelsberger). – Hauleth Mar 21 '18 at 13:43
Solution 1: git rev-parse
(Recommended)
Just do this:
git rev-parse --abbrev-ref refs/remotes/origin/HEAD
That should print out HEAD
branch of the remote, which for a hosted repo should be the default branch, whether that may be origin/main
, origin/master
, origin/develop
, origin/stable
, whatever. (If the remote is actually another working copy, the remote HEAD
is the checked-out branch.)
Your local Git repository caches this information, as the ref refs/remotes/origin/HEAD
(replace origin
by whatever the remote may be named.) Usually this gets set automatically by git clone
, but if your local repository has a slightly unusual history (such as if your local repo began its life before the remote repo did), that local ref may be missing. In which case, this will generally recreate it:
git remote set-head origin --auto
That will contact the remote, check what its actual HEAD
branch is, and update the local Git repository's refs/remotes/origin/HEAD
ref.
Since this is locally cached information, it is possible for it to become outdated, if the remote repository changes its default branch. git fetch
will not detect that change, but git remote set-head origin --auto
will check what the remote HEAD is and update this local ref to match. So you may need to run that command manually after any such change in a remote repo.
In summary:
git rev-parse --abbrev-ref refs/remotes/origin/HEAD
gives you the answer quickly, but has a small chance of failing or being wrong;
git remote set-head origin --auto &&
git rev-parse --abbrev-ref refs/remotes/origin/HEAD
is always going to be correct, but is slower.
Solution 2: git ls-remote
git ls-remote --symref origin HEAD
Example output:
ref: refs/heads/main HEAD
bbac5bc097f944b3ad94e723364c5513d27b1910 HEAD
You could even do something like this:
git ls-remote --symref origin HEAD |
egrep '^ref: refs/heads/.*\tHEAD$' |
cut -d/ -f3- |
cut $'-d\t' -f1
That will just print main
(or master
, or whatever).
I recommend solution 1 instead, because it is simpler, and I don't think this solution has any real advantages over it.
Solution 3: GitHub CLI
If the remote happens to be GitHub or GitHub Enterprise, you can also use the GitHub CLI:
gh repo view --json defaultBranchRef --jq .defaultBranchRef.name
That will print main
, or master
, or whatever the remote default branch name may be.
I don't recommend this solution either, because solutions 1 and 2 will work for any Git host (GitHub, GitLab, BitBucket, Gitea, whatever). Plus it requires you to install and configure another CLI tool.

- 4,373
- 3
- 34
- 59