On Thu, May 03 2018, Junio C Hamano wrote:
> Ævar Arnfjörð Bjarmason <[email protected]> writes:
>
>> But ^{tree} shows just the trees, but would previously be equivalent
>> to the above:
>>
>> $ git rev-parse e8f2^{tree}
>> error: short SHA1 e8f2 is ambiguous
>> hint: The candidates are:
>> hint: e8f2093055 tree
>> hint: e8f25a3a50 tree
>> hint: e8f28d537c tree
>> hint: e8f2cf6ec0 tree
>> [...]
>
> When a user says "git $cmd e8f2^{tree}", the user is telling Git
> that s/he knows e8f2 *is* a tree-ish, but for whatever reason $cmd
> wants a tree and does not accept an arbitrary tree-ish---that is the
> whole piont of appending ^{tree} as a suffix. A useful hint in such
> a case would be "oh, you said e8f2 is a tree-ish, but there are more
> than one tree-ish, so let me show them to you to help you decide
> which one among them is the one you meant". When $cmd is rev-parse,
> I would even say that the user is saying "I know e8f2 is a tree-ish,
> and I know it not a tree--it merely is a tree-ish. I want the tree
> that e8f2 thing points at".
>
> Limiting that hint to show only real trees does not make any sense
> to me. I do not think we care _too_ deeply, because most of the
> time, command line location that expects a tree-ish can be given a
> tree-ish, so there is not much reason to use ^{tree} suffix these
> days. But in a case where it _does_ matter, I think this change
> makes the "hint" almost useless.
>
> Or am I misleading what you wanted to achieve with this patch?
The reason I'm doing this is because I found it confusing that I can't
do:
for t in tag commit tree blob; do ./git --exec-path=$PWD rev-parse
7452^{$t}; done
And get, respectively, only the SHAs that match the respective type, but
currently (with released git) you can do:
for t in tag commit committish treeish tree blob; do git -c
core.disambiguate=$t rev-parse 7452; done
And while =tag doesn't work the others do (inluding =blob), so
core.disambiguate=tree gives you just trees, but ^{tree} gives you
treeish.
Why should ^{tree} be giving me ^{treeish} but =tree be giving me trees,
and =treeish be synonymous with ^{tree}?
There's no other cases I know of where the ^{<type>} peel syntax won't
give you *only* the <type> you asked for. See peel_onion() ->
peel_to_type() and how get_oid_1() will short-circuit if it has an
answer, and then finally fall back to this get_short_oid() codepath.
Looking at the code & git log maybe it'll do that internally, but when
you peel a tag or commit ^{tree} will only ever find one thing, unlike
this disambiguation case where we can match multiple things.
So:
1) Am I missing some subtlety or am I correct that there was no way to
get git to return more than one SHA-1 for ^{commit} or ^{tree} before
this disambiguation feature was added?
2) I think the behavior I've implemented is consistent with how the peel
syntax has been documented in revisions.txt:
'<rev>{caret}{<type>}', e.g. 'v0.99.8{caret}\{commit\}'::
A suffix '{caret}' followed by an object type name enclosed in
brace pair means dereference the object at '<rev>' recursively until
an object of type '<type>' is found or the object cannot be
dereferenced anymore (in which case, barf).
For example, if '<rev>' is a commit-ish, '<rev>{caret}\{commit\}'
describes the corresponding commit object.
Similarly, if '<rev>' is a tree-ish, '<rev>{caret}\{tree\}'
describes the corresponding tree object.
'<rev>{caret}0'
is a short-hand for '<rev>{caret}\{commit\}'.
Note "until an object of type '<type>' is found". I.e. my mental model
of this has been that yes you can *start* the search at a different
object (e.g. tag -> tree), but it'll only ever return the tree. The
disambiguation implementation has been inconsistent with this as
documented, because it hasn't been drilling don to an object of '<type>'
given a request like $short^{<type>}, but rather returning something
matching $short because it could be a container for <type>.
Anyway, I'm not saying I'm right. This is the first time I really look
at sha1-name.c in any detail. But the above describes the thought
process behind this patch.