Install a Python Package from GitHub with pip: branches, tags, SSH, and requirements.txt

Install Python packages from GitHub using pip: PEP 508 git URLs, branches, tags, commits, editable installs, requirements.txt, private repos over HTTPS or SSH, subdirectory packages, verification, upgrades, and common errors.

Published

Updated

Read time 8 min read

Reviewed byDeepak Prasad

Install a Python Package from GitHub with pip: branches, tags, SSH, and requirements.txt

You need Python, pip, and git on your PATH (install git with your distro package manager on Linux; on Windows use Git for Windows or winget install Git.Git). Prefer a virtual environment and python3 -m pip so you target the interpreter you intend. This guide uses Linux-style examples; on macOS you often use python3 and pip3 the same way.

Commands that clone from GitHub need network access and a reachable github.com. The long pip install lines below use {run=false} so the site Run control does not depend on git or outbound HTTPS.

Tested on: Python 3.13.3; kernel 6.14.0-37-generic.

The practical sequence (python3 -m venv, python3 -m pip install for @main and the pinned commit, python3 -m pip show sampleproject, and import sample) was run successfully on Ubuntu 25.04 after installing python3.13-venv and python3-pip with apt. If python3 -m venv complains about ensurepip, install the matching venv and pip packages (for example sudo apt install -y python3-venv python3-pip, or python3.13-venv on Python 3.13). A copy-paste flow for pypa/sampleproject is in the practical example section below.


Install Python package from GitHub using pip

pip can treat a Git repository as a version control (VCS) source: it runs git clone (or a shallow fetch), builds a wheel or runs setup.py / pyproject.toml metadata, and installs the discovered distribution into the active environment. That is how you install unreleased fixes, forks, or internal libraries before they appear on PyPI.


Basic pip install GitHub syntax

Modern pip accepts PEP 508 direct references: put the distribution name, @, then a git+ URL in quotes.

bash
python3 -m pip install "sampleproject @ git+https://github.com/pypa/sampleproject.git"

Older tutorials often use the legacy form without a name on the left (still supported by pip):

bash
python3 -m pip install "git+https://github.com/pypa/sampleproject.git#egg=sampleproject"

The repository must look like a Python package at the URL you give: usually a pyproject.toml and/or setup.cfg / setup.py at the repo root, or a subdirectory= path (covered later). A trimmed successful resolve looks like this (paths and hashes will vary):

