# Re: Updated Kernel Hacker's guide to git

12 messages from 2006-12-21 to 2006-12-22. Participants: Francis Moreau, Linus Torvalds, Carl Worth, Junio C Hamano, Jakub Narebski.
Thread: https://gitlist.dev/t/6059

## Francis Moreau, 2006-12-21 12:24

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <38b2ab8a0612210424o4ec5fcd5kb5086c52ccd76491@mail.gmail.com>
URL: https://gitlist.dev/e/38b2ab8a0612210424o4ec5fcd5kb5086c52ccd76491%40mail.gmail.com

```
Hi,

[ sorry for breaking up the thread but I'd like to fully
  understand that point and I just subscribed to git mail
  list... ]

Linus Torvalds wrote:
>
> On Wed, 20 Dec 2006, Jay Cliburn wrote:
>> $ git diff $(git merge-base master driver)..driver
>
> Be careful. This ONLY works if you don't have criss-cross merges etc, so
> you need to be somewhat careful about it. If you end up having a complex
> merge history between the origin branch and your development tree, things
> will stop working
>
> So it's actually worth understanding what the above does.
>
> Here's the picture to keep in mind: you started off with something like
> this:
>
> 	<- older			newer ->
>
> 	..--A---B---C---D
>
> where the top commit was D, and you started doing your own work off there.
> However, the tree you are tracking (doing "git fetch origin" or somethng)
> ALSO continues, so soon enough you'll have a history that looks like
>
> 	<- older			newer ->
>
> 	..--A---B---C---D---E---F---G---H <-"origin"
> 	                 \
> 	                  --X---Y---Z <- your "driver" branch"
>
> where your work is the "X-Y-Z" sequence.
>
> How, the reason you must NOT do
>
> 	git diff origin..driver
>
> or something like that, is that it will LITERALLY do a diff between those
> two heads. And while that is a perfectly normal diff, it's not what you
> want: it's the diff between the up-stream work and yours, and it will show
> that a lot of work has _not_ happened in your branch (all the E-F-G-H
> stuff), and then you've added some work (X-Y-Z).

I must really miss something but is a diff between origin and driver heads
achieved by:

	$ git diff driver origin

instead of:

	$ git diff origin..driver

?

>From the git-rev-list documentation I can read that:

	git-rev-list origin..driver == git-rev-list driver ^origin

I assume it's still true for git-diff. And the documentation says that
the above command "lists all the commits which are included in driver,
but not in origin".

So all commits included in driver are: (A-B-C-D-X-Y-Z)
all commits included in origin are: (A-B-C-D-E-F-G-H)

All the commits which are included in driver, but not in origin are:
(X-Y-Z), which is definitely not what you claimed.

I know that I'm wrong, so please shed some light in my stupid brain.

-- 
Francis

```

## Linus Torvalds, 2006-12-21 18:23

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <Pine.LNX.4.64.0612211013500.3394@woody.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0612211013500.3394%40woody.osdl.org
In-Reply-To: <38b2ab8a0612210424o4ec5fcd5kb5086c52ccd76491@mail.gmail.com>

```


On Thu, 21 Dec 2006, Francis Moreau wrote:
> 
> I must really miss something but is a diff between origin and driver heads
> achieved by:
> 
> 	$ git diff driver origin
> 
> instead of:
> 
> 	$ git diff origin..driver

No. 

	git diff origin driver

and

	git diff origin..driver

is exactly the same thing.

> From the git-rev-list documentation I can read that:
> 
> 	git-rev-list origin..driver == git-rev-list driver ^origin

Correct. However, "git diff" is very aware of things like "^origin", and 
understands that

	git diff driver ^origin

is the same thing as saying "I want what is in driver, but not in origin", 
so it needs to switch the arguments.

In short, for git diff (and ONLY) git diff, all of these are the same:

	git diff a..b
	git diff a b
	git diff b ^a

[ ADDITIONALLY git diff _also_ has a magic special case of

	git diff a b ^c

  which actually means the same as "git diff c..a" (and "b" is 
  totally ignored). That may sound strange, but it's because the 
  expression "a...b" means "b a --not $(git-merge-base a b)", and so what 
  you actually WANT is that if you do

	git diff a...b

  you should get "diff from merge-base to b", so when "a...b" expands to 
  "b a ^merge-base", then git understands that if it gets that stange 
  command line with THREE commits, and one of them is negated, you really 
  wanted the diff from the negated one to the first one ]

It basically all boils down to:

	"git diff" is special

exactly because unlike almost ALL other git commands, "git diff" does not 
work on a _list_ of commits, it only works on two end-points. That means 
that the "list operations" actually end up meaning something else for git 
diff than they do for "git log" and friends.

		Linus

```

## Carl Worth, 2006-12-22 01:23

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <87slf83erg.wl%cworth@cworth.org>
URL: https://gitlist.dev/e/87slf83erg.wl%25cworth%40cworth.org
In-Reply-To: <Pine.LNX.4.64.0612211013500.3394@woody.osdl.org>

```
On Thu, 21 Dec 2006 10:23:30 -0800 (PST), Linus Torvalds wrote:
> In short, for git diff (and ONLY) git diff, all of these are the same:
>
> 	git diff a..b
> 	git diff a b

I admit that I had had never passed a range of commits to git diff,
nor even given any thought to what it might do, but I definitely find
the above very surprising---and not necessarily very useful. Why is
anyone ever typing those two dots here if they have no effect on the
result?

> It basically all boils down to:
>
> 	"git diff" is special
>
> exactly because unlike almost ALL other git commands, "git diff" does not
> work on a _list_ of commits, it only works on two end-points. That means
> that the "list operations" actually end up meaning something else for git
> diff than they do for "git log" and friends.

Yes, "git diff" can only work on two end points. So a command like:

	git diff a b

is really easy to understand. And if the user wants to compare those
two points, why would the user ever provide them with any other
syntax?

In other words, what's the advantage of "git diff" accepting a special
syntax for a range ("a..b") and yet not actually doing anything
special with it?

In particular, the operation that would be interesting here is what
one can get with:

	git diff $(git merge-base a b) b

so why isn't _that_ the operation that is accessed with the syntax of:

	git diff a..b

Said another way, if "git log a..b" displays a range of commits, why
doesn't "git diff a..b" display the diff from the beginning of that
range to the end?

Of course, all the warnings you gave about what "git diff" would do
in the case of various criss-cross merge scenarios would still apply.

-Carl

```

## Linus Torvalds, 2006-12-22 04:13

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <Pine.LNX.4.64.0612212009370.3536@woody.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0612212009370.3536%40woody.osdl.org
In-Reply-To: <87slf83erg.wl%cworth@cworth.org>

```


On Thu, 21 Dec 2006, Carl Worth wrote:
>
> On Thu, 21 Dec 2006 10:23:30 -0800 (PST), Linus Torvalds wrote:
> > In short, for git diff (and ONLY) git diff, all of these are the same:
> >
> > 	git diff a..b
> > 	git diff a b
> 
> I admit that I had had never passed a range of commits to git diff,
> nor even given any thought to what it might do, but I definitely find
> the above very surprising---and not necessarily very useful. Why is
> anyone ever typing those two dots here if they have no effect on the
> result?

I do it all the time, I never even use the old-fashioned syntax any more. 
It's much more concise and easy to read, and it has all the nice shortcuts 
(like empty meaning "HEAD", so you can do "git diff ..next" to see the 
diff from HEAD to another branch).

It's also useful exactly because of the semantics of things like "...".

In other words, sure, "git diff a b" works, but it just _looks_ more 
pleasing to use "a..b" and you mentally always pronounce the ".." as "to".

So "git diff a b" doesn't even look good to me any more, because it's 
literally missing that mental "to" that the ".." adds for me when I read 
it.

		Linus

```

## Francis Moreau, 2006-12-22 09:35

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <38b2ab8a0612220135p6925be4cmf003811f616395ba@mail.gmail.com>
URL: https://gitlist.dev/e/38b2ab8a0612220135p6925be4cmf003811f616395ba%40mail.gmail.com
In-Reply-To: <Pine.LNX.4.64.0612211013500.3394@woody.osdl.org>

```
Linus Torvalds wrote:
>
> In short, for git diff (and ONLY) git diff, all of these are the same:
>
> 	git diff a..b
> 	git diff a b
> 	git diff b ^a
>

I think this part is really confusing. For a new comer, saying that:

	git diff a b == git diff a..b

is really not intuitive. Maybe just because adding a new symbol ".."
in git diff command line means (for me) that we're doing a special
diff. I would never thought by my own that ".." means a simple "to".

> [ ADDITIONALLY git diff _also_ has a magic special case of
>
> 	git diff a b ^c
>
>   which actually means the same as "git diff c..a" (and "b" is
>   totally ignored). That may sound strange, but it's because the
>   expression "a...b" means "b a --not $(git-merge-base a b)", and so what
>   you actually WANT is that if you do
>
> 	git diff a...b
>
>   you should get "diff from merge-base to b", so when "a...b" expands to
>   "b a ^merge-base", then git understands that if it gets that stange
>   command line with THREE commits, and one of them is negated, you really
>   wanted the diff from the negated one to the first one ]
>
> It basically all boils down to:
>
> 	"git diff" is special
>

but this very special part of git diff is also not documented at all
when reading the manual of git-diff... Maybe it can be reached by
others manuals ?

> exactly because unlike almost ALL other git commands, "git diff" does not
> work on a _list_ of commits, it only works on two end-points. That means
> that the "list operations" actually end up meaning something else for git
> diff than they do for "git log" and friends.
>

I think I got your point now: git-diff only works on two end-points.


Why not making it less special as follow:

	git diff a b
	git diff b ^a

These two diff commands are the same. They do a diff between a and b
end-points (maybe commits is better there since we don't add one more
keyword). It's similar to diff command. For me it's quite intuitive.

	git diff a..b

Ok now the command syntax is more special (maybe simply because
traditional diff() does not have a similar syntax, it's really
specific to git). "git log" and friends have a similar syntax and they
do work on a list of commits. For consistency sake, make this commad
works on commit list too. Therefore this command would end up doing
exactly the same thing like "git diff a...b"

	git diff a...b

No more need of this special syntax.


What do you think ?

thanks
-- 
Francis

```

## Junio C Hamano, 2006-12-22 10:26

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <7vvek41b29.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7vvek41b29.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <38b2ab8a0612220135p6925be4cmf003811f616395ba@mail.gmail.com>

```
"Francis Moreau" <francis.moro@gmail.com> writes:

> I think this part is really confusing. For a new comer, saying that:
>
> 	git diff a b == git diff a..b
>
> is really not intuitive. Maybe just because adding a new symbol ".."
> in git diff command line means (for me) that we're doing a special
> diff. I would never thought by my own that ".." means a simple "to".

We did not originally have "A B"; you were supposed to always
say "A..B".  But all other SCM had "A B" notation, so we added
support for both because doing so was trivial and there is no
risk of confusion (because diff is about two points while log is
about a set).  These two notations are interchangeable for
"diff".  If it confuses you, you can stick to the "git diff A B"
notation.  Of if you are like Linus, stick to "A..B" notation.
Either way, you can pretend that the other notation does not
even exist and be happy ;-).

Yes, users often wondered why "git diff" accepts "A B", "git
log" wants "A..B" and "git log A B" is a disaster.  But the root
cause of the confusion was not about notation but about the
conceptual difference (two points vs a set).

I do not think changing the meaning of "diff A..B" to what "diff
A...B" means is a good thing.  The notation "..." even _looks_
like a magic, and in diff context, what it does _is_ magic (it
is magic in log context, too).  You are giving two points, but
what actually is used as the two points for diff are different
from what you gave; in that sense, it is a very good notation.
Changing it would confuse and inconvenience people who already
understood and got used to the difference between "diff" and
"log": diff takes two points, so given usual A..B notation it
uses A and B, while log is about a set and means 'the ones
reachable from B, excluding the ones reachable from A'; "A...B"
is magic and does a magical thing in both "diff" and "log",
taking the merge bases between A and B into account.

```

## Francis Moreau, 2006-12-22 20:34

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <38b2ab8a0612221234x3832c5bfr1f64caccbb8247b9@mail.gmail.com>
URL: https://gitlist.dev/e/38b2ab8a0612221234x3832c5bfr1f64caccbb8247b9%40mail.gmail.com
In-Reply-To: <7vvek41b29.fsf@assigned-by-dhcp.cox.net>

