A powerful, lightweight command-line tool for downloading files and directories from GitHub repositories with ease. Built with Dart, ghcp provides a simple yet flexible way to fetch content from GitHub repositories without cloning the entire repository. Perfect for CI/CD pipelines, automation scripts, and selective downloads.
- Fast & Lightweight: Only downloads what you need, no repository cloning required
- Directory Support: Download entire directories with preserved structure and recursive processing
- Flexible URLs: Supports various GitHub URL formats (blob/tree, different branches)
- Recursive Downloads: Automatically handles nested directories with concurrent processing
- Concurrent Downloads: Parallel file downloads for improved performance
- File Size Awareness: Handles files up to GitHub's 100MB limit
- Installation
- Quick Start
- Usage
- Configuration
- Supported URL Formats
- Output Behavior
- Examples
- API Rate Limits
- Development
- Troubleshooting
- FAQ
- Contributing
- License
- Acknowledgments
Download the latest pre-built binary for your platform from the releases page:
Available Platforms:
- macOS: x64 (Intel), arm64 (Apple Silicon)
- Linux: x64, arm64
- Windows: x64
Linux/macOS:
# Download the appropriate binary for your platform
# Replace {version} with the latest version (e.g., v1.0.0)
# Replace {platform} with: linux or macos
# Replace {arch} with: x64 or arm64
curl -L -o ghcp.tar.gz https://github.com/aminnez/ghcp/releases/download/{version}/ghcp-{version}-{platform}-{arch}.tar.gz
# Extract and install
tar -xzf ghcp.tar.gz
chmod +x ghcp
sudo mv ghcp /usr/local/bin/
# Verify installation
ghcp --helpWindows:
# Download the binary
# Replace {version} with the latest version (e.g., v1.0.0)
Invoke-WebRequest -Uri "https://github.com/aminnez/ghcp/releases/download/{version}/ghcp-{version}-windows-x64.zip" -OutFile "ghcp.zip"
# Extract the zip file
Expand-Archive -Path "ghcp.zip" -DestinationPath "."
# Add to PATH or run directly
# You can move ghcp.exe to a directory in your PATHPrerequisites: Dart SDK Version 3.8.1 or higher (Install Dart)
# Install globally
dart pub global activate ghcp
# Update to latest version
dart pub global activate ghcpPrerequisites: Dart SDK Version 3.8.1 or higher (Install Dart)
# Clone the repository
git clone https://github.com/aminnez/ghcp.git
cd ghcp
# Install dependencies
dart pub get
# Activate globally
dart pub global activate --source path .ghcp --help# Download a single file
ghcp https://github.com/open-webui/open-webui/blob/main/docker-compose.yaml
# Download a single file with custom filename
ghcp https://github.com/open-webui/open-webui/blob/main/docker-compose.yaml compose.yml
# Download an entire directory
ghcp https://github.com/google/dart-basics/tree/master/lib
# Download directory contents directly into target folder
ghcp https://github.com/google/dart-basics/tree/master/lib ./dart-basicsghcp <github-url> [output-directory] [--token <token>] [--help]<github-url>: GitHub URL to download from (required)- Supports both
blob(single files) andtree(directories) URLs - Must follow the format:
https://github.com/owner/repo/blob|tree/branch/path
- Supports both
[output-directory]: Output directory or filename (optional, defaults to current directory)- For single files: Can specify a custom filename (e.g.,
config.yml) or directory - For directories: Specifies where to extract the directory contents
- For single files: Can specify a custom filename (e.g.,
--token <token>: GitHub personal access token for authentication-h, --help: Show help message
For private repositories or higher rate limits, you can provide a GitHub Personal Access Token:
export GITHUB_TOKEN=your_github_token
ghcp https://github.com/your-username/your-private-repo/blob/main/path/to/fileghcp https://github.com/your-username/your-private-repo/blob/main/path/to/file --token your_github_tokenNote: Environment variable takes precedence over command line flag.
| Variable | Description | Default |
|---|---|---|
GITHUB_TOKEN |
GitHub Personal Access Token for authentication | null |
- Go to GitHub Settings > Developer settings > Personal access tokens
- Click "Generate new token"
- Select appropriate scopes (at minimum
repofor private repositories) - Copy the token and set it as an environment variable
ghcp supports the following GitHub URL formats:
https://github.com/owner/repo/blob/branch/path/to/file.exthttps://github.com/owner/repo/tree/branch/path/to/directoryhttps://github.com/owner/repo/tree/branchghcp intelligently handles output paths based on the download type and specified output:
- Custom filename:
ghcp <url> config.yml→ saves asconfig.yml - Directory target:
ghcp <url> ./configs/→ saves as./configs/filename.ext - No output specified:
ghcp <url>→ saves asfilename.extin current directory
- Target directory:
ghcp <url> ./output→ extracts contents directly into./output/ - No output specified:
ghcp <url>→ extracts contents into current directory
Note: Directory contents are extracted directly into the target directory, not into a subdirectory named after the source directory.
https://github.com/microsoft/vscode/blob/main/README.mdhttps://github.com/google/dart-basics/tree/master/libhttps://github.com/facebook/react/tree/main/packageshttps://github.com/owner/repo/tree/feature-branch/src
# Download docker-compose from a repository
ghcp https://github.com/open-webui/open-webui/blob/main/docker-compose.yaml
# Download with custom filename
ghcp https://github.com/open-webui/open-webui/blob/main/docker-compose.yaml compose.yaml
# Download to specific directory (keeps original filename)
ghcp https://github.com/google/dart-basics/blob/master/pubspec.yaml ./config/# Download directory contents directly to current directory
ghcp https://github.com/google/dart-basics/tree/master/lib
# Download directory contents to specific folder
ghcp https://github.com/facebook/react/tree/main/src ./react-source
# Download documentation contents directly into docs folder
ghcp https://github.com/kubernetes/kubernetes/tree/master/docs ./k8s-docs# Using environment variable (recommended for security)
export GITHUB_TOKEN=ghp_your_token_here
ghcp https://github.com/your-org/private-repo/blob/main/config/app.yaml
# Using command line flag (less secure, visible in process list)
ghcp https://github.com/your-org/private-repo/tree/main/src --token ghp_your_token_here# Download specific branch content
ghcp https://github.com/flutter/flutter/tree/stable/packages/flutter/lib
# Download from a specific commit (use commit SHA as branch)
ghcp https://github.com/dart-lang/sdk/tree/abc123def456/pkg/analyzer
# Download nested directories
ghcp https://github.com/kubernetes/kubernetes/tree/master/cmd/kubectl/app
# Download to nested output directories
ghcp https://github.com/microsoft/vscode/tree/main/src/vs/editor ./editor-source
# Download large directories (will show progress for each file)
ghcp https://github.com/tensorflow/tensorflow/tree/master/tensorflow/python# Download multiple files (using shell scripting)
for url in \
"https://github.com/owner/repo/blob/main/file1.txt" \
"https://github.com/owner/repo/blob/main/file2.md"; do
ghcp "$url"
doneGitHub API has rate limits that affect ghcp:
- Unauthenticated requests: 60 requests per hour
- Authenticated requests: 5,000 requests per hour
The tool automatically handles rate limit information and provides clear error messages:
❌ GitHub API Error: API rate limit exceeded
Rate limit remaining: 0/60 (resets at 2024-01-01T12:00:00Z)- Use authentication: Authenticated requests have much higher limits (5,000 vs 60)
- Batch operations: Download directories instead of individual files when possible
- Be mindful of large directories: Each file in a directory requires a separate API call
- Use caching: Avoid re-downloading the same content repeatedly
# Good: Downloads entire directory in one API call (plus one per file)
ghcp https://github.com/owner/repo/tree/main/src
# Less efficient: Multiple separate commands for files in same directory
ghcp https://github.com/owner/repo/blob/main/src/file1.dart
ghcp https://github.com/owner/repo/blob/main/src/file2.dart# Clone the repository
git clone https://github.com/aminnez/ghcp.git
cd ghcp
# Install dependencies
dart pub get
# Run in development mode
dart run bin/ghcp.dart --help
# Build standalone executable
dart compile exe bin/ghcp.dart -o ghcp
# Run tests
dart test
# Run static analysis
dart analyze
# Format code
dart format .Error: Invalid GitHub URL: Not a valid GitHub URL
Solutions:
- Ensure URL starts with
https://github.com/ - Check URL format:
https://github.com/owner/repo/tree/branch/path - Verify repository exists and is accessible
Error: GitHub API Error: API rate limit exceeded
Solutions:
- Wait until rate limit resets (1 hour for unauthenticated)
- Use authentication with GitHub token
- Reduce request frequency
Error: GitHub API Error: Repository not found
Solutions:
- Verify repository exists and is spelled correctly
- Check if repository is private (requires authentication)
- Ensure you have access to the repository
Error: Error: No download URL available for path/to/file
Solutions:
- Verify the file exists in the repository
- Check if it's a valid file (not a directory)
- Ensure you have the correct branch name
Enable verbose output for debugging:
# Set debug environment variable
export DEBUG=true
ghcp <url>If you encounter network-related errors:
# Check network connectivity
ping github.com
# Test API accessibility
curl -I https://api.github.comYes! For single file downloads, you can specify a custom filename:
# Download with custom filename
ghcp https://github.com/owner/repo/blob/main/config.yaml my-config.yml
# Download Docker Compose file with shorter name
ghcp https://github.com/owner/repo/blob/main/docker/docker-compose.yml dc.ymlYes! Use a GitHub Personal Access Token with appropriate permissions:
export GITHUB_TOKEN=your_token
ghcp https://github.com/your-org/private-repo/blob/main/file.txtNo! ghcp only downloads the specific files or directories you request, making it much faster and more efficient than cloning.
Yes, by downloading a directory that contains multiple files:
ghcp https://github.com/owner/repo/tree/main/directory-with-multiple-files- blob URLs: Point to individual files
- tree URLs: Point to directories (which may contain multiple files)
ghcp provides visual feedback with progress spinners and completion messages. Successful downloads show:
Downloaded! filename.extAbsolutely! ghcp is designed for scripting and automation:
#!/bin/bash
ghcp https://github.com/owner/repo/blob/main/config.yaml ./config
echo "Config downloaded successfully!"GitHub has specific file size limits:
- Individual files: 100MB maximum (GitHub limitation)
- Directory size: No specific limit, but consider:
- API rate limits (60 calls/hour without auth, 5,000 with auth)
- Each file requires a separate API call
- Large directories may take significant time
- Network and disk space constraints
ghcp provides real-time visual feedback:
# Single file download
⏳ Downloading string_basics.dart...
✔ Downloaded! string_basics.dart
# Directory download
✔ Downloading 3 of 11 files...
⠋ Downloading basics.dart...
⠋ Downloading comparable_basics.dart...
✔ Done! date_time_basics.dart
⠋ Downloading int_basics.dart...
✔ Done! 11 of 11 files.Currently, ghcp does not support resume functionality. Interrupted downloads will need to be restarted. This is planned for a future release.
Currently, ghcp only supports GitHub.com. GitHub Enterprise support may be added in future versions based on user demand.
Contributions are welcome! Here's how you can help:
-
Fork the repository
-
Clone your fork
git clone https://github.com/your-username/ghcp.git cd ghcp -
Install dependencies
dart pub get
-
Create a feature branch
git checkout -b feature/amazing-feature
-
Make your changes and ensure quality
# Run tests dart test # Run static analysis dart analyze # Format code dart format . # Check pub publish readiness dart pub publish --dry-run
-
Commit your changes
git add . git commit -m "Add amazing feature" git push origin feature/amazing-feature
-
Submit a pull request
# Test the CLI locally
dart run bin/ghcp.dart <github-url> [output-dir]
# Build and test native executable
dart compile exe bin/ghcp.dart -o ghcp-test
./ghcp-test <github-url> [output-dir]This project follows Dart's official style guide with strict linting rules:
- Type Safety: All public APIs must have explicit type annotations
- Documentation: All public APIs should have comprehensive documentation
- Error Handling: Use custom exceptions with descriptive messages
- Testing: Maintain high test coverage for all new features
The project uses strict analysis options defined in analysis_options.yaml:
# Check for linting issues
dart analyze
# Fix auto-fixable issues
dart fix --apply- Small, focused changes: Keep PRs small and focused on a single feature/fix
- Tests required: All new functionality must include tests
- Documentation: Update README and inline docs as needed
- Code quality: Ensure all lints pass and tests succeed
- Backwards compatibility: Avoid breaking changes without discussion
This project is licensed under the MIT License - see the LICENSE file for details.
- Dart Team: For the amazing Dart programming language
- GitHub: For providing excellent APIs and platform
- Open Source Community: For inspiration and tools