Search code examples
gitgit-mergegit-squash

Squash frequent merge history from main branch into one


For example, I just merged master branch to my feature branch. Then someone pushed new stuff on master. So I merged again to keep up. And then someone pushed again... I merge again. How do I squash the previous merges so that two merge actions is combined to one?

How can I turn this:

o---o---A---B---C---D---E
         \       \   \   \
          F---G---H---I---J

into this:

o---o---A---B---C---D---E
         \               \
          F---G-----------J'

where J and J' contain exactly the same codes.


Solution

  • This method prevents the need to re-resolve merge-conflicts by re-playing the previously-resolved changes into the merge commit.

    git checkout feature
    git diff master > feature.patch
    git reset --hard G
    git branch --move trimmed_feature
    git checkout -b feature master
    git merge --strategy ours trimmed_feature --no-edit
    git apply feature.patch --index
    git commit --amend --message "Merge branch 'master' into feature"
    git branch -D trimmed_feature
    

    We first remove the old merges to create a trimmed feature branch, then create a clean feature branch from master, merge in our trimmed feature branch using git merge --strategy ours to ignore the changes, then re-apply the previously-resolved changes from the patch.