Last active
November 8, 2023 15:43
-
-
Save Daenyth/94eab3f29827dd1ae641246bdff4d2ef to your computer and use it in GitHub Desktop.
Git refresh
This file contains hidden or 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
#!/usr/bin/env bash | |
set -o errexit | |
## git refresh | |
# | |
# Update all git remotes | |
# Update local main or master branch from the remote | |
# Delete local branches tracking remotely-deleted branches | |
# Delete local branches that have been merged | |
# Print local branches that are outdated | |
function checkbranch { | |
name="$1" | |
status="$(git branch -l "$name" --format '%(refname:short)')" | |
if [[ -z "$status" ]]; then | |
return 1 | |
else | |
return 0 | |
fi | |
} | |
if checkbranch main; then | |
MAINBRANCH=main | |
elif checkbranch master; then | |
MAINBRANCH=master | |
else | |
# If we have an "upstream" branch, then our git clone is probably a fork - we should use their default branch and not origin | |
if git remote | grep -q upstream; then | |
remote=upstream | |
else | |
remote=origin | |
fi | |
# Attempt to detect the branch github declares as the main one, if possible | |
remote_url=$(git remote get-url $remote) | |
if [[ $remote_url == [email protected]* ]]; then | |
# This git repo is tracking github | |
# Extract the username and repository name from the URL | |
username=$(echo $remote_url | cut -d: -f2 | cut -d/ -f1) | |
repository=$(echo $remote_url | cut -d/ -f2 | cut -d. -f1) | |
echo "main branch not detected - attempting to query from $username/$repository on github" | |
# Try to find github auth in case the repo is private | |
if [[ -n $GITHUB_TOKEN ]]; then | |
token="$GITHUB_TOKEN" | |
elif [[ -n $GH_TOKEN ]]; then | |
token="$GH_TOKEN" | |
fi | |
if [[ -n $token ]]; then | |
auth_args="-H \"Authorization: Bearer $token\"" | |
else | |
auth_args="" | |
fi | |
# Ask github what the main branch is, using auth if we found it | |
MAINBRANCH=$(curl -s $auth_args https://api.github.com/repos/$username/$repository | jq -r .default_branch) | |
echo "Detected $MAINBRANCH as the default branch on github" | |
fi | |
fi | |
if [[ $1 == "-m" ]]; then | |
if [[ -n $2 ]]; then | |
MAINBRANCH="$2" | |
fi | |
if [[ -z $MAINBRANCH ]]; then | |
echo "Cannot change branch to main: main branch not detected. Run \`git refresh -m mainbranchname\` to change branches" | |
exit 1 | |
fi | |
git checkout $MAINBRANCH | |
shift | |
elif [[ -n $1 ]]; then | |
MAINBRANCH="$1" | |
fi | |
git remote update --prune || true | |
if [[ -n $MAINBRANCH ]]; then | |
if [[ "$(git branch | sed -n '/\* /s///p')" == "$MAINBRANCH" ]]; then | |
# On master, fast forward. | |
git merge --ff-only origin/$MAINBRANCH | |
else | |
# force-set local master to point at origin/master's commit | |
# Do this to avoid changing the reflog, or invalidating compiler cache etc | |
git branch -f $MAINBRANCH origin/$MAINBRANCH | |
fi | |
# Delete local branches that have been merged to main | |
git branch --merged origin/$MAINBRANCH | grep -v $MAINBRANCH | grep -vF '*' | xargs git branch -d | |
else | |
echo "main branch not detected. Run \`git refresh branchname\` to treat \`branchname\` as a main branch" | |
fi | |
echo "Outdated" | |
# Delete local branches which are tracking a remote branch which is gone (eg squash+merge on github) | |
git branch --format '%(upstream:track,nobracket)%09%(refname:short)' | awk -F "\t" '{ if($1 = /gone/) { print $2 } }' | xargs git branch -D | |
# List local branches not merged to master | |
if [[ -n $MAINBRANCH ]]; then | |
git branch --no-contains origin/$MAINBRANCH --sort=-committerdate -vv | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment