Last active
November 13, 2020 20:53
-
-
Save draeath/ab4f10875cd8dc861f95873ee1809d9d to your computer and use it in GitHub Desktop.
Bash script to pull github organizations. Note '-C' for git requires a modern git version.
This file contains 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
#!/bin/bash | |
# you PROBABLY want to use an ssh-key for this, or you'll | |
# be typing your password over and over and over... | |
# you MUST set ORG_NAME and ACCESS_TOKEN below! | |
# if you want to grab private repositories, the | |
# token must have the full "repos" scope selected | |
# | |
# ... note no other scopes are required, and you | |
# should take care to guard this token! | |
# | |
# https://github.com/settings/tokens | |
SELFCMD="${0}" | |
SELFNAME="$(basename "${SELFCMD}")" | |
ORG_NAME="" # SET ME! See comments above! | |
ACCESS_TOKEN="" # SET ME! See comments above! | |
GITHUB_INSTANCE="api.github.com" # enterprise accounts may need to adjust | |
PAGE="1" | |
PERPAGE="30" # max 100 per github API, default 30 | |
if [ "${#}" -eq 1 ]; then | |
function checkint() | |
{ | |
printf "%d" "${1}" &>/dev/null | |
return "${?}" | |
} | |
if checkint "${1}"; then | |
PAGE="${1}" | |
else | |
>&2 echo "(${SELFNAME}) Invalid argument. Provide no arguments (or optionally an API page number greater than or equal to 1)." | |
exit 1 | |
fi | |
fi | |
URL="https://${GITHUB_INSTANCE}/orgs/${ORG_NAME}/repos?per_page=${PERPAGE}&page=${PAGE}" | |
echo "(${SELFNAME}) requesting" "${URL}" | |
REPOLIST="$(curl -s -H "Authorization: token ${ACCESS_TOKEN}" "${URL}" | grep '"ssh_url"' | cut -d '"' -f 4)" | |
if (( ${#REPOLIST} > 0 )); then | |
for REPO in ${REPOLIST}; do | |
REPOFILE="$(echo "${REPO}" | awk -F '/' '{print $NF}')" | |
REPODIR="${REPOFILE%.git}" | |
if ! [ -x ./"$REPODIR" ]; then | |
echo "Cloning: ${REPO} (into ${REPODIR})" | |
git clone "${REPO}" "${REPODIR}" | |
for branch in $(git -C "${REPODIR}" branch --all | grep '^\s*remotes' | grep -E --invert-match '(:?HEAD|master|main)$'); do | |
echo "Tracking: ${REPO} / ${branch}" | |
git -C "${REPODIR}" branch --track "${branch##*/}" "$branch" | |
done | |
fi | |
echo "Pulling: ${REPODIR}" | |
git -C "${REPODIR}" fetch --all --prune || echo "GIT FETCH FAILED FOR: ${REPODIR}" | tee cloner-fails.log | |
git -C "${REPODIR}" gc --auto || echo "GIT GC FAILED FOR: ${REPODIR}" | tee -a cloner-fails.log | |
git -C "${REPODIR}" pull || echo "GIT PULL FAILED FOR: ${REPODIR}" | tee -a cloner-fails.log | |
unset REPOFILE | |
unset REPODIR | |
done | |
else | |
echo "(${SELFNAME}) received 0 repostory URLs - process completed or something went wrong." | |
exit 0 | |
fi | |
if [ ${#REPOLIST} -ge ${PERPAGE} ]; then | |
echo "(${SELFNAME}) recursing with PAGE=${PAGE}" | |
exec "${SELFCMD}" $(( ${PAGE} + 1 )) | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment