Skip to main content

Mirror every repo you own โ€” in one command

Project description

๐Ÿฅ” Farmore

"Mirror every repo you own โ€” in one command."

Farmore is a comprehensive Python CLI tool for backing up GitHub repositories and their associated data. Clone repositories, export issues, download releases, backup wikis, and more โ€” all with a single command.

Version: 0.9.0 License: MIT Python: 3.10+


โœจ Features

๐Ÿ”„ Repository Management

  • Bulk backups - Clone all repos for a user or organization in one command
  • Single repo backups - Backup individual repositories with the repo command
  • Repository search - Search GitHub and clone matching repositories by keyword
  • Smart updates - Automatically pulls updates for existing repositories
  • Parallel processing - Fast backups with configurable worker threads
  • SSH/HTTPS support - Tries SSH first, falls back to HTTPS with token
  • Bare/Mirror clones - Use --bare flag for true 1:1 repository backups
  • Git LFS support - Use --lfs flag for repositories with large files
  • Name regex filtering - Filter repositories by name pattern with --name-regex
  • Incremental backups - Track backup state with --incremental flag

๐Ÿ“Š Data Export

  • Issues export - Export all issues to JSON/YAML with optional comments
  • Pull requests export - Export PRs with metadata and comments
  • Workflows backup - Backup GitHub Actions workflows and run history
  • Releases download - Download releases with metadata and binary assets
  • Wiki backup - Clone repository wikis as git repositories
  • Labels export - Backup repository labels with colors
  • Milestones export - Backup milestone configuration and progress
  • Gists backup - Clone all your GitHub gists
  • Attachments download - Download images/files from issues and PRs

๐Ÿ” Access & Security

  • Private repository support - Full access with GitHub Personal Access Tokens
  • Organization repos - Backup all organization repositories
  • Starred & watched repos - Mirror repositories you've starred or are watching
  • Secrets export - Export repository secret names (values are never exposed)
  • Followers/Following - Export user's social connections
  • Webhooks export - Backup webhook configurations

๐ŸŽฏ Advanced Features

  • Flexible filtering - By visibility (public/private/all), forks, archived status
  • Rate limit handling - Automatic retries with exponential backoff
  • Organized structure - Clean directory organization separating code from data
  • Cross-platform - Works on Linux, macOS, and Windows
  • Beautiful CLI - Powered by Typer and Rich with progress bars
  • GitHub Enterprise - Support via --github-host flag
  • Discussions backup - Export repository discussions (GraphQL API)
  • Projects backup - Export Projects v2 data (GraphQL API)

๐Ÿ“ฆ Installation

Requirements

Python Version: 3.10 or higher is required.

Additional Requirements:

  • Git installed and available in PATH
  • GitHub Personal Access Token (for private repos and higher rate limits)

๐ŸŽฏ From PyPI (Recommended)

The easiest way to install Farmore is from the Python Package Index (PyPI):

pip install farmore

This is the recommended method for end users. Once installed, the farmore command will be available globally.

Verify installation:

farmore --version
farmore --help

๐Ÿงช From TestPyPI (Pre-release Testing)

To test pre-release versions before they're published to PyPI:

pip install --index-url https://test.pypi.org/simple/ farmore

When to use this:

  • Testing new features before official release
  • Helping with beta testing
  • Verifying bug fixes in development versions

Note: TestPyPI packages may not have all dependencies available. You might need to install dependencies from regular PyPI separately.


๐Ÿ“ฅ From GitHub Releases (Specific Versions)

Download a specific version from the GitHub Releases page:

  1. Download the .whl file from the release you want (e.g., farmore-0.3.0-py3-none-any.whl)
  2. Install the downloaded file:
pip install farmore-0.3.0-py3-none-any.whl

When to use this:

  • You need a specific version
  • You want to verify package integrity
  • You're installing in an offline environment (download first, install later)

Alternative - Source distribution:

# Download the .tar.gz file instead
pip install farmore-0.3.0.tar.gz

๐Ÿ”ง From Source (Development)

For developers who want to contribute or modify the code:

# Clone the repository
git clone https://github.com/miztizm/farmore.git
cd farmore

# Install in editable mode (changes to code take effect immediately)
pip install -e .

# Or install with development dependencies (recommended for contributors)
pip install -e ".[dev]"

