Search code examples
gitgit-cherry-pick

Splitting a 'mixed' dirty branch into multiple clean branches


I had a bad git workflow for a while -- I made changes regarding both subject A, subject B and subject C in the same dirtybranch, and in fact also in intermixed commits.

I want to clear this up, so that I have a clean branchA, branchB and branchC for each of these, so that I can later make separate merge requests for upstream.

I have already created branchA, used git cherry-pick --no-commit master..dirtybranch and then simply manually removed the changes regarding subjectB and C. This works although it is inelegant, and I could do the same for subjects B and C although it is looking to be more involved (because they are mixed up in the code more closely).

Therefore my question is:

  • Is there a more elegant (ie. easier) way to do this, especially when you need to go through a file line by line to pick the changes you want to keep (gui?)? I know of eg. meld or kdiff but I am not sure how to apply them here.
  • As I have already 'picked out' changes for subject A into branchA, is there a way to cherry-pick the changes from dirtybranch into eg. branchB "except for" the changes I already put into branchA? (and likewise, dirtybranch->branchC "except for" branchA and branchB)

Solution

  • I have already created branchA, used git cherry-pick --no-commit master..dirtybranch and then simply manually removed the changes regarding subjectB and C.

    A similar approach would be git reset back to the point where dirtybrach branched off from master. There, you can create a new branchA, keeping all your changes unstaged and uncommitted. I usually do this if I have mixed up my commits and want to restructure the changes into new commits.

    To separate the changes into different branches, you could find and commit all changes for branchA, stash the rest, go back to master, create branchB, apply the stash (giving you all changess from dirtybranach except those from branchA), find and commit the changes for branchB, and the whole thing again for branchC.

    That resolves your second point. As for a GUI to make this whole thing as easy as possible, I can only recommend GitKraken, which has a pretty comfortable way to select the hunks or even single lines of a file you want to stage.