Dot Dot Notation

OK, se­ri­ously? What is it with the dot no­ta­tion in git? Given this repo:

             master
               |
C1---C2---C5---C6
      \
       C3---C4
            |
          topic

How does

git log master..topic

mean to dis­play com­mits C3 and C4?

Let’s see if we can make things sim­pler.

A simple case

Imagine a repo with two branches, master and topic. The topic branch branches off of master, but there are no new com­mits on master:

             master
               |
L1---L2---L3---L4---L5---L6
                         |
                       topic

The git log out­put looks like this:

$ git log --oneline --all --graph --decorate
* 0c1d724 (topic) L6
* 5d4cdb5 L5
* ca8cf0a (HEAD -> master) L4
* 019e663 L3
* b1ea04d L2
* 83fd5ca L1

What should we ex­pect the out­put of git log master..topic to be?

$ git log --oneline --graph --decorate master..topic
* 0c1d724 (topic) L6
* 5d4cdb5 L5

That looks right. The com­mits from master to topic are L5 and L6 (not in­clud­ing the L6 com­mit at master).

OK. What if we re­verse the or­der of the com­mits?

$ git log --oneline --graph --decorate topic..master
<no output>

Order mat­ters. The dots seem to de­note the pas­sage of time. So master..topic means:

The com­mits from master to topic.1

Then it makes sense that topic..master produces no out­put be­cause

the com­mits from topic to master

is non­sen­si­cal since topic comes af­ter master.

Now with branches

Let’s go back to our first repo:

             master
               |
C1---C2---C5---C6
      \
       C3---C4
            |
          topic

What does git log master..topic, mean in this case? Commits from master to topic doesn’t make a lot of sense here.

It turns out that

master..topic

is short­hand for

^master topic

See, git log doesn’t work on se­quences of com­mits. It works on sets of com­mits. It’s right there in the doc­u­men­ta­tion.2

History-traversing com­mands, such as git log, operate on a set of com­mits, not just a sin­gle com­mit.

For these com­mands, spec­i­fy­ing a sin­gle re­vi­sion, us­ing the no­ta­tion de­scribed in the pre­vi­ous sec­tion, means the set of com­mits reach­able from the given com­mit.

A com­mit’s reach­able set is the com­mit it­self and the com­mits in its an­ces­try chain.

So master..topic means ^master topic, which means:

$ git log --oneline --graph --decorate master..topic
* 703d475 (HEAD -> topic) C4
* 3ffdcab C3
  1. Not including the master com­mit it­self. ↩︎

  2. If you’re like me, you learned Git by look­ing at ex­am­ples and mem­o­riz­ing a hand­ful of Git com­mands that you use as magic in­can­ta­tions. This post is part of my try­ing to un­der­stand what these magic spells mean. ↩︎