Skip to content

Instantly share code, notes, and snippets.

@ianmariano
Last active June 26, 2024 17:52
Show Gist options
  • Save ianmariano/b950a56bfb4d812c875a2beef3ee18b8 to your computer and use it in GitHub Desktop.
Save ianmariano/b950a56bfb4d812c875a2beef3ee18b8 to your computer and use it in GitHub Desktop.
Sync (reset) your local and origin branches to canonical upstream branches. For when you want to hard reset everything to upstream. Add to your PATH and make executable. Do git sync-all-upstream
#!/usr/bin/env bash
set -Eeuo pipefail
_die() {
echo "$*" >&2
exit 1
}
bold=$(tput bold)
normal=$(tput sgr0)
if output=$(git status --untracked-files=no --porcelain) && [ -z "$output" ]
then
echo "${bold}Working directory is clean.${normal}"
else
echo "You have uncommitted changes."
exit 1
fi
all_remotes=$(git remote)
echo "${bold}Pruning remotes...${normal}"
for r in $all_remotes
do
git remote prune "$r"
done
local_branches=$(git branch | cut -d ' ' -f 2,3 | sed -e "s/ //")
echo "${bold}Checking connectivity and determining branches to sync:${normal}"
have_master=""
have_origin=""
origin_branches=
have_upstream=""
upstream_branches=
for r in $all_remotes
do
echo -n " $r... "
if [ "origin" == "$r" ]
then
have_origin="yes"
origin_branches=$(git ls-remote -h $r | sed -E "s|.+refs/heads/||")
echo "ok"
elif [ "upstream" == "$r" ]
then
have_upstream="yes"
upstream_branches=$(git ls-remote -h $r | sed -E "s|.+refs/heads/||")
echo "ok"
elif git ls-remote --exit-code $r &>/dev/null
then
echo "ok"
else
_die "FAILED!"
fi
done
if [ -z "$have_origin" ]
then
_die "You do not have an origin defined."
fi
clean_branch_list=()
for b in $local_branches
do
for ob in $origin_branches
do
if [ "$ob" == "$b" ]
then
if [[ "$b" == "master" ]]
then
have_master="Y"
fi
if [ -z "$have_upstream" ]
then
clean_branch_list+=("$b")
else
for ub in $upstream_branches
do
if [ "$ub" == "$b" ]
then
clean_branch_list+=("$b")
fi
done
fi
fi
done
done
default_branch=$(git rev-parse --abbrev-ref origin/HEAD | awk -F/ '{print $NF}')
echo "${bold}Default branche is: $default_branch${normal}"
echo "${bold}Syncing branches...${normal}"
if [ -z "$have_master" ]
then
git checkout "$default_branch"
else
git checkout master
fi
git fetch --all --tags
for i in "${clean_branch_list[@]}"
do
git checkout $i
if [ -z "$have_upstream" ]
then
git reset --hard "origin/$i"
else
git reset --hard "upstream/$i"
git push
fi
done
git checkout "$default_branch"
echo "${bold}Done.${normal}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment