Skip to content

Instantly share code, notes, and snippets.

@Sal7one
Last active June 9, 2025 03:24
Show Gist options
  • Save Sal7one/8ad415cbf77e34cd253bf76e353b2621 to your computer and use it in GitHub Desktop.
Save Sal7one/8ad415cbf77e34cd253bf76e353b2621 to your computer and use it in GitHub Desktop.
Locally download all your repos.. don't forget to chmod x+ this
#!/bin/bash
# ==== User Configuration ====
GITHUB_USERNAME="your_github_username"
GITHUB_TOKEN="your_github_token"
PER_PAGE=100
GITHUB_API_URL="https://api.github.com"
DEST_DIR="./github_repos"
mkdir -p "$DEST_DIR"
cd "$DEST_DIR" || exit 1
# Get stats from /user endpoint
user_info=$(curl -s -u "$GITHUB_USERNAME:$GITHUB_TOKEN" "$GITHUB_API_URL/user")
public_count=$(echo "$user_info" | jq '.public_repos')
private_count=$(echo "$user_info" | jq '.total_private_repos')
total_repos=$((public_count + private_count))
echo "Total public repositories: $public_count"
echo "Total private repositories: $private_count"
echo "Total repositories (sum): $total_repos"
echo "Fetching repository list ..."
success_count=0
fail_count=0
public_cloned=0
private_cloned=0
declare -a failed_repos
page=1
while :; do
repos=$(curl -s -u "$GITHUB_USERNAME:$GITHUB_TOKEN" "$GITHUB_API_URL/user/repos?per_page=$PER_PAGE&page=$page&type=all")
repo_count=$(echo "$repos" | jq 'length')
[ "$repo_count" -eq 0 ] && break
for ((i=0; i<repo_count; i++)); do
name=$(echo "$repos" | jq -r ".[$i].name")
full_name=$(echo "$repos" | jq -r ".[$i].full_name")
private=$(echo "$repos" | jq -r ".[$i].private")
clone_url=$(echo "$repos" | jq -r ".[$i].clone_url")
if [ "$private" = "true" ]; then
# Use HTTPS with token for private
clone_url=$(echo "$clone_url" | sed "s#https://#https://$GITHUB_USERNAME:$GITHUB_TOKEN@#")
fi
echo -n "Cloning $full_name ($([ "$private" = "true" ] && echo "private" || echo "public")) ... "
if git clone "$clone_url"; then
echo "Success"
success_count=$((success_count+1))
if [ "$private" = "true" ]; then
private_cloned=$((private_cloned+1))
else
public_cloned=$((public_cloned+1))
fi
else
echo "Failed"
fail_count=$((fail_count+1))
failed_repos+=("$full_name")
fi
done
page=$((page+1))
done
echo
echo "----------------------------------------------"
echo "GitHub Repo Clone Summary for $GITHUB_USERNAME"
echo "----------------------------------------------"
echo "Total public repositories: $public_count"
echo "Total private repositories: $private_count"
echo "Total successfully cloned (public): $public_cloned"
echo "Total successfully cloned (private): $private_cloned"
echo "Total successfully cloned: $success_count"
echo "Failed to clone: $fail_count"
if [ "$fail_count" -ne 0 ]; then
echo "Failed repo names:"
for repo in "${failed_repos[@]}"; do
echo " - $repo"
done
fi
echo "Repos directory: $DEST_DIR"
echo "----------------------------------------------"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment