How to squash all merges in a branch?

好久不见. 提交于 2019-12-10 17:42:38

问题


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 make it like this:

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

That means, squashing all merges.

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

Edit

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


回答1:


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

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

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

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

Checkout base commit (in detached state):

git checkout A~0

Cherry pick 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

Force old branch and checkout:

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


来源:https://stackoverflow.com/questions/26576291/how-to-squash-all-merges-in-a-branch

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!