Skip to content

Instantly share code, notes, and snippets.

@terrisgit
Last active July 3, 2020 08:45
Show Gist options
  • Save terrisgit/eaa871da2246417b042cba20e281bad6 to your computer and use it in GitHub Desktop.
Save terrisgit/eaa871da2246417b042cba20e281bad6 to your computer and use it in GitHub Desktop.
Clone or pull multiple git repos from specific branches based on a JSON input file
#!/bin/bash
set -e
# This command reads the file repos.json and clones or pulls
# git repositories in particular branches. If there are local
# edits in these repos, they are stashed and reapplied.
#
# Credits:
# 1. https://stackoverflow.com/questions/6550484/prevent-grep-returning-an-error-when-input-doesnt-match
# 2. https://stackoverflow.com/questions/34114700/git-stash-pop-only-if-successfully-stashed-before
#
# Prerequisites:
# 1. Install 'jc' command
#
# The file repos.json looks like:
# [
# {
# "name": "foo",
# "repo": "git@github.com:org/foo.git",
# "branch": "master"
# },
# {
# "name": "bar",
# "repo": "git@github.com:org/bar.git",
# "branch": "master"
# },
# ]
#
# The name key must contain the name of the repository without
# the .git extension (extra credit to use sed to do
# this for you)
# create a unique timestamp for the stash name
t=timestamp-$(date +%s)
for row in $(jq -c '.[]' repos.json); do
_jq() {
echo ${row} | jq -r ${1}
}
NAME=$(_jq '.name')
REPO=$(_jq '.repo')
BRANCH=$(_jq '.branch')
echo
echo "*** $NAME ***"
if [ -d $NAME ]; then
cd $NAME
git fetch
# stash with message
r=$(git stash save -u $t)
git checkout $BRANCH
git pull
# if the stash was created above, reapply it
v=$(echo $r | grep $t | { grep -v grep || test $? = 1; })
if [ "$v" ]; then
git stash pop
fi
cd ..
else
git clone -b $BRANCH $REPO
fi
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment