{"thread":{"id":"58205","subject":"[filter-repo] How to reorder commits","startedAt":"2022-07-21T15:19:43Z","lastAt":"2022-07-25T21:17:32Z","messageCount":3,"participants":["Konstantin Ryabitsev","Elijah Newren"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"459633","messageId":"20220721151937.adgufwkj3uxkk3yb@meerkat.local","threadId":"58205","inReplyTo":null,"subject":"[filter-repo] How to reorder commits","fromName":"Konstantin Ryabitsev","fromEmail":"konstantin@linuxfoundation.org","sentAt":"2022-07-21T15:19:37Z","receivedAt":"2022-07-21T15:19:43Z","isPatch":false,"sender":{"key":"konstantin@linuxfoundation.org","avatar":"https://gravatar.com/avatar/7cb8827c6de56e1bd2dea16508c6708aa43feed3bf3813bcdacecdf96ceadd79?d=mp&s=160"},"body":"Elijah:\n\nIt seems filter-repo can be used to easily reorder commits, but I'm not able\nto quite figure out how to do it with callbacks. My goal is:\n\n- keep the cover letter at the start of the series in order to cleanly\n  delineate where their work starts (and thus avoid potential problems with\n  rebases and finding fork-points with base branches, which tends to give\n  newbies trouble)\n- when the author is ready to submit their work, move the cover letter to the\n  tip of the branch and tag it as \"foo-bar-v1\"\n- when the author is ready to work on their changes, they run --reroll and we\n  move the cover letter back to the start of the series, adding any necessary\n  template \"changes in vX\" entries to it\n\n(or maybe it will go completely differently -- it's all very fluid right now)\n\nBasically, is git-filter-repo the right tool to reorder commits, or is it best\nto go directly with fast-export/fast-import?\n\nThanks in advance,\nKonstantin\n"},{"id":"459800","messageId":"CABPp-BE2391i7syZJUK1Nqjk9VZhSxqto0pb7xBLDZR_fY3FXA@mail.gmail.com","threadId":"58205","inReplyTo":"20220721151937.adgufwkj3uxkk3yb@meerkat.local","subject":"Re: [filter-repo] How to reorder commits","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2022-07-22T23:18:48Z","receivedAt":"2022-07-22T23:19:10Z","isPatch":false,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Thu, Jul 21, 2022 at 8:19 AM Konstantin Ryabitsev\n<konstantin@linuxfoundation.org> wrote:\n>\n> Elijah:\n>\n> It seems filter-repo can be used to easily reorder commits, but I'm not able\n> to quite figure out how to do it with callbacks. My goal is:\n>\n> - keep the cover letter at the start of the series in order to cleanly\n>   delineate where their work starts (and thus avoid potential problems with\n>   rebases and finding fork-points with base branches, which tends to give\n>   newbies trouble)\n> - when the author is ready to submit their work, move the cover letter to the\n>   tip of the branch and tag it as \"foo-bar-v1\"\n> - when the author is ready to work on their changes, they run --reroll and we\n>   move the cover letter back to the start of the series, adding any necessary\n>   template \"changes in vX\" entries to it\n>\n> (or maybe it will go completely differently -- it's all very fluid right now)\n>\n> Basically, is git-filter-repo the right tool to reorder commits, or is it best\n> to go directly with fast-export/fast-import?\n>\n> Thanks in advance,\n> Konstantin\n\nGenerally, it makes no sense to reorder commits in filter-repo, nor\ndoes it make sense to do so using fast-export/fast-import directly.\nfast-export/fast-import don't \"apply a diff\" to get a new tree, they\nsay \"Make these files have these exact contents\".  Perhaps an example\nwould help to explain what I mean...\n\nLet's say you have a repository where some commit has a file\nconsisting of the numbers 2-9 on separate lines.  Then you had two\nmore commits after this one: Commit A has numbers 1-9 (i.e. inserting\na new first line with a \"1\"), and commit B has numbers 1-10 (i.e.\nadding \"10\" to the last line of the file).  If you reverse those two\ncommits in the fast-export/fast-import stream, then B will still have\nthe numbers 1-10 and A will still have the numbers 1-9 in the file.\nThat makes it look like B added both lines, and then A removed the\nfinal line, and the end result is a file with one less line than you\nhad before you reversed the commits.\n\nSo, generally, I think you should use a rebase-like tool for\nreordering commits rather than anything based on\nfast-export/fast-import.\n\n\nNow, with an empty commit you wouldn't run into these issues and so\nyou could get away with reordering.  But there is another issue: in\nthe fast-import stream, you have to list all ancestors of a commit\nbefore you list the commit.  And git-filter-repo parses commits as it\ngoes.  So you'd have to cache a commit or range of commits without\noutputting them, and then later dump them once the new parents have\nbeen output first.  I think a rebase-like tool would probably be\nbetter for this job, but if you really want to, you could probably get\nthis working in filter-repo with a script similar to the ones in\ncontrib/filter-repo-demos, but making sure to use steps something like\nthe following:\n  * Avoid commits getting dumped by setting \"commit.dumped = 1\" (a\n\"lie\" which prevents git-filter-repo from immediately outputting the\ncommit after your callback)\n  * Save the commits in a list somewhere\n  * As you are processing the commit(s) that need to be moved earlier\nmodify the parents of these commit(s) (i.e. the commit.parents field)\nappropriately\n  * After you've output the commit(s) that needed to be moved earlier,\niterate through the saved commit(s) and modify their parents and call\ncommit.dump() on them.\n"},{"id":"459927","messageId":"20220725211726.tkmpvgetsh4fdfdv@meerkat.local","threadId":"58205","inReplyTo":"CABPp-BE2391i7syZJUK1Nqjk9VZhSxqto0pb7xBLDZR_fY3FXA@mail.gmail.com","subject":"Re: [filter-repo] How to reorder commits","fromName":"Konstantin Ryabitsev","fromEmail":"konstantin@linuxfoundation.org","sentAt":"2022-07-25T21:17:26Z","receivedAt":"2022-07-25T21:17:32Z","isPatch":false,"sender":{"key":"konstantin@linuxfoundation.org","avatar":"https://gravatar.com/avatar/7cb8827c6de56e1bd2dea16508c6708aa43feed3bf3813bcdacecdf96ceadd79?d=mp&s=160"},"body":"On Fri, Jul 22, 2022 at 04:18:48PM -0700, Elijah Newren wrote:\n> > - keep the cover letter at the start of the series in order to cleanly\n> >   delineate where their work starts (and thus avoid potential problems with\n> >   rebases and finding fork-points with base branches, which tends to give\n> >   newbies trouble)\n> > - when the author is ready to submit their work, move the cover letter to the\n> >   tip of the branch and tag it as \"foo-bar-v1\"\n> > - when the author is ready to work on their changes, they run --reroll and we\n> >   move the cover letter back to the start of the series, adding any necessary\n> >   template \"changes in vX\" entries to it\n> >\n> > (or maybe it will go completely differently -- it's all very fluid right now)\n> >\n> > Basically, is git-filter-repo the right tool to reorder commits, or is it best\n> > to go directly with fast-export/fast-import?\n> >\n> > Thanks in advance,\n> > Konstantin\n> \n> Generally, it makes no sense to reorder commits in filter-repo, nor\n> does it make sense to do so using fast-export/fast-import directly.\n> fast-export/fast-import don't \"apply a diff\" to get a new tree, they\n> say \"Make these files have these exact contents\".  Perhaps an example\n> would help to explain what I mean...\n\nThank you for the detailed reply, Elijah. You did convince that filter-repo is\nnot the right tool for this case, so I went with cherry-pick instead. Since my\ncase is very straightforward with simple ranges and a guarantee of no\nconflicts, it's the most straightforward solution.\n\nCheers,\nKonstantin\n"}]}