Last active
July 2, 2024 14:50
-
-
Save BlueskyFR/9db8e139bfbf0e1012997631459b1568 to your computer and use it in GitHub Desktop.
Rebases a branch and manages history when the target branch rebases itself off another one
This file contains 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 | |
# Fail on first non-zero exit code | |
set -e | |
setup_colors() { | |
if [[ -t 2 ]] && [[ -z "${NO_COLOR-}" ]] && [[ "${TERM-}" != "dumb" ]]; then | |
NOFORMAT='\033[0m' RED='\033[0;31m' GREEN='\033[0;32m' ORANGE='\033[0;33m' BLUE='\033[0;34m' PURPLE='\033[0;35m' CYAN='\033[0;36m' YELLOW='\033[1;33m' | |
else | |
NOFORMAT='' RED='' GREEN='' ORANGE='' BLUE='' PURPLE='' CYAN='' YELLOW='' | |
fi | |
} | |
msg() { | |
PREFIX= | |
[[ "$1" == "-n" ]] && { PREFIX=$1; shift; } | |
echo >&2 -e $PREFIX "${1-}" | |
} | |
setup_colors | |
# This will also issue a warning if we are not currently in a git repository | |
git_dir=$(git rev-parse --absolute-git-dir) | |
# Get the first argument of the script | |
rebase_branch="$1" | |
# Display a warning if the argument wasn't provided | |
if [[ -z "$rebase_branch" ]]; then | |
msg "${RED}⚠️ Please provide a branch name to rebase onto${NOFORMAT}" | |
exit 1 | |
fi | |
# Exit if $rebase_branch contains whitespaces | |
if [[ "$rebase_branch" =~ \ ]]; then | |
msg "${RED}Are you sure you want whitespaces in the branch name? 🧐${NOFORMAT}" | |
exit 1 | |
fi | |
current_branch=$(git branch --show-current) | |
# Filename matching the current branch with the one provided | |
file=$git_dir/rebase-$current_branch-on-$rebase_branch | |
prompt_last_commit_hash() { | |
msg "${BLUE}What is the last commit hash of ${YELLOW}$rebase_branch${BLUE} you have on your branch (${YELLOW}$current_branch${BLUE})?${NOFORMAT}" | |
read -r -p ">> " last_hash | |
msg "${BLUE}Saving hash in $file...${NOFORMAT}" | |
echo $last_hash > $file | |
} | |
# Record the last hash the branch was rebased on if we did not save it last time | |
if [[ ! -f "$file" ]]; then | |
prompt_last_commit_hash | |
else | |
last_hash=$(cat $file) | |
msg "${BLUE}Hello back! It seems your branch was last rebased on this commit:${NOFORMAT}" | |
git --no-pager log -1 --oneline $last_hash | |
read -r -p "Can you confirm? [Y/N] " answer | |
if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]; then | |
msg "${BLUE}Great! ✨${NOFORMAT}" | |
elif [[ "$answer" =~ ^([nN][oO]|[nN])$ ]]; then | |
prompt_last_commit_hash | |
else | |
msg "${RED}Invalid answer!${NOFORMAT}" | |
exit 1 | |
fi | |
fi | |
msg "${PURPLE}[1/3] Fetching remote changes...${NOFORMAT}" | |
git fetch -p | |
# Do the actual rebase | |
msg "${PURPLE}[2/3] Rebasing ${YELLOW}$current_branch${PURPLE} onto ${YELLOW}origin/$rebase_branch${PURPLE} based on commit ${YELLOW}$last_hash${PURPLE}...${NOFORMAT}" | |
git rebase --onto origin/$rebase_branch $last_hash | |
# Remember what is the last commit of origin/$rebase_branch for next time | |
msg "${BLUE}[3/3] Saving the last commit hash of origin/$rebase_branch for next time...${NOFORMAT}" | |
msg "${BLUE} (in $file)${NOFORMAT}" | |
origin_last_hash=$(git rev-parse origin/$rebase_branch) | |
echo $origin_last_hash > $file | |
msg "${GREEN}Rebase successful! 🎉${NOFORMAT}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment