What are the differences between the following commands?:
git diff foo master # a
git diff foo..master # b
git diff foo...master # c
The diff manual talks about it:
Comparing branches
$ git diff topic master <1> $ git diff topic..master <2> $ git diff topic...master <3>
- Changes between the tips of the topic and the master branches.
- Same as above.
- Changes that occurred on the master branch since when the topic branch was started off it.
but isn't totally clear to me.
My consolidated version of the .. vs ... with diff vs log
Since I'd already created these images, I thought it might be worth using them in another answer, although the description of the difference between
..
(dot-dot) and...
(dot-dot-dot) is essentially the same as in manojlds's answer.The command
git diff
typically¹ only shows you the difference between the states of the tree between exactly two points in the commit graph. The..
and...
notations ingit diff
have the following meanings:In other words,
git diff foo..bar
is exactly the same asgit diff foo bar
; both will show you the difference between the tips of the two branchesfoo
andbar
. On the other hand,git diff foo...bar
will show you the difference between the "merge base" of the two branches and the tip ofbar
. The "merge base" is usually the last commit in common between those two branches, so this command will show you the changes that your work onbar
has introduced, while ignoring everything that has been done onfoo
in the mean time.That's all you need to know about the
..
and...
notations ingit diff
. However...... a common source of confusion here is that
..
and...
mean subtly different things when used in a command such asgit log
that expects a set of commits as one or more arguments. (These commands all end up usinggit rev-list
to parse a list of commits from their arguments.)The meaning of
..
and...
forgit log
can be shown graphically as below:So,
git rev-list foo..bar
shows you everything on branchbar
that isn't also on branchfoo
. On the other hand,git rev-list foo...bar
shows you all the commits that are in eitherfoo
orbar
, but not both. The third diagram just shows that if you list the two branches, you get the commits that are in either one or both of them.Well, I find that all a bit confusing, anyway, and I think the commit graph diagrams help :)
¹ I only say "typically" since when resolving merge conflicts, for example,
git diff
will show you a three-way merge.will show the differences between the topic and master branch at that point in time
this will also show the differences between the topic and master branch in that point in time
this will show all the differences between when the topic was made from the branch and after
so the first 2 commands are the same and last one just shows a wider view in the diff history
git diff foo master
Diff between the top (head) commits of foo and master.git diff foo..master
Another way of doing the same thing.git diff foo...master
Diff from the common ancestor (git merge-base foo master
) of foo and master to tip of master. In other words, shows only the changes that master branch has introduced since its common ancestor with foo.This example from GitHub explains when to use the two: