9

First of all: There are already two questions on StackOverflow with solid answers regarding this topic, but I'm still puzzling. I sort of understand the 'what', but not the 'why'.

My question is: Why shows git log A..B (double dot) the list of commits from B to A, but in order to get the diff of the same set of commits one has to write git diff A...B (triple dot).

Wouldn't it be much more consistent if git log and git diff would treat commit ranges the same way? They now appear to behave orthogonal to each other.

Maybe I'm missing some kind of insight about why it is designed like this?

Git log vs diff

Saeed Hassanvand
  • 931
  • 1
  • 14
  • 31
  • Mort's answer is pretty good, but ultimately, when you ask "why did person *X* do action *Y*" we all wind up having to speculate, unless person X wrote down his/her reasons. You'd have to ask Linus, perhaps. Note that when using `A..B` in `git log`, you never see commit `A` itself, while when using `git diff A..B`, one of the two inputs is `A` itself: another inconsistency of sorts. – torek Nov 02 '18 at 15:43
  • You don't necessarily have to speculate. Often there will be public discourse *somewhere* about it and that can be referenced to answer the question. – Catskul Apr 04 '22 at 16:52

2 Answers2

4

git diff always operates on just two commits (refs), never more never fewer, and shows the differences between them. It is not doing anything with a "range", just two commits.

git log, on the other hand, displays ranges of commits, and you can specify any number of ranges in a number of different ways. So right there, you see that git diff and git log are going to behave differently.

I don't think you can even compare two commits with a range of commits. I think it's more that "The .. syntax is a shorthand for 'from .. to' and that shorthand will mean different things in different contexts. But then we realized that there's a very frequently needed 'from the last common ancestor of .. to' idiom in git diff, so we made the similar, but slightly different ... syntax."

Mort
  • 3,379
  • 1
  • 25
  • 40
4

It seems it was simply a mistake in design:

Junio C Hamano @ 2019-12-23 18:02:

Please unlearn dot-dot and three-dots when using "git diff", which is not about ranges but about comparing two endpoints. If we were reinventing Git today from scratch, we would make "git diff A..B" an error. You can consider it a bug that the command accepts a range notation, but this will not change any time soon without a large fight to find and fix uses of the syntax in scripts by longtime Git users have written over the years.

Allowing dot-dot on the command line of "git diff", instead of diagnosing them as errors and dying, was a stupid mistake we (well, mostly Linus, but I am willing to take the blame too) made due to laziness when we reused the machinery, which we invented to parse the command line of "log" family of commands to specify ranges, to parse the command line of "diff", which accidentally ended up allowing the syntax for ranges where it shouldn't be allowed.

And worse yet, since there was only dot-dot and three-dots came much later, "git diff A..B" ended up comparing the endpoints A and B, because there didn't even A...B notation exist.

This is not limited to you but any user of modern Git is better off to pretend "git diff A..B" does not exist; please unlearn dot-dot and three-dots when using "git diff" and you'd be happier.

If you're wondering who Junio is:

Junio Hamano (Japanese: 濱野 純) is a software engineer and hacker from Japan. He is best known for leading a large team of software developers who maintain Git. Linus Torvalds, the original developer, has said that one of his big successes was recognizing Hamano's skills as a developer.

Catskul
  • 17,916
  • 15
  • 84
  • 113