threads / discuss / 6000

Commit-ish shortcut for immediate parent range

Subject: Commit-ish shortcut for immediate parent range

## tl;dr

13 messages between Oct 22, 2006 and Oct 23, 2006.

replies: 12people: 6as markdown or json

Andy Parkins· Oct 22, 2006, 14:48 UTC · lore
Hello,

Git's commit-ish is very powerful. I was wondering however, if there was a shortcut for (for example)?

 git-diff 3435fdb4c^..3435fdb4c
That is - the short range of a particular commit's parent to that commit; like
 git-diff 3435fdb4c!
Or similar.
Andy
-- 
Dr Andrew Parkins, M Eng (Hons), AMIEE
andyparkins@gmail.com
Jakub Narebski· Oct 22, 2006, 15:11 UTC · re: Andy Parkins · lore

Re: Commit-ish shortcut for immediate parent range

Andy Parkins wrote:
> Git's commit-ish is very powerful.  I was wondering however, if there was a 
> shortcut for (for example)?
> 
>  git-diff 3435fdb4c^..3435fdb4c

Thats "git-diff 3435fdb4c^ 3435fdb4c" - diff need pair of things (one or more might be implied/default), not DAG.

Show 5 quoted lines
> That is - the short range of a particular commit's parent to that commit; like
> 
>  git-diff 3435fdb4c!
> 
> Or similar.

Or similar. You have to use git-diff-tree, not git-diff as git-diff uses working tree as second tree if second argument is not given (and index as first tree if first argument is not given).

$ git diff-tree -p 3435fdb4c

(-p to show patch instead of "whatchanged" output) shows diff to parent of commit 3435fdb4c (if commit is merge commit, show nothing; use -m or -c or --cc then).

By the way 3435fdb4c.. means 3435fdb4c..HEAD, and ..3435fdb4c means HEAD..3435fdb4c (where HEAD means current branch).

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Linus Torvalds· Oct 22, 2006, 17:25 UTC · re: Andy Parkins · lore

Re: Commit-ish shortcut for immediate parent range

On Sun, 22 Oct 2006, Andy Parkins wrote:
Show 9 quoted lines
> 
> Git's commit-ish is very powerful.  I was wondering however, if there was a 
> shortcut for (for example)?
> 
>  git-diff 3435fdb4c^..3435fdb4c
> 
> That is - the short range of a particular commit's parent to that commit; like
> 
>  git-diff 3435fdb4c!

Umm. That's not actually a very sensible operation. It's only sensible in the special case of "diff", and for that special case, what we do is to actually just say that the _command_ is special, not the range.

It's called "git show".
So the thing to do is just
	git show 3435fdb4c
and be happy.
Anyway, there's two kinds of commands wrt revision ranges in git:
 - "git diff"
 - everything else

That may sound strange, but it's true. "git diff" doesn't really do "revision ranges". It does "two revision endpoints", which is literally very different from just about any other git command. All the other commands really think of commits as a "set of individual commits" (where sometimes the "set" is admittedly just a single commit).

So the reason for you wanting that "3435fdb4c^..3435fdb4c" is not that it's a particularly useful thing in _general_, it's that "git diff" wants two endpoints, and you want to have that describe a single commit.

Hopefully this explains why it's the _command_ that is special, and not the range. The range makes no sense.

				Linus
Linus Torvalds· Oct 22, 2006, 18:25 UTC · re: Linus Torvalds · lore

Re: Commit-ish shortcut for immediate parent range

On Sun, 22 Oct 2006, Linus Torvalds wrote:
Show 6 quoted lines
> 
> So the thing to do is just
> 
> 	git show 3435fdb4c
> 
> and be happy.
Btw, if you really _only_ want the diff, you can do either
	git-diff-tree -p 3435fdb4c

which is the traditional "core" command for this. Somewhat sadly, I don't think we have a way to actually turn _off_ the description printing, so while you can turn off the _diff_ with "-s", the best you can do wrt the commit message is probably to use "--pretty=oneline" to cut it down to a single line.

I wonder if we should have a "--pretty=none" thing, so that you can use the "higher-level" git commands without seeing the log message.

Hmm..
			Linus
Andy Parkins· Oct 22, 2006, 20:17 UTC · re: Linus Torvalds · lore

Re: Commit-ish shortcut for immediate parent range

On Sunday 2006, October 22 18:25, Linus Torvalds wrote:
Show 5 quoted lines
> Umm. That's not actually a very sensible operation. It's only sensible in
> the special case of "diff", and for that special case, what we do is to
> actually just say that the _command_ is special, not the range.
>
> It's called "git show".

You're entirely correct, that that is what I was looking for in that particular case. However, the reason I raised it as a question was that I was poking around with git (which I'm enjoying immensely by the way - it really is as perfect an SCM as I have ever used) and in short succession did

git-diff X^..X git-log X^..X git-format-patch X^..X

I imagined that I would eventually stumble on other git commands where I would want to do this operation again. I'm sure I will have picked an incorrect command in each case, however, they all did exactly what I wanted so I stopped looking for the "right" command :-)

Andy
-- 
Dr Andrew Parkins, M Eng (Hons), AMIEE
andyparkins@gmail.com
Linus Torvalds· Oct 22, 2006, 20:56 UTC · re: Andy Parkins · lore

Re: Commit-ish shortcut for immediate parent range

On Sun, 22 Oct 2006, Andy Parkins wrote:
Show 9 quoted lines
> 
> You're entirely correct, that that is what I was looking for in that 
> particular case.  However, the reason I raised it as a question was that I 
> was poking around with git (which I'm enjoying immensely by the way - it 
> really is as perfect an SCM as I have ever used) and in short succession did
> 
> git-diff X^..X
> git-log X^..X
> git-format-patch X^..X

Now, "git show" obviously does exactly what you probably wanted, but for future reference, the "git log" family of commands also take a "number of commits" limiter.

So you can also do things like
	git log --cc -1 X

and it will actually do something very similar to "git show". It's not _quite_ identical, but it's close - at least for the special case of a single commit.

"git show" actually uses a magic "no_walk" internal flag which means that you can give it _several_ revisions, and it will take them as a raw "list" of revisions rather than take them as a command to "walk" the revision space and then just show one of them (like the "git log --cc -1" example would do).

So with "git show", you can do
	git show X Y Z
and it will show those exact three commits. That's _different_ from
	git log --cc -3 X Y Z

which will show the three "most recent" commits when you start walking the revision DAG. (The above "git log" command really doesn't make much sense, since the output will depend on commit date - it has well-specified behaviour, but it's really a pretty random thing to do: it might, for example, show the three commits X, X^ and Z, and not Y at all).

Anyway, "git show" is a very useful thing. It's actually one of the commands I use most. If I ever want to see what happened in a single commit (eg somebody sends me a bug-report and says "commit XYZ introduced a regression"), that's what I would use.

Looking at my history, the commands I tend to use most are:
	git log
	git diff
	git pull <some-remote-repo>
	gitk ORIG_HEAD..
	git log -p some/directory/or/file
	git grep -w <some-identifier> [possibly-some-subdirectory]
	git show <some-rev>

