Skip to content

Instantly share code, notes, and snippets.

@matthewadams
Created June 8, 2025 11:46
Show Gist options
  • Save matthewadams/0ee34c224c9f57e3c06f3f63f0209502 to your computer and use it in GitHub Desktop.
Save matthewadams/0ee34c224c9f57e3c06f3f63f0209502 to your computer and use it in GitHub Desktop.
Fetch via curl a subdirectory recursively from a github repo
#!/bin/bash
# GitHub subdirectory recursive fetcher
# Usage: ./fetch_github_subdir.sh <owner> <repo> <subdirectory> [branch]
set -e
if [ $# -lt 3 ]; then
echo "Usage: $0 <owner> <repo> <subdirectory> [branch]"
echo "Example: $0 facebook react packages/react main"
exit 1
fi
OWNER="$1"
REPO="$2"
SUBDIR="$3"
BRANCH="${4:-main}"
OUTPUT_DIR="${REPO}_${SUBDIR//\//_}"
mkdir -p "$OUTPUT_DIR"
echo "Fetching directory tree from ${OWNER}/${REPO}/${SUBDIR} (branch: ${BRANCH})"
# Function to recursively fetch directory contents
fetch_directory() {
local dir_path="$1"
local api_url="https://api.github.com/repos/${OWNER}/${REPO}/contents/${dir_path}?ref=${BRANCH}"
echo "Scanning directory: $dir_path"
# Get directory contents
local response=$(curl -s "$api_url")
# Check if response is valid JSON array
if ! echo "$response" | jq -e '. | type == "array"' >/dev/null 2>&1; then
echo "Warning: Could not access directory $dir_path"
return
fi
# Process each item in the directory
echo "$response" | jq -r '.[] | "\(.type)|\(.path)|\(.download_url // "")"' | while IFS='|' read -r type path download_url; do
if [ "$type" = "file" ]; then
# Create local directory structure
local local_path="${OUTPUT_DIR}/${path#$SUBDIR/}"
local local_dir=$(dirname "$local_path")
mkdir -p "$local_dir"
echo "Downloading: $path"
if curl -s "$download_url" -o "$local_path"; then
echo "✓ Saved to $local_path"
else
echo "✗ Failed to download $path"
fi
elif [ "$type" = "dir" ]; then
# Recursively fetch subdirectory
fetch_directory "$path"
fi
done
}
# Check if jq is available
if ! command -v jq &> /dev/null; then
echo "Error: jq is required but not installed."
echo "Install with: sudo apt-get install jq (Ubuntu/Debian) or brew install jq (macOS)"
exit 1
fi
# Start recursive fetch
fetch_directory "$SUBDIR"
echo
echo "Download complete! Directory tree saved to: $OUTPUT_DIR"
echo "Directory structure preserved under: $OUTPUT_DIR"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment