Question

I have the following (simplified) scenario in my git repository:

A-B-C-F
     \
      D-E

Commit F is a fix for C and this needs to become a single commit. I tried an interactive rebase on the "main" branch using git rebase -i HEAD~2, but this results in the following:

A-B-CF
   \
    C-D-E

whereas I want it to be this:

A-B-CF
      \
       D-E

Anyone know how to achieve this? I haven't pushed anything yet.

Was it helpful?

Solution

Im going to add some detail here for the sake of clarity.

A-B-C-F    (master)
     \
      D-E  (featureA)

I attributing branch names to these because it gets confusing when talking about rebasing. The names dont matter, im assuming when you said "main" you meant the top row, which i've called master.

Your problem is actually rather complex, because you have already "shared" the C commit with another branch. Now you want to modify that commit - which means you need to change the history of the entire featureA branch.

A fair warning. If you have published these branches including either C, F, D, or E, with any other developers, they will have serious problem ater you rebase.

git checkout master
git rebase -i HEAD~2

As you know you then just need to fixup or squash the last commit into the one before. Now you will actually have this.(assuming the symbol "CF" represents the combined C and F commits.

A-B-CF   (master)
   \
    C-D-E  (featureA)

This happened because C is no longer in master, but it is in featureA. The most recent common ancestor of the two branches is B. Now, you need to get C our of the history of featureA. As a consequence, all the SHA1 commits after C will also change.

Now you need to checkout featureA and rebase master.

git checkout featureA
git rebase -i master

During the interactive rebase you need to make sure to delete the line that represents the C commit. If you do this correctly you will get this.

A-B-CF   (master)
     \
      D-E  (featureA)

Side Note

If you dont remove that C commit properly during the rebase, you will end up with the following.

A-B-CF   (master)
     \
      C-D-E  (featureA)

OTHER TIPS

Here's what I ended up with. Initial scenario:

A-B-C-F (develop)
     \
      D-E (feature)

Interactive rebase on develop with git checkout develop; git rebase -i HEAD~2, squashing F into C:

A-B-CF (develop)
   \
    C-D-E (feature)

Interactive rebase on feature with git checkout feature; git rebase -i HEAD~3, removing C:

A-B-CF (develop)
   \
    D-E (feature)

And finally a normal rebase on feature branch with git rebase CF-hash, moving the start of the branch:

A-B-CF (develop)
      \
       D-E (feature)

Not sure if this is the best way to go, but it seems to work for me.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top