Development dependencies include:

  • pytest - Testing framework
  • pytest-cov - Code coverage
  • ruff - Linting and formatting
  • mypy - Type checking
  • Additional testing utilities

Verify installation:

farmore --version
farmore --help

๐Ÿ”„ Upgrading

To upgrade to the latest version:

# From PyPI
pip install --upgrade farmore

# From TestPyPI
pip install --upgrade --index-url https://test.pypi.org/simple/ farmore

๐Ÿ—‘๏ธ Uninstalling

To remove Farmore:

pip uninstall farmore

๐Ÿš€ Quick Start

# Backup all repos for a user
farmore user miztizm

# Backup a single repository
farmore repo microsoft/vscode

# Search and clone repositories by keyword
farmore search "nuxt laravel" --limit 10

# Backup with issues and pull requests
farmore repo miztizm/hello-world --include-issues --include-pulls

# Backup everything for a repository
farmore repo python/cpython --all

# Backup all repos for an organization
farmore org github --include-issues --include-pulls

# With authentication (recommended)
export GITHUB_TOKEN=ghp_your_token_here
farmore user miztizm

"They say privacy is dead. Prove them wrong. Use a token." โ€” schema.cx


๐Ÿ”‘ Authentication

Farmore uses GitHub Personal Access Tokens (PAT) for authentication. Tokens provide:

  • Access to private repositories
  • Higher rate limits (5,000 vs 60 requests/hour)
  • Organization repository access

Creating a Token

โญ Recommended: Use Classic Personal Access Token

  1. Create a Classic PAT: https://github.com/settings/tokens

    • Click "Tokens (classic)" โ†’ "Generate new token (classic)"
    • Give it a name: farmore-backup
    • Select scope: โœ… repo (required for private repositories)
    • Optional: โœ… delete_repo (only if using farmore delete command)
    • Click "Generate token" and copy it immediately
  2. Set environment variable:

# Linux/macOS
export GITHUB_TOKEN=ghp_your_token_here

# Windows PowerShell
$env:GITHUB_TOKEN="ghp_your_token_here"

# Or create a .env file in the project directory
echo "GITHUB_TOKEN=ghp_your_token_here" > .env

Why Classic PAT?

  • โœ… Simple setup (just check repo scope)
  • โœ… Works with all repository types (personal + organization)
  • โœ… Proven reliability
  • โœ… Broader API compatibility

Rate Limits

Mode Requests/Hour Use Case
โŒ Unauthenticated 60 Small public repos only
โœ… Authenticated 5,000 Production, private repos

Security Best Practices

  • โœ… Use environment variables or .env files
  • โœ… Set token expiration (90 days recommended)
  • โœ… Use minimal required permissions
  • โŒ Never commit tokens to version control
  • โŒ Avoid --token flag (exposes in shell history)

๐Ÿ“š Commands

Farmore provides 14 commands organized into 4 categories:

๐Ÿ”„ Repository Backup

farmore user <username>

Backup all private and public repositories for a GitHub user.

# Backup all repos
farmore user miztizm

# Backup with data exports
farmore user miztizm --include-issues --include-pulls

# Filter by visibility
farmore user miztizm --visibility public

# Dry run
farmore user miztizm --dry-run

Key Options: --visibility, --include-forks, --include-archived, --include-issues, --include-pulls, --include-workflows, --include-releases, --include-wikis, --max-workers, --dry-run

farmore org <orgname>

Backup all repositories for an organization. Same options as user.

farmore repo <owner>/<repo>

Backup a single repository with optional data exports.

# Just clone
farmore repo microsoft/vscode

# Clone + data
farmore repo microsoft/vscode --include-issues --include-pulls

# Everything
farmore repo python/cpython --all

Key Options: --include-issues, --include-pulls, --include-workflows, --include-releases, --include-wikis, --all

farmore search <query> ๐Ÿ†•

Search GitHub repositories by keyword and clone matching results.

# Basic search - clone top 10 results
farmore search "smsbomber"

# Search with filters
farmore search "machine learning" --language python --min-stars 1000 --limit 20

# Search and auto-confirm (skip prompt)
farmore search "react components" --limit 5 --yes

# Custom output directory
farmore search "awesome-python" --output-dir ./my-collections --limit 15

