Git Refs and Refspecs: Grammar Reference
Git’s ref system is a tiny language for naming objects and mapping them across repositories. This post is a grammar reference first, and examples second.
Grammar reference
Ref and refname
| |
Common namespaces (grammar applies equally):
refs/heads/<branch>refs/tags/<tag>refs/remotes/<remote>/<branch>refs/notes/<name>
Symrefs (symbolic refs)
| |
Refspec (fetch/push)
| |
Semantics:
+permits non-fast-forward update.^removes matches from earlier positive fetch globs.patternmaps the*substring intodst.:with emptysrcdeletesdston push.- Bare
:(no src/dst) is deprecated matching.
Revision-ish / <start-point>
| |
Selectors:
rev^/rev^nparent (n-th for merges)rev~nfirst-parent ancestorrev@{n}n-th reflog entry (0 = current)rev@{<date>}reflog at timerev^{}peel tag to referenced objectrev^{tree|commit|blob}peel to type when ambiguous
Storage notes (minimal)
- Loose refs: files under
.git/refs/...(object ID or symref text). - Packed refs:
.git/packed-refswith optional peeled lines (^<object>). - Resolution prefers loose, then packed.
Examples and ready-to-use patterns
- Track all branches:
refs/heads/*:refs/remotes/origin/* - Exclude on fetch:
^refs/heads/wip/* - Force-push one branch:
+refs/heads/topic:refs/heads/topic - Delete remote branch:
:refs/heads/old-feature - Rename tag on push:
refs/tags/v1:refs/tags/release-1 - Parent/ancestor:
feature^,feature^2,feature~3 - Reflog selectors:
main@{2},main@{yesterday} - Peel annotated tag:
v1.2.3^{}orv1.2.3^{commit}
Quick checklist
- Only one
*per refspec glob. - Avoid control chars, space,
~ ^ : ? * [ \\in refname components. - No
//,..,.lock, or@{substrings; no leading/trailing/. - Provide a destination when globbing on push; fetch often supplies one for remote-tracking writes.