From the theoretical point of view:
- tags are symbolic names for a given revision. They always point to the same object (usually: to the same revision); they do not change.
- branches are symbolic names for line of development. New commits are created on top of branch. The branch pointer naturally advances, pointing to newer and newer commits.
From the technical point of view:
- tags reside in
refs/tags/
namespace, and can point to tag objects (annotated and optionally GPG signed tags) or directly to commit object (less used lightweight tag for local names), or in very rare cases even to tree object or blob object (e.g. GPG signature). - branches reside in
refs/heads/
namespace, and can point only to commit objects. TheHEAD
pointer must refer to a branch (symbolic reference) or directly to a commit (detached HEAD or unnamed branch). - remote-tracking branches reside in
refs/remotes/<remote>/
namespace, and follow ordinary branches in remote repository<remote>
.
See also gitglossary manpage:
branch
A “branch” is an active line of development. The most recent commit on a branch is referred to as the tip of that branch. The tip of the branch is referenced by a branch head, which moves forward as additional development is done on the branch. A single git repository can track an arbitrary number of branches, but your working tree is associated with just one of them (the “current” or “checked out” branch), and HEAD points to that branch.
tag
A ref pointing to a tag or commit object. In contrast to a head, a tag is not changed by a commit. Tags (not tag objects) are stored in
$GIT_DIR/refs/tags/
. […]. A tag is most typically used to mark a particular point in the commit ancestry chain.tag object
An object containing a ref pointing to another object, which can contain a message just like a commit object. It can also contain a (PGP) signature, in which case it is called a “signed tag object”.