threads / patch / 12294

patchTeach git-describe --long to output always the long format

Subject: [PATCH] Teach git-describe --long to output always the long format

## tl;dr

12 messages between Feb 24, 2008 and Feb 26, 2008. Diffs are folded; open one to read it.

replies: 11people: 4as markdown or json

Santi Béjar· Feb 24, 2008, 14:46 UTC · lore

Sometimes it is convenient to have the sha1 of a commit even if it matches a tag.

Signed-off-by: Santi Béjar <sbejar@gmail.com>
---
 builtin-describe.c  |   11 ++++++++++-
 t/t6120-describe.sh |    2 ++
 2 files changed, 12 insertions(+), 1 deletions(-)
Show changes to 2 files +12 −1

builtin-describe.c, t/t6120-describe.sh

diff --git a/builtin-describe.c b/builtin-describe.c
index 3428483..e46105a 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -17,6 +17,7 @@ static const char * const describe_usage[] = {
 static int debug;	/* Display lots of verbose info */
 static int all;	/* Default to annotated tags only */
 static int tags;	/* But allow any tags if --tags is specified */
+static int longformat;
 static int abbrev = DEFAULT_ABBREV;
 static int max_candidates = 10;
 const char *pattern = NULL;
@@ -155,7 +156,11 @@ static void describe(const char *arg, int last_one)
 
 	n = cmit->util;
 	if (n) {
-		printf("%s\n", n->path);
+		if (!longformat)
+			printf("%s\n", n->path );
+		else
+			printf("%s-0-g%s\n", n->path,
+				find_unique_abbrev(cmit->object.sha1, abbrev));
 		return;
 	}
 
@@ -254,6 +259,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 		OPT_BOOLEAN(0, "debug",      &debug, "debug search strategy on stderr"),
 		OPT_BOOLEAN(0, "all",        &all, "use any ref in .git/refs"),
 		OPT_BOOLEAN(0, "tags",       &tags, "use any tag in .git/refs/tags"),
+		OPT_BOOLEAN(0, "long",       &longformat, "always use long format"),
 		OPT__ABBREV(&abbrev),
 		OPT_INTEGER(0, "candidates", &max_candidates,
 			    "consider <n> most recent tags (default: 10)"),
@@ -270,6 +276,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 
 	save_commit_buffer = 0;
 
+	if (longformat && abbrev == 0)
+		die("--long is incompatible with --abbrev=0");
+
 	if (contains) {
 		const char **args = xmalloc((6 + argc) * sizeof(char*));
 		int i = 0;
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index ae8ee11..a7557bd 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -94,4 +94,6 @@ check_describe D-* --tags HEAD^^
 check_describe A-* --tags HEAD^^2
 check_describe B --tags HEAD^^2^
 
+check_describe B-0-* --long HEAD^^2^
+
 test_done
-- 
1.5.4.3.293.gac81
Shawn O. Pearce· Feb 25, 2008, 02:36 UTC · re: Santi Béjar · lore

Re: [PATCH] Teach git-describe --long to output always the long format

Santi Bjar <sbejar@gmail.com> wrote:
Show 7 quoted lines
> @@ -155,7 +156,11 @@ static void describe(const char *arg, int last_one)
>  
>  	n = cmit->util;
>  	if (n) {
> -		printf("%s\n", n->path);
> +		if (!longformat)
> +			printf("%s\n", n->path );
Extra whitespace after the "path".
> +		else
> +			printf("%s-0-g%s\n", n->path,
> +				find_unique_abbrev(cmit->object.sha1, abbrev));

Is this really that useful? Where is having the tag and the commit SHA-1 both useful?

Show 8 quoted lines
>  		return;
>  	}
>  
> @@ -254,6 +259,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
>  		OPT_BOOLEAN(0, "debug",      &debug, "debug search strategy on stderr"),
>  		OPT_BOOLEAN(0, "all",        &all, "use any ref in .git/refs"),
>  		OPT_BOOLEAN(0, "tags",       &tags, "use any tag in .git/refs/tags"),
> +		OPT_BOOLEAN(0, "long",       &longformat, "always use long format"),
Documentation?
-- 
Shawn.
Junio C Hamano· Feb 25, 2008, 03:08 UTC · re: Shawn O. Pearce · lore

Re: [PATCH] Teach git-describe --long to output always the long format

"Shawn O. Pearce" <spearce@spearce.org> writes:
Show 6 quoted lines
>> +		else
>> +			printf("%s-0-g%s\n", n->path,
>> +				find_unique_abbrev(cmit->object.sha1, abbrev));
>
> Is this really that useful?  Where is having the tag and the commit
> SHA-1 both useful?

I had the same question. The only place that I find this could be useful is when you tag, build and install, and then find glitches before pushing the results out and rewind, rebuild and re-tag. I unfortunately have this issue almost all the time.

But even then, I would probably not rely on this patch.
Santi Béjar· Feb 25, 2008, 08:34 UTC · re: Junio C Hamano · lore

Re: [PATCH] Teach git-describe --long to output always the long format

On Mon, Feb 25, 2008 at 4:08 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 16 quoted lines
> "Shawn O. Pearce" <spearce@spearce.org> writes:
>
>  >> +            else
>  >> +                    printf("%s-0-g%s\n", n->path,
>  >> +                            find_unique_abbrev(cmit->object.sha1, abbrev));
>  >
>  > Is this really that useful?  Where is having the tag and the commit
>  > SHA-1 both useful?
>
>  I had the same question.  The only place that I find this could
>  be useful is when you tag, build and install, and then find
>  glitches before pushing the results out and rewind, rebuild and
>  re-tag.  I unfortunately have this issue almost all the time.
>
>  But even then, I would probably not rely on this patch.
>

This can be usefull when more than one person can make "official" tags (or nobody), and then you have a uniqe idendifier with a descriptive name.

Santi
Junio C Hamano· Feb 25, 2008, 08:54 UTC · re: Santi Béjar · lore

Re: [PATCH] Teach git-describe --long to output always the long format

"Santi Béjar" <sbejar@gmail.com> writes:
Show 16 quoted lines
> On Mon, Feb 25, 2008 at 4:08 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> "Shawn O. Pearce" <spearce@spearce.org> writes:
>> ...
>>  > Is this really that useful?  Where is having the tag and the commit
>>  > SHA-1 both useful?
>>
>>  I had the same question.  The only place that I find this could
>>  be useful is when you tag, build and install, and then find
>>  glitches before pushing the results out and rewind, rebuild and
>>  re-tag.  I unfortunately have this issue almost all the time.
>>
>>  But even then, I would probably not rely on this patch.
>
> This can be usefull when more than one person can make "official" tags
> (or nobody), and then you have a uniqe idendifier with a descriptive
> name.

That's backwards. If you want reliable unique identifier, you would use 40-hexdigit. If you want human readable, you would use tags, and if you allow different people to distribute tags with the same name that point at different things, _you_ have a problem at higher level.

By the way, I think the naming "git describe" does is not quite right. The name of the tag _usually_ matches its path under refs/tags/ by convention, but the code seems to trust the path and does not seem to examine what the actual tag name in the annotated tag is.

I think it should name commits based on the real tag name, at least when it is only using annotated tags (i.e. the default mode of operation).

Santi Béjar· Feb 25, 2008, 09:05 UTC · re: Junio C Hamano · lore

Re: [PATCH] Teach git-describe --long to output always the long format

On Mon, Feb 25, 2008 at 9:54 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 25 quoted lines
> "Santi Béjar" <sbejar@gmail.com> writes:
>
>  > On Mon, Feb 25, 2008 at 4:08 AM, Junio C Hamano <gitster@pobox.com> wrote:
>  >> "Shawn O. Pearce" <spearce@spearce.org> writes:
>  >> ...
>
> >>  > Is this really that useful?  Where is having the tag and the commit
>  >>  > SHA-1 both useful?
>  >>
>  >>  I had the same question.  The only place that I find this could
>  >>  be useful is when you tag, build and install, and then find
>  >>  glitches before pushing the results out and rewind, rebuild and
>  >>  re-tag.  I unfortunately have this issue almost all the time.
>  >>
>  >>  But even then, I would probably not rely on this patch.
>  >
>  > This can be usefull when more than one person can make "official" tags
>  > (or nobody), and then you have a uniqe idendifier with a descriptive
>  > name.
>
>  That's backwards.  If you want reliable unique identifier, you
>  would use 40-hexdigit.  If you want human readable, you would
>  use tags, and if you allow different people to distribute tags
>  with the same name that point at different things, _you_ have a
>  problem at higher level.

Yes, I have a "problem" at a higher level, but I cannot "solve" it. This patch "workaround" this "problem", we want all to be able to tag and have descriptive and uniqe names. I think git should allows us to work this way.

Santi
Junio C Hamano· Feb 25, 2008, 20:11 UTC · re: Santi Béjar · lore

Re: [PATCH] Teach git-describe --long to output always the long format

"Santi Béjar" <sbejar@gmail.com> writes:
Show 10 quoted lines
>>  That's backwards.  If you want reliable unique identifier, you
>>  would use 40-hexdigit.  If you want human readable, you would
>>  use tags, and if you allow different people to distribute tags
>>  with the same name that point at different things, _you_ have a
>>  problem at higher level.
>
> Yes, I have a "problem" at a higher level, but I cannot "solve" it.
> This patch "workaround" this "problem", we want all to be able to tag
> and have descriptive and uniqe names. I think git should allows us to
> work this way.

Why can't you solve it? Your example of two people giving the same name to different things shows a lack of communication between developers, and as long as you and the other guy are talking with each other the problem can be solved, can't it?

SCM or any other tools may facilitate developer communication, but it is not a replacement for communication.

Inside a local repository, git already allows you to:
 * prevent such a problem by not overwriting an existing tag
   unless you ask with -f; and
 * verify that the object a tag refers to is really the object
   you expect the tag to point at with "cat-file tag".

"git describe" output can be unique only within a local repository, as it cannot read your mind and inspect random repositories other people own. In one repository, abbreviating an object name to 4 hexdigits may be enough to make it unique, but in another it may need 6 hexdigits.

If you are trying to guarantee uniqueness of something that lives for a long time (e.g. release version number that is embedded inside binaries, which is what you use "git describe" to generate), _and_ if you worry about two people in different repositories giving the same name to different things which would introduce a bogosity to that long-lived name, you would need a way that is external to the uniqueness guarantee "git describe" can give.

I do not mind low-impact new options and new features like this. Everybody loves bells and whistles. But I do want valid use cases attached to them so that (1) we can justify their existence; and (2) we can document them to explain what purpose they serve, to help people to decide when to use them.

I even suspect that the --long flag might be useful in some situation, but I do not think "a tag with the same name" is one of the problems this patch lets you solve or work around.

Jakub's "it looks more uniform and does not treat a tagged version any specially" may probably be a better argument for this new feature. I dunno.

Santi Béjar· Feb 25, 2008, 20:51 UTC · re: Junio C Hamano · lore

Re: [PATCH] Teach git-describe --long to output always the long format

On Mon, Feb 25, 2008 at 9:11 PM, Junio C Hamano <gitster@pobox.com> wrote:
Show 18 quoted lines
> "Santi Béjar" <sbejar@gmail.com> writes:
>
>
> >>  That's backwards.  If you want reliable unique identifier, you
>  >>  would use 40-hexdigit.  If you want human readable, you would
>  >>  use tags, and if you allow different people to distribute tags
>  >>  with the same name that point at different things, _you_ have a
>  >>  problem at higher level.
>  >
>  > Yes, I have a "problem" at a higher level, but I cannot "solve" it.
>  > This patch "workaround" this "problem", we want all to be able to tag
>  > and have descriptive and uniqe names. I think git should allows us to
>  > work this way.
>
>  Why can't you solve it?  Your example of two people giving the
>  same name to different things shows a lack of communication
>  between developers, and as long as you and the other guy are
>  talking with each other the problem can be solved, can't it?

But there are times when you can't/don't want to communicate (private/testing/forks, whatever).

Anyway, even if this problem is solved I feel more confortable with a version in my binary (and output) with a descriptive name and a revision id.

>  SCM or any other tools may facilitate developer communication,
>  but it is not a replacement for communication.
I know, but my problem is not lack of communication.
Show 6 quoted lines
>
>  "git describe" output can be unique only within a local
>  repository, as it cannot read your mind and inspect random
>  repositories other people own.  In one repository, abbreviating
>  an object name to 4 hexdigits may be enough to make it unique,
>  but in another it may need 6 hexdigits.

If you always use "git describe --long" it is globally unique, as long as sha1 is globally unique (at least unique enough).

Show 8 quoted lines
>  If you are trying to guarantee uniqueness of something that
>  lives for a long time (e.g. release version number that is
>  embedded inside binaries, which is what you use "git describe"
>  to generate), _and_ if you worry about two people in different
>  repositories giving the same name to different things which
>  would introduce a bogosity to that long-lived name, you would
>  need a way that is external to the uniqueness guarantee "git
>  describe" can give.
See above.
Show 5 quoted lines
>  I do not mind low-impact new options and new features like this.
>  Everybody loves bells and whistles.  But I do want valid use
>  cases attached to them so that (1) we can justify their
>  existence; and (2) we can document them to explain what purpose
>  they serve, to help people to decide when to use them.
OK.
Show 8 quoted lines
>  I even suspect that the --long flag might be useful in some
>  situation, but I do not think "a tag with the same name" is one
>  of the problems this patch lets you solve or work around.
>
>  Jakub's "it looks more uniform and does not treat a tagged
>  version any specially" may probably be a better argument for
>  this new feature.  I dunno.
>
Maybe.
Santi
Junio C Hamano· Feb 26, 2008, 09:19 UTC · re: Santi Béjar · lore

Re: [PATCH] Teach git-describe --long to output always the long format

"Santi Béjar" <sbejar@gmail.com> writes:
Show 11 quoted lines
>>  Why can't you solve it?  Your example of two people giving the
>>  same name to different things shows a lack of communication
>>  between developers, and as long as you and the other guy are
>>  talking with each other the problem can be solved, can't it?
>
> But there are times when you can't/don't want to communicate
> (private/testing/forks, whatever).
>
> Anyway, even if this problem is solved I feel more confortable
> with a version in my binary (and output) with a descriptive
> name and a revision id.

As I think about it more, I think that such a lack of communication is not something "git describe" should even claim to help working around.

But a uniform-looking describe output does have certain attractiveness:

	$ git describe --long 31e0b2c 6c0f869
        v1.5.4.3-0-g31e0b2c
        v1.5.4.3-1-g6c0f869

So I have quite a big problem with your commit log message, even though I am starting to like what it does. Perhaps this would be more to the point.

    git-describe: --long shows the object name even for a tagged commit
    
    This is useful when you want to see parts of the commit object name
    in "describe" output, even when the commit in question happens to be
    a tagged version.  Instead of just emitting the tag name, it will
    describe such a commit as v1.2-0-deadbeef (0th commit since tag v1.2
    that points at object deadbeef....).

By the way, I do not think "long" is what it does. It does not even show the full object name unless you tell it to with another option (i.e. --abbrev). The flag tells the command to use the normal output format that is used to describe most other commits (untagged ones), and signal the "taggedness" with the count part being "-0-".

Perhaps --nonexact-format, or even --redundant-output?

Hmmmmm... "--always-count", as it is about always using the counted format (which is the "normal" output format)?

I know, I am bad at naming, so I'll park the commit in 'pu', with option name kept as "--long" as in your patch.

Santi Béjar· Feb 26, 2008, 09:41 UTC · re: Junio C Hamano · lore

Re: [PATCH] Teach git-describe --long to output always the long format

On Tue, Feb 26, 2008 at 10:19 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 14 quoted lines
> "Santi Béjar" <sbejar@gmail.com> writes:
>
>  So I have quite a big problem with your commit log message, even
>  though I am starting to like what it does.  Perhaps this would be more
>  to the point.
>
>     git-describe: --long shows the object name even for a tagged commit
>
>     This is useful when you want to see parts of the commit object name
>     in "describe" output, even when the commit in question happens to be
>     a tagged version.  Instead of just emitting the tag name, it will
>     describe such a commit as v1.2-0-deadbeef (0th commit since tag v1.2
>     that points at object deadbeef....).
>
I think it's find, and to the point. Thanks.
Show 10 quoted lines
>  By the way, I do not think "long" is what it does.  It does not even
>  show the full object name unless you tell it to with another option
>  (i.e. --abbrev).  The flag tells the command to use the normal output
>  format that is used to describe most other commits (untagged ones),
>  and signal the "taggedness" with the count part being "-0-".
>
>  Perhaps --nonexact-format, or even --redundant-output?
>
>  Hmmmmm...  "--always-count", as it is about always using the counted
>  format (which is the "normal" output format)?

I call it --long for longformat, maybe --longformat, --always-long, --always-normal.

>
>  I know, I am bad at naming, so I'll park the commit in 'pu',
>  with option name kept as "--long" as in your patch.
Me too.
Santi
Jakub Narebski· Feb 25, 2008, 08:50 UTC · re: Junio C Hamano · lore

Re: [PATCH] Teach git-describe --long to output always the long format

Junio C Hamano <gitster@pobox.com> writes:
Show 13 quoted lines
> "Shawn O. Pearce" <spearce@spearce.org> writes:
> 
>>> +		else
>>> +			printf("%s-0-g%s\n", n->path,
>>> +				find_unique_abbrev(cmit->object.sha1, abbrev));
>>
>> Is this really that useful?  Where is having the tag and the commit
>> SHA-1 both useful?
> 
> I had the same question.  The only place that I find this could
> be useful is when you tag, build and install, and then find
> glitches before pushing the results out and rewind, rebuild and
> re-tag.  I unfortunately have this issue almost all the time.

Another place where it is useful is parsing git-describe output, for example in .spec file for RPM, if you want to avoid hardcoding the information about the form of tags in a project (tags can, and sometimes do, contain '-'). If you always use --long form, it is easy to separate number of commits from tag and shortened sha1 from the tag itself, for example to put closest tag as version number, and make number of commits and perhaps also shortened sha1 into release number.

-- 
Jakub Narebski
Poland
ShadeHawk on #git
Santi Béjar· Feb 25, 2008, 09:43 UTC · re: Santi Béjar · lore

This can be useful when more than one person can make "official" tags (or nobody), but you want unique identifiers with a descriptive name. Or when parsing git-describe output if you want to avoid hardcoding the information about the form of tags in a project (tags can, and sometimes do, contain '-').

Signed-off-by: Santi Béjar <sbejar@gmail.com>
---
Hi,
  this time with documentation and usecases (thanks Jakub)
Santi
 Documentation/git-describe.txt |    9 +++++++++
 builtin-describe.c             |   11 ++++++++++-
 t/t6120-describe.sh            |    2 ++
 3 files changed, 21 insertions(+), 1 deletions(-)
Show changes to 3 files +21 −1

Documentation/git-describe.txt, builtin-describe.c, t/t6120-describe.sh

diff --git a/Documentation/git-describe.txt b/Documentation/git-describe.txt
index 1c3dfb4..f46fbdd 100644
--- a/Documentation/git-describe.txt
+++ b/Documentation/git-describe.txt
@@ -51,6 +51,15 @@ OPTIONS
 	being employed to standard error.  The tag name will still
 	be printed to standard out.
 
+--long::
+	Always output the long format (the tag, the number of commits
+	and the abbreviated commit name) even when it matches a tag.
+	This can be useful when more than one person can make "official" tags
+	(or nobody), but you want unique identifiers with a descriptive
+	name. Or when parsing git-describe output if you want to avoid
+	hardcoding the information about the form of tags in a project
+	(tags can, and sometimes do, contain '-').
+
 --match <pattern>::
 	Only consider tags matching the given pattern (can be used to avoid
 	leaking private tags made from the repository).
diff --git a/builtin-describe.c b/builtin-describe.c
index 3428483..3fd2e73 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -17,6 +17,7 @@ static const char * const describe_usage[] = {
 static int debug;	/* Display lots of verbose info */
 static int all;	/* Default to annotated tags only */
 static int tags;	/* But allow any tags if --tags is specified */
+static int longformat;
 static int abbrev = DEFAULT_ABBREV;
 static int max_candidates = 10;
 const char *pattern = NULL;
@@ -155,7 +156,11 @@ static void describe(const char *arg, int last_one)
 
 	n = cmit->util;
 	if (n) {
-		printf("%s\n", n->path);
+		if (!longformat)
+			printf("%s\n", n->path);
+		else
+			printf("%s-0-g%s\n", n->path,
+				find_unique_abbrev(cmit->object.sha1, abbrev));
 		return;
 	}
 
@@ -254,6 +259,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 		OPT_BOOLEAN(0, "debug",      &debug, "debug search strategy on stderr"),
 		OPT_BOOLEAN(0, "all",        &all, "use any ref in .git/refs"),
 		OPT_BOOLEAN(0, "tags",       &tags, "use any tag in .git/refs/tags"),
+		OPT_BOOLEAN(0, "long",       &longformat, "always use long format"),
 		OPT__ABBREV(&abbrev),
 		OPT_INTEGER(0, "candidates", &max_candidates,
 			    "consider <n> most recent tags (default: 10)"),
@@ -270,6 +276,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
 
 	save_commit_buffer = 0;
 
+	if (longformat && abbrev == 0)
+		die("--long is incompatible with --abbrev=0");
+
 	if (contains) {
 		const char **args = xmalloc((6 + argc) * sizeof(char*));
 		int i = 0;
diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh
index ae8ee11..a7557bd 100755
--- a/t/t6120-describe.sh
+++ b/t/t6120-describe.sh
@@ -94,4 +94,6 @@ check_describe D-* --tags HEAD^^
 check_describe A-* --tags HEAD^^2
 check_describe B --tags HEAD^^2^
 
+check_describe B-0-* --long HEAD^^2^
+
 test_done
-- 
1.5.4.3.293.gac81

← back to recent threads