Is there a way to squash a number of commits non-interactively?
Make sure your working tree is clean, then
git reset --soft HEAD~3git commit -m 'new commit message'
I personally like wilhelmtell's solution:
git reset --soft HEAD~3git commit -m 'new commit message'
However, I made an alias with some error checking so that you can do this:
git squash 3 'my commit message'
I recommend setting up aliases that actually run scripts so that it is easier to (a) code up your scripts and (b) do more complex work with error checking. Below is a script that does the work of squash and then below that is a script for setting up your git aliases.
Script for squashing (squash.sh)
#!/bin/bash##get number of commits to squashsquashCount=$1#get the commit messageshiftcommitMsg=$@#regular expression to verify that squash number is an integerregex='^[0-9]+$'echo "---------------------------------"echo "Will squash $squashCount commits"echo "Commit message will be '$commitMsg'"echo "...validating input"if ! [[ $squashCount =~ $regex ]]then echo "Squash count must be an integer."elif [ -z "$commitMsg" ]then echo "Invalid commit message. Make sure string is not empty"else echo "...input looks good" echo "...proceeding to squash" git reset --soft HEAD~$squashCount git commit -m "$commitMsg" echo "...done"fiechoexit 0
Then to hook up that squash.sh script to a git alias, make another script for setting up your git aliases like so (create_aliases.command or create_aliases.sh):
#!/bin/shecho '-----------------------'echo 'adding git aliases....'echo '-----------------------'echogit config --global alias.squash "!bash -c 'bash <path to scripts directory>/squash.sh \$1 \$2' -"#add your other git aliases setup here#and here#etc.echo '------------------------------------'echo 'here is your global gitconfig file:'echo '------------------------------------'more ~/.gitconfigecho echoecho '----------------'echo 'end of script...'echo '----------------'
To add to the answer by wilhelmtell I find it convenient to soft reset to HEAD~2
and then amending the commit of HEAD~3
:
git reset --soft HEAD~2git commit --all --amend --no-edit
This will merge all commits to the HEAD~3
commit and use its commit message. Be sure to start from a clean working tree.