Git Tip of the Day – double and triple points syntax
Double points syntax is used mostly when selecting an interval of commits. Let’s see an example:
$ git log master..feature
This will show you all commits in the feature branch that were added since it branched off from master. To be more precise – two points syntax will select all commits available in the feature branch and not available in the master branch.
By the way, you can also write the command above like this:
$ git log feature --not master
Again it means select all commits from freature that are not in master. The advantage of the latter syntax is that you can use it with more than two branches:
$ git log feature1 feature2 --not master
This will show you commits from two feature branches that are not in master.
Of course this is not just about log command. All commands working with commit intervals should support it. E.g. format-patch:
$ git format-patch master..feature
And other commands.
Triple points syntax is on the other hand used to select commits that are in either of the branches, but not at both at the same time. An example:
$ git log master...feature
This will show you all commits that are either in master or in feature, but not in both. (If you intend to use this command, be sure to study the –left-right option, that will add indicators to each commit from which branch they are from).
Now what I find most confusing about git is a double and triple points syntax in diff command. The git authors say that diff command doesn’t operate of commit interval but on two commits (end-points) directly, therefore the above semantics doesn’t apply. They (mis)used the syntax for something else in this command. Oh, well. Let’s see.
First, the standard usage of diff command is following:
$ git diff master feature
That will display differences directly between these two commits. If you added something in feature, it will be seen as an added line in the diff/patch view. If you added something in master (since the time the feature branched off), it will be seen as a removed line in the diff/patch view. Not really handy if you want to see just the changes you made.
The double points syntax is equivalent to the no points syntax:
$ git diff master..feature
So it does not look for their common ancestor and compares it to feature, as you might expect, no. That’s what the triple points syntax is for!
$ git diff master...feature
This will finally show you the changes you have done on feature since you branched off from master. It is equivalent to:
$ git diff $(git-merge-base master feature) feature
As the bottom line, most commands use a standardized meaning of double and triple points syntax (see man gitrevisions). However the diff command uses a different syntax – triple points equals to double points in gitrevisions and double points has no special meaning. Confusing? I believe so. But the syntax is too important so we have to remember it anyway.