Using git rebase
One idea would be to checkout the branch and squash all commits into one using the iteractive rebase, then force push to update the pull request and merge (though part of this work could be delegated to Bob).
To automatically squash all commits from a branch into the first one and apply this to the pull request, you can use the following commands:
$ git checkout pull-req
$ GIT_SEQUENCE_EDITOR='sed -i "2,\$s/^pick/s/g" $1' git rebase -i origin/master
$ git push --force
GIT_SEQUENCE_EDITOR is a Git environment variable to set a temporary editor for the rebase commit list. We set it to a inline script which replaces the word pick
by s
(meaning squash
) in the beginning of all lines except the first (that's the 2,\$
in the sed
pattern). The commit list that gets passed to the script is a simple text file. Git then proceeds with the rebase and lets you edit the final commit message.
Also, with a git hook you could then more or less easily edit this final message to suit your needs (say add a visual separator between the squashed commits' messages).
Using git merge --squash
Squashing is also possible through git merge --squash
. See here for the difference between the two methods. The script bellow would squash the commits of a branch into a single commit using the merge command. It also creates a backup of the branch (just in case).
MAINBRANCH="master"
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
# update current feature branch with master
git pull origin $MAINBRANCH
# delete existing backup
git branch -D "$CURRENT_BRANCH-backup"
# backup current feature branch and go back
git checkout -b "$CURRENT_BRANCH-backup" && git checkout -
# checkout and update master branch
git checkout $MAINBRANCH && git pull
# create new branch from master
git checkout -b "$CURRENT_BRANCH-squashed"
# set it to track the corresponding feature branch
git branch "$CURRENT_BRANCH-squashed" --set-upstream-to "$CURRENT_BRANCH"
# merge and squash the feature branch into the one created
git merge --squash $CURRENT_BRANCH
# commit the squashed changes
git commit
# force push to the corresponding feature branch
git push -f . HEAD:$CURRENT_BRANCH
# checkout the feature branch
git checkout $CURRENT_BRANCH
# delete the squashed copy
git branch -D "$CURRENT_BRANCH-squashed"