I found @sky's answer helpful. And I made it into a squash-rebase function.
Assuming you are on your-branch
, what this does is create a branch your-branch-tmp
that is the result of doing merge --squash
on main. It also preserves all the commit messages and lets you edit. Importantly, it also leaves your current branch alone.
After running squash-rebase, if you're satisfied with what it did, you must do a hard reset to the tmp branch. Then in effect you've completed a squash rebase.
function squash-rebase() {
MESSAGES="$(git log $(git merge-base main HEAD)..HEAD --reverse --format=%B)"
SRC_BRANCH="$(git_current_branch)"
TMP_BRANCH="$(git_current_branch)-tmp"
echo "creating temp branch $TMP_BRANCH from $(git_current_branch)"
git checkout -b $TMP_BRANCH main # create tmp branch from main and checkout
git merge $SRC_BRANCH --squash
git commit -m "$MESSAGES" -n
git commit --amend -n # just so you can edit the messages
git checkout $SRC_BRANCH
echo "IMPORTANT: run git reset --hard $TMP_BRANCH to complete squash rebase."
echo "First, though, you may run git diff $TMP_BRANCH to make sure no changes."
echo "Finally, delete the tmp branch with git branch -D $TMP_BRANCH"
}
Note: assumes you are using oh-my-zsh, otherwise you may have to find another way to get current branch name.