tags:

views:

98

answers:

2

In my git repository, I have merged branch "B" into "master", getting the the following structure:

--> A --> B --> C --> D  (branch master)
    |           |  
    F --> G --> H        (branch B)

I now want to combine the branches to get the following history:

--> A --> B --> F --> G --> H --> D

How can I do this?

Regards, Jochen

+1  A: 

I would branch from A and then cherry pick in the commits that you want

so:

git checkout -b my-branch A
git cherry-pick B
git cherry-pick F
git cherry-pick G
git cherry-pick H
git cherry-pick D
Rob Di Marco
+5  A: 

I assume C is a merge commit, and that's the reason you don't want to have it in your result.

What you need, to do what you want, is git rebase

Let's start of with yet another schematic commit graph. To leave the original branches intact we will operate on a new branch called rebasing

git checkout -b rebasing master

--> A --> B------------------- --> C --> D         (branch master) (branch rebasing)
     \                           /
      +----+->  F --> G --> H -+                   (branch topic)

Just rebase everything between topic and rebasing onto topic.

git rebase --onto topic topic rebasing

or do the same with a shorter command

git rebase topic

-> A -> B -----------------> C -> D                (branch master)
    \                      /
     +---+>  F -> G -> H +                         (branch topic)
                          \
                           +---------> B -> D      (branch rebasing)

Now when we just look at rebasing we have a straight line form A to D.

-> A -> F -> G -> H -> B -> D                      (branch rebasing)

So, the only problem right now might be that the order is different from what you expected. You could easily fix that by reordering commits with git rebase --interactive, if you want to.

Or you rebase everything in a slightly more complicated way. Let's start again.

--> A --> B------------------- --> C --> D         (branch master) (branch rebasing)
     \                           /
      +----+->  F --> G --> H -+                   (branch topic)

First take everything from C to the tip of master (aka. D) and put it on the tip of topic (aka. H) :

git rebase --onto topic C master

-> A -> B ----------------> C -> D                (branch master)
    \                      /
     +----> F -> G -> H +                         (branch topic)
                          \
                           +---------> D           (branch rebasing)

One last rebase, at the end, and we are finished.

git rebase B

     +----> F -> G -> H +                         (branch topic)
    /                     \
-> A -> B ----------------> C -> D                (branch master)
         \
          +------------------------> F -> G -> H -> D   (branch rebasing)

Voila!

-> A -> B -> F -> G -> H -> D                      (branch rebasing)
davrieb