Thursday, 27 December 2018

GIT: Commit references

4.1. Predecessor commits, parents and commit references

Each commit has zero or more direct predecessor commits. The first commit has zero parents, merge commits have two or more parents, most commits have one parent.
Commit reference overview
In Git you frequently want to refer to certain commits. For example, you want to tell Git to show you all changes which were done in the last three commits. Or you want to see the differences introduced between two different branches.
Git allows addressing commits via commit reference for this purpose.
A commit reference can be a simple reference (simple ref), in this case it points directly to a commit. This is the case for a commit hash or a tag. A commit reference can also be symbolic reference (symbolic ref, symref). In this case it points to another reference (either simple or symbolic). For example HEAD is a symbolic ref for a branch, if it points to a branch. HEAD points to the branch pointer and the branch pointer points to a commit.

4.2. Branch references and the HEAD reference

A branch points to a specific commit. You can use the branch name as reference to the corresponding commit. You can also use HEAD to reference the corresponding commit.

4.3. Parent and ancestor commits

You can use ^ (caret) and ~ (tilde) to reference predecessor commit objects from other references. You can also combine the ^ and ~ operators. 
The Git terminology is parent for ^ and ancestor for ~.

4.4. Using caret and tilde for commit references

[reference]~1 describes the first predecessor of the commit object accessed via [reference]. [reference]~2 is the first predecessor of the first predecessor of the [reference] commit. [reference]~3 is the first predecessor of the first predecessor of the first predecessor of the [reference] commit, etc.
[reference]~ is an abbreviation for [reference]~1.
For example, you can use the HEAD~1 or HEAD~ reference to access the first parent of the commit to which the HEADpointer currently points.
[reference]^1 also describes the first predecessor of the commit object accessed via [reference].
For example HEAD^ is the same as HEAD~ and is the same as HEAD~3.
The difference is that [reference]^2 describes the second parent of a commit. A merge commit typically has two predecessors. HEAD^3 means ‘the third parent of a merge’ and in most cases this won’t exist (merges are generally between two commits, though more is possible).
Commit reference pointer example
[reference]^ is an abbreviation for [reference]^1.

4.5. Commit ranges with the double dot operator

You can also specify ranges of commits. This is useful for certain Git commands, for example, for seeing the changes between a series of commits.
The double dot operator allows you to select all commits which are reachable from a commit c2 but not from commit c1. The syntax for this is "c1..c2". A commit A is reachable from another commit B if A is a direct or indirect parent of B.
Think of c1..c2 as all commits as of c1 (not including c1) until commit c2.
For example, you can ask Git to show all commits which happened between HEAD and HEAD~4.
git log HEAD~4..HEAD
This also works for branches. To list all commits which are in the "master" branch but not in the "testing" branch, use the following command.
git log testing..master
You can also list all commits which are in the "testing" but not in the "master" branch.
git log master..testing

4.6. Commit ranges with the triple dot operator

The triple dot operator allows you to select all commits which are reachable either from commit c1 or commit c2 but not from both of them.
This is useful to show all commits in two branches which have not yet been combined.
# show all commits which
# can be reached by master or testing
# but not both
git log master...testing

0 comments:

Post a Comment