Every now and then, one may wish to have had a simple script to check out or
update all the github repos you have, at once, using a single command.
This can be for the reason of backups, or simply, check out new ones that you don’t have etc,
or, keeping a local up-to-date copy of everything.
Well, I wrote a similar little script some time back for BitBucket.
(https://emberlabs.tech/2023/05/08/easily-mirror-a-bitbucket-repo/)
This should work just fine on pretty much any Linux or Mac install (or similar with a bash).
Nuf of the talk! Show me the code!! =D
#!/bin/bash
# GH Mass checkout.
# V 1.0 - 2025-11-23 Spruce
# Prerequisites: curl and jq
# Place your GH PAT in ~/.gitpat (contents / read-only needed)
# Relies on SSH for cloning/pull, add your public key to GH.
ORG="[Your ORG name here]"
PAT="[Your GH PAT]"
CDIR="$(pwd)"
if [ "${PAT}" == "" ]
then
if [ -e ~/.gitpat ]
then
PAT="$(grep github ~/.gitpat | head -1)"
else
echo "No PAT available."
echo "Create a PAT (Profile -> Settings -> Developer settings -> PAT"
echo "Select fine-grained, account/org, and all repos, then select contents with read-only."
exit 1
fi
fi
function GetRepoLists {
echo ""
echo -n "Updating the repolists : "
rm -f repolist.*
for page in $(seq 1 20) ; do
echo -n "${page} "
curl -s \
-H "Accept: application/vnd.github+json" \
-H "X-GitHub-Api-Version: 2022-11-28" \
-H "Authorization: Bearer ${PAT}" \
"https://api.github.com/orgs/${ORG}/repos?per_page=100&page=${page}" \
| jq -r '.[].ssh_url' > repolist.${page}
if [ ! -s "repolist.${page}" ]
then
rm -f "repolist.${page}"
break
fi
done
echo ""
cat repolist.* > repolist
rm -f repolist.*
}
function ClonePull {
mkdir -p ${ORG}
while IFS= read -r URL; do
repo="${URL##*/}"
repobase="${repo%.git}"
if [ -e "${ORG}/${repobase}" ]
then
echo "Updating ${ORG}/${repobase}"
cd ${ORG}/${repobase}
git pull
cd ${CDIR}
else
echo "Cloning ${URL}"
cd ${ORG}
git clone ${URL}
fi
done < "./repolist"
}
function GitExec {
GITCMD="$1"
cd ${ORG}
for repo in *
do
echo "Executing ${GITCMD} in ${ORG}/${repo}"
cd ${CDIR}/${ORG}/${repo}
git ${GITCMD}
cd ${CDIR}
done
}
# --- Actions -------------------------------------------------------
case "$1" in
full)
GetRepoLists
ClonePull
;;
pull)
GitExec "pull"
;;
fetch)
GitExec "fetch"
;;
*)
echo "Usage:"
echo " "
echo " full Update existing and clone new repos."
echo " fetch Execute a fetch on all existing repos."
echo " pull Execute a pull on all existing repos."
;;
esac
Njoy!!
