From: Junio C Hamano <hidden> Date: 2016-06-15 22:58:02
So here is a set of small preparatory steps to help the other topic
to allow "git describe -contains v1.8.3" omit trailing "^0" from its
output. We do not want to prevent people from allowing "name-rev"
to convert object names other than commit-ishes.
The series should apply on 96ffd4ca (Merge branch
'nk/name-rev-abbreviated-refs', 2013-06-30).
Junio C Hamano (4):
name-ref: factor out name shortening logic from name_ref()
name-rev: allow converting the exact object name at the tip of a ref
describe: use argv-array
describe/name-rev: tell name-rev to peel the incoming object to commit first
builtin/describe.c | 32 ++++++++-------
builtin/name-rev.c | 113 ++++++++++++++++++++++++++++++++++++++++++++---------
2 files changed, 112 insertions(+), 33 deletions(-)
--
1.8.3.2-853-ga8cbcc9
From: Junio C Hamano <hidden> Date: 2016-06-15 22:58:02
The logic will be used in a new codepath for showing exact matches.
Signed-off-by: Junio C Hamano <redacted>
---
builtin/name-rev.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
From: Junio C Hamano <hidden> Date: 2016-06-15 22:58:02
"git name-rev" is supposed to convert 40-hex object names into
strings that name the same objects based on refs, that can be fed to
"git rev-parse" to get the same object names back, so
$ git rev-parse v1.8.3 v1.8.3^0 | git name-rev --stdin
8af06057d0c31a24e8737ae846ac2e116e8bafb9
edca4152560522a431a51fc0a06147fc680b5b18 (tags/v1.8.3^0)
has to have "^0" at the end, as "edca41" is a commit, not the tag
that references it.
The command however did not bother to see if the object is at the
tip of some ref, and failed to convert a tag object.
Teach it to show this instead:
$ git rev-parse v1.8.3 v1.8.3^0 | git name-rev --stdin
8af06057d0c31a24e8737ae846ac2e116e8bafb9 (tags/v1.8.3)
edca4152560522a431a51fc0a06147fc680b5b18 (tags/v1.8.3^0)
Signed-off-by: Junio C Hamano <redacted>
---
builtin/name-rev.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
From: Junio C Hamano <hidden> Date: 2016-06-15 22:58:02
With this on top of the other patches in this series, you would get:
$ git describe --contains $(git rev-parse v1.8.3 v1.8.3^0)
v1.8.3
v1.8.3
while you can still differentiate tags and the commits they point at
with:
$ git name-rev --refs=tags/\* --name-only $(git rev-parse v1.8.3 v1.8.3^0)
v1.8.3
v1.8.3^0
The difference in these two behaviours is achieved by adding --peel-to-commit
option to "name-rev" and using it when "describe" internally calls it.
Signed-off-by: Junio C Hamano <redacted>
---
builtin/describe.c | 1 +
builtin/name-rev.c | 35 +++++++++++++++++++++++++----------
2 files changed, 26 insertions(+), 10 deletions(-)
@@ -320,6 +321,8 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)OPT_BOOLEAN(0,"undefined",&allow_undefined,N_("allow to print `undefined` names")),OPT_BOOLEAN(0,"always",&always,N_("show abbreviated commit object as fallback")),+OPT_BOOLEAN(0,"peel-to-commit",&peel_to_commit,+N_("peel tag object names in the input to a commmit")),OPT_END(),};
@@ -343,17 +346,29 @@ int cmd_name_rev(int argc, const char **argv, const char *prefix)continue;}-o=deref_tag(parse_object(sha1),*argv,0);-if(!o||o->type!=OBJ_COMMIT){+commit=NULL;+object=parse_object(sha1);+if(object){+structobject*peeled=deref_tag(object,*argv,0);+if(peeled&&peeled->type==OBJ_COMMIT)+commit=(structcommit*)peeled;+}++if(!object){+fprintf(stderr,"Could not get object for %s. Skipping.\n",+*argv);+continue;+}+if(peel_to_commit&&!commit){fprintf(stderr,"Could not get commit for %s. Skipping.\n",-*argv);+*argv);continue;}--commit=(structcommit*)o;-if(cutoff>commit->date)-cutoff=commit->date;-add_object_array((structobject*)commit,*argv,&revs);+if(commit){+if(cutoff>commit->date)+cutoff=commit->date;+}+add_object_array(object,*argv,&revs);}if(cutoff)
From: Junio C Hamano <hidden> Date: 2016-06-15 22:58:02
Instead of using a hand allocated args[] array, use argv-array API
to manage the dynamically created list of arguments when invoking
name-rev.
Signed-off-by: Junio C Hamano <redacted>
---
builtin/describe.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
From: Michael Haggerty <hidden> Date: 2016-06-15 22:58:02
On 07/08/2013 12:33 AM, Junio C Hamano wrote:
quoted hunk
The logic will be used in a new codepath for showing exact matches.
Signed-off-by: Junio C Hamano <redacted>
---
builtin/name-rev.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
In my opinion this would be a tad clearer if each of the branches of the
"if" returned the value directly rather than setting refname and relying
on the "return" statement that follows. But it's probably a matter of
taste.
quoted hunk
struct name_ref_data {
int tags_only;
int name_only;
@@ -134,13 +145,7 @@ static int name_ref(const char *path, const unsigned char *sha1, int flags, void if (o && o->type == OBJ_COMMIT) { struct commit *commit = (struct commit *)o;- if (can_abbreviate_output)- path = shorten_unambiguous_ref(path, 0);- else if (!prefixcmp(path, "refs/heads/"))- path = path + 11;- else if (!prefixcmp(path, "refs/"))- path = path + 5;-+ path = name_ref_abbrev(path, can_abbreviate_output); name_rev(commit, xstrdup(path), 0, 0, deref); } return 0;
"git name-rev" is supposed to convert 40-hex object names into
strings that name the same objects based on refs, that can be fed to
"git rev-parse" to get the same object names back, so
$ git rev-parse v1.8.3 v1.8.3^0 | git name-rev --stdin
8af06057d0c31a24e8737ae846ac2e116e8bafb9
edca4152560522a431a51fc0a06147fc680b5b18 (tags/v1.8.3^0)
Wait, what?
$ git name-rev 8af060
8af060 tags/v1.8.3^0
Isn't this a failure specific to --stdin?
Teach it to show this instead:
$ git rev-parse v1.8.3 v1.8.3^0 | git name-rev --stdin
8af06057d0c31a24e8737ae846ac2e116e8bafb9 (tags/v1.8.3)
edca4152560522a431a51fc0a06147fc680b5b18 (tags/v1.8.3^0)
Wait, what is name-rev?
Finds symbolic names suitable for human digestion for revisions
given in any format parsable by git rev-parse.
It is meant to name _revisions_ (aka. commits): in that context, what
sense does it make to distinguish between tags/v1.8.3 and
tags/v1.8.3^0?
With this on top of the other patches in this series, you would get:
$ git describe --contains $(git rev-parse v1.8.3 v1.8.3^0)
v1.8.3
v1.8.3
while you can still differentiate tags and the commits they point at
with:
$ git name-rev --refs=tags/\* --name-only $(git rev-parse v1.8.3 v1.8.3^0)
v1.8.3
v1.8.3^0
The difference in these two behaviours is achieved by adding --peel-to-commit
option to "name-rev" and using it when "describe" internally calls it.
Essentially a revert of [2/4] for describe-purposes, achieved by
adding an ugly command-line option to name-rev. Before we argue any
further, let me ask: who uses name-rev (and depends strongly on its
output)?! Our very own testsuite does not exercise it. There are
exactly two users of describe/name-rev:
1. prompt, obviously.
2. DAG-tests, for simplification.
I really can't imagine it being useful elsewhere.
This leaks the memory allocated by "args". The original did, too, and it
is probably not that big a deal (we exit right after anyway). The fix
would be something like:
rc = cmd_name_rev(args.argc, args.argv, prefix);
argv_array_clear(&args);
return rc;
-Peff
From: Jeff King <hidden> Date: 2016-06-15 22:58:02
On Sun, Jul 07, 2013 at 03:33:44PM -0700, Junio C Hamano wrote:
With this on top of the other patches in this series, you would get:
$ git describe --contains $(git rev-parse v1.8.3 v1.8.3^0)
v1.8.3
v1.8.3
while you can still differentiate tags and the commits they point at
with:
$ git name-rev --refs=tags/\* --name-only $(git rev-parse v1.8.3 v1.8.3^0)
v1.8.3
v1.8.3^0
The difference in these two behaviours is achieved by adding --peel-to-commit
option to "name-rev" and using it when "describe" internally calls it.
I am somewhat mixed on this.
You are changing the default behavior of name-rev and adding a new
option to restore it, so I wonder who (if anyone) might be broken. The
documentation is now also out of date; not only does it not mention
"peel-to-commit", but it claims the argument to name-rev is a
committish, which is not really true without that option.
On the other hand, the new default behavior seems way more sane to me.
In general, I would expect name-rev to:
1. Behave more or less the same between "git name-rev $sha1" and "echo
$sha1 | git name-rev --stdin". Your patch improves that. Though I
note that --peel-to-commit does not affect --stdin at all. Should
it? And of course the two differ in that the command line will take
any rev-parse expression, and --stdin only looks for full sha1s.
2. If name-rev prints "$X $Y", I would expect "git rev-parse $X" to
equal "git rev-parse $Y". With peeling, that is not the case, and
you get the misleading example that Ram showed:
$ git name-rev 8af0605
8af0605 tags/v1.8.3^0
or more obviously weird:
$ git name-rev v1.8.3
v1.8.3 tags/v1.8.3^0
So I think your series moves in a good direction, but I would just worry
that it is breaking backwards compatibility (but like I said, I am not
clear on who is affected and what it means for them).
-Peff
From: Jeff King <hidden> Date: 2016-06-15 22:58:02
On Mon, Jul 08, 2013 at 06:38:32PM +0530, Ramkumar Ramachandra wrote:
Junio C Hamano wrote:
quoted
With this on top of the other patches in this series, you would get:
$ git describe --contains $(git rev-parse v1.8.3 v1.8.3^0)
v1.8.3
v1.8.3
while you can still differentiate tags and the commits they point at
with:
$ git name-rev --refs=tags/\* --name-only $(git rev-parse v1.8.3 v1.8.3^0)
v1.8.3
v1.8.3^0
The difference in these two behaviours is achieved by adding --peel-to-commit
option to "name-rev" and using it when "describe" internally calls it.
Essentially a revert of [2/4] for describe-purposes, achieved by
adding an ugly command-line option to name-rev.
I don't think it is a revert. The two patches complement each other.
2/4 is basically "if we have a non-commit object which is pointed at
directly by a tip, make sure we name it by that tip". But you can only
get such an object by "name-rev --stdin", since name-rev peels its
command-line arguments.
4/4 is "stop peeling command line objects, so we can find their exact
tips". IOW, it lets the command line do the same thing that --stdin was
able to do in 2/4.
Before we argue any further, let me ask: who uses name-rev (and
depends strongly on its output)?! Our very own testsuite does not
exercise it. There are exactly two users of describe/name-rev:
1. prompt, obviously.
2. DAG-tests, for simplification.
Yeah, I'm not clear on who we are breaking with the change in default
peeling behavior, nor why the "describe --contains" wrapper wants to
keep it.
-Peff