Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I split up a large Git branch into lots of smaller branches?

I have imported from SVN into Git, now I have one big branch, like this:

  • work on feature C
  • work on feature B
  • work on feature C
  • work on feature C
  • work on feature B
  • work on feature A

I want separate feature branches, for A, B, C. I'm cherry picking commits to new branches but this doesn't remove them from the original branch so I have to manually track which ones I have pulled out.

There are around 800 commits to split up, and maybe 50 features/bugfixes.

It would be nice to have the ones I have pulled out reflected this way somehow in the git log, so I know which ones I have already done. Is this possible?

I can rebase the entire branch, skipping the commits I have pulled out, but I'm worried this will cause lots of conflicts. I don't want to resolve 500 conflicts every time I pull a commit out.

What's the best method of pulling out commits from one uber branch onto smaller feature branches, whilst keeping track of your progress?

like image 603
Michael Parker Avatar asked Sep 22 '12 03:09

Michael Parker


People also ask

Can we work on multiple branches in git?

You can have many branches in your repository, but only one of these will be "checked out" as the working-tree so that you can work on it and make changes. git worktree adds the concept of additional working trees. This means you can have two (or more) branches checked-out at once.


2 Answers

What I do in this case is use interactive rebase.

At your HEAD, create your branches A, B, and C. Also create a "backup" branch (you could name it backup) in case things go wrong and you need your original HEAD back.

git branch feature-a git branch feature-b git branch feature-c git-branch backup-before-rebase 

Then, create a branch at the commit you want them to start from, maybe at a convenient stable commit. Call it new_trunk or something.

git checkout HEAD~50       ## this will be the new tree-trunk git branch new_trunk 

Then, do interactive rebases and pick out the commits you want to keep in that branch. Used this way, it's basically like cherry-picking in bulk.

git checkout feature-a git rebase -i new_trunk    ## -i is for "Interactive" 

When you're done, you should have 3 branches with separate histories starting from new_trunk and a backup branch reflecting the old HEAD if you still need it.

like image 157
willoller Avatar answered Sep 27 '22 19:09

willoller


Personally I would really consider pros and cons of such large changes (once more if you've already done this). If you run into conflicts (which is in large rebase/cherry-pick annoying and hard-to-solve by itself) you will probably have tough times when merging features back to your "master" branch.

Wouldn't be better/easier to freeze your big-branch, get it "done" (or "good enough") and make new feature-branches on it? (Or exclude only some branches?)

But to your question:

If you want to track changes/missing commits automatically use git cherry command.

git cherry featureBranch bigBranch 

If there were no conflicts while cherrypicking or rebasing your feature branch you can use previous code with some additional pipes:

git cherry featureBranch bigBranch | awk '{ print "pick " $2 }' | tee remaining 

This will print (and save to file called "remaining") commits missing in featureBranch. You can add this to interactive rebase on bigBranch to throw away commits you don't want anymore. (Maybe you can script it even more with "ed" editor as git editor and passing commands to standard input of interactive rebase but I didn't tried it.)

like image 35
Josef Cech Avatar answered Sep 27 '22 21:09

Josef Cech