{"thread":{"id":"47874","subject":"Is there any way to \"interrupt\" a rebase?","startedAt":"2018-02-19T19:35:52Z","lastAt":"2018-02-23T13:12:46Z","messageCount":10,"participants":["Hilco Wijbenga","brian m. carlson","Jeff King","Phillip Wood","Johannes Schindelin","Jacob Keller"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"339635","messageId":"CAE1pOi1XtrWqG7mOdrNt10YoZG0LOAB7i9cc1Gi8oWhULxE57A@mail.gmail.com","threadId":"47874","inReplyTo":null,"subject":"Is there any way to \"interrupt\" a rebase?","fromName":"Hilco Wijbenga","fromEmail":"hilco.wijbenga@gmail.com","sentAt":"2018-02-19T19:35:25Z","receivedAt":"2018-02-19T19:35:52Z","isPatch":false,"sender":{"key":"hilco.wijbenga@gmail.com","avatar":null},"body":"Hi all,\n\nWhen maintaining a long running branch, I regularly rebase onto our\nactive development branch so that my branch stays up-to-date. What\nhappens fairly often is that during such a rebase, Git will exit\nbecause of rebase/merge conflicts. Nothing unexpected there, of\ncourse, but as it sometimes turns out, the conflict should have been\nfixed in an earlier commit. The only way that I know of to fix this,\nis to abort the rebase and start over with \"git rebase ...\n--interactive\" then \"edit\" every commit and go through them\none-by-one. This is often overkill, though. Is there a better way?\nPerhaps I could \"rewind\" the rebase to an earlier commit and restart\nfrom there?\n\nSo a scenario like this:\n\nmy-branch : X -> A -> B -> C -> D -> E -> F -> G\nbase-branch : X -> Y\n\ngit rebase --onto base-branch HEAD~7\ncommit A --> conflicts\n... lots of work ...\ncommit B --> conflicts\n... lots of work ...\ncommit C (Git handles conflicts)\ncommit D (no conflict)\ncommit E --> conflicts\n... er, that should have been fixed in commit C\n\nHow do I keep all the work I did for commits A and B? I get the\nimpression that rerere does not help here because I did not finish the\nrebase succesfully (and that makes perfect sense, of course). Is there\na way at this point in the rebase to \"go back\" to commit C (so without\n\"git rebase --abort\")?\n\n(Surely, it's not as simple as doing a \"git reset --hard\nsha-of-commit-C\" is it?)\n\nCheers,\nHilco\n"},{"id":"339646","messageId":"20180219223653.GE6619@genre.crustytoothpaste.net","threadId":"47874","inReplyTo":"CAE1pOi1XtrWqG7mOdrNt10YoZG0LOAB7i9cc1Gi8oWhULxE57A@mail.gmail.com","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"brian m. carlson","fromEmail":"sandals@crustytoothpaste.net","sentAt":"2018-02-19T22:36:53Z","receivedAt":"2018-02-19T22:37:04Z","isPatch":false,"sender":{"key":"sandals@crustytoothpaste.net","avatar":"https://avatars.githubusercontent.com/u/497054?v=4"},"body":"On Mon, Feb 19, 2018 at 11:35:25AM -0800, Hilco Wijbenga wrote:\n> So a scenario like this:\n> \n> my-branch : X -> A -> B -> C -> D -> E -> F -> G\n> base-branch : X -> Y\n> \n> git rebase --onto base-branch HEAD~7\n> commit A --> conflicts\n> ... lots of work ...\n> commit B --> conflicts\n> ... lots of work ...\n> commit C (Git handles conflicts)\n> commit D (no conflict)\n> commit E --> conflicts\n> ... er, that should have been fixed in commit C\n> \n> How do I keep all the work I did for commits A and B? I get the\n> impression that rerere does not help here because I did not finish the\n> rebase succesfully (and that makes perfect sense, of course). Is there\n> a way at this point in the rebase to \"go back\" to commit C (so without\n> \"git rebase --abort\")?\n\nWhat I do in this case is I unstage all the changes from the index, make\nthe change that should have gone into commit C, use git commit --fixup\n(or --squash), and then restage the rest of the changes and continue\nwith the rebase.  I can then use git rebase -i --autosquash afterwards\nto insert the commit into the right place.\n-- \nbrian m. carlson / brian with sandals: Houston, Texas, US\nhttps://www.crustytoothpaste.net/~bmc | My opinion only\nOpenPGP: https://keybase.io/bk2204\n"},{"id":"339686","messageId":"CAE1pOi070p9VNPnLS3jSXp7TrbR2fhOc7sx+58exAp92k4D0dw@mail.gmail.com","threadId":"47874","inReplyTo":"20180219223653.GE6619@genre.crustytoothpaste.net","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"Hilco Wijbenga","fromEmail":"hilco.wijbenga@gmail.com","sentAt":"2018-02-19T23:09:23Z","receivedAt":"2018-02-19T23:09:49Z","isPatch":false,"sender":{"key":"hilco.wijbenga@gmail.com","avatar":null},"body":"On Mon, Feb 19, 2018 at 2:36 PM, brian m. carlson\n<sandals@crustytoothpaste.net> wrote:\n> On Mon, Feb 19, 2018 at 11:35:25AM -0800, Hilco Wijbenga wrote:\n>> So a scenario like this:\n>>\n>> my-branch : X -> A -> B -> C -> D -> E -> F -> G\n>> base-branch : X -> Y\n>>\n>> git rebase --onto base-branch HEAD~7\n>> commit A --> conflicts\n>> ... lots of work ...\n>> commit B --> conflicts\n>> ... lots of work ...\n>> commit C (Git handles conflicts)\n>> commit D (no conflict)\n>> commit E --> conflicts\n>> ... er, that should have been fixed in commit C\n>>\n>> How do I keep all the work I did for commits A and B? I get the\n>> impression that rerere does not help here because I did not finish the\n>> rebase succesfully (and that makes perfect sense, of course). Is there\n>> a way at this point in the rebase to \"go back\" to commit C (so without\n>> \"git rebase --abort\")?\n>\n> What I do in this case is I unstage all the changes from the index, make\n> the change that should have gone into commit C, use git commit --fixup\n> (or --squash), and then restage the rest of the changes and continue\n> with the rebase.  I can then use git rebase -i --autosquash afterwards\n> to insert the commit into the right place.\n\nYes, that's essentially what I end up doing too. Obviously, in cases\nlike this, Murphy likes to drop by so commit D will have made changes\nto the same files as commit C and you can't cleanly move the fix-up\ncommit to commit C. :-( I had hoped there might be an easier/cleaner\nway to do it.\n"},{"id":"339690","messageId":"20180220035016.GA17967@sigill.intra.peff.net","threadId":"47874","inReplyTo":"CAE1pOi1XtrWqG7mOdrNt10YoZG0LOAB7i9cc1Gi8oWhULxE57A@mail.gmail.com","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-02-20T03:50:16Z","receivedAt":"2018-02-20T03:50:25Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Feb 19, 2018 at 11:35:25AM -0800, Hilco Wijbenga wrote:\n\n> git rebase --onto base-branch HEAD~7\n> commit A --> conflicts\n> ... lots of work ...\n> commit B --> conflicts\n> ... lots of work ...\n> commit C (Git handles conflicts)\n> commit D (no conflict)\n> commit E --> conflicts\n> ... er, that should have been fixed in commit C\n> \n> How do I keep all the work I did for commits A and B? I get the\n> impression that rerere does not help here because I did not finish the\n> rebase succesfully (and that makes perfect sense, of course). Is there\n> a way at this point in the rebase to \"go back\" to commit C (so without\n> \"git rebase --abort\")?\n\nrerere should help, since the resolutions are stored when you run \"git\ncommit\". Of course, sometimes there are changes outside of the\nconflicted regions that are necessary.\n\nOne thing you can do is to repeat the rebase, but simply pick the\nresolved state at each step. E.g.:\n\n  # remember the failed attempt; you could also store the sha1 in an\n  # environment variable, or even store individual commits.\n  git tag failed\n\n  # now abort and retry the rebase\n  git rebase --abort\n  git rebase -i\n\n  # we should have stopped on commit A with conflicts. Now we can say\n  # \"make the tree just like the other time we saw A\".\n  git checkout failed~4 -- .\n\n  # or if you want to review the changes, try this:\n  git checkout -p failed~4\n\nAnd so on. You visit each commit as before, but you can always grab your\nprevious work (or parts of it, with pathspec limiting or \"-p\") instead\nof repeating the work.\n\nI often do something like this for complicated merges (e.g., of two\nlong-running branches). I try the merge first, only to find that some\npreparatory steps would make it a lot easier. So I commit the merged\nresult (even sometimes half-finished), \"reset --hard\" back to the\noriginal, do the early steps, and then re-merge. And then I \"checkout\n-p\" to pick my work out of the earlier failed attempt.\n\n> (Surely, it's not as simple as doing a \"git reset --hard\n> sha-of-commit-C\" is it?)\n\nNot quite that simple, but that's another approach. If you \"git reset\n--hard\" you'll lose D and E, since the rebase has already applied them.\nBut you could then replay them manually, like this:\n\n  # go back to C and fix it\n  git reset --hard C\n  fix fix fix\n  git commit --amend -m 'fixed C'\n\n  # now replay the other commits on top\n  git cherry-pick D\n  git cherry-pick E\n\n  # and then continue on with any other rebased patches\n  git rebase --continue\n\n-Peff\n"},{"id":"339695","messageId":"c1586003-1c7f-c9c9-9912-d48243305fa3@talktalk.net","threadId":"47874","inReplyTo":"CAE1pOi1XtrWqG7mOdrNt10YoZG0LOAB7i9cc1Gi8oWhULxE57A@mail.gmail.com","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2018-02-20T10:20:19Z","receivedAt":"2018-02-20T10:20:28Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 19/02/18 19:35, Hilco Wijbenga wrote:\n> \n> Hi all,\n> \n> When maintaining a long running branch, I regularly rebase onto our\n> active development branch so that my branch stays up-to-date. What\n> happens fairly often is that during such a rebase, Git will exit\n> because of rebase/merge conflicts. Nothing unexpected there, of\n> course, but as it sometimes turns out, the conflict should have been\n> fixed in an earlier commit. The only way that I know of to fix this,\n> is to abort the rebase and start over with \"git rebase ...\n> --interactive\" then \"edit\" every commit and go through them\n> one-by-one. This is often overkill, though. Is there a better way?\n> Perhaps I could \"rewind\" the rebase to an earlier commit and restart\n> from there?\n> \n> So a scenario like this:\n> \n> my-branch : X -> A -> B -> C -> D -> E -> F -> G\n> base-branch : X -> Y\n> \n> git rebase --onto base-branch HEAD~7\n> commit A --> conflicts\n> .... lots of work ...\n> commit B --> conflicts\n> .... lots of work ...\n> commit C (Git handles conflicts)\n> commit D (no conflict)\n> commit E --> conflicts\n> .... er, that should have been fixed in commit C\n> \n> How do I keep all the work I did for commits A and B? I get the\n> impression that rerere does not help here because I did not finish the\n> rebase succesfully (and that makes perfect sense, of course). Is there\n> a way at this point in the rebase to \"go back\" to commit C (so without\n> \"git rebase --abort\")?\n> \n> (Surely, it's not as simple as doing a \"git reset --hard\n> sha-of-commit-C\" is it?)\n\nHi Hilco\n\nIn the past when I've wanted to edit the commit directly rather than\ncreate a fixup I've done something like\n\n git log --pretty=\"pick %h %s\" C..\n git rebase --edit-todo\n<paste the output of git log into the editor>\n git checkout C\n<amend this commit>\n git commit --amend\n git rebase --continue\n\n\nBest Wishes\n\nPhillip\n> Cheers,\n> Hilco\n> \n\n"},{"id":"339698","messageId":"nycvar.QRO.7.76.6.1802201147300.31@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","threadId":"47874","inReplyTo":"CAE1pOi070p9VNPnLS3jSXp7TrbR2fhOc7sx+58exAp92k4D0dw@mail.gmail.com","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-02-20T11:03:13Z","receivedAt":"2018-02-20T11:03:27Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hilco,\n\nOn Mon, 19 Feb 2018, Hilco Wijbenga wrote:\n\n> On Mon, Feb 19, 2018 at 2:36 PM, brian m. carlson\n> <sandals@crustytoothpaste.net> wrote:\n> > On Mon, Feb 19, 2018 at 11:35:25AM -0800, Hilco Wijbenga wrote:\n> >> So a scenario like this:\n> >>\n> >> my-branch : X -> A -> B -> C -> D -> E -> F -> G\n> >> base-branch : X -> Y\n> >>\n> >> git rebase --onto base-branch HEAD~7\n> >> commit A --> conflicts\n> >> ... lots of work ...\n> >> commit B --> conflicts\n> >> ... lots of work ...\n> >> commit C (Git handles conflicts)\n> >> commit D (no conflict)\n> >> commit E --> conflicts\n> >> ... er, that should have been fixed in commit C\n> >>\n> >> How do I keep all the work I did for commits A and B? I get the\n> >> impression that rerere does not help here because I did not finish the\n> >> rebase succesfully (and that makes perfect sense, of course). Is there\n> >> a way at this point in the rebase to \"go back\" to commit C (so without\n> >> \"git rebase --abort\")?\n> >\n> > What I do in this case is I unstage all the changes from the index, make\n> > the change that should have gone into commit C, use git commit --fixup\n> > (or --squash), and then restage the rest of the changes and continue\n> > with the rebase.  I can then use git rebase -i --autosquash afterwards\n> > to insert the commit into the right place.\n> \n> Yes, that's essentially what I end up doing too. Obviously, in cases\n> like this, Murphy likes to drop by so commit D will have made changes\n> to the same files as commit C and you can't cleanly move the fix-up\n> commit to commit C. :-( I had hoped there might be an easier/cleaner\n> way to do it.\n\nI am a heavy user of interactive rebase. Which is unsurprising, given that\nI implemented the first version of it.\n\nAnd I find myself in the same situation quite often (as of recent, more\noften when doing complicated rebases involving non-linear commit\ntopologies, but I digress).\n\nBeing that familiar with the internals of the interactive rebase command\ngives me the opportunity to do \"clever\" things.\n\nMy number one strategy is to mix interactive rebase with cherry-pick: I\n`git reset --hard HEAD^` (which refers to the rewritten C), fix up the\ncommit as intended, then look at the latest interactive rebase command\nlisted in the output of `git status`, then determine the commit range of\ncommits I want to replay on top and then call `git cherry-pick <range>`\n(in your case, that would be `git cherry-pick C..E`.\n\nAdmittedly, this strategy is a bit cumbersome because a lot of\nbook-keeping is performed by my working memory instead of Git.\n\nWhen I am particularly tired and overworked (and therefore know that my\nworking memory is less useful than usual), I therefore resort to my\nsecond-favorite strategy: U use the `done` file.\n\nI literally copy parts of $GIT_DIR/rebase-merge/done to the beginning of\n$GIT_DIR/rebase-merge/git-rebase-todo (the most convenient way to open the\nlatter is `git rebase --edit-todo`). In your case, those would be the\n`pick` lines cherry-picking D and E. Then, as before, `git reset --hard\n<commit>` (where I look up the `<commit>` using an aliased version of `git\nlog --graph --oneline --left-right --boundary`), amend the commit, and\nthen `git rebase --continue`.\n\nIt might be even possible to design a new subcommand for the interactive\nrebase to facilitate a variation of this strategy (possibly even making\nuse of the fact that the interactive rebase accumulates mappings between\nthe original commits and the rewritten ones in\n$GIT_DIR/rebase-merge/rewritten-list, intended for use in the post-rewrite\nhook).\n\nCiao,\nJohannes\n"},{"id":"339701","messageId":"nycvar.QRO.7.76.6.1802201240010.31@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","threadId":"47874","inReplyTo":"nycvar.QRO.7.76.6.1802201147300.31@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-02-20T11:44:51Z","receivedAt":"2018-02-20T11:45:05Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hilco,\n\nOn Tue, 20 Feb 2018, Johannes Schindelin wrote:\n\n> When I am particularly tired and overworked (and therefore know that my\n> working memory is less useful than usual), I therefore resort to my\n> second-favorite strategy: U use the `done` file.\n> \n> I literally copy parts of $GIT_DIR/rebase-merge/done to the beginning of\n> $GIT_DIR/rebase-merge/git-rebase-todo (the most convenient way to open the\n> latter is `git rebase --edit-todo`). In your case, those would be the\n> `pick` lines cherry-picking D and E. Then, as before, `git reset --hard\n> <commit>` (where I look up the `<commit>` using an aliased version of `git\n> log --graph --oneline --left-right --boundary`), amend the commit, and\n> then `git rebase --continue`.\n> \n> It might be even possible to design a new subcommand for the interactive\n> rebase to facilitate a variation of this strategy (possibly even making\n> use of the fact that the interactive rebase accumulates mappings between\n> the original commits and the rewritten ones in\n> $GIT_DIR/rebase-merge/rewritten-list, intended for use in the post-rewrite\n> hook).\n\nThis feature might look somewhat like this:\n\n\tgit rebase --replay-latest-commits 3\n\nand it would not even have to look at the `rewritten-list`. All it would\ndo is to put back the latest `pick` from the `done` file (in case of merge\nconflicts) into the `git-rebase-todo` file, then insert `pick lines for\nHEAD~3.. at the beginning of that todo file, and then `git reset --hard\nHEAD~3`.\n\nBy not using the original lines from the `done` file (i.e. *different*\nfrom what I described as my second-favorite strategy), you would also get\nthe resolved merge conflicts rather than having to re-resolve them.\n\n(This all would of course only work properly without --preserve-merges and\nwithout the upcoming --recreate-merges.)\n\nCiao,\nJohannes\n"},{"id":"339742","messageId":"20180220205603.GA13721@sigill.intra.peff.net","threadId":"47874","inReplyTo":"nycvar.QRO.7.76.6.1802201240010.31@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-02-20T20:56:03Z","receivedAt":"2018-02-20T20:56:10Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Feb 20, 2018 at 12:44:51PM +0100, Johannes Schindelin wrote:\n\n> > It might be even possible to design a new subcommand for the interactive\n> > rebase to facilitate a variation of this strategy (possibly even making\n> > use of the fact that the interactive rebase accumulates mappings between\n> > the original commits and the rewritten ones in\n> > $GIT_DIR/rebase-merge/rewritten-list, intended for use in the post-rewrite\n> > hook).\n> \n> This feature might look somewhat like this:\n> \n> \tgit rebase --replay-latest-commits 3\n> \n> and it would not even have to look at the `rewritten-list`. All it would\n> do is to put back the latest `pick` from the `done` file (in case of merge\n> conflicts) into the `git-rebase-todo` file, then insert `pick lines for\n> HEAD~3.. at the beginning of that todo file, and then `git reset --hard\n> HEAD~3`.\n\nKeep in mind that the \"pick\" lines could be \"edit\", \"squash\", etc.\n\nI think the general form of your original email's proposal is something\nlike: What if we had a \"git rebase --rewind\" that could \"undo\" the prior\ncommand? So if I had a todo file like:\n\n  pick 1\n  edit 2\n  x make test\n  edit 3\n  x make test\n  pick 4\n\nand I failed at the second \"make test\", then I'd have:\n\n  pick 1\n  edit 2\n  x make test\n  edit 3\n  x make test\n\nin the \"done\" file, with the final pick remaining in \"todo\". Could I\nthen ask to \"rewind\" my state by moving \"x make test\" back to the\n\"todo\". And two rewinds would get me back to applying patch 3, which I\ncould then fix up and re-run my test. Or four rewinds would get me back\nto patch 2, which maybe is where I made the initial mistake.\n\nThat's a bit more primitive than what you're proposing in this\nfollow-on, because you'd be doing the replay yourself (unless we remap\nthe commits). But it's very easy to reason about and implement.\n\nAnyway, just musing at this point. I haven't thought it through, but I\nlike the direction of everything you're saying. ;)\n\n-Peff\n"},{"id":"339758","messageId":"CA+P7+xpWi0kekTM3aJ4VnxtVh0DpGb_U2D6=cUCqz0XqvYwJTQ@mail.gmail.com","threadId":"47874","inReplyTo":"20180220205603.GA13721@sigill.intra.peff.net","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2018-02-20T22:40:09Z","receivedAt":"2018-02-20T22:40:35Z","isPatch":false,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Tue, Feb 20, 2018 at 12:56 PM, Jeff King <peff@peff.net> wrote:\n> On Tue, Feb 20, 2018 at 12:44:51PM +0100, Johannes Schindelin wrote:\n>\n>> > It might be even possible to design a new subcommand for the interactive\n>> > rebase to facilitate a variation of this strategy (possibly even making\n>> > use of the fact that the interactive rebase accumulates mappings between\n>> > the original commits and the rewritten ones in\n>> > $GIT_DIR/rebase-merge/rewritten-list, intended for use in the post-rewrite\n>> > hook).\n>>\n>> This feature might look somewhat like this:\n>>\n>>       git rebase --replay-latest-commits 3\n>>\n>> and it would not even have to look at the `rewritten-list`. All it would\n>> do is to put back the latest `pick` from the `done` file (in case of merge\n>> conflicts) into the `git-rebase-todo` file, then insert `pick lines for\n>> HEAD~3.. at the beginning of that todo file, and then `git reset --hard\n>> HEAD~3`.\n>\n> Keep in mind that the \"pick\" lines could be \"edit\", \"squash\", etc.\n>\n> I think the general form of your original email's proposal is something\n> like: What if we had a \"git rebase --rewind\" that could \"undo\" the prior\n> command? So if I had a todo file like:\n>\n>   pick 1\n>   edit 2\n>   x make test\n>   edit 3\n>   x make test\n>   pick 4\n>\n> and I failed at the second \"make test\", then I'd have:\n>\n>   pick 1\n>   edit 2\n>   x make test\n>   edit 3\n>   x make test\n>\n> in the \"done\" file, with the final pick remaining in \"todo\". Could I\n> then ask to \"rewind\" my state by moving \"x make test\" back to the\n> \"todo\". And two rewinds would get me back to applying patch 3, which I\n> could then fix up and re-run my test. Or four rewinds would get me back\n> to patch 2, which maybe is where I made the initial mistake.\n>\n> That's a bit more primitive than what you're proposing in this\n> follow-on, because you'd be doing the replay yourself (unless we remap\n> the commits). But it's very easy to reason about and implement.\n>\n> Anyway, just musing at this point. I haven't thought it through, but I\n> like the direction of everything you're saying. ;)\n>\n> -Peff\n\nUsing a --rewind that simply tracks the point of each history and can\nreset back to each seems a bit more inline with what the original\nsuggestion is. Sort of like \"undo\" in an editor might. You could even\nadd a \"rewind=x\" so it could go back more than one step at a time, tho\njust re-running rewind until you get where you want would be doable as\nwell.\n\nI like the overall direction of both these suggestions.\n\nThanks,\nJake\n"},{"id":"340032","messageId":"041177b6-e33b-085c-5546-56dbdec75fa3@talktalk.net","threadId":"47874","inReplyTo":"nycvar.QRO.7.76.6.1802201240010.31@ZVAVAG-6OXH6DA.rhebcr.pbec.zvpebfbsg.pbz","subject":"Re: Is there any way to \"interrupt\" a rebase?","fromName":"Phillip Wood","fromEmail":"phillip.wood@talktalk.net","sentAt":"2018-02-23T13:12:37Z","receivedAt":"2018-02-23T13:12:46Z","isPatch":false,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"On 20/02/18 11:44, Johannes Schindelin wrote:\n> \n> Hi Hilco,\n> \n> On Tue, 20 Feb 2018, Johannes Schindelin wrote:\n> \n>> When I am particularly tired and overworked (and therefore know that my\n>> working memory is less useful than usual), I therefore resort to my\n>> second-favorite strategy: U use the `done` file.\n>>\n>> I literally copy parts of $GIT_DIR/rebase-merge/done to the beginning of\n>> $GIT_DIR/rebase-merge/git-rebase-todo (the most convenient way to open the\n>> latter is `git rebase --edit-todo`). In your case, those would be the\n>> `pick` lines cherry-picking D and E. Then, as before, `git reset --hard\n>> <commit>` (where I look up the `<commit>` using an aliased version of `git\n>> log --graph --oneline --left-right --boundary`), amend the commit, and\n>> then `git rebase --continue`.\n>>\n>> It might be even possible to design a new subcommand for the interactive\n>> rebase to facilitate a variation of this strategy (possibly even making\n>> use of the fact that the interactive rebase accumulates mappings between\n>> the original commits and the rewritten ones in\n>> $GIT_DIR/rebase-merge/rewritten-list, intended for use in the post-rewrite\n>> hook).\n> \n> This feature might look somewhat like this:\n> \n> \tgit rebase --replay-latest-commits 3\n> \n> and it would not even have to look at the `rewritten-list`. All it would\n> do is to put back the latest `pick` from the `done` file (in case of merge\n> conflicts) into the `git-rebase-todo` file, then insert `pick lines for\n> HEAD~3.. at the beginning of that todo file, and then `git reset --hard\n> HEAD~3`.\n> \n> By not using the original lines from the `done` file (i.e. *different*\n> from what I described as my second-favorite strategy), you would also get\n> the resolved merge conflicts rather than having to re-resolve them.\n\nYes that's why I prefer using pasting the output of git log rather than\nbits of rebase-merge/done into the todo list when rewinding manually.\n\n> \n> (This all would of course only work properly without --preserve-merges and\n> without the upcoming --recreate-merges.)\n\nIt shouldn't be too hard to support --recreate-merges in the case where\nyou don't go past a merge commit, one would just have to check\nrefs/rewritten to see if any label commands need to be inserted.\n\nBest Wishes\n\nPhillip\n\n> Ciao,\n> Johannes\n> \n\n"}]}