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.
source to share
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
source to share