Refs and Names

Git's object system stores most of the data for projects tracked in Git, but only provides SHA-1 hashes. This is basically useless if you want to make practical use of Git, so Git also has a naming mechanism called “refs” that provide human-meaningful names for objects.

There are two kinds of refs:

Anywhere you could use a SHA-1, you can use a ref instead. Git interprets them identically, after resolving the ref down to the SHA-1.


Every operation in Git that uses a name of some sort, including branching (branch names), tagging (tag names), fetching (remote-tracking branch names), and pushing (many kinds of name), expands those names to refs, using a namespace convention. The following namespaces are common:

There are also a few special refs directly in the refs/ namespace, most notably:

Tools can invent new refs for their own purposes, or manipulate existing refs; the convention is that tools that use refs (which is, as I said, most of them) respect the state of the ref as if they'd created that state themselves, rather than sanity-checking the ref before using it.

Special refs

There are a handful of special refs used by Git commands for their own operation. These refs do not begin with refs/:

Examining and manipulating refs

The git show-ref command will list the refs in namespaces under refs in your repository, printing the SHA-1 hashes they resolve to. Pass --head to also include HEAD.

The following commands can be used to manipulate refs directly:

Additionally, you can see what ref a given name resolves to using git rev-parse --symbolic-full-name <name> or git show-ref <name>.