{"thread":{"id":"38397","subject":"Pretty format specifier for commit count?","startedAt":"2015-01-19T01:29:27Z","lastAt":"2015-01-22T12:52:43Z","messageCount":7,"participants":["Josh Triplett","Michael J Gruber","Jeff King","josh@joshtriplett.org"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"254872","messageId":"20150119012926.GA24004@thin","threadId":"38397","inReplyTo":null,"subject":"Pretty format specifier for commit count?","fromName":"Josh Triplett","fromEmail":"josh@joshtriplett.org","sentAt":"2015-01-19T01:29:27Z","receivedAt":"2015-01-19T01:29:27Z","isPatch":false,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"I'd like to use git-log to generate a Debian changelog file (with one\nentry per commit), which has entries like this:\n\npackage-name (version-number) unstable; urgency=low\n\n * ...\n\n -- Example Person <person@example.org>  RFC822-date\n\nSince I'm intentionally generating one entry per commit, I can generate\n*almost* all of this with git log:\n\ngit log --pretty='format:packagename (FIXME) unstable; urgency=low%n%n  * %s%n%w(0,4,4)%+b%w(0,0,0)%n -- %an <%ae>  %aD%n'\n\nThis produces entries like this:\n\npackagename (FIXME) unstable; urgency=low\n\n  * Example change\n\n    Long description of example change.\n\n -- Josh Triplett <josh@joshtriplett.org>  Thu, 8 Jan 2015 16:36:52 -0800\n\npackagename (FIXME) unstable; urgency=low\n\n  * Initial version\n\n -- Josh Triplett <josh@joshtriplett.org>  Thu, 8 Jan 2015 16:36:51 -0800\n\nWould it be possible to add a format specifier producing a commit count,\nsimilar to that provided by git-describe?  Such a specifier would allow\nfilling in the version number in the format above (replacing the FIXME).\n(Note that the version numbers need to monotonically increase; otherwise\nI would just use the commit hash as the version numer.)\n\n- Josh Triplett\n"},{"id":"254877","messageId":"54BD0C85.1070001@drmicha.warpmail.net","threadId":"38397","inReplyTo":"20150119012926.GA24004@thin","subject":"Re: Pretty format specifier for commit count?","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2015-01-19T13:54:13Z","receivedAt":"2015-01-19T13:54:13Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Josh Triplett schrieb am 19.01.2015 um 02:29:\n> I'd like to use git-log to generate a Debian changelog file (with one\n> entry per commit), which has entries like this:\n> \n> package-name (version-number) unstable; urgency=low\n> \n>  * ...\n> \n>  -- Example Person <person@example.org>  RFC822-date\n> \n> Since I'm intentionally generating one entry per commit, I can generate\n> *almost* all of this with git log:\n> \n> git log --pretty='format:packagename (FIXME) unstable; urgency=low%n%n  * %s%n%w(0,4,4)%+b%w(0,0,0)%n -- %an <%ae>  %aD%n'\n> \n> This produces entries like this:\n> \n> packagename (FIXME) unstable; urgency=low\n> \n>   * Example change\n> \n>     Long description of example change.\n> \n>  -- Josh Triplett <josh@joshtriplett.org>  Thu, 8 Jan 2015 16:36:52 -0800\n> \n> packagename (FIXME) unstable; urgency=low\n> \n>   * Initial version\n> \n>  -- Josh Triplett <josh@joshtriplett.org>  Thu, 8 Jan 2015 16:36:51 -0800\n> \n> Would it be possible to add a format specifier producing a commit count,\n> similar to that provided by git-describe?  Such a specifier would allow\n> filling in the version number in the format above (replacing the FIXME).\n> (Note that the version numbers need to monotonically increase; otherwise\n> I would just use the commit hash as the version numer.)\n> \n> - Josh Triplett\n> \n\nCan you be a bit more specific about the type count that you are after?\n\"git describe\" counts commits since the most recent tag (possibly within\na specific subset of all tags). Is that your desired format?\n\n(I won't suggest scripting around rev-list, describe and log -1 because\nyou know that already...)\n\nMichael\n"},{"id":"254910","messageId":"20150120011724.GA1944@thin","threadId":"38397","inReplyTo":"54BD0C85.1070001@drmicha.warpmail.net","subject":"Re: Pretty format specifier for commit count?","fromName":"Josh Triplett","fromEmail":"josh@joshtriplett.org","sentAt":"2015-01-20T01:17:25Z","receivedAt":"2015-01-20T01:17:25Z","isPatch":false,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"On Mon, Jan 19, 2015 at 02:54:13PM +0100, Michael J Gruber wrote:\n> Josh Triplett schrieb am 19.01.2015 um 02:29:\n> > I'd like to use git-log to generate a Debian changelog file (with one\n> > entry per commit), which has entries like this:\n> > \n> > package-name (version-number) unstable; urgency=low\n> > \n> >  * ...\n> > \n> >  -- Example Person <person@example.org>  RFC822-date\n> > \n> > Since I'm intentionally generating one entry per commit, I can generate\n> > *almost* all of this with git log:\n> > \n> > git log --pretty='format:packagename (FIXME) unstable; urgency=low%n%n  * %s%n%w(0,4,4)%+b%w(0,0,0)%n -- %an <%ae>  %aD%n'\n> > \n> > This produces entries like this:\n> > \n> > packagename (FIXME) unstable; urgency=low\n> > \n> >   * Example change\n> > \n> >     Long description of example change.\n> > \n> >  -- Josh Triplett <josh@joshtriplett.org>  Thu, 8 Jan 2015 16:36:52 -0800\n> > \n> > packagename (FIXME) unstable; urgency=low\n> > \n> >   * Initial version\n> > \n> >  -- Josh Triplett <josh@joshtriplett.org>  Thu, 8 Jan 2015 16:36:51 -0800\n> > \n> > Would it be possible to add a format specifier producing a commit count,\n> > similar to that provided by git-describe?  Such a specifier would allow\n> > filling in the version number in the format above (replacing the FIXME).\n> > (Note that the version numbers need to monotonically increase; otherwise\n> > I would just use the commit hash as the version numer.)\n> > \n> > - Josh Triplett\n> > \n> \n> Can you be a bit more specific about the type count that you are after?\n> \"git describe\" counts commits since the most recent tag (possibly within\n> a specific subset of all tags). Is that your desired format?\n\nThat might work, since the repository in question has no tags; I'd\nactually like \"commits since root commit\".\n\nI could imagine scenarios in which both \"most recent tag\" and \"commits\nsince most recent tag\" would be useful format specifiers; however, for\nthis use case, I'm looking for \"commits since root commit\".\n\n> (I won't suggest scripting around rev-list, describe and log -1 because\n> you know that already...)\n\nRight.  Though as far as I can tell, git describe doesn't actually do\nwhat I'm looking for.  rev-list --count $commit does (though that'd be\nN**2), as would something like rev-list --reverse HEAD | nl | while read\ncount hash ; do ..., but I'd like to do better than that.\n\n- Josh Triplett\n"},{"id":"254960","messageId":"20150120214952.GA18778@peff.net","threadId":"38397","inReplyTo":"20150120011724.GA1944@thin","subject":"Re: Pretty format specifier for commit count?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-01-20T21:49:53Z","receivedAt":"2015-01-20T21:49:53Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Jan 19, 2015 at 05:17:25PM -0800, Josh Triplett wrote:\n\n> > Can you be a bit more specific about the type count that you are after?\n> > \"git describe\" counts commits since the most recent tag (possibly within\n> > a specific subset of all tags). Is that your desired format?\n> \n> That might work, since the repository in question has no tags; I'd\n> actually like \"commits since root commit\".\n\nThat's basically a generation number. But I'm not sure if that's really\nwhat you want; in a non-linear history it's not unique (two children of\ncommit X are both X+1). It sounds like you really just want commits\ncounting up from the root, and with side branches to have their own\nunique numbers. So something like:\n\n       C\n      /\n  A--B--D\n\n  A=1\n  B=2\n  C=3\n  D=4\n\nexcept the last two are assigned arbitrarily. You need some rules for\nlinearizing the commits.\n\nGit's default output order is deterministic when walking backwards\nthrough history from a specific set of starting points. We keep a queue\nof commits to visit, sorted by timestamp, with ties in timestamps broken\nby whichever was added \"first\" (so two parents of a merge get the first\nparent added first, then the second). E.g. (and remember we're walking\nbackwards from the tip here, but you could do the backwards walk and\nthen reverse it, and start numbering from the other end):\n\n       C--E\n      /    \\\n  A--B--D---F\n\nIf we start at F, we might visit F, E, D, C, B, A. Or maybe C before D,\nbut only if its commit timestamp is newer (and if they tie, we\ndefinitely visit D first, because it will have been queued first).\n\nBut that's not deterministic as you add more starting points (either new\nref tips, or just new merges we have to cross). For example, imagine\nthis:\n\n         G--H\n        /    \\\n       C--E   \\\n      /    \\   \\\n  A--B--D---F---I\n\nIf we start at I, then we might visit H and G first, meaning we learn\nabout C much earlier than we otherwise would. Then we hit F, and get to\nC from there. But now it it may be in a different position with respect\nto D!\n\nI suspect your problem statement may simply assume a linear history,\nwhich makes this all much simpler. But we are not likely to add a\nfeature to git that will break badly once you have a non-linear history. :)\n\nI think in the linear case that a generation number _would_ be correct,\nand it is a useful concept by itself. So that may be the best thing to\nadd.\n\n-Peff\n"},{"id":"254965","messageId":"20150120231110.GC14475@cloud","threadId":"38397","inReplyTo":"20150120214952.GA18778@peff.net","subject":"Re: Pretty format specifier for commit count?","fromName":"","fromEmail":"josh@joshtriplett.org","sentAt":"2015-01-20T23:11:10Z","receivedAt":"2015-01-20T23:11:10Z","isPatch":false,"sender":{"key":"josh@joshtriplett.org","avatar":"https://avatars.githubusercontent.com/u/162737?v=4"},"body":"On Tue, Jan 20, 2015 at 04:49:53PM -0500, Jeff King wrote:\n> On Mon, Jan 19, 2015 at 05:17:25PM -0800, Josh Triplett wrote:\n> \n> > > Can you be a bit more specific about the type count that you are after?\n> > > \"git describe\" counts commits since the most recent tag (possibly within\n> > > a specific subset of all tags). Is that your desired format?\n> > \n> > That might work, since the repository in question has no tags; I'd\n> > actually like \"commits since root commit\".\n> \n> That's basically a generation number. But I'm not sure if that's really\n> what you want; in a non-linear history it's not unique (two children of\n> commit X are both X+1).\n\nThat would actually be perfectly fine.  If I need to distinguish\nbranches, I can either use branch/tag names, or append a commit hash.  I\ndon't mind the following:\n\n /-B-\\\nA     D\n \\-C-/\n\nA=1\nB=C=2\nD=3\n\nI could (and probably should) append \"+hash\" to the version number for\nuniqueness, and if I care what order B and C sort in, I can use tags,\nbranches, or some other more clever mechanism.\n\n> It sounds like you really just want commits\n> counting up from the root, and with side branches to have their own\n> unique numbers. So something like:\n> \n>        C\n>       /\n>   A--B--D\n> \n>   A=1\n>   B=2\n>   C=3\n>   D=4\n> \n> except the last two are assigned arbitrarily. You need some rules for\n> linearizing the commits.\n\nI don't care about the numbers assigned to anything not reachable from\nthe committish I start from.\n\n> But that's not deterministic as you add more starting points (either new\n> ref tips, or just new merges we have to cross). For example, imagine\n> this:\n> \n>          G--H\n>         /    \\\n>        C--E   \\\n>       /    \\   \\\n>   A--B--D---F---I\n> \n> If we start at I, then we might visit H and G first, meaning we learn\n> about C much earlier than we otherwise would. Then we hit F, and get to\n> C from there. But now it it may be in a different position with respect\n> to D!\n\nRight, the numbers need to always stay the same as you add more commits\nover time.  If walking a given graph assigns a given set of generation\nnumbers, walking any subgraph should assign all the same generation\nnumbers to the common nodes.\n\n> I suspect your problem statement may simply assume a linear history,\n> which makes this all much simpler. But we are not likely to add a\n> feature to git that will break badly once you have a non-linear history. :)\n\nNot assuming a linear history, but assuming a linear changelog file. :)\n\n> I think in the linear case that a generation number _would_ be correct,\n> and it is a useful concept by itself. So that may be the best thing to\n> add.\n\nSounds good to me.\n\n- Josh Triplett\n"},{"id":"255075","messageId":"54C0CCA2.3060307@drmicha.warpmail.net","threadId":"38397","inReplyTo":"20150120231110.GC14475@cloud","subject":"Re: Pretty format specifier for commit count?","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2015-01-22T10:10:42Z","receivedAt":"2015-01-22T10:10:42Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"josh@joshtriplett.org schrieb am 21.01.2015 um 00:11:\n> On Tue, Jan 20, 2015 at 04:49:53PM -0500, Jeff King wrote:\n>> On Mon, Jan 19, 2015 at 05:17:25PM -0800, Josh Triplett wrote:\n>>\n>>>> Can you be a bit more specific about the type count that you are after?\n>>>> \"git describe\" counts commits since the most recent tag (possibly within\n>>>> a specific subset of all tags). Is that your desired format?\n>>>\n>>> That might work, since the repository in question has no tags; I'd\n>>> actually like \"commits since root commit\".\n>>\n>> That's basically a generation number. But I'm not sure if that's really\n>> what you want; in a non-linear history it's not unique (two children of\n>> commit X are both X+1).\n> \n> That would actually be perfectly fine.  If I need to distinguish\n> branches, I can either use branch/tag names, or append a commit hash.  I\n> don't mind the following:\n> \n>  /-B-\\\n> A     D\n>  \\-C-/\n> \n> A=1\n> B=C=2\n> D=3\n> \n> I could (and probably should) append \"+hash\" to the version number for\n> uniqueness, and if I care what order B and C sort in, I can use tags,\n> branches, or some other more clever mechanism.\n> \n>> It sounds like you really just want commits\n>> counting up from the root, and with side branches to have their own\n>> unique numbers. So something like:\n>>\n>>        C\n>>       /\n>>   A--B--D\n>>\n>>   A=1\n>>   B=2\n>>   C=3\n>>   D=4\n>>\n>> except the last two are assigned arbitrarily. You need some rules for\n>> linearizing the commits.\n> \n> I don't care about the numbers assigned to anything not reachable from\n> the committish I start from.\n> \n>> But that's not deterministic as you add more starting points (either new\n>> ref tips, or just new merges we have to cross). For example, imagine\n>> this:\n>>\n>>          G--H\n>>         /    \\\n>>        C--E   \\\n>>       /    \\   \\\n>>   A--B--D---F---I\n>>\n>> If we start at I, then we might visit H and G first, meaning we learn\n>> about C much earlier than we otherwise would. Then we hit F, and get to\n>> C from there. But now it it may be in a different position with respect\n>> to D!\n> \n> Right, the numbers need to always stay the same as you add more commits\n> over time.  If walking a given graph assigns a given set of generation\n> numbers, walking any subgraph should assign all the same generation\n> numbers to the common nodes.\n> \n>> I suspect your problem statement may simply assume a linear history,\n>> which makes this all much simpler. But we are not likely to add a\n>> feature to git that will break badly once you have a non-linear history. :)\n> \n> Not assuming a linear history, but assuming a linear changelog file. :)\n> \n>> I think in the linear case that a generation number _would_ be correct,\n>> and it is a useful concept by itself. So that may be the best thing to\n>> add.\n> \n> Sounds good to me.\n> \n> - Josh Triplett\n\nWe do have a linear history when we walk with --first-parent :)\n\nSo, for the changelog for commits \"on a branch\", where \"on a branch\" is\nnot the git concept but defined by \"git rev-list --first-parent\" (more\nlike hg branches), the count from root would be deterministic and the\nright concept given the appropriate branch workflow.\n\nGeneration numbers are monotonous but may increase by steps greater than\n1 on that \"branch\" if I remember them correctly. I.e., merge commits are\n\"weighted\" by the number of commits that get merged in.\n\nMichael\n"},{"id":"255089","messageId":"20150122125243.GB19681@peff.net","threadId":"38397","inReplyTo":"54C0CCA2.3060307@drmicha.warpmail.net","subject":"Re: Pretty format specifier for commit count?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-01-22T12:52:43Z","receivedAt":"2015-01-22T12:52:43Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jan 22, 2015 at 11:10:42AM +0100, Michael J Gruber wrote:\n\n> We do have a linear history when we walk with --first-parent :)\n\nYes, but I do not think it is robust to adding new commits on top. E.g.,\ngiven:\n\n  A--B--C---F\n      \\    /\n       D--E\n\na --first-parent walk from F will show F-C-B-A. Now imagine the branch\nadvances to I:\n\n          G--H---I\n         /      /\n  A--B--C---F--J\n      \\    /\n       D--E\n\nA walk from I will show I-H-G-C-B-A. F is no longer mentioned at all,\nand A, B, and C are now at different positions.\n\nThis might be OK in Josh's case. I have an intuition that commits can\nonly be _removed_ in this case. Which means position from the _top_\nmight change, but the position from the root will always be the same\n(and that is what he wants to be stable).  But I did not think hard\nenough to convince myself that this is always the case.\n\n> So, for the changelog for commits \"on a branch\", where \"on a branch\" is\n> not the git concept but defined by \"git rev-list --first-parent\" (more\n> like hg branches), the count from root would be deterministic and the\n> right concept given the appropriate branch workflow.\n\nCertainly the distance to root is deterministic. But I think we are\nreally counting \"number of commits to be output between the root and\nthis commit\". I guess if:\n\n  1. You only ever start from one traversal point.\n\n  2. You are picking only one parent for each merge.\n\nthen we know that our queue of commits to examine only ever has 0 or 1\nitems in it. And therefore a commit is either shown in the same\nposition from the end, or not shown at all. Because once we get there,\nit is deterministic which commits we will show.\n\n> Generation numbers are monotonous but may increase by steps greater than\n> 1 on that \"branch\" if I remember them correctly. I.e., merge commits are\n> \"weighted\" by the number of commits that get merged in.\n\nSort of. It is the longest distance to (any) root from the commit. So it\nis the max() of the generations of the parents, plus one. So for a\nsimple branch/merge between two lines of development, the increase is\nthe number of commits that are merged. But a branch that has its own\nbranches will not increase the generation count by the total number of\ncommits, but rather by the longest individual sub-branch.\n\n-Peff\n"}]}