Created
March 2, 2015 04:35
-
-
Save ar45/035b56b5b5bf4ff8c785 to your computer and use it in GitHub Desktop.
Keep your forked repository in sync with upstream
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
# | |
# Script to keep github forked repository in sync with upstream. | |
# synchronizes branches which names match between REMOTE and UPSTREAM | |
# | |
# Uses the following shell variables, maybe passed on the command line | |
# path=/path/to/git/dir upstream=upstream_repo remote=origin ./syncrepository.sh | |
# | |
# Author: Aron Podrigal <[email protected]> | |
# | |
#!/bin/bash | |
# repository directory | |
GIT_DIR=${path:-"./"} | |
# SET THIS TO YOUR UPSTREAM NAME | |
UPSTREAM=${upstream:-"upstream"} | |
# NMAE OF REMOTE | |
REMOTE=${remote:-"origin"} | |
# FORCE CHECKOUT WITH -f OPTION "yes/no". | |
# if checkout to remote branch fails and this is | |
# set to "no", then it will try to | |
# stash any local changes, and pop it afterwards | |
FORCE_CHECKOUT=no | |
# set file LOGFILE=~/sync.log to redirect stdout | |
LOGFILE= | |
# set file ERROR_LOG=~/sync_err.log to redirect stderr | |
ERROR_LOG= | |
# redirect output | |
[ ! -z $LOGFILE ] && exec 1>>$LOGFILE | |
[ ! -z $ERROR_LOG ] && exec 2>>$ERROR_LOG | |
# logger function | |
function mlog() | |
{ | |
if [ ! -z ${!2} ]; then | |
echo "[`date`] $1" >> ${!2} | |
else | |
if [ "$2" = "ERROR_LOG" ]; then | |
echo "[`date`] $1" >&2 | |
else | |
echo "[`date`] $1" | |
fi | |
fi | |
} | |
cd $GIT_DIR || exit 1 | |
git fetch || { mlog "Couldn't fetch remotes. terminating" "ERROR_LOG"; exit 1; } | |
UPSTREAM_BRANCHES=`git branch --list -r $UPSTREAM/* |awk '{sub(/^'$UPSTREAM'\//,"",$1); print $1}'` | |
REMOTE_BRANCHES=`git branch --list -r $REMOTE/* |awk '{sub(/^'$REMOTE'\//,"",$1); print $1}'` | |
if [ -z $UPSTREAM_BRANCHES ]; then | |
mlog "NOTICE: no upstream branches found for '$UPSTREAM'." "LOGFILE" | |
fi | |
# initialize stashed to false | |
stashed=1 | |
for branch in $UPSTREAM_BRANCHES; do | |
remote_exists=1; | |
for remote_b in $REMOTE_BRANCHES; do | |
if [ $remote_b = $branch ]; then | |
remote_exists=0 | |
break | |
fi | |
done | |
if [ $remote_exists ]; then | |
# checkout the remote branch and merge in upstream | |
git checkout $REMOTE/$branch | |
if [ $? -ne 0 ]; then | |
mlog "git checkout returned error" "ERROR_LOG" | |
if [ $stashed -eq 0 ]; then | |
mlog "working directory was previously stashed, so we're forcing checkout" "LOGFILE" | |
git checkout $REMOTE/$branch -f || { mlog "couldn't checkout ${REMOTE}/${branch}, terminating." "ERROR_LOG"; exit 1; } | |
else | |
mlog "trying to stash before checkout.." "LOGFILE" | |
git stash || { mlog "could not stash either terminating" "ERROR_LOG"; exit 1; } | |
# keep track that we've stashed away, so we'll pop afterwards | |
stashed=0 | |
git checkout $REMOTE/$branch || { mlog "couldn't checkout ${REMOTE}/${branch}, terminating." "ERROR_LOG"; exit 1; } | |
fi | |
fi | |
git merge --ff $UPSTREAM/$branch || { mlog "'git merge --ff ${UPSTREAM}/${branch}' into ${REMOTE}/${branch} failed." "ERROR_LOG"; } | |
git push $REMOTE HEAD:$branch && mlog "'git merge --ff ${UPSTREAM}/${branch}' into ${REMOTE}/${branch} successfuly pushed to remote." "LOGFILE" \ | |
|| { mlog "'git merge --ff ${UPSTREAM}/${branch}' into ${REMOTE}/${branch} failed to push to remote." "ERROR_LOG"; } | |
else | |
mlog "New upstream branch '$branch' found" "LOGFILE" | |
# push to remote | |
git push $REMOTE $UPSTREAM/$branch:refs/heads/$branch && mlog "'git push $REMOTE $UPSTREAM/$branch:refs/heads/$branch' <New Branch> successful." "LOGFILE" \ | |
|| { mlog "'git push $REMOTE $UPSTREAM/$branch:refs/heads/$branch' <New Branch> failed." "ERROR_LOG"; } | |
fi | |
done | |
if [ $stashed -eq 0 ]; then | |
git stash pop | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment