{"thread":{"id":"50160","subject":"A few questions regarding git annotated tags","startedAt":"2019-01-05T15:50:47Z","lastAt":"2019-01-10T13:24:57Z","messageCount":3,"participants":["Michal Novotny","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"366176","messageId":"CANT8FXRRTpAaW0JxYCt94f52eKAz1cBAGpPA84CUTMJUgQrkuw@mail.gmail.com","threadId":"50160","inReplyTo":null,"subject":"A few questions regarding git annotated tags","fromName":"Michal Novotny","fromEmail":"clime@redhat.com","sentAt":"2019-01-05T15:50:30Z","receivedAt":"2019-01-05T15:50:47Z","isPatch":false,"sender":{"key":"clime@redhat.com","avatar":null},"body":"Hello,\n\nI am making an rpm packaging application called rpkg-util\n(https://pagure.io/rpkg-util) that can render parts of rpm metadata\nfrom git metadata, e.g. software version. It uses annotated tags to\nstore most of the data that are then rendered to an rpm spec file\n(e.g. the version or changelog).\n\nNow I would like to make sure that I am not omitting some better\napproach than the one that I am currently using and for that I would\nlike to ask the following questions.\n\nI could potentially make it so that I tag subtrees instead of commits\nand then derive the needed information from these subtree tags. This\ncould be useful if I have multiple rpm packages in different subtrees\nof the same repo. I could then tag the subtree where the rpm package\nis placed.\n\nThis could bring some simplification into the code but as far as I\nknow, you cannot easily checkout a tree tag, which is something a\npackager should be able to do easily: to checkout a state of repo when\na certain subpackage was tagged. This is the first question. Can you\ne.g. do:\n\ngit tag somename HEAD:\n\nand then do something similar to\n\ngit checkout somename\n\nwhich would restore the repository or at least the respective subtree\nof it into the state when \"somename\" tag was created?\n\nRight now, I am putting a package name directly into tag name so I\nknow what tags belong to what package based on that. And I am using\nnormal annotated tags. This works quite well, I would say, but at one\npoint I need to use shared state to move the discovered package name\nfrom one part of the code to another so that the other part can work\nwith the correct subset of the available annotated tags. I wouldn't\nneed to do that if I could derive the correct tag subset based just on\nthe path to the subtree where a package is placed. The path can be\nsimply an input parameter of all my functions and they could all fetch\nthe correct tag subset based just on that information. Those functions\nare independent of each other, they all derive some information from\nthe tags but each one is specialized to fetch a different piece of\ninformation. This would be nice. Right now some of my functions accept\nname when they need to fetch the associated tag set and work with it\nand some accept path if they don't require the tag set.\n\nAlternative approach to creating the tree tags would be to store the\npath information into annotated tag message, which I could do. But is\nthere a relatively simple way to filter tags based on their message\ncontent? Can I put the information into some other part of tag than\nname or the message so that it can be easily filtered?\n\nIt would be also good if the association of the tags to the subtrees\nwas made obvious (it will no longer be obvious when it won't depend on\nname of the tag) but that's a different problem that I could\npotentially solve if I can make the tag<->subtree relation work in\nsome way. I am pretty happy with the current name-based solution but I\ndon't want to miss something obvious or less obvious.\n\nThank you\nMichal Novotny\n"},{"id":"366204","messageId":"20190106065032.GC4207@sigill.intra.peff.net","threadId":"50160","inReplyTo":"CANT8FXRRTpAaW0JxYCt94f52eKAz1cBAGpPA84CUTMJUgQrkuw@mail.gmail.com","subject":"Re: A few questions regarding git annotated tags","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2019-01-06T06:50:33Z","receivedAt":"2019-01-06T06:50:37Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jan 05, 2019 at 04:50:30PM +0100, Michal Novotny wrote:\n\n> I could potentially make it so that I tag subtrees instead of commits\n> and then derive the needed information from these subtree tags. This\n> could be useful if I have multiple rpm packages in different subtrees\n> of the same repo. I could then tag the subtree where the rpm package\n> is placed.\n> \n> This could bring some simplification into the code but as far as I\n> know, you cannot easily checkout a tree tag, which is something a\n> packager should be able to do easily: to checkout a state of repo when\n> a certain subpackage was tagged. This is the first question. Can you\n> e.g. do:\n> \n> git tag somename HEAD:\n> \n> and then do something similar to\n> \n> git checkout somename\n> \n> which would restore the repository or at least the respective subtree\n> of it into the state when \"somename\" tag was created?\n\nNo, there's no easy way to check out a bare tree (and in fact, HEAD is\nforbidden to point to a non-commit).\n\nYou could hack around that by making a new commit that wraps the tree,\nlike:\n\n  commit=$(echo 'wrap foo package' | git commit-tree HEAD:foo)\n  git tag foo-1.2.3 $commit\n\nThere are also useful things to do with the tag of the bare tree. E.g.,\nexport it via git-archive, diff it, \"git checkout -p\" changes from it,\netc. But actually creating a working tree state from it is awkward:\n\n  # move to being on an \"unborn\" branch foo\n  git checkout --orphan foo\n\n  # load the desired tree state; \"-u\" will update the working tree\n  # files\n  git read-tree -m -u foo-1.2.3\n\n  # if we were to commit now, it would become the root commit of the\n  # \"foo\" branch, with no parents. That would make it pretty useful for\n  # things like merging between tags.\n  git commit -m 'kind of weird'\n\nSo it seems kind of awkward and useless.  I'm not sure I totally\nunderstand your problem space, but if you can have actual commits with a\nlogical progression (i.e., where the parent links actually mean\nsomething), I think Git's tools will be more useful.\n\n> Right now, I am putting a package name directly into tag name so I\n> know what tags belong to what package based on that. And I am using\n> normal annotated tags. This works quite well, I would say, but at one\n> point I need to use shared state to move the discovered package name\n> from one part of the code to another so that the other part can work\n> with the correct subset of the available annotated tags. I wouldn't\n> need to do that if I could derive the correct tag subset based just on\n> the path to the subtree where a package is placed.\n\nI'm not sure I understand this bit. Even if you tag a subtree, like:\n\n  git tag foo-1.2.3 HEAD:foo\n\nthen that tree doesn't \"know\" that it was originally at the path \"foo\".\nYou'd have to tag the root tree, and then know to look in the \"foo\"\nsubtree from there. At which point you might as well tag the commit that\ncontains that root tree. Whether it happens to touch the \"foo\" path or\nnot, it represents a particular state.\n\n> Alternative approach to creating the tree tags would be to store the\n> path information into annotated tag message, which I could do. But is\n> there a relatively simple way to filter tags based on their message\n> content? Can I put the information into some other part of tag than\n> name or the message so that it can be easily filtered?\n\nI don't think there's an easy way to show only tags matching a pattern.\nYou could do something like:\n\n  git tag -m 'path: foo' foo\n\n  git for-each-ref --format='%(refname:strip=2) %(subject)' refs/tags/ |\n  grep 'path: foo' |\n  awk '{print $1}'\n\nto grep their subjects (or body, if you want to make the grep stage a\nlittle more clever). Obviously that is not really a structured lookup,\nbut if you control the tag contents, it might be OK.\n\nIn commit messages there's a concept of machine-readable trailers, like\n\"Signed-off-by\", etc, and even some tools for displaying those. But\nthere's not currently any support for parsing them out of tag objects.\n\n\nI sort of answered your questions literally, but TBH I'm still not\nentirely sure what you're trying to accomplish. So hopefully it was\nuseful, but feel free to follow up with more questions. ;)\n\n-Peff\n"},{"id":"366502","messageId":"CANT8FXSqmGqj3yFDMCYEKmiR04qYmqt7L67k2Ny4FxX3Lh0ktA@mail.gmail.com","threadId":"50160","inReplyTo":"20190106065032.GC4207@sigill.intra.peff.net","subject":"Re: A few questions regarding git annotated tags","fromName":"Michal Novotny","fromEmail":"clime@redhat.com","sentAt":"2019-01-10T13:24:43Z","receivedAt":"2019-01-10T13:24:57Z","isPatch":false,"sender":{"key":"clime@redhat.com","avatar":null},"body":"Hey Jeff!\n\nOn Sun, Jan 6, 2019 at 7:50 AM Jeff King <peff@peff.net> wrote:\n>\n> On Sat, Jan 05, 2019 at 04:50:30PM +0100, Michal Novotny wrote:\n>\n> > I could potentially make it so that I tag subtrees instead of commits\n> > and then derive the needed information from these subtree tags. This\n> > could be useful if I have multiple rpm packages in different subtrees\n> > of the same repo. I could then tag the subtree where the rpm package\n> > is placed.\n> >\n> > This could bring some simplification into the code but as far as I\n> > know, you cannot easily checkout a tree tag, which is something a\n> > packager should be able to do easily: to checkout a state of repo when\n> > a certain subpackage was tagged. This is the first question. Can you\n> > e.g. do:\n> >\n> > git tag somename HEAD:\n> >\n> > and then do something similar to\n> >\n> > git checkout somename\n> >\n> > which would restore the repository or at least the respective subtree\n> > of it into the state when \"somename\" tag was created?\n>\n> No, there's no easy way to check out a bare tree (and in fact, HEAD is\n> forbidden to point to a non-commit).\n>\n> You could hack around that by making a new commit that wraps the tree,\n> like:\n>\n>   commit=$(echo 'wrap foo package' | git commit-tree HEAD:foo)\n>   git tag foo-1.2.3 $commit\n>\n> There are also useful things to do with the tag of the bare tree. E.g.,\n> export it via git-archive, diff it, \"git checkout -p\" changes from it,\n> etc. But actually creating a working tree state from it is awkward:\n>\n>   # move to being on an \"unborn\" branch foo\n>   git checkout --orphan foo\n>\n>   # load the desired tree state; \"-u\" will update the working tree\n>   # files\n>   git read-tree -m -u foo-1.2.3\n>\n>   # if we were to commit now, it would become the root commit of the\n>   # \"foo\" branch, with no parents. That would make it pretty useful for\n>   # things like merging between tags.\n>   git commit -m 'kind of weird'\n>\n> So it seems kind of awkward and useless.  I'm not sure I totally\n> understand your problem space, but if you can have actual commits with a\n> logical progression (i.e., where the parent links actually mean\n> something), I think Git's tools will be more useful.\n>\n> > Right now, I am putting a package name directly into tag name so I\n> > know what tags belong to what package based on that. And I am using\n> > normal annotated tags. This works quite well, I would say, but at one\n> > point I need to use shared state to move the discovered package name\n> > from one part of the code to another so that the other part can work\n> > with the correct subset of the available annotated tags. I wouldn't\n> > need to do that if I could derive the correct tag subset based just on\n> > the path to the subtree where a package is placed.\n>\n> I'm not sure I understand this bit. Even if you tag a subtree, like:\n>\n>   git tag foo-1.2.3 HEAD:foo\n>\n> then that tree doesn't \"know\" that it was originally at the path \"foo\".\n> You'd have to tag the root tree, and then know to look in the \"foo\"\n> subtree from there. At which point you might as well tag the commit that\n> contains that root tree. Whether it happens to touch the \"foo\" path or\n> not, it represents a particular state.\n>\n> > Alternative approach to creating the tree tags would be to store the\n> > path information into annotated tag message, which I could do. But is\n> > there a relatively simple way to filter tags based on their message\n> > content? Can I put the information into some other part of tag than\n> > name or the message so that it can be easily filtered?\n>\n> I don't think there's an easy way to show only tags matching a pattern.\n> You could do something like:\n>\n>   git tag -m 'path: foo' foo\n>\n>   git for-each-ref --format='%(refname:strip=2) %(subject)' refs/tags/ |\n>   grep 'path: foo' |\n>   awk '{print $1}'\n>\n> to grep their subjects (or body, if you want to make the grep stage a\n> little more clever). Obviously that is not really a structured lookup,\n> but if you control the tag contents, it might be OK.\n>\n> In commit messages there's a concept of machine-readable trailers, like\n> \"Signed-off-by\", etc, and even some tools for displaying those. But\n> there's not currently any support for parsing them out of tag objects.\n>\n>\n> I sort of answered your questions literally, but TBH I'm still not\n> entirely sure what you're trying to accomplish. So hopefully it was\n> useful, but feel free to follow up with more questions. ;)\n\nNo, I think you summed it up pretty well for me.\n\nI would like to ask one more question, which is now unrelated.\n\nBut I will probably ask in a new thread.\n\nThank you!\nclime\n\n>\n> -Peff\n"}]}