ghp-import

A small CLI that copies a built docs directory straight onto your repo's gh-pages branch.

Tool
PyPI
v2.1.0
626stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
38/100Needs Attention
Development Activity0
Maintenance0
Community72
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
58/100Fair
Architecture55
Code Quality58
Innovation50
Learning Curve70

ghp-import is a single-file command-line tool that publishes a directory of built static files (documentation, a static site) to the gh-pages branch of a Git repository, so it can be served by GitHub Pages. It handles branch creation, commit history rewriting, and pushing in one command, and is widely used as the publishing step inside documentation toolchains like MkDocs and Sphinx.

What You Get

  • A single CLI command (ghp-import) that stages a directory as a commit on the gh-pages branch
  • Options to push directly to a remote (-p), force-push (-f), or drop prior history (-o/--no-history)
  • Support for custom target branches (-b), remotes (-r), and path prefixes (-x) for partial deploys
  • Automatic .nojekyll and CNAME file generation for GitHub Pages configuration (-n, -c)
  • No GitHub API dependency — it operates purely through local git plumbing, so it works with any git remote, not just GitHub

Common Use Cases

  • Publishing MkDocs- or Sphinx-built documentation sites to GitHub Pages as part of a CI job
  • Deploying a static site generator’s build output to gh-pages without maintaining a second worktree
  • Automating a docs build && ghp-import -np dist/ one-liner in a Makefile or GitHub Actions workflow
  • Serving custom domains for a docs site by combining ghp-import’s CNAME support with a project’s DNS setup

Under The Hood

Architecture: The entire tool lives in one module, ghp_import.py, structured as a sequence of small functions — run() shells out to the local git binary, mk_when()/rm_rf() handle timestamps and cleanup, and a main() wires up an optparse-based CLI; there’s no package layout beyond the single file, which is also why the README explicitly documents copying it standalone into other projects. Tech Stack: Pure Python 2/3-compatible code (per its python2/python3 GitHub topics) with a single runtime dependency, python-dateutil, and git itself as an external process dependency invoked via subprocess calls rather than a git binding library. Code Quality: The module is compact (~300 lines) and readable, using docstrings on public functions, but has no visible automated test suite in the cloned tree and dependency-injects very little — behavior is driven almost entirely by CLI flags rather than an importable API surface. API Design: Its entire public interface is the optparse-driven CLI documented in the README (options like -n, -c, -m, -p, -x, -f, -o, -r, -b, -s, -l); this is intentionally a tool, not a library, and its ergonomics are those of a well-documented Unix-style flag set with sensible defaults (origin/gh-pages).

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search