CLI tool
josegonzalez/python-github-backup avatar
josegonzalez/python-github-backup

python-github-backup: Backup Scope, Installation, and Constraints

backup a github user or organization

1,594 stars268 forksPythonMIT

At a glance

What is it?
python-github-backup is a Python CLI for archiving GitHub users and organizations, with selective repository clones and JSON exports for issues, discussions, metadata, and related content. Its coverage depends on authentication, token permissions, Git tooling, and the selected flags.
Who is it for?
Adopt python-github-backup when you need a selectable local archive of public or authorized GitHub content across repositories, issues, pull requests, discussions, releases, wikis, and related metadata. Do not treat it as a guaranteed complete export unless you confirm the selected flags, token visibility, API permissions, and required tools cover every asset you need.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What python-github-backup Captures

python-github-backup addresses local retention of GitHub content for users who need more control over repository and metadata archives than Git itself provides. A Git clone preserves the contents and history of one repository, while this project can traverse repositories associated with a GitHub user or organization and write selected categories into an output directory. The README describes an entire account or organization scope, including starred repositories, issues, discussions, and wikis, with repositories and wikis represented as clones and issues and discussions represented as JSON.

Selection is explicit. Repository clones require `--repositories`, bare clones require `--bare`, and wiki clones require `--wikis`. Issues, comments, events, timelines, pull requests, reviews, commits, labels, hooks, milestones, security advisories, releases, and assets each have separate flags. Account-level material such as starred repositories, watched repositories, followers, following users, gists, and starred gists is also opt-in through distinct options.

This design suits a targeted archival policy. An organization can retain source histories and discussion records without exporting every optional category. The trade-off is that the operator must define the policy correctly. The help text describes `--all` as including everything, but it marks several options as exceptions. The individual flags are the more precise expression of intended scope.

Authentication and GitHub Access Boundaries

Every backup is constrained by what the supplied credentials can see. The CLI accepts a classic personal access, OAuth, or JSON Web token through `-t` or `--token`. It also accepts a fine-grained personal access token through `-f` or `--token-fine`, can read a token from GitHub CLI with `--token-from-gh`, and can authenticate as a GitHub app with `--as-app`.

The README documents token paths using the `file://` form and macOS Keychain lookup through `--keychain-name` and `--keychain-account`. These options change where the token comes from, not what the archive necessarily contains. Private repositories requested with `--private` remain subject to the permissions associated with the authenticated identity. Hooks are documented as working only when authenticated. The README does not provide a complete token permission matrix for organizations, repositories, or GitHub apps.

For organizations, `-O` marks the target as an organization. `-R` limits processing to one named repository. `-N` applies a Python regular expression to names, while `-L` restricts allowed languages. These filters can reduce API work and archive size, but they also make completeness dependent on matching rules. A regular expression that omits a repository cannot be detected from successful command completion alone.

The README does not clearly state whether a token is optional for public content without private-repository requests. That uncertainty matters for unattended use. Verify the intended authentication path before scheduling backups, especially when the process must access organization-owned or private repositories.

Install github-backup on Python 3.10 or Newer

The package requires Python 3.10 or higher and Git 1.9 or newer. Installation through PyPI is the documented baseline:

bash
pip install github-backup

This installs the package and registers the `github-backup` console script defined in `setup.py`. A newcomer may need to invoke the script through its installed path if the Python scripts directory is not in `$PATH`. The README gives this form as an example:

bash
~/.local/bin/github-backup

The README also documents installation directly from GitHub:

bash
pip install git+https://github.com/josegonzalez/python-github-backup.git#egg=github-backup

The expected result is a command that can display CLI help. The repository includes a Dockerfile based on `python:3.12-alpine3.22`. It installs Git and Git LFS, builds the project into `/app/.venv`, switches to the `appuser` account, and exposes `github-backup` as the container entrypoint. This is useful when an isolated runtime is needed, but the README does not document a complete `docker run` invocation.

First Use with the Documented CLI

The README provides the basic help command:

bash
github-backup -h

That command is the safest first check after installation because it exposes the options available in the installed version. The documented help output identifies the positional `USER` argument, token options, output-directory selection, repository selection, organization mode, incremental modes, metadata options, and release options.

For a real backup, the CLI requires a GitHub username or organization target. The README does not provide a complete example combining a token, output directory, and repository filter, so this article does not invent one. The documented interface shows the relevant flags: `-o` sets the output directory, `-R` limits backup to a repository, `-O` identifies an organization target, `--repositories` includes repository clones, `--issues` includes issue JSON, and `--repositories --bare` requests bare clones.

A practical first use can therefore begin with the help command, followed by a small invocation assembled from those documented options and the actual username or organization. The operator should replace all target names with values that exist and that the chosen token can access. After completion, inspect the output directory rather than assuming a particular filename layout, because the README does not specify one.

Incremental Runs, Fetch Behavior, and Large Assets

