1

I have a long linear git history. I want to rebase some commits so it is as if I created a feature branch and merged it back to master using git merge --no-ff master.

Current

A -> B -> C -> D -> E -> F
                         master

Desired

                   master
A -> B   ->   E -> F
      \      /
       C -> D
            feature

I thought to do something like

git checkout D
git checkout -b feature
git rebase B
git merge --no-ff E

But D already has B in its history, so this doesn't do anything. I know how to rebase E off of B (Split a git branch into two branches?), but here, the desired version of E has two parents.

Some additional details is that originally my project was structured like Desired, and E is really a merge commit. I somehow then linearized my history using git rebase to remove some unwanted files from old commits.

Community
  • 1
  • 1
Micah Smith
  • 4,203
  • 22
  • 28

2 Answers2

1

You can do this by resetting master to B to be able to create the merge commit E:

git checkout D
git checkout -b feature
git checkout master

                         master
A -> B -> C -> D -> E -> F
               feature

 

git reset --hard B

     master
A -> B 
      \      
       C -> D
            feature

 

git merge --no-ff feature

              master
A -> B   ->   E
      \      /
       C -> D
            feature

 

git cherry-pick F

                   master
A -> B   ->   E -> F
      \      /
       C -> D
            feature

Maybe not the shortest solution but it does things in the right order so it makes it easier to understand.

Note: Don't forget to save somewhere the hash of F as git reset --hard B will make it become a dangling commit.

Thibault D.
  • 10,041
  • 3
  • 25
  • 56
0
git checkout -b feature D
git checkout -b master F
git rebase -i B  # change pick C, pick D to drop C, drop D
git merge D
Pockets
  • 1,186
  • 7
  • 12