{"thread":{"id":"22660","subject":"Walking commits from the first","startedAt":"2010-02-15T04:39:02Z","lastAt":"2010-02-15T14:20:12Z","messageCount":5,"participants":["Pavan Kumar Sunkara","Jeff King","Jon Seymour"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"134599","messageId":"e72faaa81002142039h5531a19y354d24e595295bb1@mail.gmail.com","threadId":"22660","inReplyTo":"e72faaa81002142037g7f5f518erb9fefbb239124bc5@mail.gmail.com","subject":"Walking commits from the first","fromName":"Pavan Kumar Sunkara","fromEmail":"pavan.sss1991@gmail.com","sentAt":"2010-02-15T04:39:02Z","receivedAt":"2010-02-15T04:39:02Z","isPatch":false,"sender":{"key":"pavan.sss1991@gmail.com","avatar":"https://avatars.githubusercontent.com/u/174703?v=4"},"body":"Hi,\n\n When you clone a big git repository and would like to read and\nunderstand the source code, you need to checkout and read every commit\nright from the first commit. As per my knowledge, there is no command\n(even with flags) to checkout the first commit of the repository.\n\nIf there is some command, please put it in user's manual\n\nAlso if we somehow managed to do it by a series of commands, after we\nfinish reading it then we need to redo it all over again to checkout\nthe next commit.\n\nSo, what i would like to have is something like this:\n1) git checkout --first\n   Checksout the commit #1 of the git repository\n2) git checkout --next\n   Checksout the next commit\n\nWhat I think:\n\nI know that every git commit is a vertice in a DAG which has it's edge\npointed to it's parent. So, walking from the latest commits to old\ncommits is easy but the reverse is not.\nI would like to know if there is any problem if we make the walking\nbidirectional. What i mean is, when a new commit is created, create an\nedge not only from it to it's parent but also from it's parent to it.\nAlso, have something for the first commit of the repo which can be\nreferred as INIT (similiar to HEAD)\n\n-pavan\n"},{"id":"134629","messageId":"20100215080646.GD5347@coredump.intra.peff.net","threadId":"22660","inReplyTo":"e72faaa81002142039h5531a19y354d24e595295bb1@mail.gmail.com","subject":"Re: Walking commits from the first","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-02-15T08:06:46Z","receivedAt":"2010-02-15T08:06:46Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 15, 2010 at 10:09:02AM +0530, Pavan Kumar Sunkara wrote:\n\n>  When you clone a big git repository and would like to read and\n> understand the source code, you need to checkout and read every commit\n> right from the first commit. As per my knowledge, there is no command\n> (even with flags) to checkout the first commit of the repository.\n> \n> If there is some command, please put it in user's manual\n\nIn most repositories, you can do this:\n\n  git checkout `git rev-list --reverse HEAD | head -n 1`\n\nbut...\n\n> I know that every git commit is a vertice in a DAG which has it's edge\n> pointed to it's parent. So, walking from the latest commits to old\n> commits is easy but the reverse is not.\n> I would like to know if there is any problem if we make the walking\n> bidirectional. What i mean is, when a new commit is created, create an\n> edge not only from it to it's parent but also from it's parent to it.\n> Also, have something for the first commit of the repo which can be\n> referred as INIT (similiar to HEAD)\n\nIt is not as simple as that, for two reasons.\n\nFor walking backwards, you can take multiple paths from merge commits\n(which have multiple parents). So there may actually be several \"first\ncommits\" if unrelated lines of development were merged together. For\nexample, in git.git:\n\n  $ git log --format='%h %p' |\n    grep ' $'\n  16d6b8a\n  cb07fc2\n  161332a\n  1db95b0\n  2744b23\n  e83c516\n\nThere are six root commits. You can see what they are by piping the\nabove into \"tr -d ' ' | git log --no-walk --stdin\".\n\nFor your \"--next\" suggestion, it is even worse. There may be an infinite\nnumber of commits that point to a given commit as the parent. So there\nis no such thing as \"what came next from X\". You can only ask\n\"leading up to some commit Y which is a descendant of X, what was the\ncommit that came after X\". But while there are a finite number of\nanswers, there is not necessarily just one. If two branches diverged at\nX and then remerged before Y, they are both equally \"next\".\n\n-Peff\n"},{"id":"134635","messageId":"e72faaa81002150333r4eb27a15t7de6b3c820eb4bc2@mail.gmail.com","threadId":"22660","inReplyTo":"20100215080646.GD5347@coredump.intra.peff.net","subject":"Re: Walking commits from the first","fromName":"Pavan Kumar Sunkara","fromEmail":"pavan.sss1991@gmail.com","sentAt":"2010-02-15T11:33:14Z","receivedAt":"2010-02-15T11:33:14Z","isPatch":false,"sender":{"key":"pavan.sss1991@gmail.com","avatar":"https://avatars.githubusercontent.com/u/174703?v=4"},"body":"> In most repositories, you can do this:\n>\n>  git checkout `git rev-list --reverse HEAD | head -n 1`\n>\n\nThanks for the command\n\n> It is not as simple as that, for two reasons.\n>\n> For walking backwards, you can take multiple paths from merge commits\n> (which have multiple parents). So there may actually be several \"first\n> commits\" if unrelated lines of development were merged together. For\n> example, in git.git:\n>\n>  $ git log --format='%h %p' |\n>    grep ' $'\n>  16d6b8a\n>  cb07fc2\n>  161332a\n>  1db95b0\n>  2744b23\n>  e83c516\n>\n> There are six root commits. You can see what they are by piping the\n> above into \"tr -d ' ' | git log --no-walk --stdin\".\n>\n> For your \"--next\" suggestion, it is even worse. There may be an infinite\n> number of commits that point to a given commit as the parent. So there\n> is no such thing as \"what came next from X\". You can only ask\n> \"leading up to some commit Y which is a descendant of X, what was the\n> commit that came after X\". But while there are a finite number of\n> answers, there is not necessarily just one. If two branches diverged at\n> X and then remerged before Y, they are both equally \"next\".\n>\n> -Peff\n>\n\nMy bad. I never thought of branch merging while writing this\nSo, if i want to get the second commit, Is this enough or will i get\nthe problem of branch diverging, if there is a branch diverging from\nthere.\n\ngit checkout `git rev-list --reverse HEAD | head -n 2`\n\nEven though we have the problem branches to travel reversely, we can\ndo it in another way. As, we have the timestamp for every commit, then\nit will be easy to implement --next. Take the next commit in timeline\nand checkout. Even though it's completely different branch, no problem\nas long as we are going in order.\n\nAlso we can have git checkout --next --same-branch to checkout the\nnext commit in timeline of the same branch.\n"},{"id":"134640","messageId":"2cfc40321002150605l4de9d970t919ee56d7a3d697e@mail.gmail.com","threadId":"22660","inReplyTo":"e72faaa81002150333r4eb27a15t7de6b3c820eb4bc2@mail.gmail.com","subject":"Re: Walking commits from the first","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2010-02-15T14:05:35Z","receivedAt":"2010-02-15T14:05:35Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Mon, Feb 15, 2010 at 10:33 PM, Pavan Kumar Sunkara\n<pavan.sss1991@gmail.com> wrote:\n>> In most repositories, you can do this:\n>>\n>>  git checkout `git rev-list --reverse HEAD | head -n 1`\n>>\n>\n> Thanks for the command\n>\n>> It is not as simple as that, for two reasons.\n>>\n>> For walking backwards, you can take multiple paths from merge commits\n>> (which have multiple parents). So there may actually be several \"first\n>> commits\" if unrelated lines of development were merged together. For\n>> example, in git.git:\n>>\n>>  $ git log --format='%h %p' |\n>>    grep ' $'\n>>  16d6b8a\n>>  cb07fc2\n>>  161332a\n>>  1db95b0\n>>  2744b23\n>>  e83c516\n>>\n>> There are six root commits. You can see what they are by piping the\n>> above into \"tr -d ' ' | git log --no-walk --stdin\".\n>>\n>> For your \"--next\" suggestion, it is even worse. There may be an infinite\n>> number of commits that point to a given commit as the parent. So there\n>> is no such thing as \"what came next from X\". You can only ask\n>> \"leading up to some commit Y which is a descendant of X, what was the\n>> commit that came after X\". But while there are a finite number of\n>> answers, there is not necessarily just one. If two branches diverged at\n>> X and then remerged before Y, they are both equally \"next\".\n>>\n>> -Peff\n>>\n>\n> My bad. I never thought of branch merging while writing this\n> So, if i want to get the second commit, Is this enough or will i get\n> the problem of branch diverging, if there is a branch diverging from\n> there.\n>\n\nIt's not merging that's the problem - it's forking. Merges are easy to\ncomprehend - a merge has a finite number of input branches all of\nwhich are immediately discoverable with an O(1) operation. A merge,\nonce performed, is immutable for all time.  The number of forks from a\ngiven commit is fundamentally unbounded and requires comprehensive\nknowledge of the entire history of the repository.\n\n> git checkout `git rev-list --reverse HEAD | head -n 2`\n>\n> Even though we have the problem branches to travel reversely, we can\n> do it in another way. As, we have the timestamp for every commit, then\n> it will be easy to implement --next. Take the next commit in timeline\n> and checkout. Even though it's completely different branch, no problem\n> as long as we are going in order.\n>\n> Also we can have git checkout --next --same-branch to checkout the\n> next commit in timeline of the same branch.\n\nIf your goal is to understand the source code, then reviewing commits\nin time order from start to finish is unlikely to be\nvery helpful.\n\nThe reason is that two adjacent commits in this order will unlikely to\nhave any semantic relationship of any value unless they happen to be\non the same stream of development.\n\nThe history is useful for understanding how something came to be -\ncommits followed backwards down one merge branch will tend to have\nsome semantic relationship to each other unless your committers are on\nacid. Trying to comprehend the evolution of history by replaying it\nforwards and keeping track of n parallel threads of development as\nthey diverge seems like an unnecessarily complicated way of trying to\ncomprehend the world.\n\njon.\n\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"134642","messageId":"2cfc40321002150620i7e290c10pfc978ec9754a914a@mail.gmail.com","threadId":"22660","inReplyTo":"2cfc40321002150605l4de9d970t919ee56d7a3d697e@mail.gmail.com","subject":"Re: Walking commits from the first","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2010-02-15T14:20:12Z","receivedAt":"2010-02-15T14:20:12Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Tue, Feb 16, 2010 at 1:05 AM, Jon Seymour <jon.seymour@gmail.com> wrote:\n> On Mon, Feb 15, 2010 at 10:33 PM, Pavan Kumar Sunkara\n>\n> The history is useful for understanding how something came to be -\n> commits followed backwards down one merge branch will tend to have\n> some semantic relationship to each other unless your committers are on\n> acid. Trying to comprehend the evolution of history by replaying it\n> forwards and keeping track of n parallel threads of development as\n> they diverge seems like an unnecessarily complicated way of trying to\n> comprehend the world.\n>\n\nThat said, of course, git once had an option to rev-list that I\ncontributed (--merge-order) that attempted to create the best possible\nlinear history by performing a topological sort that minimised the\nnumber of \"jumps\" between semantically unrelated commits in the linear\norder. The algorithm was kind of cool (based as it was on a\nconservation of mass analogy), but it eventually got stripped out for\nvarious eminently understandable reasons (like no-one was using it, I\nwasn't maintaining it and it was the only remaining use of a\ndependency on the open-ssl infinite precision integer arithmetic\nlibraries that complicated the build).\n\ngit rev-list --topo-order will do a topological sort that guarantees\nthat you never visit a commit before visiting all its ancestors.\n\n\n> jon.\n>\n>> --\n>> To unsubscribe from this list: send the line \"unsubscribe git\" in\n>> the body of a message to majordomo@vger.kernel.org\n>> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>>\n>\n"}]}