{"thread":{"id":"23603","subject":"Alter parent ID of existing commit object","startedAt":"2010-04-26T10:13:53Z","lastAt":"2010-04-26T23:34:12Z","messageCount":4,"participants":["Paul Richards","Jonathan Nieder","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"140404","messageId":"n2xa1138db31004260313jcd22b2ebw403ca2bd547e784b@mail.gmail.com","threadId":"23603","inReplyTo":null,"subject":"Alter parent ID of existing commit object","fromName":"Paul Richards","fromEmail":"paul.richards@gmail.com","sentAt":"2010-04-26T10:13:53Z","receivedAt":"2010-04-26T10:13:53Z","isPatch":false,"sender":{"key":"paul.richards@gmail.com","avatar":"https://gravatar.com/avatar/79ad1fd7cbf40f3c342e4f2586a69ecde83b3f05804639cbc709a812d47613d1?d=mp&s=160"},"body":"Hi,\nIs it possible to edit an old commit object and only alter the ID of\nthe parent commit but otherwise leave all the other information intact\n(tree, message, authors, date, etc).\n\nI'd expect such a command to return the new hash of the modified commit.\n\n\n\n-- \nPaul Richards\n"},{"id":"140409","messageId":"20100426103637.GA8896@progeny.tock","threadId":"23603","inReplyTo":"n2xa1138db31004260313jcd22b2ebw403ca2bd547e784b@mail.gmail.com","subject":"Re: Alter parent ID of existing commit object","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-04-26T10:38:02Z","receivedAt":"2010-04-26T10:38:02Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Hi Paul,\n\nPaul Richards wrote:\n\n> Is it possible to edit an old commit object and only alter the ID of\n> the parent commit but otherwise leave all the other information intact\n> (tree, message, authors, date, etc).\n> \n> I'd expect such a command to return the new hash of the modified commit.\n\nThe standard answer to this question is to say “use grafts and\nfilter-branch”.  The git-filter-branch(1) man page explains this\napproach.  It is very powerful, but sometimes I do not want to have\nthat much power.\n\nSo I will tell a secret: in the scenarios when I wanted something like\nthis (actually, what I have occasionally wanted is to transform a\nsingle-parent commit into a merge), I did something like the following:\n\n  $ git cat-file commit $rev\n  tree dcd2cc4b76f8756423f5c1ab7d2c62d458a8b15f\n  parent 5f1e6d9ce35e212708f9adc55e6b9a7e0d296df4\n  author Will Palmer <wmpalmer@gmail.com> 1272275407 -0500\n  committer Jonathan Nieder <jrnieder@gmail.com> 1272275443 -0500\n  \n  pretty: Respect --abbrev option\n  \n  Prior to this, the output of git log -1 --format=%h was always 7\n  characters long, without regard to whether --abbrev had been passed.\n  \n  Signed-off-by: Will Palmer <wmpalmer@gmail.com>\n  Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n  $ git cat-file commit $rev >tmp\n  $ sed -i -e \"s/parent .*/parent $(git rev-parse othercommit)/\" tmp\n  $ git hash-object -t commit -w tmp\n  ca55c560685284ac6d121939b2cd881f426e7074\n\nEasy.  Still, I would be happy to see this packaged in a command, so I\ncould recommend it in combination with ‘git replace’ to people who are\nscared of sed.\n\nThanks for bringing it up.\nJonathan\n"},{"id":"140410","messageId":"k2za1138db31004260402le42e15fhc791700cbf28b17e@mail.gmail.com","threadId":"23603","inReplyTo":"20100426103637.GA8896@progeny.tock","subject":"Re: Alter parent ID of existing commit object","fromName":"Paul Richards","fromEmail":"paul.richards@gmail.com","sentAt":"2010-04-26T11:02:09Z","receivedAt":"2010-04-26T11:02:09Z","isPatch":false,"sender":{"key":"paul.richards@gmail.com","avatar":"https://gravatar.com/avatar/79ad1fd7cbf40f3c342e4f2586a69ecde83b3f05804639cbc709a812d47613d1?d=mp&s=160"},"body":"On 26 April 2010 11:38, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Hi Paul,\n>\n> Paul Richards wrote:\n>\n>> Is it possible to edit an old commit object and only alter the ID of\n>> the parent commit but otherwise leave all the other information intact\n>> (tree, message, authors, date, etc).\n>>\n>> I'd expect such a command to return the new hash of the modified commit.\n>\n> The standard answer to this question is to say “use grafts and\n> filter-branch”.  The git-filter-branch(1) man page explains this\n> approach.  It is very powerful, but sometimes I do not want to have\n> that much power.\n>\n> So I will tell a secret: in the scenarios when I wanted something like\n> this (actually, what I have occasionally wanted is to transform a\n> single-parent commit into a merge), I did something like the following:\n>\n>  $ git cat-file commit $rev\n>  tree dcd2cc4b76f8756423f5c1ab7d2c62d458a8b15f\n>  parent 5f1e6d9ce35e212708f9adc55e6b9a7e0d296df4\n>  author Will Palmer <wmpalmer@gmail.com> 1272275407 -0500\n>  committer Jonathan Nieder <jrnieder@gmail.com> 1272275443 -0500\n>\n>  pretty: Respect --abbrev option\n>\n>  Prior to this, the output of git log -1 --format=%h was always 7\n>  characters long, without regard to whether --abbrev had been passed.\n>\n>  Signed-off-by: Will Palmer <wmpalmer@gmail.com>\n>  Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n>  $ git cat-file commit $rev >tmp\n>  $ sed -i -e \"s/parent .*/parent $(git rev-parse othercommit)/\" tmp\n>  $ git hash-object -t commit -w tmp\n>  ca55c560685284ac6d121939b2cd881f426e7074\n>\n> Easy.  Still, I would be happy to see this packaged in a command, so I\n> could recommend it in combination with ‘git replace’ to people who are\n> scared of sed.\n>\n> Thanks for bringing it up.\n> Jonathan\n>\n\n\nThanks, this looks perfect.  I knew about \"cat-file\", but\n\"hash-object\" was the missing command for me here. :)\n\n\n\n-- \nPaul Richards\n"},{"id":"140457","messageId":"m31ve1eqm1.fsf@localhost.localdomain","threadId":"23603","inReplyTo":"20100426103637.GA8896@progeny.tock","subject":"Re: Alter parent ID of existing commit object","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-04-26T23:34:12Z","receivedAt":"2010-04-26T23:34:12Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jonathan Nieder <jrnieder@gmail.com> writes:\n\n> Hi Paul,\n> \n> Paul Richards wrote:\n> \n> > Is it possible to edit an old commit object and only alter the ID of\n> > the parent commit but otherwise leave all the other information intact\n> > (tree, message, authors, date, etc).\n> > \n> > I'd expect such a command to return the new hash of the modified commit.\n> \n> The standard answer to this question is to say “use grafts and\n> filter-branch”.  The git-filter-branch(1) man page explains this\n> approach.  It is very powerful, but sometimes I do not want to have\n> that much power.\n\nThis also rewrites history up from the changed commit, which is\nsomething that you need to take into account.  It is IMVHO best\nsolution if rewritten part of history was not published, e.g. in the\ncase of private repository / private development.\n\nIn the case of already published history you can use \"git replace\"\nmechanism instead (with git-cat-file + git-hash-object).\n\nGrafts _without_ using \"git filter-branch\" do not rewrite history, but\nare not transferrable.  The modern 'refs/replaces/*' mechanism is.\n\n\nJust FYI, as I guess in your situation grafts+git-filter-branch\nwould be best solution (after running git-filter-branch you can\nremove graft).\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"}]}