DEV Community

Discussion on: What is your favourite Git command?

Collapse
 
kkm000 profile image
Cy "kkm" K'Nelson

A little hands-on tutorial. A ref is any file under .git/refs, and a few well-known others, e.g. .git/HEAD: branch heads, tags, etc. Each of them is a simple one-line file containing either a full SHA, or a name of another ref, called a symbolic ref. And example of a symbolic ref is normally the HEAD: type cat .git/HEAD, and it prints ref: refs/heads/master. It's a ref that is akin to a symlink to another ref. Now do cat .git/refs/heads/master. This is a normal, non-sybolic ref to a SHA.

Every time a ref changes (e.g., when you check out another branch, or detach HEAD by checking out a SHA), the old pointer would be irreversibly lost. For convenience, Git can store the old value in the reflog (reflog can be disabled, but enabled by default in non-bare repos). Git locally keeps a log of previous pointers, with the date of modification. These are kept under .git/logs, and the directory mirrors the structure of that above: HEAD's log is in logs/HEAD, .git/refs/heads/master's log is in .git/logs/refs/heads/master, and so on. Try cat .git/logs/HEAD.

Refs are symbolic names for points in history. Try these command in order (assuming you are on the master branch:
(1) git log -1 --oneline , which is a shorthand for
(2) git log -1 --oneline HEAD, which Git resolves (remember that little HEAD file above?) into
(3) git log -1 --oneline refs/heads/master.
(4) git log -1 --oneline master is also special: Git checks if one of refs/heads/master or refs/tags/master exists (I forgot in which order), and also ends up showing you git log -1 --oneline refs/heads/master. All these log commands yield the same output.

reflog is the command that lets you see the history of these ref changes. Try git reflog (a shorthand for git reflog show HEAD), and git reflog show --all, and you'll grok it at once. `man git-reflog has all the rest you need.