Created
July 15, 2025 21:57
-
-
Save donnyquixotic/44b1d11e6d599ea0e85915001a76c4b9 to your computer and use it in GitHub Desktop.
Creates alias `git squash` for simple sequential commit squashing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # description: | |
| # creates git alias 'squash' that squashes the last n commits with a new commit message | |
| # | |
| # usage: | |
| # `git squash <n> "<commit-message>"` e.g. `git squash 3 "feat(scope): my new feature"` | |
| # or | |
| # `git squash -n <n> -m "<commit-message>"` e.g. `git squash -n 3 -m "feat(scope): my new feature"` | |
| # | |
| # params: | |
| # <n> number of commits to squash (including current commit) | |
| # <commit-message> the new commit message for the squashed commit | |
| # | |
| # executed commands: | |
| # - validates input parameters | |
| # - checks if enough commits exist to squash | |
| # - resets soft to go back n commits (keeping changes staged) | |
| # - commits with the new message | |
| # | |
| # assumptions: | |
| # - you are in the root directory of the repository | |
| # - you are on the correct branch | |
| # - the number provided includes the most recent/current commit | |
| # | |
| # create alias: | |
| # save this file and run `chmod +x squash-commits.sh && ./squash-commits.sh` | |
| git config --global alias.squash '! _() { | |
| # Parse arguments | |
| if [ "$1" = "-n" ]; then | |
| # Flag-based syntax: git squash -n 5 -m "message" | |
| if [ -z "$2" ] || [ -z "$4" ] || [ "$3" != "-m" ]; then | |
| echo "Usage: git squash -n <number> -m \"<commit-message>\"" | |
| return 1 | |
| fi | |
| num_commits="$2" | |
| commit_message="$4" | |
| else | |
| # Positional syntax: git squash 5 "message" | |
| if [ -z "$1" ] || [ -z "$2" ]; then | |
| echo "Usage: git squash <number> \"<commit-message>\"" | |
| echo " or: git squash -n <number> -m \"<commit-message>\"" | |
| return 1 | |
| fi | |
| num_commits="$1" | |
| commit_message="$2" | |
| fi | |
| # Validate that num_commits is a positive integer | |
| if ! [[ "$num_commits" =~ ^[1-9][0-9]*$ ]]; then | |
| echo "Error: Number of commits must be a positive integer" | |
| return 1 | |
| fi | |
| # Check if we have enough commits to squash | |
| commit_count=$(git rev-list --count HEAD) | |
| if [ "$num_commits" -gt "$commit_count" ]; then | |
| echo "Error: Cannot squash $num_commits commits, only $commit_count commits exist" | |
| return 1 | |
| fi | |
| # Check if repository is clean (no uncommitted changes) | |
| if ! git diff-index --quiet HEAD --; then | |
| echo "Warning: You have uncommitted changes. They will be included in the squashed commit." | |
| read -p "Continue? (y/N): " -n 1 -r | |
| echo | |
| if [[ ! $REPLY =~ ^[Yy]$ ]]; then | |
| echo "Aborted." | |
| return 1 | |
| fi | |
| fi | |
| echo "Squashing last $num_commits commits with message: \"$commit_message\"" | |
| # Reset to n commits back, keeping changes staged | |
| git reset --soft HEAD~"$num_commits" && | |
| # Commit with the new message | |
| git commit -m "$commit_message" && | |
| echo "✓ Successfully squashed $num_commits commits!" | |
| }; _' | |
| echo "Git alias 'squash' has been created successfully!" | |
| echo "" | |
| echo "Usage examples:" | |
| echo " git squash 3 \"feat(auth): add user authentication\"" | |
| echo " git squash -n 5 -m \"refactor: optimize database queries\"" | |
| echo "" | |
| echo "Note: This will squash the last n commits (including the current one) into a single commit." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment