Is there a way to squash a number of commits non-interactively? Is there a way to squash a number of commits non-interactively? git git

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.