Re: [PATCH v3 09/12] get_short_oid / peel_onion: ^{tree} should be tree, not treeish
- From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- Date
- May 8, 2018, 18:53 UTC
- Message-ID
- <87a7tax9m1.fsf@evledraar.gmail.com>
- In-Reply-To
- <20180508143408.GA30183@sigill.intra.peff.net>
On Tue, May 08 2018, Jeff King wrote:
Show 29 quoted lines
> On Mon, May 07, 2018 at 01:08:46PM +0900, Junio C Hamano wrote:
>
>> Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:
>>
>> > Right, and I'm with you so far, this makes sense to me for all existing
>> > uses of the peel syntax, otherwise v2.17.0^{tree} wouldn't be the same
>> > as rev-parse v2.17.0^{tree}^{tree}...
>>
>> More importantly, you could spell v2.17.0 part of the above with a
>> short hexadecimal string. And that string should be naming some
>> tree-ish, the most important thing being that it is *NOT* required
>> to be a tree (and practically, it is likely that the user has a
>> tree-ish that is *NOT* a tree).
>>
>> I guess I have a reaction to the title
>>
>> "get_short_oid/peel_onion: ^{tree} should be tree"
>>
>> "X^{tree}" should *RESULT* in a tree, but it should *REQUIRE* X to
>> be a tree-ish. It is unclear "should be tree" is about the former
>> and I read (perhaps mis-read) it as saying "it should require X to
>> be a tree"---that statement is utterly incorrect as we agreed above.
>
> FWIW, I had the same feeling as you when reading this, that this commit
> (and the one after) are doing the wrong thing. And these paragraphs sum
> it up. The "^{tree}" is about asking us to peel to a tree, not about
> resolving X in the first place. We can use it as a _hint_ when resolving
> X, but the correct hint is "something that can be peeled to a tree", not
> "is definitely a tree".Maybe I'm just being dense, but I still don't get from this & Junio's E-Mails what the general rule should be.
I think a response to the part after "leaving that aside" of my upthread E-Mail (https://public-inbox.org/git/87lgczyfq6.fsf@evledraar.gmail.com/) would help me out.
Not to belabor the point, but here's a patch I came up with to revisions.txt that's a WIP version of something that would describe the worldview after this v3:
diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt
index dfcc49c72c..0bf68f4ad2 100644
--- a/Documentation/revisions.txt
+++ b/Documentation/revisions.txt
@@ -143,29 +143,52 @@ thing no matter the case.
'<rev>{caret}1{caret}1{caret}1'. See below for an illustration of
the usage of this form. '<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).
+ dereferenced anymore (in which case either return that object type, or 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\}'.
+
'rev{caret}\{object\}' can be used to make sure 'rev' names an
object that exists, without requiring 'rev' to be a tag, and
without dereferencing 'rev'; because a tag is already an object,
it does not have to be dereferenced even once to get to an object.
+
'rev{caret}\{tag\}' can be used to ensure that 'rev' identifies an
existing tag object.
++
+Object types that don't have a 1=1 mapping to other object types
+cannot be dereferenced with the peel syntax, and will return an
+error. E.g. '<treeid>{caret}{commit}' or '<treeid>{caret}{tree}' is
+allowed because a tag can only point to one commit, and a commit can
+only point to one tree. But '<treeid>{caret}{blob}' will always
+produce an error since trees in general don't 1=1 map to blobs, even
+though the specific '<treeid>' in question might only contain one
+blob. Note that '<tagid>{caret}{blob}' is not an error if '<tagid>' is
+a tag that points directly to a blob, since that again becomes
+unambiguous.
++
+'<rev>{caret}{<type>}' takes on a different meaning when '<rev>' is a
+SHA-1 that's ambiguous within the object store. In that case we don't
+have a 1=1 mapping anymore. E.g. e8f2 in git.git can refer to multiple
+objects of all the different object types. In that case
+{caret}{<type>} should always be an error to be consistent with the
+logic above, but that wouldn't be useful to anybody. Instead it'll
+fall back to being selector syntax for the given object types,
+e.g. e8f2{caret}{tag} will (as of writing this) return the v2.17.0
+tag, and {caret}{commit}, {caret}{tree} and {caret}{blob} will return
+commit, tree and blob objects, respectively.
+
[...]My understanding of what you two are saying is that somehow the peel semantics should be preserved when we take this beyond the 1=1 mapping case, but I don't see how if we run with that how we wouldn't need to introduce the concept of blobish for consistency as I noted upthread.
So it would be very useful to me if you or someone who understands the behavior you & Junio seem to want could write a version of the patch I have above where the last paragraph is different, and describes the desired semantics, because I still don't get it. Why would we 1=many peel commits to trees as a special case, but not 1=many do the same for trees & blobs?