and while I think that "git pull" and "gitk ORIG_HEAD.." thing tends to be something special to being a top-level maintainer (although maybe I'm wrong - you'd probably do the same just because you're following a remote tree under active development), all the rest are commands that everybody should know so intimately that they don't even need to think about them.

"git grep" in particular seems to be something that a lot of people haven't necessarily even realized is there. Yet it's actually extremely powerful and efficient both for the "current tree" and for "old revisions".

It's interesting: I used to do a lot of "plain grep" usage, but with git, most of my greps by far are all of the form "git grep". I've gotten so used to it that I find myself wanting to do "git grep" even on non-git stuff, and if I look at somebody elses tar-ball I often end up doing

	git init-db
	git add .

just to be able to do "git grep" on it. I've totally stopped doing the "find . -name '*.[ch]' | xargs grep -w" sequence that I _used_ to do a lot of.

			Linus
Jakub Narebski· Oct 22, 2006, 21:41 UTC · re: Linus Torvalds · lore

Re: Commit-ish shortcut for immediate parent range

Linus Torvalds wrote:
Show 11 quoted lines
> Now, "git show" obviously does exactly what you probably wanted, but for 
> future reference, the "git log" family of commands also take a "number of 
> commits" limiter.
> 
> So you can also do things like
> 
>         git log --cc -1 X
> 
> and it will actually do something very similar to "git show". It's not 
> _quite_ identical, but it's close - at least for the special case of a 
> single commit.

And of course this shortcut is not documented. git-log(1) and git-rev-list(1) talks only about "--max-count=<n>", and "-n <n>", and doesn't talk about possible shortcuts "-n<n>" and "-<n>". Perhaps because those shortcuts are discouraged?

Additionally you can find "-n <n>" shortcut only further on the git-rev-list(1).

Patch will follow.
BTW. what does "recursive diff" mean (in git)?
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Jakub Narebski· Oct 22, 2006, 22:33 UTC · re: Johannes Schindelin · lore

Re: Commit-ish shortcut for immediate parent range

Johannes Schindelin wrote:
Show 5 quoted lines
> On Sun, 22 Oct 2006, Jakub Narebski wrote:
> 
>> BTW. what does "recursive diff" mean (in git)?
> 
> AFAIU it means that the diff code recurses into subdirectories.
When git-diff _doesn't_ recurse into subdirectories?
-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Junio C Hamano· Oct 22, 2006, 23:36 UTC · re: Jakub Narebski · lore

Re: Commit-ish shortcut for immediate parent range

Jakub Narebski <jnareb@gmail.com> writes:
Show 9 quoted lines
> Johannes Schindelin wrote:
>
>> On Sun, 22 Oct 2006, Jakub Narebski wrote:
>> 
>>> BTW. what does "recursive diff" mean (in git)?
>> 
>> AFAIU it means that the diff code recurses into subdirectories.
>
> When git-diff _doesn't_ recurse into subdirectories?
When it is not told to.

The Porcelainish commands (git-diff, git-show) default to recursive, but low-level commands don't.

Compare these three:
	git diff --raw v1.4.3.1^^^..v1.4.3.1^^
	git diff-tree v1.4.3.1^^^..v1.4.3.1^^
	git diff-tree -r v1.4.3.1^^^..v1.4.3.1^^
Linus Torvalds· Oct 23, 2006, 03:33 UTC · re: Jakub Narebski · lore

Re: Commit-ish shortcut for immediate parent range

On Sun, 22 Oct 2006, Jakub Narebski wrote:
> 
> BTW. what does "recursive diff" mean (in git)?

For projects with subdirectories (and git itself has almost none), the default "raw, nonrecursive" diff looks something like this:

	f8829caee311207afbc882794bdc5aa0db5caf33
	:040000 040000 db7ae247da2ede4d0f932b86771424534d2960b8 9033be5eb62db6fd778793f9f51e28734bb3d9f8 M      arch
	:040000 040000 c96e5293819986ae7c13a8ef779c5f2066b9575f 5950afceabd99053964778b49df19ba794a21b75 M      include
while the same commit with "raw, recursive" looks like
	f8829caee311207afbc882794bdc5aa0db5caf33
	:100644 100644 88b72c9a84957f2ac787ccf83fa46c4dbb0818d2 2de4d3c367a2c2da9adb6bcf29b5105c46c01f78 M      arch/mips/mm/init.c
	:100644 100644 4bdaa05f485b446e0d66587015cbd8378abf4a69 4a61e624b0ecfcd921a560d426e92e1df2df1de2 M      arch/mips/mm/pgtable-32.c
	:100644 100644 44b5e97fff65f75286fdd15f33c2bcf40841082a 8d600d307d5ddb3f617ffc34929ea98d4613b4a7 M      arch/mips/mm/pgtable-64.c
	:100644 100644 9ab59e2bb23368530fa67c95af0d6ab2c4f7fe8f e3c9925876a3ce4eb80ec67937362cd7d014ad2f M      include/asm-mips/cacheflush.h
	:100644 100644 6959bdb59310b096ec7797e0a31c78fde5aa9afc 02c8a13fc894838b27336ae42fbb542f87132e01 M      include/asm-mips/fixmap.h
ie the "recursive" diff will recurse into subdirectories.

A _patch_ is always recursive (you cannot make a patch-like diff for just the "tree entry", only for actual blobs), so you can only see this difference for raw git SHA1 diffs.

		Linus
Johannes Schindelin· Oct 22, 2006, 20:55 UTC · re: Linus Torvalds · lore

Re: Commit-ish shortcut for immediate parent range

Hi,
On Sun, 22 Oct 2006, Linus Torvalds wrote:
> Anyway, there's two kinds of commands wrt revision ranges in git:
> 
>  - "git diff"
>  - everything else

Well, there is also "git format-patch". If you provide it with only one commit-ish "<rev>", it will believe you actually meant "<rev>..".

Ciao, Dscho

Jeff King· Oct 22, 2006, 19:53 UTC · re: Andy Parkins · lore

Re: Commit-ish shortcut for immediate parent range

On Sun, Oct 22, 2006 at 03:48:35PM +0100, Andy Parkins wrote:
Show 10 quoted lines
> Git's commit-ish is very powerful.  I was wondering however, if there was a 
> shortcut for (for example)?
> 
>  git-diff 3435fdb4c^..3435fdb4c
> 
> That is - the short range of a particular commit's parent to that commit; like
> 
>  git-diff 3435fdb4c!
> 
> Or similar.

I think a more general (but possibly harder to implement and use!) form would be a commit-ish token for "refer to previous commit-ish." This would not increase expressiveness, but could save a lot of typing. So if '!' meant "the last sha1/ref parsed", your example range would be:

  3435fdb4c^..!
but you could also do more exotic things like:
  3435fdb4c~25..!~20

Obviously you could think of more interesting ways to refer to previous THINGS. But I think in most cases in which you have repeated refs, you really are just repeating one ref twice as a basis for a range.

The '!' character is probably a bad choice, since it's generally an interactive shell metacharacter. I'm not sure what would be a better choice; we're running low on punctuation.

At any rate, I'm not convinced this is a worthwhile optimization. It's annoying to have to re-specify a long sha1, but in 99% of cases, you really are looking for sha1^..sha1. As others have pointed out, that's already handled through git-show.

-Peff

← back to recent threads