Hi Hilco, On Mon, 19 Feb 2018, Hilco Wijbenga wrote: > On Mon, Feb 19, 2018 at 2:36 PM, brian m. carlson > <sandals@xxxxxxxxxxxxxxxxxxxx> wrote: > > On Mon, Feb 19, 2018 at 11:35:25AM -0800, Hilco Wijbenga wrote: > >> So a scenario like this: > >> > >> my-branch : X -> A -> B -> C -> D -> E -> F -> G > >> base-branch : X -> Y > >> > >> git rebase --onto base-branch HEAD~7 > >> commit A --> conflicts > >> ... lots of work ... > >> commit B --> conflicts > >> ... lots of work ... > >> commit C (Git handles conflicts) > >> commit D (no conflict) > >> commit E --> conflicts > >> ... er, that should have been fixed in commit C > >> > >> How do I keep all the work I did for commits A and B? I get the > >> impression that rerere does not help here because I did not finish the > >> rebase succesfully (and that makes perfect sense, of course). Is there > >> a way at this point in the rebase to "go back" to commit C (so without > >> "git rebase --abort")? > > > > What I do in this case is I unstage all the changes from the index, make > > the change that should have gone into commit C, use git commit --fixup > > (or --squash), and then restage the rest of the changes and continue > > with the rebase. I can then use git rebase -i --autosquash afterwards > > to insert the commit into the right place. > > Yes, that's essentially what I end up doing too. Obviously, in cases > like this, Murphy likes to drop by so commit D will have made changes > to the same files as commit C and you can't cleanly move the fix-up > commit to commit C. :-( I had hoped there might be an easier/cleaner > way to do it. I am a heavy user of interactive rebase. Which is unsurprising, given that I implemented the first version of it. And I find myself in the same situation quite often (as of recent, more often when doing complicated rebases involving non-linear commit topologies, but I digress). Being that familiar with the internals of the interactive rebase command gives me the opportunity to do "clever" things. My number one strategy is to mix interactive rebase with cherry-pick: I `git reset --hard HEAD^` (which refers to the rewritten C), fix up the commit as intended, then look at the latest interactive rebase command listed in the output of `git status`, then determine the commit range of commits I want to replay on top and then call `git cherry-pick <range>` (in your case, that would be `git cherry-pick C..E`. Admittedly, this strategy is a bit cumbersome because a lot of book-keeping is performed by my working memory instead of Git. When I am particularly tired and overworked (and therefore know that my working memory is less useful than usual), I therefore resort to my second-favorite strategy: U use the `done` file. I literally copy parts of $GIT_DIR/rebase-merge/done to the beginning of $GIT_DIR/rebase-merge/git-rebase-todo (the most convenient way to open the latter is `git rebase --edit-todo`). In your case, those would be the `pick` lines cherry-picking D and E. Then, as before, `git reset --hard <commit>` (where I look up the `<commit>` using an aliased version of `git log --graph --oneline --left-right --boundary`), amend the commit, and then `git rebase --continue`. It might be even possible to design a new subcommand for the interactive rebase to facilitate a variation of this strategy (possibly even making use of the fact that the interactive rebase accumulates mappings between the original commits and the rewritten ones in $GIT_DIR/rebase-merge/rewritten-list, intended for use in the post-rewrite hook). Ciao, Johannes