Repeated backups can use `-i` for incremental mode or `--incremental-by-files` for a file-modification-based strategy. Repository fetches normally use Git pruning, but `--no-prune` disables that behavior. This distinction matters when the desired archive should retain local references or when pruning would remove fetched objects. The README does not explain the exact comparison rules used by either incremental mode, so operators should inspect existing output before relying on it to represent every historical GitHub state.

Large assets require separate decisions. `--lfs` clones Git LFS repositories, but the help text explicitly says Git LFS must be installed. Release backups can include `--assets`, while `--skip-assets-on` excludes assets for selected release channels and `--skip-prerelease` omits prereleases. `--latest-releases NUMBER_OF_LATEST_RELEASES` limits recent releases, and `--starred-skip-size-over MB` can skip large starred repositories. These filters control transfer volume, but they define policy boundaries. A backup that skips LFS content, assets, prereleases, or repositories over a size threshold is not a byte-for-byte archive.

The CLI also provides `--throttle-limit`, `--throttle-pause`, and `--retries MAX_RETRIES`. The README does not state their units, defaults, or interaction. They should be adjusted only after confirming behavior in `github-backup -h` and reviewing logs. Increasing retries can prolong a failed run, while an unsuitable throttle configuration can slow transfer or increase request pressure.

Backup Limitations and Manual Git Comparison

The main limitation is that backup completeness depends on flags, credentials, external tools, and GitHub-side visibility. The project can request an extensive set of content, but the README does not document guarantees around deleted resources, inaccessible organization data, transient API failures, or restoration. It also does not document a rollback or restore command. This is a backup-oriented exporter, not a documented mirror of every possible GitHub state.

Several narrower constraints are explicit. `--hooks` works only when authenticated. Git LFS depends on a separate installation. SSH cloning through `--prefer-ssh` depends on working SSH credentials and host configuration. macOS Keychain options apply only on macOS. Existing output directories can be skipped with `--skip-existing`, and archived projects can be omitted with `--skip-archived`. Each option can prevent selected data from entering a new archive.

Manual `git clone` is a different approach for repository retention. It is simpler for one known repository and preserves Git history without requiring this project to coordinate many GitHub object categories. python-github-backup becomes more relevant when the archive must traverse a user or organization and combine repository clones with JSON metadata. If only source history is required, manual Git operations expose fewer selection and credential paths, although they do not retain issues, discussions, releases, or account metadata.

Maintenance, Licensing, and Upgrade Surface

The repository is not archived. Its last push was on 2026-10-13, and the listed releases include version 0.65.1 on 2026-08-01, 0.65.0 on 2026-07-27, and 0.64.2 on 2026-07-18. These dates indicate recent project changes, but they do not establish compatibility with every future GitHub API change. The package metadata labels the project `Development Status :: 5 - Production/Stable` and declares support for Python 3.10 through 3.14.

Upgrading can affect both the Python package and its command-line behavior. `setup.py` declares `python_requires=">=3.10"`, while the repository Dockerfile is fixed to Python 3.12 and Alpine 3.22. A deployment should check its Python version and container base before changing the image or package release. The repository includes `CHANGES.rst`, but the README does not document migration steps for each version.

The package is distributed under the MIT License, and `LICENSE.txt` is present at the repository root. That permits reuse and modification under the license's conditions, including preservation of its copyright and permission notice. It does not grant additional rights to GitHub-hosted content, and backup copies may contain private data, credentials embedded in configuration, or content subject to separate terms. This is a licensing boundary, not legal advice.

Editorial conclusion

Adopt python-github-backup when you need a selectable local archive of public or authorized GitHub content across repositories, issues, pull requests, discussions, releases, wikis, and related metadata. Do not treat it as a guaranteed complete export unless you confirm the selected flags, token visibility, API permissions, and required tools cover every asset you need. Before the first production run, verify the installed version, authentication method, output directory, and a small repository backup.

Frequently asked questions

What does python-github-backup require?

It requires Python 3.10 or higher and Git 1.9 or newer. Cloning Git LFS repositories also requires Git LFS to be installed.

How do I install python-github-backup?

The documented PyPI command is `pip install github-backup`. The README also documents installation directly from GitHub.

Does python-github-backup include issues and discussions?

They are separate options. Use `--issues` for issues and `--discussions` for discussions; issue comments, events, and timelines also have their own flags.

Can python-github-backup back up private repositories?

The `--private` option requests private repositories, but the README does not guarantee access. The authenticated identity or token must have permission to read each repository and other requested content.

Does the project document a restore or rollback command?

The README does not document a restore or rollback command. It documents backup selection, output, incremental modes, and cloning options, but not restoration behavior.

Official sources

  1. Issues
  2. josegonzalez/python-github-backup on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/josegonzalez-python-github-backup.svg)](https://hysenlabs.com/projects/josegonzalez-python-github-backup)

Was this useful?