Created
September 12, 2023 16:26
-
-
Save summersab/faf335c03d8d1686c258354e1d58a418 to your computer and use it in GitHub Desktop.
Simple script to keep the local and remote origin of forked repos fresh
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 | |
if [[ -z "${1}" ]] || [[ "${1}" == "-h" ]] || [[ "${1}" == "--help" ]] | |
then | |
echo "This is a simple script to keep the local and remote of your forked" | |
echo "repositories fresh. It does so by:" | |
echo " 1. Detecting if the repo's origin and upstream are different (indicating" | |
echo " a fork)" | |
echo " 2. Performing a \`fetch --all\` on the repo to update from origin and" | |
echo " upstream" | |
echo " 3. Pushing any changes to the repo's origin to keep it updated, as well" | |
echo "" | |
echo "Usage: git-update.sh <search-path> <ssh-certificate>" | |
echo "" | |
echo "Please specify a path for the script to use to find git repositories." | |
echo "" | |
echo "Optionally, specify the path of a SSH certificate if one is needed for" | |
echo "accessing/updating the repositories in the search path. This should also" | |
echo "be provided if your SSH cert is password protected so the script will" | |
echo "only request your password once." | |
echo "" | |
exit | |
fi | |
if [ ! -z "${2}" ] | |
then | |
eval $(ssh-agent) 1>/dev/null | |
ssh-add "${2}" | |
gitparams="'ssh -i ${2}'" | |
echo "${gitparams}" | |
fi | |
echo "" | |
echo "Searching for .git directories in "$(realpath ${1}) | |
for repo in $(find "${1}" -name .git -type d) | |
do | |
dirname="${repo::-4}" | |
# This checks to see if the upstream and origin are different (indicating a fork) | |
if [[ $(git -C "${dirname}" remote get-url upstream 2>/dev/null) != "" ]] && \ | |
[[ $(git -C "${dirname}" remote get-url origin) != $(git -C "${dirname}" remote get-url upstream 2>/dev/null) ]] | |
then | |
# Get the current and default (i.e. master/main) branch names | |
current=$(git -C "${dirname}" rev-parse --abbrev-ref HEAD) | |
default=$(git -C "${dirname}" symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@') | |
echo "Updating $(basename $(git -C "${dirname}" rev-parse --show-toplevel 2>/dev/null) 2>/dev/null):${default} in ${dirname}" | |
# If the current and default branch names are different, the repo is | |
# currently on a branch other than the default. Stash any changes | |
if [[ "${current}" != "${default}" ]] | |
then | |
git -C "${dirname}" stash &>/dev/null | |
fi | |
# Switch to the master branch and `fetch --all` | |
git -C "${dirname}" switch ${default} &>/dev/null | |
git -C "${dirname}" fetch --all 2>&1 | sed "s/^/ /" | |
# Push any updates to the remote origin | |
if [ ! -z "${2}" ] | |
then | |
GIT_SSH_COMMAND="ssh -i ${2}" git -C "${dirname}" push origin "${current}" 2>&1 | sed "s/^/ /" | |
else | |
git -C "${dirname}" push origin "${current}" 2>&1 | sed "s/^/ /" | |
fi | |
# If necessary, switch back to the previous branch and restore the stash | |
git -C "${dirname}" switch ${current} &>/dev/null | |
if [[ "${current}" != "${default}" ]] | |
then | |
git -C "${dirname}" stash pop &>/dev/null | |
fi | |
echo "" | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment