Can't diff against the 00000000 revision

5 messages, 2 authors, 2016-06-15 · open the first message on its own page

Can't diff against the 00000000 revision

From: Stefan Monnier <hidden>
Date: 2016-06-15 23:07:42

If I look at the initial commit on a branch, I see something like:

    % git show d59cfff346c3e210adc26501f8cebf8da5ab2e7d
    commit d59cfff346c3e210adc26501f8cebf8da5ab2e7d
    Author: Stefan Monnier [off-list ref]
    Date:   Wed Dec 2 20:46:51 2015 -0500
    
        Initial release
    
    diff --git a/bugit b/bugit
    new file mode 100755
    index 0000000..681bd38
    --- /dev/null
    +++ b/bugit
    @@ -0,0 +1,512 @@
    ...

which is great.  But I can't get the same result with

    git diff 0000000..681bd38

because it complains:

    % git diff 0000000..681bd38
    fatal: ambiguous argument '0000000..681bd38': unknown revision or path not in the working tree.
    Use '--' to separate paths from revisions, like this:
    'git <command> [<revision>...] -- [<file>...]'
    %

I bumped into this problem in a post-receive hook where I need to pay
attention to all newly added files, and where this problem means that
I can't use the same code for a newly added branch as for a push on
a pre-existing branch.

I currently work around the problem by adding a dummy empty branch, but
being able to use the revision 00000000 as a known reference to an empty
tree would come in really handy, and since it's already used at various
places in Git (post-receive hook and "git show" output, at least), it
would seem like a natural extension.


        Stefan

Re: Can't diff against the 00000000 revision

From: Jeff King <hidden>
Date: 2016-06-15 23:07:43

On Tue, Jan 12, 2016 at 10:17:24AM -0500, Stefan Monnier wrote:
If I look at the initial commit on a branch, I see something like:

    % git show d59cfff346c3e210adc26501f8cebf8da5ab2e7d
    commit d59cfff346c3e210adc26501f8cebf8da5ab2e7d
    Author: Stefan Monnier [off-list ref]
    Date:   Wed Dec 2 20:46:51 2015 -0500
    
        Initial release
    
    diff --git a/bugit b/bugit
    new file mode 100755
    index 0000000..681bd38
    --- /dev/null
    +++ b/bugit
    @@ -0,0 +1,512 @@
    ...

which is great.  But I can't get the same result with

    git diff 0000000..681bd38

because it complains:

    % git diff 0000000..681bd38
    fatal: ambiguous argument '0000000..681bd38': unknown revision or path not in the working tree.
    Use '--' to separate paths from revisions, like this:
    'git <command> [<revision>...] -- [<file>...]'
    %
Right. There is no "000000" blob; it's just a syntactic placeholder.

If you want to diff against the empty blob, you can. Its name is:

  $ git hash-object -t blob /dev/null
  e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
I bumped into this problem in a post-receive hook where I need to pay
attention to all newly added files, and where this problem means that
I can't use the same code for a newly added branch as for a push on
a pre-existing branch.
Keep in mind that the "000000" in your example is showing the change in
the _blob_, not the change in revisions. Even if it were not 0's, you
could not run "git diff A..B" on it, because that syntax only works with
commits.

So the corner case you need to deal with is not about a newly added
branch; it is about a newly added file (or in the opposite direction, a
deleted file).

Or from your description, maybe you are also running into the all-zero
sha1 in the argument to the post-receive hook (where it is standing in
for a commit sha1 on a newly-pushed branch).
I currently work around the problem by adding a dummy empty branch, but
being able to use the revision 00000000 as a known reference to an empty
tree would come in really handy, and since it's already used at various
places in Git (post-receive hook and "git show" output, at least), it
would seem like a natural extension.
The empty tree also has a name:

  $ git hash-object -t tree /dev/null
  4b825dc642cb6eb9a060e54bf8d69288fbee4904

and you can diff against that.

And hopefully that explains why "000000" does not necessarily make a
good placeholder for "the empty thing". There are multiple empty things,
and it is not clear what:

  git diff 0000000 1234abcd

means. Is 0000000 a tree? A blob?

-Peff

Re: Can't diff against the 00000000 revision

From: Jeff King <hidden>
Date: 2016-06-15 23:07:43

On Tue, Jan 12, 2016 at 10:32:39AM -0500, Jeff King wrote:
quoted
I currently work around the problem by adding a dummy empty branch, but
being able to use the revision 00000000 as a known reference to an empty
tree would come in really handy, and since it's already used at various
places in Git (post-receive hook and "git show" output, at least), it
would seem like a natural extension.
The empty tree also has a name:

  $ git hash-object -t tree /dev/null
  4b825dc642cb6eb9a060e54bf8d69288fbee4904
By the way, the empty tree and empty blob objects are baked-in to git,
so you can always rely on diffing against them. IOW, it is fine to
write:

  while read old new ref; do
	if test "$old" = "0000000000000000000000000000000000000000"; then
		old=4b825dc642cb6eb9a060e54bf8d69288fbee4904
	fi
	git diff-tree $old $new | whatever_checks_you_want_to_do
  done

in your post-receive hook.

-Peff

Re: Can't diff against the 00000000 revision

From: Stefan Monnier <hidden>
Date: 2016-06-15 23:07:43

quoted
I currently work around the problem by adding a dummy empty branch, but
being able to use the revision 00000000 as a known reference to an empty
tree would come in really handy, and since it's already used at various
places in Git (post-receive hook and "git show" output, at least), it
would seem like a natural extension.
The empty tree also has a name:

  $ git hash-object -t tree /dev/null
  4b825dc642cb6eb9a060e54bf8d69288fbee4904
Yay!

   git diff 4b825dc642cb6eb9a060e54bf8d69288fbee4904..d59cfff346c3e210adc26501f8cebf8da5ab2e7d

seems to give me the expected diff.
Thanks!
And hopefully that explains why "000000" does not necessarily make a
good placeholder for "the empty thing". There are multiple empty things,
and it is not clear what:
  git diff 0000000 1234abcd
means. Is 0000000 a tree? A blob?
Well, Git is the one who uses 000000 to refer to an empty thing, but
indeed it seems like it does inconsistently: it's sometimes used as the
"empty blob" and sometimes as an "empty tree".


        Stefan

Re: Can't diff against the 00000000 revision

From: Jeff King <hidden>
Date: 2016-06-15 23:07:43

On Tue, Jan 12, 2016 at 11:26:24AM -0500, Stefan Monnier wrote:
quoted
And hopefully that explains why "000000" does not necessarily make a
good placeholder for "the empty thing". There are multiple empty things,
and it is not clear what:
quoted
  git diff 0000000 1234abcd
quoted
means. Is 0000000 a tree? A blob?
Well, Git is the one who uses 000000 to refer to an empty thing, but
indeed it seems like it does inconsistently: it's sometimes used as the
"empty blob" and sometimes as an "empty tree".
Yes. You can think of it kind of like a NULL pointer; it just means
"nothing". So its meaning is context-dependent. The problem is if we
expect to feed it back to git in a place where the context isn't
obvious.

-Peff
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help