Last active
August 5, 2022 15:58
-
-
Save eddiemoya/0a58e3f8c23523fe10fcdcb2c7daefbc to your computer and use it in GitHub Desktop.
Checks to see if the given branch is fast-forward-mergable with the given base. If not, it attempts to rebase the branch. If any conflicts arise, the rebase is aborted and the script exists with non-zero status.
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
#!/bin/bash | |
underline=$(tput sgr 0 1) # Underline | |
bold=$(tput bold) # Bold | |
normal=$(tput rmso) # Normal | |
# Dims | |
red=$(tput setaf 1) # red | |
green=$(tput setaf 2) # magenta | |
blue=$(tput setaf 4) # blue | |
yellow=$(tput setaf 3) # yellow | |
magenta=$(tput setaf 5) # magenta | |
cyan=$(tput setaf 6) # cyan | |
white=$(tput setaf 7) # white | |
#Reset | |
reset=$(tput sgr0) # Reset | |
function get_merge_revs { | |
MERGE=$(git rev-parse --abbrev-ref $REV); | |
MERGE_REV=$(git rev-parse $REV); | |
SHORT_MERGE_REV=$(echo $MERGE_REV | cut -c 1-7); | |
} | |
function get_orig_merge_revs { | |
ORIG_MERGE=$(git rev-parse --abbrev-ref $REV); | |
ORIG_MERGE_REV=$(git rev-parse $REV); | |
ORIG_SHORT_MERGE_REV=$(echo $MERGE_REV | cut -c 1-7); | |
} | |
function get_base_revs { | |
CURRENT=$(git rev-parse --abbrev-ref $REV); | |
CURRENT_REV=$(git rev-parse $REV); | |
SHORT_CURRENT_REV=$(echo $CURRENT_REV | cut -c 1-7); | |
} | |
function is_ffable { | |
echo "....."; | |
git merge-base --is-ancestor $CURRENT_REV $MERGE_REV; | |
ffable=$?; | |
if [ $VERBOSE == true ]; then | |
echo -e "${cyan}(A)${reset}: (${cyan}$CURRENT${reset}) \t[${cyan}$CURRENT_REV${reset}]"; | |
echo -e "${magenta}(B)${reset}: (${magenta}$MERGE${reset}) \t[${magenta}$MERGE_REV${reset}]\n"; | |
if [ $ffable == 0 ]; then | |
echo -e "${green}[*] Yes! Revision ${B_label}${green} CAN be Fast-Forward merged into ${A_label}${green}.${reset}" | |
else | |
echo -e "${red}[!] Well, fuck! Revision ${B_label}${red} can NOT be Fast-Forward merged into ${A_label}${green}!${reset}" | |
fi | |
fi | |
} | |
# Performs a reverse rebase where the current revision becomes the base for the revision that is passed. | |
function mebase { | |
# echo "Checking out $MERGE....."; | |
git checkout --quiet $MERGE; | |
TMP_REV=$(git rev-parse HEAD); | |
# Verify that we have checked out the correct revision | |
if [ "$MERGE_REV" == "$TMP_REV" ]; then | |
echo "Performing rebase of ($MERGE) [$SHORT_MERGE_REV] onto ($CURRENT) [$SHORT_CURRENT_REV]..."; | |
echo "....."; | |
git rebase --quiet $CURRENT_REV > /dev/null; | |
has_conflicts=$(git status --porcelain | grep "U"); | |
# local merged_files=$(git status --porcelain); | |
if [ -n "$has_conflicts" ]; then | |
echo "${red}"; | |
echo -e "[!] Conflicting files"; | |
echo ${has_conflicts} | sed 's/UU/\'$'\nUU/g'; | |
echo "${reset}"; | |
echo -e "[*] Branch has conflicts. Aboting Rebase..."; | |
git rebase --abort; | |
else | |
#Reset the merge vars | |
REV="HEAD"; | |
echo "[*] Revision ($MERGE) [$SHORT_MERGE_REV] has been properly rebased onto ($CURRENT) [$SHORT_CURRENT_REV] and updated."; | |
get_merge_revs; | |
fi | |
# echo "[*] Checking out your original branch: ($CURRENT) [$SHORT_CURRENT_REV]..."; | |
git checkout --quiet $ORIG_MERGE; | |
else | |
echo "\n${attention}[!] Checkout of $MERGE seems to have failed. Check spelling, make sure you pushed, try again." | |
exit() { return $1;} | |
fi | |
} | |
function ask_rebase { | |
printf "[${blue}?${reset}] Perform ${underline}${red}rebase${reset}? [Yes/no] : " | |
read do_rebase; | |
} | |
REV="HEAD"; | |
get_orig_merge_revs; | |
REV=$1; | |
get_merge_revs; | |
REV=$2; | |
get_base_revs; | |
echo "Current position is [${cyan}$SHORT_CURRENT_REV${reset}] (${cyan}$CURRENT${reset})"; | |
#Backup var for safe keeping after rebases. | |
BRANCH=$MERGE; | |
VERBOSE=true; | |
is_ffable; | |
if [ "$ffable" -gt 0 ]; then | |
ask_rebase; | |
if [ $do_rebase == "Yes" ]; then | |
mebase; | |
if [ -n "$has_conflicts" ]; then | |
exit() { return $1;} | |
else | |
echo -e "\nNew revisions (after rebase)" | |
is_ffable; | |
fi | |
else | |
echo "Nothing left to do..."; | |
exit() { return $1;} | |
fi | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment