Last active
April 9, 2019 07:48
-
-
Save datashaman/0dd6d294c68a16181141d9c41285e9fb to your computer and use it in GitHub Desktop.
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 | |
| # | |
| # Lives here: https://gist.github.com/datashaman/0dd6d294c68a16181141d9c41285e9fb | |
| # | |
| # Refresh your working copy branches. Assumes that you have a source | |
| # repository on _origin_ remote, and a fork on _$GIT_REFRESH_REMOTE_ remote. | |
| # | |
| # Required .env variables: | |
| # GIT_REFRESH_REMOTE - set to the remote name for your fork. | |
| # | |
| # Optional .env variables: | |
| # GIT_REFRESH_BASE - set to your base branch, defaults to master. Don't use origin. | |
| # GIT_REFRESH_INTERACTIVE - Set to true if you want to rebase interactively. Doesn't check if rebase is necessary. | |
| # GIT_REFRESH_PUSH - Set to true if you want to push to your fork during the refresh. | |
| # | |
| # It does as little work as possible to get a complete set of refreshed | |
| # local branches. | |
| # | |
| # Steps: | |
| # | |
| # - Update remote branches (with prune) | |
| # - Remove any local merged branches whose remote has disappeared | |
| # - For each local branch: | |
| # - Check hashes to see if rebase is necessary | |
| # - If interactive or rebase is necessary: | |
| # - Perform rebase on origin/$GIT_REFRESH_BASE | |
| # - If the upstream is origin/$GIT_REFRESH_BASE: | |
| # - If the branch is $GIT_REFRESH_BASE: | |
| # - Push it to your fork | |
| # - Else: | |
| # - Push it to your fork and set upstream (new branch) | |
| # - Else: | |
| # - Force push (with lease) if necessary to your fork | |
| # - Else: | |
| # - Force push (with lease) if necessary to your fork | |
| set -e | |
| function maybe_push_branch () | |
| { | |
| LOCAL_HASH=$(git rev-parse $REFNAME) | |
| UPSTREAM_HASH=$(git rev-parse $UPSTREAM) | |
| if [ "$LOCAL_HASH" != "$UPSTREAM_HASH" ]; then | |
| git push --force-with-lease $GIT_REFRESH_REMOTE $REFNAME | |
| fi | |
| } | |
| function push_rebase () | |
| { | |
| if [ "$UPSTREAM" == "origin/$GIT_REFRESH_BASE" ]; then | |
| if [ "$REFNAME" == "$GIT_REFRESH_BASE" ]; then | |
| git push $GIT_REFRESH_REMOTE $REFNAME | |
| else | |
| git push -u $GIT_REFRESH_REMOTE $REFNAME | |
| fi | |
| else | |
| maybe_push_branch | |
| fi | |
| } | |
| function refresh_branch () | |
| { | |
| ORIGIN_HASH=$(git rev-parse origin/$GIT_REFRESH_BASE) | |
| BASE_HASH=$(git merge-base $GIT_REFRESH_BASE $REFNAME) | |
| if [ "$GIT_REFRESH_INTERACTIVE" == "true" -o "$ORIGIN_HASH" != "$BASE_HASH" ]; then | |
| git rebase $($GIT_REFRESH_INTERACTIVE && echo -i) origin/$GIT_REFRESH_BASE $REFNAME | |
| $GIT_REFRESH_PUSH && push_rebase | |
| else | |
| $GIT_REFRESH_PUSH && maybe_push_branch | |
| fi | |
| } | |
| function usage () | |
| { | |
| cat <<EOF | |
| Usage: ${0##*/} [-h] [-i] [-p] | |
| refresh git branches | |
| -h display this help and exit | |
| -i rebase branches interactively | |
| -p push to the fork during refresh | |
| EOF | |
| } | |
| GIT_REFRESH_BASE=master | |
| GIT_REFRESH_INTERACTIVE=false | |
| GIT_REFRESH_PUSH=false | |
| export HUSKY_IGNORE=true | |
| source .env | |
| OPTIND=1 | |
| while getopts "hip" opt | |
| do | |
| case "${opt}" in | |
| h) | |
| usage | |
| exit 0 | |
| ;; | |
| i) | |
| GIT_REFRESH_INTERACTIVE=true | |
| ;; | |
| p) | |
| GIT_REFRESH_PUSH=true | |
| ;; | |
| *) | |
| usage | |
| exit 0 | |
| ;; | |
| esac | |
| done | |
| shift "$((OPTIND-1))" | |
| if [ -z "$GIT_REFRESH_REMOTE" ]; then | |
| echo "Please set GIT_REFRESH_REMOTE in .env" | |
| exit 1 | |
| fi | |
| git remote update -p origin $GIT_REFRESH_REMOTE | |
| CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) | |
| git checkout master | |
| git branch -vv | grep ' gone' | cut -d' ' -f3 | xargs -r branch -d | |
| BRANCHES=$(git for-each-ref --format='%(refname:short),%(upstream:short)' refs/heads/) | |
| for BRANCH in $BRANCHES | |
| do | |
| REFNAME=${BRANCH%,*} | |
| UPSTREAM=${BRANCH#*,} | |
| refresh_branch $REFNAME $UPSTREAM | |
| done | |
| git checkout $CURRENT_BRANCH |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment