Search code examples
gitbranch

Interleave two branches into linear history


I have two branches a and b on top of a main branch, where each branch has commits at different points in time.

For example:

                c5 ---- c7   <-- a
               /
c1 -- c2 -- c3               <-- main
             \
             c4 ---- c6      <-- b

I'd like to interleave the commits from a and b according to their author date into a linear history and fast-forward main.

c1 -- c2 -- c3 -- c4 -- c5 -- c6 -- c7     <-- main

Is there a better way to achieve this than manually cherry-picking the commits from a and b onto main?


Solution

  • Yes, list them in author-date order and cherry-pick the list.

    git checkout main
    git rev-list --reverse --author-date-order a...b | git cherry-pick --stdin
    

    . . . I see the --stdin option is all but undocumented, it's used in an example on the manpage, that's a pretty clear doc bug.


    The three-dot syntax a...b is convenience shorthand for a b --not $(git merge-base --all a b). To extend it to more branches you need to use the full spelling and extend that, a b c --not $(git merge-base --all a b c).