```
On 12/22/06, Junio C Hamano <junkio@cox.net> wrote:
> "Francis Moreau" <francis.moro@gmail.com> writes:
>
> > I think this part is really confusing. For a new comer, saying that:
> >
> >       git diff a b == git diff a..b
> >
> > is really not intuitive. Maybe just because adding a new symbol ".."
> > in git diff command line means (for me) that we're doing a special
> > diff. I would never thought by my own that ".." means a simple "to".
>
> We did not originally have "A B"; you were supposed to always
> say "A..B".  But all other SCM had "A B" notation, so we added
> support for both because doing so was trivial and there is no
> risk of confusion (because diff is about two points while log is
> about a set).  These two notations are interchangeable for
> "diff".  If it confuses you, you can stick to the "git diff A B"
> notation.  Of if you are like Linus, stick to "A..B" notation.
> Either way, you can pretend that the other notation does not
> even exist and be happy ;-).
>

no, no, I think you miss my point here. What is confusing, and it
seems I'm not the only one to find it confusing,  is the fact that
"git diff A B == git diff A..B", not the "A..B" notation per se.

git diff A B, is really intuitive and easy to understand because we
all use to using the diff "A B" notation and it always has worked with
2 endpoints. So I would bet that all newbies who use for the first
time the git diff command will use "A B" notation, not "A..B" one.

> Yes, users often wondered why "git diff" accepts "A B", "git
> log" wants "A..B" and "git log A B" is a disaster.  But the root
> cause of the confusion was not about notation but about the
> conceptual difference (two points vs a set).
>
> I do not think changing the meaning of "diff A..B" to what "diff
> A...B" means is a good thing.  The notation "..." even _looks_
> like a magic, and in diff context, what it does _is_ magic (it
> is magic in log context, too).  You are giving two points, but

But ".." is magic too ! I would really expect something magic to
happen when using the "A..B" notation because I'm a new comer in git
and I never used the "A..B" notation before.

And since I already used this notation when using git log command, I
would expect "git diff A..B" to give the current result given by "git
diff A...B".

But yes, now I have understand that git diff works with end points
unlike git log, I can stick with two notations:

        git diff A B
        git diff A...B (3 dots)

and I'm happy ;)

thanks
-- 
Francis

```

## Carl Worth, 2006-12-22 22:20

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <877iwjinda.wl%cworth@cworth.org>
URL: https://gitlist.dev/e/877iwjinda.wl%25cworth%40cworth.org
In-Reply-To: <Pine.LNX.4.64.0612212009370.3536@woody.osdl.org>

```
On Thu, 21 Dec 2006 20:13:52 -0800 (PST), Linus Torvalds wrote:
> I do it all the time, I never even use the old-fashioned syntax any more.
> It's much more concise and easy to read, and it has all the nice shortcuts
> (like empty meaning "HEAD", so you can do "git diff ..next" to see the
> diff from HEAD to another branch).

I can understand the advantage of a shortcut like "git diff ..next",
but I still don't understand why it's the comparison of HEAD and next
that's really interesting here. Wouldn't comparing the merge-base to
next be more desirable? For example, if I'm considering whether to
merge in next or not, why should I care to see in the diff all the
irrelevant stuff that's happened on HEAD since next branched off?

But, really, I still don't understand exactly _what_ "diff a..b" even
means. Can you explain it to me?

Presumably the rev-parse magic is happening to the arguments. So does
the diff code just end up seeing the expanded equivalent of "b ^a" and
then just use the ^ to decide which tree to be on the left side or
something?

> It's also useful exactly because of the semantics of things like "...".

And now I'm really confused. If I'm not mistaken, rev-parse will turn
"a...b" into something like "a b ^$(merge-base a b)", right? So does
the diff code now end up seeing three different tree specifiers? What
does it do with that? And how is this useful? (As you said before,
diff is always going to end up acting on only two items, so I don't
see where there could be an interesting distinction from how you
obtain two items from "a..b" compared to "a...b".) But it might be
just that I'm really confused here.

> So "git diff a b" doesn't even look good to me any more, because it's
> literally missing that mental "to" that the ".." adds for me when I read
> it.

OK, that's fine. But can you comment on why you want the comparison
between the tips and not something based on a comparison from the
merge-base to a tip?

-Carl

```

## Linus Torvalds, 2006-12-22 22:34

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <Pine.LNX.4.64.0612221432430.3671@woody.osdl.org>
URL: https://gitlist.dev/e/Pine.LNX.4.64.0612221432430.3671%40woody.osdl.org
In-Reply-To: <877iwjinda.wl%cworth@cworth.org>

```


On Fri, 22 Dec 2006, Carl Worth wrote:
> 
> I can understand the advantage of a shortcut like "git diff ..next",
> but I still don't understand why it's the comparison of HEAD and next
> that's really interesting here.

I can't understand why people complain about this.

YOU DON'T HAVE TO USE IT. 

Nobvody forces you. Really. And dammit, if I want to compare HEAD and 
next, I compare HEAD and next. You have absolutely no business saying that 
you don't understand why I'd want to do it. It's MY LIFE.

> But, really, I still don't understand exactly _what_ "diff a..b" even
> means. Can you explain it to me?

It means exactly the same as "diff a b".

It's that simple.

So now go away. Stop complaining.

		Linus

```

