Arne
Arne

Reputation: 23

Rebase single commit without replaying subsequent commits

I have two branches, B1 and B2, in the following setup

          [B1]
-o-o-d1-d2-d3 
      \
       c1-c2-c3  
            [B2]

I would like to switch commit c1 to B1 in order to achieve the following setup

-o-o-d1-c1-d2-d3
         \
          c2-c3

I know that I can cherry-pick c1 onto the first branch. But my history is cleaner if I had the changes of c1 only on branch B1. (I admit, the problem can be seen rather as an aesthetic one... but I hope that git has a nice solution for it.)

Upvotes: 2

Views: 227

Answers (2)

Philippe
Philippe

Reputation: 31227

You just have to do:

git checkout B1
git rebase c1

The rebase will re-apply onto c1 all the commits that from the last common ancestor between the commit c1 and the branch B1 i.e. all the commits in B1 from d1 (the last common ancestor).

In your case, d2 and d3.

Upvotes: 2

Romain Valeri
Romain Valeri

Reputation: 22067

Short answer

git checkout c1
git cherry-pick d2 d3
git branch -f B1 [HEAD]

Step by step process (with a temp branch for clarity)

Initial situation

-o-o-d1-d2-d3 <<< B1
      \
       c1-c2-c3 <<< B2

First point a temp branch to c1

git checkout -b B3 c1

Phase 2

-o-o-d1-d2-d3 <<< B1
      \
       c1 <<< B3
         \
          c2-c3 <<< B2

Then you recover d2 and d3

git cherry-pick d2 d3

Phase 3

-o-o-d1-d2-d3 <<< B1
      \
       c1-d2'-d3' <<< B3
         \
          c2-c3 <<< B2

and you'll finally have to move B1 to point to our new construct (B3)

git checkout -B B1 B3
# and destroy the temp branch
git branch -d B3

(Of course this means a rewitten history of B1.)

Upvotes: 1

Related Questions