# Sort by stars (descending)
farmore search "cli tools" --language go --sort stars --order desc --limit 25

# Flat structure (no owner subdirectories)
farmore search "react hooks" --flat-structure --limit 10

Key Options:

  • --limit (1-100): Maximum repositories to clone (default: 10)
  • --language: Filter by programming language (e.g., "python", "javascript", "go")
  • --min-stars: Minimum number of stars required
  • --sort: Sort order - "best-match" (default), "stars", "forks", or "updated"
  • --order: Sort direction - "desc" (default) or "asc"
  • --yes / -y: Skip confirmation prompt
  • --output-dir: Custom output directory (default: ./search-results/<query>/)
  • --flat-structure: Clone repos directly without owner subdirectories
  • --workers: Number of parallel workers for cloning (default: 4)

Output Structure (Default):

search-results/
โ””โ”€โ”€ <sanitized-query>/
    โ”œโ”€โ”€ <owner1>/
    โ”‚   โ””โ”€โ”€ <repo1>/
    โ”œโ”€โ”€ <owner2>/
    โ”‚   โ””โ”€โ”€ <repo2>/
    โ””โ”€โ”€ <owner3>/
        โ””โ”€โ”€ <repo3>/

Output Structure (Flat - with --flat-structure):

search-results/
โ””โ”€โ”€ <sanitized-query>/
    โ”œโ”€โ”€ <repo1>/
    โ”œโ”€โ”€ <repo2>/
    โ””โ”€โ”€ <repo3>/

Note: When using --flat-structure, repositories with duplicate names will have their owner appended (e.g., repo-owner) to avoid conflicts.

Rate Limits:

  • Search API: 30 requests/minute (authenticated users)
  • Unauthenticated: 10 requests/minute

Note: The search command uses GitHub's search API with support for advanced search qualifiers. You can also use GitHub's native search syntax directly in the query (e.g., "language:python stars:>1000").


๐Ÿ“Š Data Export

farmore issues <owner>/<repo>

Export issues to JSON/YAML.

farmore issues microsoft/vscode
farmore issues miztizm/hello-world --state open --include-comments

Options: --format [json|yaml], --state [all|open|closed], --include-comments

farmore pulls <owner>/<repo>

Export pull requests to JSON/YAML.

farmore pulls microsoft/vscode
farmore pulls miztizm/hello-world --state open --include-comments

Options: --format [json|yaml], --state [all|open|closed], --include-comments

farmore workflows <owner>/<repo>

Backup GitHub Actions workflows.

farmore workflows microsoft/vscode
farmore workflows actions/checkout --include-runs

Options: --include-runs

farmore releases <owner>/<repo>

Download releases and assets.

farmore releases microsoft/vscode
farmore releases nodejs/node --download-assets

Options: --download-assets

farmore wiki <owner>/<repo>

Clone repository wiki.

farmore wiki python/cpython

๐Ÿ” Profile & Discovery

farmore profile [username]

Export user profile.

farmore profile              # Your profile
farmore profile miztizm      # Another user's profile

Options: --format [json|yaml]

farmore starred [username]

Mirror starred repositories.

farmore starred              # Your starred repos
farmore starred miztizm      # Another user's starred repos

farmore watched [username]

Mirror watched repositories.

farmore watched

๐Ÿ” Security & Management

farmore secrets <owner>/<repo>

Export repository secret names (values never exposed).

farmore secrets miztizm/farmore

Options: --format [json|yaml]

farmore delete <owner>/<repo>

Delete a repository (requires confirmation).

farmore delete miztizm/old-project
farmore delete miztizm/test-repo --force  # Skip confirmation

โš ๏ธ Warning: Requires delete_repo scope in your GitHub token.


๐Ÿ“‚ Directory Structure

Farmore organizes backups with a clean structure that separates code from metadata:

backups/
โ””โ”€โ”€ <username>/
    โ”œโ”€โ”€ profile.json                          # User profile
    โ”œโ”€โ”€ repos/                                # Git repositories
    โ”‚   โ”œโ”€โ”€ private/<owner>/<repo>/
    โ”‚   โ”œโ”€โ”€ public/<owner>/<repo>/
    โ”‚   โ”œโ”€โ”€ starred/<owner>/<repo>/
    โ”‚   โ”œโ”€โ”€ watched/<owner>/<repo>/
    โ”‚   โ”œโ”€โ”€ organizations/<owner>/<repo>/
    โ”‚   โ””โ”€โ”€ forks/<owner>/<repo>/
    โ””โ”€โ”€ data/                                 # Metadata
        โ”œโ”€โ”€ issues/<owner>_<repo>_issues.json
        โ”œโ”€โ”€ pulls/<owner>_<repo>_pulls.json
        โ”œโ”€โ”€ workflows/<owner>_<repo>/
        โ”œโ”€โ”€ releases/<owner>_<repo>/
        โ”œโ”€โ”€ wikis/<owner>_<repo>.wiki/
        โ””โ”€โ”€ secrets/<owner>_<repo>_secrets.json

Example:

# After: farmore user miztizm --include-issues --include-pulls
backups/miztizm/
โ”œโ”€โ”€ profile.json
โ”œโ”€โ”€ repos/
โ”‚   โ”œโ”€โ”€ public/miztizm/farmore/
โ”‚   โ””โ”€โ”€ private/miztizm/secret-project/
โ””โ”€โ”€ data/
    โ”œโ”€โ”€ issues/
    โ”‚   โ”œโ”€โ”€ miztizm_farmore_issues.json
    โ”‚   โ””โ”€โ”€ miztizm_secret-project_issues.json
    โ””โ”€โ”€ pulls/
        โ”œโ”€โ”€ miztizm_farmore_pulls.json
        โ””โ”€โ”€ miztizm_secret-project_pulls.json

๐Ÿ”ง How It Works

  1. Discovery - Uses GitHub API to find repositories
  2. Filtering - Applies visibility, fork, and archived filters
  3. Parallel Processing - Processes multiple repos simultaneously
  4. Smart Cloning - Tries SSH first, falls back to HTTPS
  5. Progress Reporting - Real-time progress with rich output
  6. Summary - Final statistics and error reporting

Key Features:

  • Incremental backups - Updates existing repos, clones new ones
  • Error resilience - Continues even if individual repos fail
  • Rate limit aware - Handles GitHub API limits automatically
  • Organized output - Auto-categorizes by type

๐Ÿ› ๏ธ Development

Setup

git clone https://github.com/miztizm/farmore.git
cd farmore
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate
pip install -e ".[dev]"

Testing

pytest                                    # Run all tests
pytest --cov=farmore --cov-report=html   # With coverage
pytest tests/test_github_api.py          # Specific test

Code Quality

black farmore/        # Format
ruff check farmore/   # Lint
mypy farmore/         # Type check

๐Ÿ“„ License

MIT License - see LICENSE file for details.


๐Ÿค Contributing

Contributions welcome! Please:

  1. Check existing issues and PRs
  2. Follow the existing code style
  3. Add tests for new features
  4. Update documentation

๐Ÿ’ฌ Support

  • ๐Ÿ› For bugs, Issues
  • ๐Ÿ“ฉ For questions, Email

๐ŸŒŸ Acknowledgments

Built with Typer, Rich, Requests, and PyYAML.


"Control is an illusion. But backups? Those are real." โ€” schema.cx

Made with ๐Ÿฅ” by miztizm

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

farmore-0.10.0.tar.gz (129.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

farmore-0.10.0-py3-none-any.whl (107.3 kB view details)

Uploaded Python 3

File details

Details for the file farmore-0.10.0.tar.gz.

File metadata

  • Download URL: farmore-0.10.0.tar.gz
  • Upload date:
  • Size: 129.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for farmore-0.10.0.tar.gz
Algorithm Hash digest
SHA256 8b5c6326493f10c3e134b2d4fea2525bd56d2d8d7ba353ae783078600d2d9350
MD5 d281d72baa724a0cdbd01a49d99a37c1
BLAKE2b-256 1c72c37b6913607f524074b683e93ddcfd6769cba51bd3cf7313641a7b6ccfcd

See more details on using hashes here.

File details

Details for the file farmore-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: farmore-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 107.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for farmore-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d8f1c07778ac6ab30844af9ebfc4a6e0806f8d25c55106f2bbcb6c2a6adde9b7
MD5 7e5677942326737346d659b7b14d312a
BLAKE2b-256 ac465163119d21ef9cbfc4b3df2c6a64c26961ffd99886a005435d96a66465b8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page