5

Let's say I have a git repository that looks like this:

merge-base---A1--A2------A3------A4 (branchA)
          \
           ----------B1------B2 (branchB)

To make things simpler, let's say the commits on branchA are strictly modifications to fileA, and the commits on branchB are strictly modifications to fileB.

I want to combine these branches into a third branch, branchAB, where the commits will be ordered by date:

merge-base---A1--A2------A3------A4 (branchA)
          \
           ----------B1------B2 (branchB)
            \
             A1--A2--B1--A3--B2--A4 (branchAB)

Is there a way to automatically do this with a single git command, or am I stuck with manual methods (e.g. cherry picking or rebase -i)?

BTW, merge-base is a tag.

splicer
  • 5,344
  • 4
  • 42
  • 47

2 Answers2

9

Here's a solution that does what I want, based on adymitruk's original answer:

git checkout -b branchAB merge-base
git merge branchA
git merge branchB
git rebase --onto merge-base merge-base branchAB
Community
  • 1
  • 1
splicer
  • 5,344
  • 4
  • 42
  • 47
  • I know the first merge is a fast-forward only. So why not just create the ab branch on top of one of the other branches as a starting point? – Adam Dymitruk Mar 23 '11 at 23:03
  • @adymitruk: Won't that re-order the commits so that you get all of one branch's commits followed by all of the other branch's commits? It's very important that the order (based on date) be preserved. – splicer Mar 24 '11 at 00:29
  • @adymitruk: Thinking about it a bit more, yes it should be fine to start branchAB at the tip of branchA, then merge-in branchB. The important thing is to do a `rebase --onto` to remove the merge history on branchAB, reordering the commits by date. – splicer Mar 24 '11 at 15:27
  • 1
    If work continues on both branchA and branchB after this merging step, will this procedure also continue to work? Or does the rebase screw that up? – Chris Cleeland Apr 23 '12 at 17:12
1

This should do it:

git branch branchAB branchA
git checkout branchB
git merge branchA
git rebase --onto A1^ B1^ branchAB

The rebase will "eat" the merge commit as --preserve-merges was not specified.

hope this helps

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
  • Close, but there are two problems with your solution. First, rather than creating a third branch, branchAB, it modifies branchB. Second, the last command deletes A4 from the combined branch (branchB). Other than those two things, it does exactly what I want. Thanks! If you can fix the two issues I mentioned, I'll mark your answer as accepted ;) – splicer Mar 23 '11 at 21:29
  • done. No need to do a fast-forward merge, just create the AB branch on top of one of the others. – Adam Dymitruk Mar 23 '11 at 22:59
  • I just tried your edited solution (substituting `A1^` and `B1^` with `merge-base`). Unfortunately, it doesn't even come close to working. `branchAB` ends up the same as `branchA`, and `branchB` gets altered to point to *Merge branch 'branchA' into branchB*. – splicer Mar 24 '11 at 01:38
  • To clarify, by "your edited solution" I meant revision 3 of your answer. Revision 1 was closer. – splicer Mar 24 '11 at 02:06
  • git rebase --onto branchB branchA branchAB – Yohann Streibel Feb 25 '19 at 14:17