{"thread":{"id":"23860","subject":"Need to change old commit (and regenerate tree)","startedAt":"2010-05-20T19:17:03Z","lastAt":"2010-05-21T21:46:29Z","messageCount":6,"participants":["Antriksh Pany","Andreas Schwab","Jon Seymour","Geert Uytterhoeven"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"141986","messageId":"AANLkTilTAknKPFv5AZBrwsITPsRlVSnsuX8TDXlUTWmw@mail.gmail.com","threadId":"23860","inReplyTo":null,"subject":"Need to change old commit (and regenerate tree)","fromName":"Antriksh Pany","fromEmail":"antriksh.pany@gmail.com","sentAt":"2010-05-20T19:17:03Z","receivedAt":"2010-05-20T19:17:03Z","isPatch":false,"sender":{"key":"antriksh.pany@gmail.com","avatar":null},"body":"Hi all\n\nMy question is this: I have two branches (say B and C) where one is\nreachable from the other (say B is ancestor of C), and if they are\nseparately rebased about/onto the same point, why do B and C become\nnon-overlapping branches?\n\nLet me explain with an example.\n\nSay I have the following commit line:\n\nA--------o--------o--------o--------B--------o--------o--------C\n\nA, B and C are branches (so that B is reachable from C, and A is\nreachable from B). [For ease, I am drawing the branches at the same\nlevel since there are no real diverging branches here.]\n\nI then realise that I want to change the commit A and have both B and\nC rebased on this changed commit.\n\nNow when I do a\n  $ git rebase --onto A2 A C\n\nThis results in two parallel trees like these:\n\nA--------o--------o--------o--------B--------o--------o--------o(old C)\n\nA2--------o--------o--------o--------o--------o--------o--------C\n\nNow I go about rebasing B. I can of course 'reset' B to C~3. But\nalternatively, if I decide to do a rebase:\n  $ git rebase --onto A2 A B\n\nI will end up getting\n\nA--------o--------o--------o--------o(old B)--------o--------o--------o(old C)\n\nA2--------o--------o--------o--------o--------o--------o--------C\n   \\\n     ` -----o--------o--------o--------B\n\nInstead of (what I initially expected):\n\nA--------o--------o--------o--------o(old B)--------o--------o--------o(old C)\n\nA2--------o--------o--------o--------B--------o--------o--------C\n\n\nSo what I am missing here? Aren't the new commits B~1, B~2, B~3\nidentical to C~4, C~5, C~6 (respectively) in all ways so as to have\ngotten them the same SHA1 and hence appear as what I expected them to\nappear?\n\nI have taken a simple example here. In reality, I wanted to change a\nnot so new commit (on the main line), and there were many branches\ndiverging out from the main line after the (bad) commit. I initially\nthought I could just write a simple script that would rebase all\nbranches that have the bad commit as an ancestor, and the new tree\nwould be a mirror image of the original. But that was not to be! There\nis also the problem of resetting tags (and possible notes).\n\n\nI am sorry if this has already been discussed, please point me to the\nright resource if so.\n\nMy git version:\n  $ git --version\n  git version 1.7.0.5\n\nThanks\nAntriksh Pany\n"},{"id":"141990","messageId":"m2sk5mtecw.fsf@igel.home","threadId":"23860","inReplyTo":"AANLkTilTAknKPFv5AZBrwsITPsRlVSnsuX8TDXlUTWmw@mail.gmail.com","subject":"Re: Need to change old commit (and regenerate tree)","fromName":"Andreas Schwab","fromEmail":"schwab@linux-m68k.org","sentAt":"2010-05-20T22:09:19Z","receivedAt":"2010-05-20T22:09:19Z","isPatch":false,"sender":{"key":"schwab@linux-m68k.org","avatar":"https://avatars.githubusercontent.com/u/2175493?v=4"},"body":"Antriksh Pany <antriksh.pany@gmail.com> writes:\n\n> Instead of (what I initially expected):\n>\n> A--------o--------o--------o--------o(old B)--------o--------o--------o(old C)\n>\n> A2--------o--------o--------o--------B--------o--------o--------C\n>\n>\n> So what I am missing here? Aren't the new commits B~1, B~2, B~3\n> identical to C~4, C~5, C~6 (respectively) in all ways so as to have\n> gotten them the same SHA1 and hence appear as what I expected them to\n> appear?\n\nNo, they have a different commit time, which is also part of the hash.\n\nAndreas.\n\n-- \nAndreas Schwab, schwab@linux-m68k.org\nGPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5\n\"And now for something completely different.\"\n"},{"id":"141992","messageId":"AANLkTim0M-PJC655bhfcQ6mBYTPt9TK9Ys8qJBJd1UPS@mail.gmail.com","threadId":"23860","inReplyTo":"m2sk5mtecw.fsf@igel.home","subject":"Re: Need to change old commit (and regenerate tree)","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2010-05-20T23:05:46Z","receivedAt":"2010-05-20T23:05:46Z","isPatch":false,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"On Fri, May 21, 2010 at 8:09 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:\n> Antriksh Pany <antriksh.pany@gmail.com> writes:\n>\n>> Instead of (what I initially expected):\n>>\n>> A--------o--------o--------o--------o(old B)--------o--------o--------o(old C)\n>>\n>> A2--------o--------o--------o--------B--------o--------o--------C\n>>\n>>\n>> So what I am missing here? Aren't the new commits B~1, B~2, B~3\n>> identical to C~4, C~5, C~6 (respectively) in all ways so as to have\n>> gotten them the same SHA1 and hence appear as what I expected them to\n>> appear?\n>\n> No, they have a different commit time, which is also part of the hash.\n>\n\nOf course, even if the commit time was forged to be the same, the\nparent of B~3 is different to the parent of C~6 and since the parent\nis also contributes bits to the respective hashes, B~3 will\nnecessarily (unlikely hash collisions excepted!) have a different hash\nto C~6\n\njon.\n"},{"id":"142014","messageId":"AANLkTinzl_sc9G1PUtLczEjHFdpRqMFuKkEiQTUXaEgQ@mail.gmail.com","threadId":"23860","inReplyTo":"m2sk5mtecw.fsf@igel.home","subject":"Re: Need to change old commit (and regenerate tree)","fromName":"Geert Uytterhoeven","fromEmail":"geert@linux-m68k.org","sentAt":"2010-05-21T05:31:47Z","receivedAt":"2010-05-21T05:31:47Z","isPatch":false,"sender":{"key":"geert@linux-m68k.org","avatar":"https://gravatar.com/avatar/8105b34f653a7b5b98e225e565b11ebcc762ad4ab1a9d905a4663db029a9e6bc?d=mp&s=160"},"body":"On Fri, May 21, 2010 at 00:09, Andreas Schwab <schwab@linux-m68k.org> wrote:\n> Antriksh Pany <antriksh.pany@gmail.com> writes:\n>\n>> Instead of (what I initially expected):\n>>\n>> A--------o--------o--------o--------o(old B)--------o--------o--------o(old C)\n>>\n>> A2--------o--------o--------o--------B--------o--------o--------C\n>>\n>>\n>> So what I am missing here? Aren't the new commits B~1, B~2, B~3\n>> identical to C~4, C~5, C~6 (respectively) in all ways so as to have\n>> gotten them the same SHA1 and hence appear as what I expected them to\n>> appear?\n>\n> No, they have a different commit time, which is also part of the hash.\n\nIndeed.\n\nTo avoid this, you have to:\n  - rebase B on top of A2 first,\n\n        git rebase --onto A2 A B\n\n  - rebase of C on top of the new B.\n\n        git rebase --onto B B_old C\n       (\"git rebase --onto B A C\" should work too, as usually git is\nsmart enough to see\n        that A-B_old is already applied. Use \"git rebase --skip\" if it isn't)\n\nIf A is an ancestor of A2, you can simplify to:\n\n    git rebase A2 B\n    git rebase B C\n\n(Disclaimer: the examples without --onto I use almost daily, the ones\nwith I don't)\n\nGr{oetje,eeting}s,\n\n\t\t\t\t\t\tGeert\n\n--\nGeert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org\n\nIn personal conversations with technical people, I call myself a hacker. But\nwhen I'm talking to journalists I just say \"programmer\" or something like that.\n\t\t\t\t\t\t\t    -- Linus Torvalds\n"},{"id":"142066","messageId":"AANLkTin77rXsU28ikOZx8mxpQANHjaEET--RiR6lGd3a@mail.gmail.com","threadId":"23860","inReplyTo":"AANLkTim0M-PJC655bhfcQ6mBYTPt9TK9Ys8qJBJd1UPS@mail.gmail.com","subject":"Re: Need to change old commit (and regenerate tree)","fromName":"Antriksh Pany","fromEmail":"antriksh.pany@gmail.com","sentAt":"2010-05-21T18:18:17Z","receivedAt":"2010-05-21T18:18:17Z","isPatch":false,"sender":{"key":"antriksh.pany@gmail.com","avatar":null},"body":"Hi Jon\n\nI guess the parent of both B~3 as well as C~6 is A2. So if, as you\nsay, the time can be made\nidentical, they should yield the same SHA1 IMHO.\n\nOn Fri, May 21, 2010 at 12:05 AM, Jon Seymour <jon.seymour@gmail.com> wrote:\n> On Fri, May 21, 2010 at 8:09 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:\n>> Antriksh Pany <antriksh.pany@gmail.com> writes:\n>>\n>>> Instead of (what I initially expected):\n>>>\n>>> A--------o--------o--------o--------o(old B)--------o--------o--------o(old C)\n>>>\n>>> A2--------o--------o--------o--------B--------o--------o--------C\n>>>\n>>>\n>>> So what I am missing here? Aren't the new commits B~1, B~2, B~3\n>>> identical to C~4, C~5, C~6 (respectively) in all ways so as to have\n>>> gotten them the same SHA1 and hence appear as what I expected them to\n>>> appear?\n>>\n>> No, they have a different commit time, which is also part of the hash.\n>>\n>\n> Of course, even if the commit time was forged to be the same, the\n> parent of B~3 is different to the parent of C~6 and since the parent\n> is also contributes bits to the respective hashes, B~3 will\n> necessarily (unlikely hash collisions excepted!) have a different hash\n> to C~6\n>\n> jon.\n>\n"},{"id":"142070","messageId":"AANLkTin8p1Wdbx0-UXuwOtHn8Z4XKnDBAPVOumnz5YLt@mail.gmail.com","threadId":"23860","inReplyTo":"AANLkTinzl_sc9G1PUtLczEjHFdpRqMFuKkEiQTUXaEgQ@mail.gmail.com","subject":"Re: Need to change old commit (and regenerate tree)","fromName":"Antriksh Pany","fromEmail":"antriksh.pany@gmail.com","sentAt":"2010-05-21T21:46:29Z","receivedAt":"2010-05-21T21:46:29Z","isPatch":false,"sender":{"key":"antriksh.pany@gmail.com","avatar":null},"body":"Thanks a lot.\n\nI guess it is then not so straightforward to regenerate trees with\ntheir relative structure\nintact when an old commit changes. I was initially of the opinion that\nit would be a trivial\nrebasing of all branches from which the commit was reachable.\nApparently, not so.\n\nOn Fri, May 21, 2010 at 6:31 AM, Geert Uytterhoeven\n<geert@linux-m68k.org> wrote:\n> On Fri, May 21, 2010 at 00:09, Andreas Schwab <schwab@linux-m68k.org> wrote:\n>> Antriksh Pany <antriksh.pany@gmail.com> writes:\n>>\n>>> Instead of (what I initially expected):\n>>>\n>>> A--------o--------o--------o--------o(old B)--------o--------o--------o(old C)\n>>>\n>>> A2--------o--------o--------o--------B--------o--------o--------C\n>>>\n>>>\n>>> So what I am missing here? Aren't the new commits B~1, B~2, B~3\n>>> identical to C~4, C~5, C~6 (respectively) in all ways so as to have\n>>> gotten them the same SHA1 and hence appear as what I expected them to\n>>> appear?\n>>\n>> No, they have a different commit time, which is also part of the hash.\n>\n> Indeed.\n>\n> To avoid this, you have to:\n>  - rebase B on top of A2 first,\n>\n>        git rebase --onto A2 A B\n>\n>  - rebase of C on top of the new B.\n>\n>        git rebase --onto B B_old C\n>       (\"git rebase --onto B A C\" should work too, as usually git is\n> smart enough to see\n>        that A-B_old is already applied. Use \"git rebase --skip\" if it isn't)\n>\n> If A is an ancestor of A2, you can simplify to:\n>\n>    git rebase A2 B\n>    git rebase B C\n>\n> (Disclaimer: the examples without --onto I use almost daily, the ones\n> with I don't)\n>\n> Gr{oetje,eeting}s,\n>\n>                                                Geert\n>\n> --\n> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org\n>\n> In personal conversations with technical people, I call myself a hacker. But\n> when I'm talking to journalists I just say \"programmer\" or something like that.\n>                                                            -- Linus Torvalds\n>\n"}]}