Last active
January 21, 2026 22:08
-
-
Save kyletimmermans/e5c25f3ffed5a123ac5b34b189eca23b to your computer and use it in GitHub Desktop.
GitHub Repo & Gist Backup Script
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
| #!/usr/bin/env bash | |
| set -e | |
| # Must have jq & gh (GitHub CLI tool) installed | |
| # Stargazer.py by github.com/zhuozhiyongde/gaze-stars | |
| # Get personal access token with access to "repos" and "gists" in developer settings | |
| printf "\n" | |
| read -e -r -p "Enter Username: " USERNAME | |
| read -s -r -p "Enter Access Token: " TOKEN | |
| printf "\n\n" | |
| read -e -r -p "Download Repositories? (Y/n): " GETREPOS | |
| read -e -r -p "Download Gists? (Y/n): " GETGISTS | |
| read -e -r -p "Generate Starred List? (Y/n): " GETSTARS | |
| if ! [[ "${GETREPOS}" =~ ^[Yy]$ ]] && ! [[ "${GETGISTS}" =~ ^[Yy]$ ]] && ! [[ "${GETSTARS}" =~ ^[Yy]$ ]]; then | |
| printf "\n%s\n" "Nothing chosen to backup ..." | |
| exit 1 | |
| fi | |
| DATETIME=$(date +'%b-%d-%Y_%H-%M-%S') | |
| mkdir "GitHubBackup_${DATETIME}" | |
| cd "GitHubBackup_${DATETIME}" | |
| printf "%s" "${TOKEN}" > temptoken.txt | |
| gh auth login --with-token < temptoken.txt | |
| rm temptoken.txt | |
| if [[ "${GETREPOS}" =~ ^[Yy]$ ]]; then | |
| printf "\n%s\n" "Downloading Repositories..." | |
| mkdir Repos && cd Repos | |
| curl --silent -L -H "Authorization: Bearer ${TOKEN}" "https://api.github.com/search/repositories?q=user:${USERNAME}" \ | |
| | jq -r '.items[].full_name' \ | |
| | xargs -I {} gh repo clone {} | |
| cd .. | |
| fi | |
| if [[ "${GETGISTS}" =~ ^[Yy]$ ]]; then | |
| printf "\n%s\n" "Downloading Gists..." | |
| mkdir Gists && cd Gists | |
| curl --silent -L -H "Authorization: Bearer ${TOKEN}" https://api.github.com/gists \ | |
| | jq -r '.[].html_url' \ | |
| | xargs -I {} gh gist clone {} | |
| # Rename gist dirs | |
| curl --silent -L -H "Authorization: Bearer ${TOKEN}" https://api.github.com/gists \ | |
| | jq -r '.[] | "\(.id) \(.files | keys[0])"' \ | |
| | xargs -n 2 mv | |
| cd .. | |
| fi | |
| inplace_sed() { | |
| if sed --version 2>/dev/null | grep -q "GNU"; then | |
| sed -E -i "$@" | |
| else | |
| sed -E -i '' "$@" | |
| fi | |
| } | |
| if [[ "${GETSTARS}" =~ ^[Yy]$ ]]; then | |
| printf "\n%s\n" "Generating Starred List..." | |
| mkdir Stars && cd Stars | |
| curl -q -sS -LJO https://github.com/zhuozhiyongde/gaze-stars/raw/refs/heads/main/Stargazer.py | |
| chmod a+x Stargazer.py | |
| mkdir template && cd template/ | |
| cat >> template.md <<EOF | |
| <div align="center"> | |
| # GitHub Starred List | |
| Gernerated by [gaze-stars](https://github.com/zhuozhiyongde/gaze-stars) | |
| </div><br> | |
| [[GENERATE HERE]] | |
| EOF | |
| cd .. | |
| GITHUB_USERNAME="${USERNAME}" GITHUB_TOKEN="${TOKEN}" OUTPUT_PATH="GitHub_Starred_List.md" SORT_BY="updated" python3 Stargazer.py | |
| rm Stargazer.py && rm -rf template/ | |
| inplace_sed 's/^\| 仓库名称 \| 描述 \| Star数 \|$/| Repository | Description | Star Count |/g' "GitHub_Starred_List.md" | |
| inplace_sed 's/^\- \[未分类仓库\]\(#未分类仓库\)$/- [Uncategorized](#uncategorized)/g' "GitHub_Starred_List.md" | |
| inplace_sed 's/^## 未分类仓库$/## Uncategorized/g' "GitHub_Starred_List.md" | |
| mv data.json GitHub_Starred_List.json | |
| cd .. | |
| fi | |
| cd .. | |
| printf "\n" | |
| read -e -r -p "Zip Up Backup Folder? (Y/n): " DOZIP | |
| if [[ "${DOZIP}" =~ ^[Yy]$ ]]; then | |
| printf "\n%s\n" "Choose a compression method for the zip archive:" | |
| printf "%s\n" "------------------------------------------------" | |
| PS3='> ' | |
| select OPT in "deflate (default)" "bzip2" "store (no compression)"; do | |
| case $OPT in | |
| "deflate (default)") | |
| COMPRESSION_METHOD="deflate" | |
| break | |
| ;; | |
| "bzip2") | |
| COMPRESSION_METHOD="bzip2" | |
| break | |
| ;; | |
| "store (no compression)") | |
| COMPRESSION_METHOD="store" | |
| break | |
| ;; | |
| *) | |
| printf "%s\n" "Invalid zip compression option. Try again" | |
| ;; | |
| esac | |
| done | |
| printf "\n" | |
| read -e -r -p "Password Protect Zip Folder? (Y/n): " DOPASSWORD | |
| printf "\n" | |
| if [[ "${DOPASSWORD}" =~ ^[Yy]$ ]]; then | |
| # If password mismatch fails, don't exit entire script | |
| while true; do | |
| if zip -e -r -dd -T -MM -Z "${COMPRESSION_METHOD}" "GitHubBackup_${DATETIME}.zip" "GitHubBackup_${DATETIME}/"; then | |
| break | |
| fi | |
| done | |
| else | |
| zip -r -dd -T -MM -Z "${COMPRESSION_METHOD}" "GitHubBackup_${DATETIME}.zip" "GitHubBackup_${DATETIME}/" | |
| fi | |
| rm -rf "GitHubBackup_${DATETIME}/" | |
| fi | |
| printf "\nStatus: \033[1;92m%s\033[0m\n" "Finished" | |
| printf " %s\n\n" "- Note: Remove the token from 'gh' if you want!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment