Search code examples
gitversion-controlgit-rebasegit-cherry-pick

Stitch two independent branch histories together


I have two independent branches in my Git repository:

A---B---C branch "old"
X---Y---Z branch "master"

I want to generate the following history:

A---B---C---X---Y---Z

I tried this with the following rebase command (current branch is "master"):

git rebase --strategy=recursive --strategy-option=theirs old master

This fails with:

First, rewinding head to replay your work on top of it...
fatal: Could not parse object 'fb56e6e20ea4a605503732df1f5a0a407808dffa^'

fb56e6 is the first commit of the "old" branch.

As an alternative I used the cherry pick command (current branch is "master"):

git rev-list --reverse old | git cherry-pick --stdin --keep-redundant-commits -X theirs

This works fine, but all commits get a new "committer". Is there a way to tell cherry pick that it should not set the committer? If not, is there a way to achieve what I want with rebase?


Solution

  • I solved it using git filter-branch:

    FIX_COMMITTER='
        if test "$GIT_AUTHOR_NAME" != "$GIT_COMMITTER_EMAIL"; then
            GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
            GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"
            export GIT_COMMITTER_EMAIL
            export GIT_COMMITTER_NAME
        fi
    '
    git filter-branch -f --env-filter "$FIX_COMMITTER" -- master
    

    Source of the idea: https://gist.github.com/maciej/5875814