text
Building sampleproject @ git+https://github.com/pypa/sampleproject.git@<commit>
Installed sampleproject-4.0.0 (from git+https://github.com/pypa/sampleproject.git@<commit>)

Official reference: VCS support in pip.


Practical example: install pypa/sampleproject

The pypa/sampleproject repository is PyPA’s official packaging demo: it ships pyproject.toml, builds cleanly, and is safe to experiment with. The distribution name on PyPI is sampleproject, but the importable package in the tree is named sample—so pip show sampleproject and import sample go together.

  1. Create and activate a virtual environment. On Debian/Ubuntu, if python3 -m venv fails because ensurepip is missing, install venv and pip first, for example sudo apt install -y python3-venv python3-pip (or python3.13-venv to match your interpreter).
bash
python3 -m venv .venv
source .venv/bin/activate
# Windows (cmd): .venv\Scripts\activate.bat
  1. Install the latest main branch with a PEP 508 URL:
bash
python3 -m pip install "sampleproject @ git+https://github.com/pypa/sampleproject.git@main"
  1. Pin an exact commit for reproducible builds (replace with your own git rev-parse output when you need a lock):
bash
python3 -m pip install "sampleproject @ git+https://github.com/pypa/sampleproject.git@621e4974ca25ce531773def586ba3ed8e736b3fc"
  1. Confirm metadata and import:
bash
python3 -m pip show sampleproject
python3 -c "import sample; print(sample.__file__)"

Typical pip show sampleproject output (paths vary by machine):

text
Name: sampleproject
Version: 4.0.0
Location: .../site-packages
Requires: peppercorn
Required-by:
  1. Drop the same URL into requirements.txt as a single line (see the requirements file guide for full files):
text
sampleproject @ git+https://github.com/pypa/sampleproject.git@main

Install package from a GitHub branch

Pin the branch with @branch after the .git (or repository) path.

bash
python3 -m pip install "sampleproject @ git+https://github.com/pypa/sampleproject.git@main"

Use the real branch name (develop, release/1.x, and so on). If the branch does not exist, git reports “not found” and pip aborts.


Install package from a GitHub tag or release

Git tags mark releases (for example v1.2.3). Put the tag after @ exactly as git tag lists it.

bash
python3 -m pip install "yourpkg @ git+https://github.com/yourorg/yourrepo.git@v1.2.3"

Confirm the tag exists with git ls-remote --tags https://github.com/yourorg/yourrepo.git before pinning it in production files.


Install package from a specific commit

Use the 40-character SHA-1 (or the short SHA git accepts) as the @ suffix for a reproducible install.

bash
python3 -m pip install "sampleproject @ git+https://github.com/pypa/sampleproject.git@621e4974ca25ce531773def586ba3ed8e736b3fc"

That pins your environment to an exact snapshot until you upgrade the URL.


Install GitHub package in editable mode

Editable installs (-e) keep the project linked into site-packages so code changes in the clone are visible immediately—useful while you contribute upstream or patch a fork.

bash
python3 -m pip install -e "git+https://github.com/pypa/sampleproject.git#egg=sampleproject"

PEP 508 style with editable is also available on recent pip:

bash
python3 -m pip install -e "sampleproject @ git+https://github.com/pypa/sampleproject.git"

Editable installs still require a proper package layout and build backend.


Add GitHub package to requirements.txt

Use the same PEP 508 line you would pass on the command line—one dependency per line. See also the pip requirements file tutorial for broader context.

text
# requirements.txt (fragment)
sampleproject @ git+https://github.com/pypa/sampleproject.git@main
anotherpkg @ git+https://github.com/org/repo.git@v2.0.0#subdirectory=packages/client

Install with:

bash
python3 -m pip install -r requirements.txt

Install package from a private GitHub repository

Private repos need authentication that git understands over HTTPS or SSH. Never commit personal access tokens (PATs) into public repos; prefer short-lived tokens, environment variables, or SSH keys.

Install using HTTPS token

GitHub supports embedding a PAT in the HTTPS URL (the token acts as the password; username is often arbitrary or git):

bash
python3 -m pip install "mypkg @ git+https://<TOKEN>@github.com/org/private-repo.git@main"

Prefer reading the token from the environment so it does not sit in shell history, for example by expanding ${GITHUB_TOKEN} in CI. Rotate tokens if they leak.

Install using SSH

If your SSH key is loaded (ssh -T git@github.com works), use an SSH-style git URL:

bash
python3 -m pip install "mypkg @ git+ssh://git@github.com/org/private-repo.git@main"

This avoids putting secrets on the command line when keys are managed by an agent.


Install a GitHub subdirectory package

Monorepos keep Python code in a subfolder. Append #subdirectory=path/to/package to the git URL (PEP 508 allows the fragment on the URL).

bash
python3 -m pip install "client @ git+https://github.com/org/monorepo.git@main#subdirectory=python/client"

The subdirectory must contain pyproject.toml or legacy packaging metadata for that distribution.


Check if the GitHub package was installed

Use pip show and a quick import test. The distribution name you pass to pip may differ from the Python import name (for pypa/sampleproject, use pip show sampleproject but import sample).

bash
python3 -m pip show sampleproject
python3 -c "import sample; print(sample.__file__)"

pip list and pip freeze also list installed versions; freeze is what many people capture for lock-style files.


Upgrade or reinstall a GitHub package

Pass --upgrade (and optionally --force-reinstall) so pip fetches the latest commit for a moving branch or reapplies a build after local changes in an editable checkout.

bash
python3 -m pip install --upgrade --force-reinstall "sampleproject @ git+https://github.com/pypa/sampleproject.git@main"

If metadata caching confuses you after a tag move, bump the pinned commit or clear pip’s cache with care (pip cache subcommands).


Common errors while installing Python packages from GitHub

git command not found

pip shells out to git. Install git (sudo apt install git on Debian/Ubuntu), open a new terminal, and confirm git --version. On minimal CI images, add a git package to the image definition.

Repository is not a Python package

If the repo is documentation-only or missing packaging metadata at the chosen path, pip stops with metadata or build errors. Clone with git clone and inspect pyproject.toml, setup.cfg, or setup.py, or set subdirectory= correctly.

Could not find pyproject.toml or setup.py

Same root cause: wrong directory, wrong branch, or the project uses a non-standard layout. Open the ref you pinned (@branch / @tag) in the browser and confirm the packaging files exist at that revision.

Authentication failed for private repository

HTTPS: token missing, expired, or lacking repo scope. SSH: host key prompts in non-interactive CI, missing deploy key, or wrong git@github.com:org/repo.git spelling. Test outside pip with git ls-remote <url>.

Branch, tag, or commit not found

Typo in @ref, renamed branch, or force-pushed history. Run git ls-remote https://github.com/org/repo.git to list refs you can pin.


pip install from GitHub quick reference table

Goal Example pattern
Latest default branch "pkg @ git+https://github.com/org/repo.git"
Branch "pkg @ git+https://github.com/org/repo.git@branch-name"
Tag "pkg @ git+https://github.com/org/repo.git@v1.2.3"
Commit "pkg @ git+https://github.com/org/repo.git@abcdef1"
Editable python3 -m pip install -e "git+https://github.com/org/repo.git#egg=pkg"
Subdirectory URL ends with #subdirectory=path/to/pkg
Private HTTPS "pkg @ git+https://TOKEN@github.com/org/repo.git@main" (prefer env var)
Private SSH "pkg @ git+ssh://git@github.com/org/repo.git@main"

Summary

Installing from GitHub with pip means passing a git+https:// (or git+ssh://) URL, optionally pinned with @branch, @tag, or @commit, and using PEP 508 Distribution @ URL form in modern requirements.txt files. Editable installs help when you hack on the source; subdirectory= covers monorepos. Private repos need HTTPS tokens or SSH keys, and most failures are missing git, wrong paths, or auth. Keep environments isolated with a venv, verify with pip show and import, and consult pip’s VCS documentation when URLs get complex. The pypa/sampleproject practical section shows a full venv flow, a commit pin, and the common case where the distribution name differs from the import package (sampleproject vs sample).


References


Frequently Asked Questions

1. How do I pip install a Python package from a specific GitHub branch?

Append @branch-name to the repository URL inside the git+https URL, for example pip install "mypkg @ git+https://github.com/org/repo.git@develop", or use the legacy form pip install git+https://github.com/org/repo.git@develop#egg=mypkg.

2. How do I install a private GitHub repository with pip?

Use a personal access token in an HTTPS URL, or prefer SSH with a URL like git+ssh://git@github.com/org/repo.git and keys loaded in your agent; avoid committing tokens into requirements files.

3. How do I put a GitHub dependency in requirements.txt?

Add one PEP 508 line per dependency such as mypkg @ git+https://github.com/org/repo.git@main or the equivalent legacy git+ line that pip documents for your pip version.
Azka Iftikhar

Computer Scientist

Proficient in multiple programming languages, including C++, Golang, and Java, she brings a versatile skillset to tackle a wide array of challenges. Experienced Computer Scientist and Web Developer, …