How do I squash all the merges in a branch?

I have a branch like this:

A---B---B1---B2---D---E---E1---E2---G---H
     \           /     \           /
      C1---C2---’       F1---F2---’

      

I want to rewrite it and do it like this:

A---B---B1---B2---D---E---E1---E2---G---H

      

This means that all merges are merged.

The branch is very long. How can this be done automatically?

Edit

This is not a linearization of history. I want to squash all merges like D and G.

+3


source to share


1 answer


This should do the trick. Since we select cherry, the commit, author and author date messages will be the same as the original commits, including merges.

Alternatively, you can get the commit message and blame information from the last commit to the branch before the merge, i.e. the merge of the second parent, by adding the following line to the first condition:

git commit --amend -C $(git rev-parse $rev^2)

      

These commands can easily be converted to script if you do this often.

Performing checksum fixing (in a separate state):



git checkout A~0

      

Cherry selects all commits:

for rev in $(git rev-list  HEAD..branch-name --first-parent --reverse)
do
    if [[ $(git show --summary --format="%P" $rev | wc -w ) -gt 1 ]]
    then
        git cherry-pick $rev --mainline 1
        # git commit --amend -C $(git rev-parse $rev^2)
    else
        git cherry-pick $rev
    fi
done

      

Forcing branch and checkout:

git branch -f branch-name HEAD
git checkout branch-name

      

+2


source







All Articles