Git references

We said that a Git repository can be imagined as an acyclic graph, where every node, the commit, has a parent and a unique SHA-1 identifier. But during the previous chapters, we even used some references such as the HEAD, branches, tags, and so on.

Git manages these references as files in the .git/refs repository folder:

Git references

If you open one of those files, you will find it inside the SHA-1 of the commit they are tied to. As you can see, there are subfolders for tags and branches (called heads).

Symbolic references

The HEAD file instead is located in the .git folder, as shown in the following screenshot:

Symbolic references

HEAD is a symbolic reference; symbolic references are references that point to other references, using the ref: <reference> syntax. In this case, the HEAD is currently pointing to the master branch; if you check out another branch, you will see the file's content change, as shown in the following screenshot:

Symbolic references

Ancestry references

In Git you often need to reference the past (for example, the last commit); for this scope, we can use two different special characters which are the tilde ~ and the caret ^.

The first parent

Suppose you want to completely delete the last x4y5z6 commit:

The first parent

A way to do this is to move the HEAD pointer to the a1b2c3 commit, using the --hard option:

$ git reset --hard a1b2c3

Another way to do this is to move the pointer back to the parent commit. To define the parent, you have to specify a starting point reference, which can be the HEAD, a specific commit, a tag, or a branch and then one of two special characters: the tilde ~, for the first parent and the caret ^ for the second one (remember that commits can have two parents when they represent a merge result).

Let's get under the lens of the tilde ~. With the <ref>~<number> notation, we can specify how many steps backward we are going to take; going back to the example, an equivalent of the previous command is this:

$ git reset --hard HEAD~1

The HEAD~1 notation tells Git to point to the first parent commit of the actual commit (the HEAD, indeed). Note that HEAD~1 and HEAD~ are equivalent.

You can also go backward by more than one step, simply incrementing the number; a HEAD~3 reference will point to the third ancestor of the HEAD:

The first parent

The second parent

With the ^ caret character, instead we reference the second parent of a commit, but only starting from the number 2; the ref^1 notation references the first parent, as does the ref~1 notation whereas ref^ and ref~1 are equivalent. Also note that ref^1 and ref^ are equivalent.

The ^ and ~ operators can be combined; here's a diagram showing how to reference various commits using HEAD as the starting point:

The second parent
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset