Is it possible to retroactively turn a set of commits into a branch?

GitBranch

Git Problem Overview


Say I have a git repository and I've been working on master, can I retroactively create a branch. For example:

A - B - C - A1 - D - A2 - E

I want to make it look like this:

A - A1 - A2   
\           \   
B - C - D - E

The specific use case is when I've cherry-picked a bunch of commits into an old version branch and it needs to go into multiple older versions and I don't want to repeat the cherry-pick on all those revision.

Essentially it's something that would have been good as a feature or topic branch in the first place but wasn't created like that.

Git Solutions


Solution 1 - Git

If you want all the commits after revision XXX to have happened in a branch, I find this a lot easier than the other proposed methods.

$ git branch fixes       # copies master to new branch
$ git reset --hard XXX   # resets master to XXX

The commits are now only in the "fixes" branch.

This procedure is described in git's help page for reset under "Undo a commit, making it a topic branch".

Solution 2 - Git

Of course you can. (With Git there isn’t much than you can’t do anyway. :)

git checkout -b new-branch hash-of-A
git cherry-pick hash-of-A1
git cherry-pick hash-of-A2

This will create a new branch, starting from the commit A. Afterwards you go back to the same commit again, creating another branch:

git checkout -b new-branch2 hash-of-A
git cherry-pick hash-of-B
git cherry-pick hash-of-C
git cherry-pick hash-of-D
git cherry-pick hash-of-E
git merge new-branch

Now you simply have to merge new-branch and new-branch2 to get the structure you want and drop your old branch.

Of course what Dustin said still holds: the hashes of the commits will change so you should only do that if you haven’t published your changes yet.

Solution 3 - Git

You can't do that transparently because the hashes will have to change, but you basically just need to branch HEAD and rebase -i both branches to drop the respective changes.

Solution 4 - Git

What you want to do is to actually rewrite history. The identifiers of commits would change, and in some cases the changeset given by commits would change. So if there is a chance that somebody could have based work on old version of the branch you want to change, better to not do this. But if you didn't publish this branch, feel free.

Let us assume that a branch we want to change is named 'master', and that the point where we want to start new branch is named 'A' (in given example one of names you can use is 'master~6').

First, lets create new branch from commit 'A', let's name it 'fixes'

$ git checkout -b fixes A

This would also make branch 'fixes' current. Because there are only a few commits that we want to un-cherry-pick, we can cherry pick them on branch 'fixes':

$ git cherry-pick A1
$ git cherry-pick A2

Then we want to remove commits 'A1' and 'A2' from branch 'master'. Because there are only a few commits we want to remove, and possibly many more we want to keep, we eould use 'git rebase --interactive' for that:

$ git rebase -i fixes master

An editor will be fired up with all the commits in 'master' after commit 'A' (which is common commit i.e. merge base of branch 'master' and branch 'fixes'). The list would look like this:

pick deadbee B
pick fa1afe1 C
pick a98d4ba A1
...

Remove lines with commits 'A1' and 'A2', save changes, close editor (or otherwise send changes to inetractive rebase) and git would reapply all commits except those that you have deleted.

Then you can finalize with

$ git merge fixes

(git-rebase left us on rewritten branch 'master').

Solution 5 - Git

Forget all that cherry-picking. Just rebase -i twice omitting the changes, making a new branch each time and then merging the 2.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOttoView Question on Stackoverflow
Solution 1 - GitalltomView Answer on Stackoverflow
Solution 2 - GitBombeView Answer on Stackoverflow
Solution 3 - GitDustinView Answer on Stackoverflow
Solution 4 - GitJakub NarębskiView Answer on Stackoverflow
Solution 5 - GitAdam DymitrukView Answer on Stackoverflow