Re: Is "show-ref -h" a good test for an empty repository?

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

Re: Is "show-ref -h" a good test for an empty repository?

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:45:19

Jeff King [off-list ref] writes:
On Sun, Sep 07, 2008 at 10:21:16AM -0400, Eric Gerlach wrote:
quoted
quoted
quoted
I'm trying to test to see if "git diff --cached" will fail because 
there  are no existing commits.  I've come up with running "git 
show-ref -h -q"  and testing its return value.  My hypothesis is: If 
Maybe "git rev-parse --verify HEAD"?
That seems like it would work too... any reason one would be better than  
the other?
My thinking was:

  1. It's a plumbing command, and so less likely to change its behavior
     versus "git diff".

  2. The seems more obvious to me. rev-parse --verify is meant to ask
     "is this a valid object name?"

It is slightly different from your show-ref. Yours asks "is there
anything in refs/heads in this repository?" Mine asks "does the current
HEAD exist?" In practice, they are both reasonable tests, since once you
have a branch, it is very difficult to get HEAD to point to something
invalid short of editing manually to some bogus value. But you might
prefer one over the other depending on what you are trying to say.
All depends on how "an empty repository" is defined.  My definition of an
empty repository would have been:

 - No objects in it;
 - No index;
 - No refs except symrefs.

Re: Is "show-ref -h" a good test for an empty repository?

From: Jeff King <hidden>
Date: 2016-06-15 22:45:19

On Sun, Sep 07, 2008 at 10:31:52AM -0700, Junio C Hamano wrote:
All depends on how "an empty repository" is defined.  My definition of an
empty repository would have been:

 - No objects in it;
 - No index;
 - No refs except symrefs.
Agreed. In the original message, he used the phrase "no existing
commits" which I latched onto (to mean "no existing commits on this
branch"). But the subject does say "empty repository". :)

Eric, maybe you can tell us more about what you're trying to accomplish?

-Peff

Re: Is "show-ref -h" a good test for an empty repository?

From: Eric Gerlach <hidden>
Date: 2016-06-15 22:45:19

Jeff King wrote:
On Sun, Sep 07, 2008 at 10:31:52AM -0700, Junio C Hamano wrote:
quoted
All depends on how "an empty repository" is defined.  My definition of an
empty repository would have been:

 - No objects in it;
 - No index;
 - No refs except symrefs.
Agreed. In the original message, he used the phrase "no existing
commits" which I latched onto (to mean "no existing commits on this
branch"). But the subject does say "empty repository". :)

Eric, maybe you can tell us more about what you're trying to accomplish?
Sure, I'm writing a patch for the debcommit script for the Debian 
project.  It's a script which parses the Debian changelog for a package, 
generates a commit message, and commits to an SCM system.

The case I'm looking to protect against is the following:

$ mkdir -p new-repo/debian
$ cd new-repo
$ git init
$ vi debian/changelog (add a few lines)
$ git add debian/changelog
$ debcommit

(which runs
$ git diff --cached debian/changelog)

If I can test before the git-diff, then I can run "diff debian/changelog 
/dev/null" instead of the git-diff and all is well.

I don't want to test failure of the git-diff itself, because I want 
debcommit to fail if there's something wrong *other* than a new repo. 
Also, I want to use a git command to do it, because I don't have any 
guarantees about how things are setup, other than "we're using git."

I'm okay with debcommit proceeding if the repo has a commit but is 
borked from manually editing the HEAD ref, but I'm not sure how the 
maintainers of the script feel about that.  So if it's possible to 
differentiate between the two cases, bonus, but not necessary.

So that's where I'm sitting.  Jeff and Junio, thanks for the help and 
discussion.  This is great :-)

(BTW, I'm leaning to the rev-parse right now; looking at the source it 
seems to be more precise, i.e. has fewer ways to fail)

Cheers,

Eric

Re: Is "show-ref -h" a good test for an empty repository?

From: Jeff King <hidden>
Date: 2016-06-15 22:45:19

On Mon, Sep 08, 2008 at 09:24:39AM -0400, Eric Gerlach wrote:
The case I'm looking to protect against is the following:

$ mkdir -p new-repo/debian
$ cd new-repo
$ git init
$ vi debian/changelog (add a few lines)
$ git add debian/changelog
$ debcommit

(which runs
$ git diff --cached debian/changelog)

If I can test before the git-diff, then I can run "diff debian/changelog  
/dev/null" instead of the git-diff and all is well.
In that case, I would use the "rev-parse --verify HEAD" I mentioned,
since it exactly covers the situation you are trying to avoid.  What you
are saying is something like:

  if there is a previous commit on the current branch
    diff against previous commit on the current branch
  else
    diff against /dev/null

So your "show-ref" attempt could actually say "yes, the repo is
non-empty" but your diff would still fail (because the commits just
weren't on the current branch).


As an aside, it's too bad "--root" isn't more widely supported. Then

  git diff --root --cached

would do what you want without the need for any conditionals. But it
seems that --root only works between trees. Something like the patch
below would help, but I'm sure this is covering only one of many cases.

---
diff --git a/builtin-diff.c b/builtin-diff.c
index 52470c7..43db970 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -317,8 +317,11 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
 				break;
 			else if (!strcmp(arg, "--cached")) {
 				add_head_to_pending(&rev);
-				if (!rev.pending.nr)
-					die("No HEAD commit to compare with (yet)");
+				if (!rev.pending.nr) {
+					if (!rev.show_root_diff)
+						die("No HEAD commit to compare with (yet)");
+					add_empty_to_pending(&rev);
+				}
 				break;
 			}
 		}
diff --git a/revision.c b/revision.c
index 2f646de..7ec3990 100644
--- a/revision.c
+++ b/revision.c
@@ -145,16 +145,27 @@ void add_pending_object(struct rev_info *revs, struct object *obj, const char *n
 	add_pending_object_with_mode(revs, obj, name, S_IFINVALID);
 }
 
-void add_head_to_pending(struct rev_info *revs)
+static void add_to_pending_by_name(struct rev_info *revs, const char *name)
 {
 	unsigned char sha1[20];
 	struct object *obj;
-	if (get_sha1("HEAD", sha1))
+	if (get_sha1(name, sha1))
 		return;
 	obj = parse_object(sha1);
 	if (!obj)
 		return;
-	add_pending_object(revs, obj, "HEAD");
+	add_pending_object(revs, obj, name);
+}
+
+void add_head_to_pending(struct rev_info *revs)
+{
+	add_to_pending_by_name(revs, "HEAD");
+}
+
+void add_empty_to_pending(struct rev_info *revs)
+{
+	add_to_pending_by_name(revs,
+			"4b825dc642cb6eb9a060e54bf8d69288fbee4904");
 }
 
 static struct object *get_reference(struct rev_info *revs, const char *name, const unsigned char *sha1, unsigned int flags)
diff --git a/revision.h b/revision.h
index 2fdb2dd..8c990d5 100644
--- a/revision.h
+++ b/revision.h
@@ -152,6 +152,7 @@ extern void add_object(struct object *obj,
 extern void add_pending_object(struct rev_info *revs, struct object *obj, const char *name);
 
 extern void add_head_to_pending(struct rev_info *);
+extern void add_empty_to_pending(struct rev_info *);
 
 enum commit_action {
 	commit_ignore,
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help