# Revision range notations

History traversing commands such as `git log`

operate on a set of commits, not
just a single commit.

For these commands, specifying a single revision, using the notation described in
the previous section, means the set of commits `reachable`

from the given commit.

A commit’s reachable set is the commit itself and the commits in its ancestry chain.

### Commit Exclusions

**^<rev> (caret) Notation**

To exclude commits reachable from a commit, a prefix ^ notation is used. E.g.
*^r1 r2* means commits reachable from *r2* but exclude the ones reachable from
*r1* (i.e. *r1* and its ancestors).

### Dotted Range Notations

**The .. (two-dot) Range Notation**

The *^r1 r2* set operation appears so often that there is a shorthand for it.
When you have two commits *r1* and *r2* (named according to the syntax explained
in SPECIFYING REVISIONS above), you can ask for commits that are reachable from
*r2* excluding those that are reachable from *r1* by *^r1 r2* and it can be written
as *r1..r2*.

**The … (three dot) Symmetric Difference Notation**

A similar notation *r1...r2* is called symmetric difference of *r1* and *r2* and
is defined as *r1 r2 --not $(git merge-base --all r1 r2)*. It is the set of commits
that are reachable from either one of *r1* (left side) or *r2* (right side) but
not from both.

In these two shorthand notations, you can omit one end and let it default to `HEAD`

.
For example, *origin..* is a shorthand for *origin..HEAD* and asks "What did I do
since I forked from the origin branch?" Similarly, *..origin* is a shorthand for
*HEAD..origin* and asks "What did the origin do since I forked from them?" Note that
*..* would mean *HEAD..HEAD* which is an empty range that is both reachable and
unreachable from `HEAD`

.

### Other <rev>^ Parent Shorthand Notations

Three other shorthands exist, particularly useful for merge commits, for naming a set that is formed by a commit and its parent commits.

The *r1^@* notation means all parents of *r1*.

The *r1^!* notation includes commit *r1* but excludes all of its parents. By itself,
this notation denotes the single commit *r1*.

The *<rev>^-<n>* notation includes *<rev>* but excludes the <n>th parent (i.e. a
shorthand for *<rev>^<n>..<rev>*), with <n> = 1 if not given. This is typically
useful for merge commits where you can just pass *<commit>^-* to get all the commits
in the branch that was merged in merge commit *<commit>* (including *<commit>* itself).

While *<rev>^<n>* was about specifying a single commit parent, these three notations
also consider its parents. For example you can say *HEAD^2^@*, however you cannot
say *HEAD^@^2*.