## Junio C Hamano, 2006-12-22 22:45

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <7v7iwjwnwh.fsf@assigned-by-dhcp.cox.net>
URL: https://gitlist.dev/e/7v7iwjwnwh.fsf%40assigned-by-dhcp.cox.net
In-Reply-To: <877iwjinda.wl%cworth@cworth.org>

```
Carl Worth <cworth@cworth.org> writes:

> On Thu, 21 Dec 2006 20:13:52 -0800 (PST), Linus Torvalds wrote:
>> I do it all the time, I never even use the old-fashioned syntax any more.
>> It's much more concise and easy to read, and it has all the nice shortcuts
>> (like empty meaning "HEAD", so you can do "git diff ..next" to see the
>> diff from HEAD to another branch).
>
> I can understand the advantage of a shortcut like "git diff ..next",
> but I still don't understand why it's the comparison of HEAD and next
> that's really interesting here. Wouldn't comparing the merge-base to
> next be more desirable?

"git diff ...next" should work just as well, I think.

> But, really, I still don't understand exactly _what_ "diff a..b" even
> means. Can you explain it to me?

diff between two points.

> Presumably the rev-parse magic is happening to the arguments. So does
> the diff code just end up seeing the expanded equivalent of "b ^a" and
> then just use the ^ to decide which tree to be on the left side or
> something?

Exactly; diff just reuses the non-magic part of revision
parameter parsing without using the ancestry traversal
machinery (which is the magic part).

>> It's also useful exactly because of the semantics of things like "...".
>
> And now I'm really confused. If I'm not mistaken, rev-parse will turn
> "a...b" into something like "a b ^$(merge-base a b)", right? So does
> the diff code now end up seeing three different tree specifiers? What
> does it do with that?

It knows that rev-parse makes it "b a ^base", and it knows what
the user meant is "base..b".

That's all because we teach them to spell "a...b" when they want
"base..b".  Similarly, because we allow them to spell "a..b"
when they mean "between two points, a and b", it handles "b ^a"
as the equivalent to giving two trees separately, as "a b".

> And how is this useful? (As you said before,
> diff is always going to end up acting on only two items, so I don't
> see where there could be an interesting distinction from how you
> obtain two items from "a..b" compared to "a...b".) But it might be
> just that I'm really confused here.

I do not think you are seriously saying that comparing A and
B in this picture is meaningless:

      o---o---B
     /
 ---M---o---A

Yes, it is often useful to compare M and B, but that "often" is
limited to the phase of the workflow where you are at A and are
contemplating of merging B.  But merging two forked branches is
not the only thing you do.

Comparing two revisions regardless of how they are topologically
related is useful as often.  It is only that it may not as
useful while you are trying to merge B into A.

So there are two ways to let you do both, and they need to be
specified differently (.. vs ...)  because you need to tell it
to do which one.

```

## Jakub Narebski, 2006-12-22 23:00

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <emhnsm$iuo$1@sea.gmane.org>
URL: https://gitlist.dev/e/emhnsm%24iuo%241%40sea.gmane.org
In-Reply-To: <877iwjinda.wl%cworth@cworth.org>

```
[Cc: Carl Worth <cworth@cworth.org>, Linus Torvalds <torvalds@osdl.org>
 git@vger.kernel.org]

Carl Worth wrote:

> On Thu, 21 Dec 2006 20:13:52 -0800 (PST), Linus Torvalds wrote:
>> I do it all the time, I never even use the old-fashioned syntax any more.
>> It's much more concise and easy to read, and it has all the nice shortcuts
>> (like empty meaning "HEAD", so you can do "git diff ..next" to see the
>> diff from HEAD to another branch).
> 
> I can understand the advantage of a shortcut like "git diff ..next",
> but I still don't understand why it's the comparison of HEAD and next
> that's really interesting here. Wouldn't comparing the merge-base to
> next be more desirable? For example, if I'm considering whether to
> merge in next or not, why should I care to see in the diff all the
> irrelevant stuff that's happened on HEAD since next branched off?
> 
> But, really, I still don't understand exactly _what_ "diff a..b" even
> means. Can you explain it to me?

For me, it's just a bit of syntactic sugar (I always have in mind that
git-log and friends outputs commit list and use revisions range, while
git-diff and friends needs two (or less) revisions) allowing to
copy'n'paste arguments from "git log a..b" to "git diff a..b"
 
> Presumably the rev-parse magic is happening to the arguments. So does
> the diff code just end up seeing the expanded equivalent of "b ^a" and
> then just use the ^ to decide which tree to be on the left side or
> something?

And that is just implementation. I don't think anyone uses "git diff b ^a".

>> It's also useful exactly because of the semantics of things like "...".
> 
> And now I'm really confused. If I'm not mistaken, rev-parse will turn
> "a...b" into something like "a b ^$(merge-base a b)", right? So does
> the diff code now end up seeing three different tree specifiers? What
> does it do with that? And how is this useful? (As you said before,
> diff is always going to end up acting on only two items, so I don't
> see where there could be an interesting distinction from how you
> obtain two items from "a..b" compared to "a...b".) But it might be
> just that I'm really confused here.

I would have thought that it would be combined diff of a and b against
it's merge base... but it is not.

"git diff a...b" is turned into "git diff a b ^$(git merge-base a b)",
and by a bit of magic (and by a convention) it is turned into
"git diff ^$(merge-base a b) a" (and a...b ceases to be _symmetric_
for git-diff).

I'd like for "git diff --cc a...b" to do 'the right thing' and show
git diff --cc for pretended merge (I'm not sure if with or without
resolving trivial conflicts).

>> So "git diff a b" doesn't even look good to me any more, because it's
>> literally missing that mental "to" that the ".." adds for me when I read
>> it.
> 
> OK, that's fine. But can you comment on why you want the comparison
> between the tips and not something based on a comparison from the
> merge-base to a tip?

a..b does not imply merge-base, a...b does.

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git

```

## Carl Worth, 2006-12-22 23:31

Subject: Re: Updated Kernel Hacker's guide to git
Message-ID: <8764c3ik3m.wl%cworth@cworth.org>
URL: https://gitlist.dev/e/8764c3ik3m.wl%25cworth%40cworth.org
In-Reply-To: <7v7iwjwnwh.fsf@assigned-by-dhcp.cox.net>

```
On Fri, 22 Dec 2006 14:45:18 -0800, Junio C Hamano wrote:
> Exactly; diff just reuses the non-magic part of revision
> parameter parsing without using the ancestry traversal
> machinery (which is the magic part).

Thanks, that helps.

> It knows that rev-parse makes it "b a ^base", and it knows what
> the user meant is "base..b".

Ahah! So the "a...b" syntax is how to get at what:

	git diff $(git merge-base a b) b

would give. Thanks for explaining, since that was not at all obvious.

> That's all because we teach them to spell "a...b" when they want
> "base..b".  Similarly, because we allow them to spell "a..b"
> when they mean "between two points, a and b", it handles "b ^a"
> as the equivalent to giving two trees separately, as "a b".

Where is that teaching happening exactly? Both the "a..b" and "a...b"
forms seem to be entirely missing from the documentation of git
diff. :-)

> I do not think you are seriously saying that comparing A and
> B in this picture is meaningless:
>
>       o---o---B
>      /
>  ---M---o---A

No, I'm certainly not saying that that that comparison is meaningless.

All I was trying to say is that comparing M to B would be meaningful
too, and I hoped that git would provide good syntax for both. If I'm
understanding things correctly now, what exists is:

  git diff A B
  git diff A..B

	Compare A to B

  git diff A...B

	Compare M to B

So, at the beginning of this thread I wasn't aware that git provided
any short syntax for the "M to B" comparison, (the thread started with
suggestions for adding "git diff $(git merge-base A B) B" to the
hackers guide).

Now, I'm happy to know that git does provide a short syntax for that
useful operation.

My only comment now is that the distinction between ".." and "..." in
git-diff is quite surprising. In fact, in one sense it's exactly
opposite from the distinction of ".." and "..." as used in git log.

For example, given the above graph, "git diff A..B" shows changes due
to all 5 of commits on both branches while "git log -p A..B" shows
only the changes of the 3 commits from M to B.

Meanwhile, "git diff A...B" shows changes due to the 3 commits from M
to B while "git log -p A...B" shows the changes from all 5 of the
commits on both branches.

That's really surprising behavior (to me at least).

-Carl

```
