Search code examples
gitrebasesquashgit-squash

How to propagate squashed commit from master to develop and feature branches


I squashed initial commits in master to one commit using git rebase, generating a new squashed commit, but on develop branch, the commits remain as it is. How do I replace the old commits with new squashed commit in master to develop and other feature branches?

Current State

I--A--B                     :Master
       \ C--D               :Develop

After Squashing

I--S                        :Master
 \ A--B--C--D               :Develop

What I want

I--S                        :Master
   \ C--D                   :Develop

Solution

  • git rebase Master Develop
    

    This command applies A, B, C and D onto S. Because the changes of A and B have already been included in S, they are skipped. Only C and D will be reapplied. The history of Develop will be:

    I--S--C'--D'      :Develop
    

    And the history of Master is unchanged:

    I--S              :Master
    

    You may encounter conflicts during the rebase. If any occurs,

    1. run git status to find the conflicting files;
    2. edit the files until they have the right contents;
    3. run git add <files>;
    4. run git rebase --continue.

    My understanding on git rebase --onto A B C, in bash:

    commits=$(git rev-list --reverse B..C)
    # if C is not a branch name, it leads to detached HEAD state.
    git checkout C
    git reset A --hard
    for c in $commits;do
        git cherry-pick $c
    done
    

    A, B, C are commit-ish. It's just a rough simulation. Some commits may be skipped like merge-commits and commits whose changes have been included beforehand by other commits.