Rework get_rev_name to return NULL rather than "undefined" when a reference is undefined. If --undefined is passed (default) git-name-rev prints "undefined" for the name, else it die()s. Make git-describe use --no-undefined when calling git-name-rev so that --contains behavior matches the standard git-describe one. Signed-off-by: Pierre Habouzit <madcoder@xxxxxxxxxx> --- On sam, déc 22, 2007 at 06:02:44 +0000, Pierre Habouzit wrote: > Like I said on IRC, I saw that git describe --contains has a bad > behaviour: > > $ git describe --match='asd*' HEAD; echo $? > fatal: cannot describe 'e272415ab7da3bde51af2ce95c88d7be3abfba28' > 128 > $ git describe --contains HEAD; echo $? > undefined > 0 Okay here is a patch to have git-name-rev have a strict mode where it rejects undefined's. With this patch: $ git describe --contains HEAD fatal: cannot describe 'e26a806b93f2f2f2354831ce0f943347a8ba7c3e' This patch is minimal and looks safe for master to me. A better patch would probably to have shared some logic between name-rev and describe, but this would have been a quite larger patch, and I was uncomfortable with it. builtin-describe.c | 3 ++- builtin-name-rev.c | 34 ++++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/builtin-describe.c b/builtin-describe.c index 18eab47..3428483 100644 --- a/builtin-describe.c +++ b/builtin-describe.c @@ -271,10 +271,11 @@ int cmd_describe(int argc, const char **argv, const char *prefix) save_commit_buffer = 0; if (contains) { - const char **args = xmalloc((5 + argc) * sizeof(char*)); + const char **args = xmalloc((6 + argc) * sizeof(char*)); int i = 0; args[i++] = "name-rev"; args[i++] = "--name-only"; + args[i++] = "--no-undefined"; if (!all) { args[i++] = "--tags"; if (pattern) { diff --git a/builtin-name-rev.c b/builtin-name-rev.c index a0c89a8..f22c8b5 100644 --- a/builtin-name-rev.c +++ b/builtin-name-rev.c @@ -125,18 +125,18 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void } /* returns a static buffer */ -static const char* get_rev_name(struct object *o) +static const char *get_rev_name(struct object *o) { static char buffer[1024]; struct rev_name *n; struct commit *c; if (o->type != OBJ_COMMIT) - return "undefined"; + return NULL; c = (struct commit *) o; n = c->util; if (!n) - return "undefined"; + return NULL; if (!n->generation) return n->tip_name; @@ -159,7 +159,7 @@ static char const * const name_rev_usage[] = { int cmd_name_rev(int argc, const char **argv, const char *prefix) { struct object_array revs = { 0, 0, NULL }; - int all = 0, transform_stdin = 0; + int all = 0, transform_stdin = 0, allow_undefined = 1; struct name_ref_data data = { 0, 0, NULL }; struct option opts[] = { OPT_BOOLEAN(0, "name-only", &data.name_only, "print only names (no SHA-1)"), @@ -169,6 +169,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) OPT_GROUP(""), OPT_BOOLEAN(0, "all", &all, "list all commits reachable from all refs"), OPT_BOOLEAN(0, "stdin", &transform_stdin, "read from stdin"), + OPT_BOOLEAN(0, "undefined", &allow_undefined, "allow to print `undefined` names"), OPT_END(), }; @@ -226,7 +227,7 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) else if (++forty == 40 && !ishex(*(p+1))) { unsigned char sha1[40]; - const char *name = "undefined"; + const char *name = NULL; char c = *(p+1); forty = 0; @@ -240,11 +241,10 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) } *(p+1) = c; - if (!strcmp(name, "undefined")) + if (!name) continue; - fwrite(p_start, p - p_start + 1, 1, - stdout); + fwrite(p_start, p - p_start + 1, 1, stdout); printf(" (%s)", name); p_start = p + 1; } @@ -260,18 +260,32 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix) max = get_max_object_index(); for (i = 0; i < max; i++) { struct object * obj = get_indexed_object(i); + const char *name; if (!obj) continue; if (!data.name_only) printf("%s ", sha1_to_hex(obj->sha1)); - printf("%s\n", get_rev_name(obj)); + name = get_rev_name(obj); + if (name) + printf("%s\n", name); + else if (allow_undefined) + printf("undefined\n"); + else + die("cannot describe '%s'", sha1_to_hex(obj->sha1)); } } else { int i; for (i = 0; i < revs.nr; i++) { + const char *name; if (!data.name_only) printf("%s ", revs.objects[i].name); - printf("%s\n", get_rev_name(revs.objects[i].item)); + name = get_rev_name(revs.objects[i].item); + if (name) + printf("%s\n", name); + else if (allow_undefined) + printf("undefined\n"); + else + die("cannot describe '%s'", sha1_to_hex(revs.objects[i].item->sha1)); } } -- 1.5.4.rc1.1123.ge26a8
Attachment:
pgpDWfo6WJgZF.pgp
Description: PGP signature