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 <git@xxxxxxxxxxxxxxxxxxxx> --- 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