dot-files/scripts/git-ffw

69 lines
2.1 KiB
Plaintext
Raw Permalink Normal View History

#!/usr/bin/env bash
# Adapted from <https://stackoverflow.com/questions/4318161>
SHOW_UPDATE=0
usage() {
echo "usage: git ffwd [remote]..."
echo ""
echo "Fast forward all local branches tracking remote branches"
echo "If given a list of remote, will update branches tracking those"
echo "Otherwise will update all remotes"
}
ffwd() {
CLB="$(git rev-parse --abbrev-ref HEAD)"
for REMOTE in "$@"; do
git remote update "$REMOTE"
while read -r RB LB; do
ARB="refs/remotes/$REMOTE/$RB"
ALB="refs/heads/$LB"
NBEHIND=$(( $(git rev-list --count "$ALB..$ARB" 2>/dev/null) +0))
NAHEAD=$(( $(git rev-list --count "$ARB..$ALB" 2>/dev/null) +0))
if [ "$NBEHIND" -gt 0 ]; then
if [ "$NAHEAD" -gt 0 ]; then
echo " branch $LB is $NBEHIND commit(s) behind and $NAHEAD commit(s) ahead of $REMOTE/$RB. could not be fast-forwarded"
elif [ "$LB" = "$CLB" ]; then
echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. fast-forward merge"
git merge --ff -q "$ARB" # Can't reset the current branch
else
echo " branch $LB was $NBEHIND commit(s) behind of $REMOTE/$RB. resetting local branch to remote"
git branch -f "$LB" -t "$ARB" >/dev/null
fi
elif [ "$SHOW_UPDATE" -eq 1 ]; then
echo " nothing to do for branch $LB"
fi
done <<< "$(git remote show "$REMOTE" -n |
awk '/merges with remote/{print $5" "$1}')"
done
}
REMOTES=()
if [ $# -gt 0 ]; then
# Check for help flag
for arg in "$@"; do
case "$arg" in
--help|-h)
usage
exit 0
;;
--show-update|-s)
SHOW_UPDATE=1
;;
*)
REMOTES+=("$arg")
;;
esac
done
fi
if [ ${#REMOTE[@]} -gt 0 ]; then
# Call ffwd with all given remotes
ffwd "${REMOTE[@]}"
else
# Call ffwd with all remotes in the repository
ffwd "$(git remote)"
fi