{"thread":{"id":"3613","subject":"git-rev-list feature request","startedAt":"2006-03-10T01:07:07Z","lastAt":"2006-03-10T05:16:45Z","messageCount":7,"participants":["Paul Mackerras","Linus Torvalds","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"17402","messageId":"17424.53563.622642.738307@cargo.ozlabs.ibm.com","threadId":"3613","inReplyTo":null,"subject":"git-rev-list feature request","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2006-03-10T01:07:07Z","receivedAt":"2006-03-10T01:07:07Z","isPatch":false,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Hi,\n\nI'd like to implement a new features in gitk to enable it to show the\nrelationship of a given commit to the tags and other references.  What\nI would like is for git-rev-list to be able to output a dense graph\ncontaining only one or more specified commits plus all the commits\nthat have a reference (i.e. a file under $GIT_DIR/refs that contains\ntheir SHA1 ID), plus the merges that are needed to complete the\ngraph.\n\nIt would be nice also to be able to combine that with the existing\nability to output a dense graph containing the commits that modify a\nspecified set of files or directories.\n\nIn other words, I would like to be able to select any combination of\n(a) some explicitly specified commits\n(b) commits that have a reference\n(c) commits that affect specified files or directories\n\nand have git-rev-list output a graph that shows the relationship of\nthose commits.\n\nPossible?\n\nThanks,\nPaul.\n"},{"id":"17404","messageId":"Pine.LNX.4.64.0603091950360.18022@g5.osdl.org","threadId":"3613","inReplyTo":"17424.53563.622642.738307@cargo.ozlabs.ibm.com","subject":"Re: git-rev-list feature request","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-10T03:56:20Z","receivedAt":"2006-03-10T03:56:20Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 10 Mar 2006, Paul Mackerras wrote:\n> \n> It would be nice also to be able to combine that with the existing\n> ability to output a dense graph containing the commits that modify a\n> specified set of files or directories.\n> \n> In other words, I would like to be able to select any combination of\n> (a) some explicitly specified commits\n> (b) commits that have a reference\n> (c) commits that affect specified files or directories\n> \n> and have git-rev-list output a graph that shows the relationship of\n> those commits.\n> \n> Possible?\n\nYeah. I _think_ what you want is\n\n - phase 1: generate the current graph that we already do for\n\n\tgit-rev-list --all ^cmit\n\n - phase 2: start at \"cmit\", and mark everything that refers to it as \n   \"show me\" (including \"cmit\" itself, which was originally marked \n   uninteresting)\n\nSo phase 1 already exists and was the hard part. phase 2 is just walking \nthe graph (that is now all in memory) from \"cmit\" using the \"object->refs\" \nreverse references that got built up during phase 1.\n\nThe only question is how to show the ref-names, or, more properly, what to \ndo when we have a ref-name, but the commit it points to wasn't interesting \nbecause it didn't change the set of files we used to determine interest...\n\nAnd where to find the sucker^H^H^H^H^H^Hhelpful soul to actually do the \nwork.\n\n\t\tLinus\n"},{"id":"17405","messageId":"7vhd663owv.fsf@assigned-by-dhcp.cox.net","threadId":"3613","inReplyTo":"Pine.LNX.4.64.0603091950360.18022@g5.osdl.org","subject":"Re: git-rev-list feature request","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-03-10T04:27:12Z","receivedAt":"2006-03-10T04:27:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Linus Torvalds <torvalds@osdl.org> writes:\n\n> So phase 1 already exists and was the hard part. phase 2 is just walking \n> the graph (that is now all in memory) from \"cmit\" using the \"object->refs\" \n> reverse references that got built up during phase 1.\n\nEh,... what reverse references???\n"},{"id":"17406","messageId":"Pine.LNX.4.64.0603092035310.18022@g5.osdl.org","threadId":"3613","inReplyTo":"7vhd663owv.fsf@assigned-by-dhcp.cox.net","subject":"Re: git-rev-list feature request","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-10T04:46:46Z","receivedAt":"2006-03-10T04:46:46Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 9 Mar 2006, Junio C Hamano wrote:\n\n> Linus Torvalds <torvalds@osdl.org> writes:\n> \n> > So phase 1 already exists and was the hard part. phase 2 is just walking \n> > the graph (that is now all in memory) from \"cmit\" using the \"object->refs\" \n> > reverse references that got built up during phase 1.\n> \n> Eh,... what reverse references???\n\nHeh. Exercise left to the reader. Right now we do only forward references \n(and rev-list.c actually turns that off, since it has no use for them). \n\nBut doing reverse refs should be easy - in the same place we do the \nforward ones. I'd suggest making \"track_object_refs == -1\" mean \"reverse \nrefs\".\n\n(I think the only thing that uses forwards refs is fsck. Nobody else wants \nthem, or would prefer the reverse kind - since forwards refs you can \njust look up yourself anyway).\n\n\t\tLinus\n"},{"id":"17407","messageId":"17425.1459.786864.172060@cargo.ozlabs.ibm.com","threadId":"3613","inReplyTo":"Pine.LNX.4.64.0603091950360.18022@g5.osdl.org","subject":"Re: git-rev-list feature request","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2006-03-10T04:50:59Z","receivedAt":"2006-03-10T04:50:59Z","isPatch":false,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"Linus Torvalds writes:\n\n> Yeah. I _think_ what you want is\n> \n>  - phase 1: generate the current graph that we already do for\n> \n> \tgit-rev-list --all ^cmit\n> \n>  - phase 2: start at \"cmit\", and mark everything that refers to it as \n>    \"show me\" (including \"cmit\" itself, which was originally marked \n>    uninteresting)\n\nI'm not sure if that's what I want.  Is that how \"git-rev-list -- foo\" \nworks?\n\nWhat I want is basically just what \"git-rev-list -- foo\" does, but\nwith some extra flexibility in choosing what commits are interesting -\nthat is, to be able to say that a commit is interesting if it affects\nsome file, has a reference under .git/refs, or if it is one of a set\nof specified commits.\n\nPaul.\n"},{"id":"17412","messageId":"Pine.LNX.4.64.0603092056300.18022@g5.osdl.org","threadId":"3613","inReplyTo":"17425.1459.786864.172060@cargo.ozlabs.ibm.com","subject":"Re: git-rev-list feature request","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-10T05:14:49Z","receivedAt":"2006-03-10T05:14:49Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 10 Mar 2006, Paul Mackerras wrote:\n\n> Linus Torvalds writes:\n> \n> > Yeah. I _think_ what you want is\n> > \n> >  - phase 1: generate the current graph that we already do for\n> > \n> > \tgit-rev-list --all ^cmit\n> > \n> >  - phase 2: start at \"cmit\", and mark everything that refers to it as \n> >    \"show me\" (including \"cmit\" itself, which was originally marked \n> >    uninteresting)\n> \n> I'm not sure if that's what I want.  Is that how \"git-rev-list -- foo\" \n> works?\n\nNope. \"git-rev-list -- foo\" will just start from the heads given, and walk \ndown. \n\n> What I want is basically just what \"git-rev-list -- foo\" does, but\n> with some extra flexibility in choosing what commits are interesting -\n> that is, to be able to say that a commit is interesting if it affects\n> some file, has a reference under .git/refs, or if it is one of a set\n> of specified commits.\n\nAhh, ok, you actually wanted something simpler than I thought you might.\n\nWhat you want is (in its most trivial form) really trivial: mark the \nspecial commits you want to save with TREECHANGE, so that they aren't \npruned by the logic that prunes off the \"this commit doesn't change the \nfile, so ignore it\" commits.\n\nHOWEVER. That trivial thing has problems. What if the history got \nsimplified at a merge because one side of the merge changed it, and the \nother one did not - in that case we'll follow the history down the leg \nthat didn't change (since that's the history that ended up being the final \none). Now, that means that we will totally prune out the other parent \ninfo, and the commits you want to remain simply won't be \"connected\" any \nmore.\n\nTo explain that better, let's say that history looks like this:\n\n\t     a\n\t    / \\\n\t   b   c\n\t   |   |\n\t   d   e\n\t    \\ /\n\t     f\n\nand you're following file \"foo\", which is the same in \"a\" and \"c\". The \nfact that they are the same there means that the name pruning will decide \nthat the history that led to \"a\" through \"b\" wasn't interesting, so it \nwill prune that out, and make the whole history be\n\n\t   a\n\t   |\n\t   c\n\t   |\n\t   e\n\t   |\n\t   f\n\nand then after that, it will remove all commits that didn't actually \nchange foo at all (we know \"a\" was such a commit since we already \nsimplified the merge, but let's say that \"e\" was one too), so you get\n\n\t   c\n\t   |\n\t   f\n\nas the final simplified history right now.\n\nNow, the problem is that what should you do if you want to tag \"d\" and \"e\" \nas inherently interesting (perhaps because they are tagged releases)?\n\nNow, the \"e\" case is the above trivial case: just mark any \"inherently \ninteresting\" commit with the TREECHANGE flag, and the history won't be \npruned away. So it now looks like\n\n\t   c\n\t   |\n\t   e    <- faked \"interesting\"\n\t   |\n\t   f\n\nhowever, the fact that you did the same to \"d\" means that we will have \nthat too on our list of \"interesting\" commits, even though we've pruned \naway all of the history leading _from_ it, so the trivial algorithm would \nactually result in\n\n\t     c\n\t     |\n\t d   e\n\t  \\ /\n\t   f\n\nin that case. We'd see \"d\" because it's somehow intrisically interesting, \nbut it ends up being shown as that \"dead tip\", because the merge that \nwould reach it was simplified away.\n\nIs that what you'd want?\n\nIf so, then the appended trivial path should effectively do what you ask \nfor. It keeps all the revs you passed in as \"interesting\" whether they are \nor not, so now you can effectively just pass in all the refs you want, and \nit will never remove any of the positive refs you passed it.\n\nIf you want a commit that has a ref pointing to it be marked as \ninteresting only if we see it while parsing the tree, then you need to do \nslightly more (in \"rewrite_one()\", you should look up whether that commit \nhas a ref pointing to it).\n\n\t\tLinus\n\n----\ndiff --git a/revision.c b/revision.c\nindex 713f27e..90d3764 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -149,7 +149,8 @@ static struct commit *get_commit_referen\n \t\tif (flags & UNINTERESTING) {\n \t\t\tmark_parents_uninteresting(commit);\n \t\t\trevs->limited = 1;\n-\t\t}\n+\t\t} else\n+\t\t\tobject->flags |= TREECHANGE;\n \t\treturn commit;\n \t}\n \n"},{"id":"17413","messageId":"Pine.LNX.4.64.0603092114570.18022@g5.osdl.org","threadId":"3613","inReplyTo":"Pine.LNX.4.64.0603092056300.18022@g5.osdl.org","subject":"Re: git-rev-list feature request","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-03-10T05:16:45Z","receivedAt":"2006-03-10T05:16:45Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 9 Mar 2006, Linus Torvalds wrote:\n> \n> Ahh, ok, you actually wanted something simpler than I thought you might.\n\nBtw, what I _thought_ you migth want is to do the current \"strong \npruning\", and then look up - from the stuff left behind - which ones reach \nto a ref or a tag. That's where the reverse refs would come in, and it \nrequires some fundamental surgery (but it shouldn't be hard at all).\n\n\t\tLinus\n"}]}