{"thread":{"id":"65838","subject":"Pinned references?","startedAt":"2026-06-18T18:37:38Z","lastAt":"2026-06-21T21:53:09Z","messageCount":4,"participants":["Erik Östlund","Patrick Steinhardt","Junio C Hamano","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"545885","messageId":"CANE2Nt_LP9odF9tVsy8di54eSH=QJxif2WQfHC+TQGGFeVcjvg@mail.gmail.com","threadId":"65838","inReplyTo":null,"subject":"Pinned references?","fromName":"Erik Östlund","fromEmail":"erik.ostlund@gmail.com","sentAt":"2026-06-18T18:37:26Z","receivedAt":"2026-06-18T18:37:38Z","isPatch":false,"body":"I'd like to be able to express a reference together with an expected\nobject ID, for example with strawman syntax like:\n\nrefs/tags/v1.2.3?oid=a1b2c3d4\n\nThe intended semantics would be that both the reference and object ID\nmust exist, and Git should fail if the reference does not resolve to the\nspecified object ID.\n\nTags are nice because they convey human meaning. Object IDs are nice\nbecause they are immutable. As it is, I often have to choose between the\ntwo, or represent them separately in external tooling.\n\nIs there existing terminology, prior discussion, or an accepted Git-native\napproach for this kind of \"ref plus expected OID\" invariant? I\nsearched both the Git reference documentation and the mailing list\narchives, but couldn't find what I was looking for.\n\nThanks,\nErik\n"},{"id":"545923","messageId":"ajTx9vLIWK5wvTHM@pks.im","threadId":"65838","inReplyTo":"CANE2Nt_LP9odF9tVsy8di54eSH=QJxif2WQfHC+TQGGFeVcjvg@mail.gmail.com","subject":"Re: Pinned references?","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-06-19T07:38:30Z","receivedAt":"2026-06-19T07:38:36Z","isPatch":false,"body":"On Thu, Jun 18, 2026 at 08:37:26PM +0200, Erik Östlund wrote:\n> I'd like to be able to express a reference together with an expected\n> object ID, for example with strawman syntax like:\n> \n> refs/tags/v1.2.3?oid=a1b2c3d4\n> \n> The intended semantics would be that both the reference and object ID\n> must exist, and Git should fail if the reference does not resolve to the\n> specified object ID.\n> \n> Tags are nice because they convey human meaning. Object IDs are nice\n> because they are immutable. As it is, I often have to choose between the\n> two, or represent them separately in external tooling.\n> \n> Is there existing terminology, prior discussion, or an accepted Git-native\n> approach for this kind of \"ref plus expected OID\" invariant? I\n> searched both the Git reference documentation and the mailing list\n> archives, but couldn't find what I was looking for.\n\nYou can already kind of do this:\n\n    $ git rev-parse v2.54.0\n    0b13e48a3a30cdfa94e8ef842e24d6045ab3d015\n\n    $ git rev-parse v2.54.0-0-g0b13e48a3\n    0b13e48a3a30cdfa94e8ef842e24d6045ab3d015\n\n    $ git rev-parse v2.54.0-0-g95e20213f\n    95e20213faefeb95df29277c58ac1980ab68f701\n\nThis is described under gitrevisions(7), `<describeOutput>`. The only\ngotcha is that this format will not verify that the tag and the object\nID actually match. But other than that it gives you the ability to have\nboth the human-readable name and the machine-readable commit ID in\nthere.\n\nAs said, we don't verify that those two revisions actually match. So in\nthe case where they don't the result is certainly going to be lots of\nconfusion. It certainly is one of the more surprising syntaxes that we\nhave in Git.\n\nPatrick\n"},{"id":"545994","messageId":"xmqqeci2lcpc.fsf@gitster.g","threadId":"65838","inReplyTo":"ajTx9vLIWK5wvTHM@pks.im","subject":"Re: Pinned references?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-06-19T16:25:19Z","receivedAt":"2026-06-19T16:25:21Z","isPatch":false,"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> You can already kind of do this:\n>\n>     $ git rev-parse v2.54.0\n>     0b13e48a3a30cdfa94e8ef842e24d6045ab3d015\n>\n>     $ git rev-parse v2.54.0-0-g0b13e48a3\n>     0b13e48a3a30cdfa94e8ef842e24d6045ab3d015\n>\n>     $ git rev-parse v2.54.0-0-g95e20213f\n>     95e20213faefeb95df29277c58ac1980ab68f701\n>\n> This is described under gitrevisions(7), `<describeOutput>`. The only\n> gotcha is that this format will not verify that the tag and the object\n> ID actually match. But other than that it gives you the ability to have\n> both the human-readable name and the machine-readable commit ID in\n> there.\n>\n> As said, we don't verify that those two revisions actually match. So in\n> the case where they don't the result is certainly going to be lots of\n> confusion. It certainly is one of the more surprising syntaxes that we\n> have in Git.\n\nIt is very unlikely we would change this, but it is a fun thought\nexperiment to imagine what would have happened if we insisted (i.e.,\nverified and then died if it does not hold true) on the presence of\nv2.54.0 tag and when the \"hop\" count is \"-0-\", we also insisted that\nthe hexadecimal part exactly matched the contents of v2.54.0 tag, or\nwhen the \"hop\" count is not zero, we insisted that the hexadecimal\npart names a commit that is descendant of the commit v2.54.0 names.\n\n"},{"id":"546094","messageId":"20260621215307.GD2297179@coredump.intra.peff.net","threadId":"65838","inReplyTo":"xmqqeci2lcpc.fsf@gitster.g","subject":"Re: Pinned references?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2026-06-21T21:53:07Z","receivedAt":"2026-06-21T21:53:09Z","isPatch":false,"body":"On Fri, Jun 19, 2026 at 09:25:19AM -0700, Junio C Hamano wrote:\n\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > You can already kind of do this:\n> >\n> >     $ git rev-parse v2.54.0\n> >     0b13e48a3a30cdfa94e8ef842e24d6045ab3d015\n> >\n> >     $ git rev-parse v2.54.0-0-g0b13e48a3\n> >     0b13e48a3a30cdfa94e8ef842e24d6045ab3d015\n> >\n> >     $ git rev-parse v2.54.0-0-g95e20213f\n> >     95e20213faefeb95df29277c58ac1980ab68f701\n> >\n> > This is described under gitrevisions(7), `<describeOutput>`. The only\n> > gotcha is that this format will not verify that the tag and the object\n> > ID actually match. But other than that it gives you the ability to have\n> > both the human-readable name and the machine-readable commit ID in\n> > there.\n> >\n> > As said, we don't verify that those two revisions actually match. So in\n> > the case where they don't the result is certainly going to be lots of\n> > confusion. It certainly is one of the more surprising syntaxes that we\n> > have in Git.\n> \n> It is very unlikely we would change this, but it is a fun thought\n> experiment to imagine what would have happened if we insisted (i.e.,\n> verified and then died if it does not hold true) on the presence of\n> v2.54.0 tag and when the \"hop\" count is \"-0-\", we also insisted that\n> the hexadecimal part exactly matched the contents of v2.54.0 tag, or\n> when the \"hop\" count is not zero, we insisted that the hexadecimal\n> part names a commit that is descendant of the commit v2.54.0 names.\n\nThis is somewhat related to the thread here:\n\n  https://lore.kernel.org/git/CAFb48S8LDz4kiWsKSCBn8J=AHyQ5SVPFH4GY=z+8=DntT=PyAw@mail.gmail.com/\n\nThe problem there was the opposite. A name \"foo-gcc14\" was taken as a\ndescribe name (for object \"cc14\") when it was not. But one thing I noted\nthere is that you probably can't be too picky about having \"foo\" when\nyou see \"foo-g1234abcd\". Part of the point of putting the hash in the\ndescribed name is that the receiver does not necessarily have your same\nrefs!\n\nSo insisting that \"v2.54.0-0-g1234abcd\" have both \"v2.54.0\" and\n\"1234abcd\" locally is probably going to cause some regressions. We could\nquietly accept it as \"1234abcd\" if your \"v2.54.0\" ref is missing\nentirely, though that is perhaps missing the point of the original\nrequest.\n\nThe discussion around this patch series might also be relevant:\n\n  https://lore.kernel.org/git/xmqqed1i4pga.fsf@gitster.g/\n\n-Peff\n"}]}