Skip to content

Instantly share code, notes, and snippets.

@emmanuelbernard
Created November 7, 2010 12:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save emmanuelbernard/666113 to your computer and use it in GitHub Desktop.
Save emmanuelbernard/666113 to your computer and use it in GitHub Desktop.
Synchronize all changes (incl new branches and tags) from repo A to repo B, where B is a bare repo.
#!/bin/bash
#Synchronize all changes (incl new branches and tags) from repo A to repo B, where B is a bare repo.
#B must be an bare clone of A (initial setup)
#A' must be a clone of A where origin points to A
#There are probably more optimized ways to do this. the advantage of this method is that no branch is deleted from the backup repo
#so the source repo is not 100% trusted
#make sure to define BACKUP_REPO and INTERMEDIARY_REPO
#define where repo B resides (Git repo URL) eg file://${HOME}/path/to/repo.git
BACKUP_REPO="file://${HOME}/path/to/repo.git"
#A' repo location we will cd into
INTERMEDIARY_REPO=${HOME}/repoAPrime
#cd into the A' repo
cd ${INTERMEDIARY_REPO}
get_branches() {
flags=""
if [ $2 == "remote" ] ; then
flags="-r"
fi
branches=`git branch $flags | sed -e "s/*//g"`
i=0
for b in $branches ; do
cl=`echo $b | sed -e "s:\s*::g" -e "s:origin/::g"`
eval "$1[$i]=$cl"
let "i=$i + 1"
done
}
localize() {
rb=$1
if [ $rb == "HEAD" ] ; then
echo "Not processing HEAD"
else
local=$2
echo "Localizing $rb"
found="FALSE"
for l in ${local[*]} ; do
if [ $found == "FALSE" ] ; then
if [ $l == $rb ] ; then
found="TRUE"
fi
fi
done
if [ $found == "FALSE" ] ; then
echo "... adding a local branch for $rb"
git checkout -q -f -b $rb origin/$rb
else
echo "... no need to add local branch for $rb"
fi
fi
}
git fetch origin
git fetch --tags origin
get_branches local_branches local
get_branches remote_branches remote
echo "Local: [${local_branches[*]}] and is of size ${#local_branches[*]}"
echo "Remote: [${remote_branches[*]}] and is of size ${#remote_branches[*]}"
for rb in ${remote_branches[*]} ; do
argument=`echo ${local_branches[@]}`
localize $rb "$argument"
done
unset local_branches
get_branches local_branches local
echo "After localizing, local: [${local_branches[*]}] and is of size ${#local_branches[*]}"
for lb in ${local_branches[*]} ; do
echo "Updating $lb"
git checkout -q -f $lb
git pull -q origin $lb
git push ${BACKUP_REPO} $lb
done
git push ${BACKUP_REPO} --tags
@maniksurtani
Copy link

Thanks for fixing this. :-) You can actually remove line 68 altogether and replace line 69 with:

localize $rb $local_branches

@emmanuelbernard
Copy link
Author

Nope,

localize $rb $local_branches

failed for me as only the first local branch was passed to localize. Somehow in bash, passing arrays is not trivial

@maniksurtani
Copy link

Hmm, yes you are right. BASH is a PITA. Anyway I got it working with

localize $rb "${local_branches[*]}"

which is essentially the same as what you did, minus the sub-shell execution. :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment