Skip to content

Instantly share code, notes, and snippets.

@eddiemoya
Created April 23, 2014 17:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eddiemoya/11225462 to your computer and use it in GitHub Desktop.
Save eddiemoya/11225462 to your computer and use it in GitHub Desktop.
Bash script that checks if a branch is fast-forwardable, and it its not offers to rebase it for you. Once rebased, the script asks before ff merging.
#!/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
#Bolds
bred=${txtbld}$(tput setaf 1) # red
bgreen=${txtbld}$(tput setaf 2) # magenta
bblue=${txtbld}$(tput setaf 4) # blue
byellow=${txtbld}$(tput setaf 3) # yellow
bmagenta=${txtbld}$(tput setaf 5) # magenta
bcyan=${txtbld}$(tput setaf 6) # cyan
bwhite=${txtbld}$(tput setaf 7) # white
#Resets
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_current_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=$?;
local A_label="${cyan}${bold}(A)${reset}";
local B_label="${bmagenta}(B)${reset}";
if [ $VERBOSE == true ]; then
echo -e "${A_label}: (${cyan}$CURRENT${reset}) \t[${cyan}$CURRENT_REV${reset}]";
echo -e "${B_label}: (${magenta}$MERGE${reset}) \t[${magenta}$MERGE_REV${reset}]\n";
if [ $ffable == 0 ]; then
echo -e "${bgreen}[*]${reset} ${green}Yes! Revision ${B_label}${green} CAN be Fast-Forward merged into ${A_label}${green}.${reset}"
else
echo -e "${bred}[!]${reset} ${red}Well, fuck! Revision ${B_label}${red} can NOT be Fast-Forward merged into ${A_label}${green}!${reset}"
fi
fi
}
function ferge {
echo "Performing a Fast-Forward merge of $MERGE";
echo ".....";
git merge --ff-only $MERGE_REV;
}
# 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 -i $CURRENT_REV;
#Reset the merge vars
REV="HEAD";
#update_merge_branch;
get_merge_revs;
get_orig_merge_revs;
echo "Checkout out your original branch: ($CURRENT) [$SHORT_CURRENT_REV].....";
git checkout --quiet $CURRENT;
else
echo "Checkout of $MERGE seems to have failed."
exit() { return $1;}
fi
}
function update_merge_branch {
if [ "$MERGE" -ne "$BRANCH" ]; then
git update-ref refs/heads/$BRANCH $REV;
fi
echo "[*] Revision ($MERGE) [$SHORT_MERGE_REV] has been properly rebased onto ($CURRENT) [$SHORT_CURRENT_REV] and updated.";
}
function ask_rebase {
printf "[${bblue}?${reset}] Perform ${underline}${red}rebase${reset}? [Yes/no] : "
read do_rebase;
echo ".....";
}
function ask_ferge {
printf "${bblue}[?]${reset} Perform ${red}merge${reset}? [Yes/no] : "
read do_ferge;
echo ".....";
}
echo "${underline}Current${reset} position is [${cyan}$SHORT_CURRENT_REV${reset}] ( ${cyan}$CURRENT${reset})"
REV=$1;
get_merge_revs;
REV="HEAD";
get_current_revs;
#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;
echo -e "\nNew revisions (after rebase)"
is_ffable;
else
echo "Nothing left to do...";
exit() { return $1;}
fi
fi
if [ "$ffable" -eq 0 ]; then
ask_ferge;
if [ $do_ferge == "Yes" ]; then
ferge;
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