On Tue, May 08 2018, Jeff King wrote: > On Mon, May 07, 2018 at 01:08:46PM +0900, Junio C Hamano wrote: > >> Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> 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@xxxxxxxxxxxxxxxxxxx/) 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?