Last active
November 7, 2019 18:43
-
-
Save aks/d33cd1855fbd0e258a51a3f647d9368a to your computer and use it in GitHub Desktop.
Bash script to squash all commits in the current branch (against master)
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
| #!/usr/bin/env bash | |
| # squash-all [BASE_BRANCH] | |
| PROG="${0##*/}" | |
| DIR="${0%/*}" | |
| talk() { echo 1>&2 "$*" ; } | |
| vtalk() { (( verbose )) && talk "$*" ; } | |
| error() { talk "$*" ; exit 1 ; } | |
| usage() { | |
| (( $# > 0 )) && talk "$*" | |
| cat 1>&2 <<USAGE | |
| usage: $PROG [options] [BASE_BRANCH [BRANCH_NAME]] | |
| This script will squash all the commits in BRANCH_NAME, if given. If | |
| not given the current branch in the current workding directory is used. | |
| If BASE_BRANCH is given, then it is used as the base-branch for the merge | |
| that squashes the commits in the target branch. If BASE_BRANCH is not | |
| given, "master" is assumed. | |
| Unless -a is given, confirmation of actions is confirmed with a prompt | |
| to the user for a yes or no answer. | |
| Options: | |
| -a go ahead; do the change | |
| -h show this help | |
| -n don't do any changes, but show the commands | |
| -v be verbose | |
| USAGE | |
| exit | |
| } | |
| run() { | |
| if [[ -n "$norun" ]]; then | |
| talk "(norun) $@" | |
| else | |
| safe_run "$@" | |
| fi | |
| return 0 | |
| } | |
| safe_run() { | |
| if [[ -n "$verbose$norun" ]]; then | |
| talk ">> $@" | |
| fi | |
| if ! eval "$@" ; then | |
| code=$? | |
| return $code | |
| fi | |
| return 0 | |
| } | |
| set_branch() { | |
| if [[ -n "$1" ]] ; then | |
| branch_name="$1" | |
| else | |
| branch_name=`current_branch` | |
| fi | |
| } | |
| current_branch() { | |
| if [[ -z "$current_branch" ]] ; then | |
| current_branch="$(git rev-parse --abbrev-ref HEAD)" | |
| fi | |
| echo "$current_branch" | |
| } | |
| set_base_branch() { | |
| base_branch="${1:-master}" | |
| } | |
| validate_branch_name() { | |
| if [[ -z "$branch_name" ]]; then | |
| echo "No branch name! (detached HEAD?)" | |
| exit | |
| fi | |
| } | |
| validate_base_branch() { | |
| case "$base_branch" in | |
| master|mast|m) base_branch=master ;; | |
| releases|release|rel|r) base_branch=releases ;; | |
| *) error "Only 'releases' or 'master' can be used as a base branch!" ;; | |
| esac | |
| } | |
| confirm_go_ahead() { | |
| while (( ! go_ahead )) ; do | |
| talk "Branch '${branch_name}' will be merged with '${base_branch}'" | |
| talk " .. and all local commits squashed" | |
| read -p "Okay? [yN]" ans | |
| ans="${ans:-no}" | |
| case "${ans,,}" in | |
| yes|ye|y) go_ahead=1 ;; | |
| no|n) error "Nothing done." ;; | |
| *) talk "Please answer yes or no, or just <return> for 'no'" ;; | |
| esac | |
| done | |
| } | |
| get_merge_base_commit() { | |
| vtalk "Computing common base commit for $base_branch and $branch_name .." | |
| safe_run "git merge-base '$base_branch' '$branch_name'" | |
| } | |
| squash_commits() { | |
| local base_commit="$1" | |
| run "git reset --soft $base_commit && git commit -a" | |
| } | |
| maybe_checkout_branch() { | |
| if [[ "$branch_name" != `current_branch` ]] ; then | |
| vtalk "Checking out $branch_name." | |
| run "git checkout $branch_name" | |
| fi | |
| } | |
| ################################################## | |
| go_ahead= norun= verbose= | |
| while getopts 'ahnv' opt ; do | |
| case "$opt" in | |
| h) usage ;; | |
| a) go_ahead=1 ;; | |
| n) norun=1 ;; | |
| v) vebose=1 ;; | |
| esac | |
| done | |
| shift $(( OPTIND - 1 )) | |
| (( $# > 2 )) && usage "Too many arguments!" | |
| set_base_branch "$1" | |
| set_branch "$2" | |
| validate_branch_name | |
| validate_base_branch | |
| confirm_go_ahead | |
| set -x | |
| maybe_checkout_branch | |
| merge_base_commit=`get_merge_base_commit` | |
| squash_commits $merge_base_commit | |
| exit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment