Hendrik Wiese
Hendrik Wiese

Reputation: 2219

git, reorder commits in messed up branches

I've got a git repo that I would like to restructure completely.

All in all I've got three features, let's call them feature A, B, C, that I've been working on for the past few weeks. Unfortunately I've been a bit unthoughtful regarding how to use branches to split my working on the features correctly, and I somehow also jumped from feature to feature even between commits.

So now I've got three branches A_devel, B_devel, C_devel and in each branch a bunch of commits that belong to each of the three features. Some commits of feature A also containing some changes for feature B in B_devel, some of B with changes for A in C_devel and so on. Some commits are even in the master branch, containing changes for any of the features. And all the commits are also already pushed to origin.

It's a complete chaos...

... that I would like to clean up now.

At least I can see from the commit messages and in some cases just from the code diffs what I've been working on in every particular commit. So I know which commit belongs to which feature. I just need to know how to actually move the commits to the corresponding correct branch.

//edit: by the way, I have to mention that I'm the only one working on this repo, locally as well as on origin. So most likely no one would have problems with a changed history... just in case that's going to be necessary.

Upvotes: 1

Views: 121

Answers (2)

Ashutosh Jindal
Ashutosh Jindal

Reputation: 18869

Please note the following before reading the rest of the answer:

  1. git reset or rebase both do history rewriting, so they should not be used if the history was published. This shouldn't be a problem in your case, since you are the only one using the repo.
  2. cherry-pick, as of v1.7.1, can cherry-pick multiple commits, so you can use this to "yank" more than one commit out.

So my suggested strategy would be something as follows. Consider the following structure which has a mish-mash of changes related to features A and B on two branches:

      A1--A2--B1--B2--A3 (A_Devel HEAD)
     /
o-o-X (master HEAD)
     \ 
      B3--B4--A4--B5 (B_Devel HEAD)

what we want is:

      A1--A2--A3--A4 (A_Devel HEAD)
     /
o-o-X (master HEAD)
     \ 
      B1--B2--B3--B4--B5 (B_Devel HEAD)

Make sure that all feature branches have all relevant commits + some unneeded ones

Copy all commit related to feature A to A_Devel from B_Devel:

  1. git checkout A_Devel
  2. git cherry-pick A4

giving

      A1--A2--B1--B2--A3--A4 (A_Devel HEAD)
     /
o-o-X (master HEAD)
     \ 
      B3--B4--A4--B5 (B_Devel HEAD)

  1. git checkout B_Devel
  2. git cherry-pick B1 B2

giving

      A1--A2--B1--B2--A3--A4 (A_Devel HEAD)
     /
o-o-X (master HEAD)
     \ 
      B3--B4--A4--B5--B1--B2 (B_Devel HEAD)


Now remove the irrelevant commits

  1. git checkout A_Devel
  2. git rebase -i HEAD~~~~ (we wanna remove B1, B2)
  3. Editor opens up with: pick B1 pick B2 pick A3 pick A4

Delete the first two lines and save and exit from editor. Wait for rebase to finish.

Now we'll have:

      A1--A2--A3--A4 (A_Devel HEAD)
     /
o-o-X (master HEAD)
     \ 
      B3--B4--A4--B5--B1--B2 (B_Devel HEAD)

Similarly, for branch B_Devel:

  1. git checkout B_Devel
  2. git rebase -i HEAD~~~~~~ (we wanna change stuff in the last 6 commits)
  3. Editor opens up with: pick B3 pick B4 pick A4 pick B5 pick B1 pick B2

delete the line with A1 and reorder the remaining 'B' changes so that they look like:

 pick B1
 pick B2
 pick B3
 pick B4
 pick B5

Save, exit, wait for rebase to finish which will finally give us:

      A1--A2--A3--A4 (A_Devel HEAD)
     /
o-o-X (master HEAD)
     \ 
      B1--B2--B3--B4--B5 (B_Devel HEAD)

Upvotes: 1

blas3nik
blas3nik

Reputation: 1381

Definitely not a nice solution, but if you're going through the whole log, you could theoretically use a combination of git cherry-pick <commithash> to get one commit from one branch to another one, and git rebase -i (interactive rebase) to reorder commits in your branch.

Read more on this here.

Upvotes: 1

Related Questions