When name-rev constructs possible names for a rev, it assigns the
taggerdate to an annotated tag and ULONG_MAX to other names such as
lightweight tags and branch names. Practically, this rules out even
naming a tagged commit by the tag if that is lightweight and there is
another possible indirect name (e.g. foo~5) coming from an annotated
tag.

Instead, assign the commit date to lightweight tags or branch refs so
that they get their fair chance of being picked up.

Signed-off-by: Michael J Gruber <g...@drmicha.warpmail.net>
---

Originally, I didn't even think of submitting this as is until I noticed that
all tests succeed with it (bar one for git-prompt.h which looked strange
anyways); rather, I thought about another switch "--lightweight" or so.

I still submit it as RFD. This origin of my foray into name-rev came from
git describe, where a fair expectation should be that "--contains" mode
is the same as the odinary mode, albeit with a different direction in
time/traversal. (Technically, describe --contains is name-rev.)

Consider the following:

git init
echo past >tense
git add tense
git commit -m past
git tag -m past -a past
echo present >tense
git commit -am present
git tag present
echo future >tense
git commit -am future

"git describe past present future" gives

past
past-1-g5ad942f
future

because (as documented) it does not consider lightweight tags, and thus
has to describe present from the past.

"git describe --tags past present future" gives

past
present
future

because (as documented) it does consider lightweight tags.

"git describe --contains past present future" gives

past^0
future~1
future^0

and I have a hard time matching that with the documentation
(describe doc claims that --tags is automatic; name-rev doc does not
distinguish between tag types).
"--tags" does not make any difference here, nor does "--all"
(besides fully qualifying the tags).

"git describe --contains past present future" gives

past^0
present
future^0

with this patch (I'm tempted to say: with the present patch),
which is what I would expect.

I'm wondering whether I'm overlooking any side-effects that our test
suite doesn't cover, though. In any case, we may want to have
lightweight tags allowed based on an extra flag (like the
existing --tags for describe, which means something else for name-rev).

 builtin/name-rev.c     | 2 ++
 t/t9903-bash-prompt.sh | 2 +-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/builtin/name-rev.c b/builtin/name-rev.c
index 8bdc3eaa6f..75ba7bbad5 100644
--- a/builtin/name-rev.c
+++ b/builtin/name-rev.c
@@ -207,6 +207,8 @@ static int name_ref(const char *path, const struct 
object_id *oid, int flags, vo
        if (o && o->type == OBJ_COMMIT) {
                struct commit *commit = (struct commit *)o;
 
+               if (taggerdate == ULONG_MAX) /* lightweight tag */
+                       taggerdate = commit->date;
                path = name_ref_abbrev(path, can_abbreviate_output);
                name_rev(commit, xstrdup(path), taggerdate, 0, 0, deref);
        }
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index 97c9b32c2e..d467d5957d 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -107,7 +107,7 @@ test_expect_success 'prompt - describe detached head - 
contains' '
 '
 
 test_expect_success 'prompt - describe detached head - branch' '
-       printf " ((tags/t2~1))" >expected &&
+       printf " ((b1~1))" >expected &&
        git checkout b1^ &&
        test_when_finished "git checkout master" &&
        (
-- 
2.12.0.384.g157040b11f.dirty

Reply via email to