Why Git use 2 different commands to show HEAD?

I noticed there are 2 HEADs:

  • .git\HEAD
  • .git\refs\remotes\origin\HEAD

When I use git show-ref HEAD, it only gives me this:

  • Switching branches with IntelliJ & Git
  • Git: How to undo unstaged changes in a certain folder
  • git-svn fails to dcommit, even after clean checkout
  • Is there some purely PHP GIT server?
  • Split git repo in a squashed public and initial private
  • GIT repositories with some different files
  • ce0762c073b407d794f54f0b5d2a50375fdcb609 refs/remotes/origin/HEAD

    Whle when I use git rev-parse HEAD, it gives me the value of .git\HEAD:


    Why Git use 2 different commands to show HEAD? Any strong reason?

  • Count number of lines in a git repository
  • Setting path to git executable in RStudio under OSX Mountain Lion
  • How to close off a Git Branch?
  • Redo wrong merge in GIT
  • Adding older versions of code to git repo
  • Git enumerates nonexistent untracked files slowly
  • 2 Solutions collect form web for “Why Git use 2 different commands to show HEAD?”

    git-show-ref shows a list of references in your repository and their commit IDs. It should probably be called git-show-refs. It’s preferred over directly referencing files in the .git directory.

    When you say git show-ref HEAD you’re not asking for HEAD. What you’re asking for is any references in the list which match the pattern HEAD. HEAD itself is normally filtered out, so you get refs/remotes/origin/HEAD. You can include HEAD with --head.

    $ git show-ref --head HEAD
    f37beeea95f3b0e6b064f6d4b5f835a058e0568c HEAD
    aa1124b89f38eed793e2b9f2d2b2ba5d80a27a20 refs/remotes/origin/HEAD

    So you shouldn’t be using git show-ref <ref> to look up references.

    git-rev-parse takes a revision parameter and gives back a commit ID. Its meant to deal with the myriad different ways you can refer to a commit. For example…

    $ git rev-parse --verify master
    $ git rev-parse --verify heads/master
    $ git rev-parse --verify refs/heads/master

    git rev-parse --verify <ref> is what you should be using to look up the commit ID of a reference.

    .git/HEAD is used by Git to hold the current ref. So when you’re on master, it will be ref: refs/heads/master. When you are on detached HEAD, it will be a commit’s hash.

    .git/refs/remotes/origin/HEAD is actually a remote ref that points to the default branch on remote. When master is the default remote branch, it will be ref: refs/remotes/origin/master (if your remote is origin). It’s possible to have a default remote branch other than master but I have noticed that it will not correctly reflect that.


    $ git remote show github

    will always tell you the correct default remote branch.

    See this answer of How does origin/HEAD get set? for more details.

    git show-ref shows you refs, which are local branches, remote branches, tags, stash refs.


    git show-ref HEAD

    Git is using the “HEAD” as pattern

    git show-ref [-q|--quiet] [--verify] [--head] [-d|--dereference]
             [-s|--hash[=<n>]] [--abbrev[=<n>]] [--tags]
             [--heads] [--] [<pattern>…​]

    and only showing refs that match.

    See git-show-ref doc.

    I mostly use git branch with -a or -r options to see branches, git tag to see tags, and rarely use git show-ref.

    Git Baby is a git and github fan, let's start git clone.