# Portage: the package manager behind emerge, and the spec that freed it

> Portage is Gentoo's package management and distribution system, written in Python with Bash, and the interesting part is not emerge but PMS, the specification that documents its behaviour so other package managers can consume the same ebuild repositories. It is a mirror repository with no GitHub releases, so most of the real documentation lives in files inside the tree.

**gentoo/portage** — [MIRROR] Package management system

- Repository: https://github.com/gentoo/portage
- Website: https://gitweb.gentoo.org/proj/portage.git
- Stars: 680 · Forks: 292
- Language: Python
- License: GPL-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/gentoo-portage

## A source based package manager built on ebuilds

Portage is the package management and distribution system for Gentoo, written in Python with Bash. The defining idea is that software is built from source on the machine that installs it, using ebuilds as the recipes, and Portage is the machinery that resolves those recipes, runs the phases, and keeps the result consistent with what the system expects. The audience is broader than Gentoo users alone. Because the Package Manager Specification standardises and documents the behaviour of Portage, ebuild repositories can be used by other package managers, which means a team can keep an ebuild tree as its source of truth even if it does not run Gentoo on the build hosts. The GitHub repository you are looking at is a mirror, and the project's own project page lives at gitweb.gentoo.org, with the specification itself hosted at dev.gentoo.org and maintained in its own git repository.

## PMS turns an implementation into a contract

The Package Manager Specification Project, abbreviated PMS, is the part of this project that generalises beyond Gentoo. The README states it plainly: PMS standardises and documents the behaviour of Portage so that ebuild repositories can be used by other package managers. That is a different kind of artefact from a tool. A tool can be reimplemented, but a specification is a promise about what an ebuild means, what the phases do, what the environment variables guarantee, and how conflicts are reported. The practical effect is that the expensive part of the Gentoo ecosystem, the accumulated ebuild corpus, is no longer locked to one implementation. It also means the specification has to be read as a separate document from the code, and that a change in Portage behaviour that contradicts PMS is a defect rather than a preference. The repository links three places to look: the Gentoo project page, the PMS document, and the PMS git repository.

## Fourteen console entry points share one dispatcher

The manifest gives a clear picture of the command surface, and every script points at the same entry function, portage.util.bin_entry_point:bin_entry_point. The list includes archive-conf, dispatch-conf, ebuild, egencache, emaint, emerge, emirrordist, env-update, fixpackages, glsa-check, gpkg-sign, portageq, quickpkg and regenworld. Each of those names hints at a distinct job. ebuild is the lower level tool for running the phases of a single ebuild, egencache regenerates the metadata cache, emirrordist mirrors a binary package tree, glsa-check relates to security advisories, and the two conf commands handle the various configuration file styles a system may have. portageq is the exception to the pattern, since it is a query interface rather than an action, and it is the tool you reach for when you want a value from the configuration without changing anything. The packaging also declares pytest markers named ft, stress and unit, which is how the test suite is divided into functional, stress and unit runs.

## Python and Bash, with optional native extensions

The dependency policy is unusually strict for a package manager. The README says Python and Bash should be the only hard dependencies, and that Python 3.9 is the minimum supported version. The manifest agrees, declaring requires-python of 3.9 or newer. On top of that sits an optional layer. Portage includes native extensions that can be built in the source tree:

```bash
    python setup.py build_ext --inplace --portage-ext-modules
```

What those extensions do is narrow and specific. They consist of libc bindings used to validate LC_CTYPE and LC_COLLATE behaviour for EAPI 6, which is the locale-sensitive part of the equation and the part that a pure Python implementation would have to approximate. If the extensions have not been built, Portage falls back to ctypes. That fallback is what keeps the hard dependency list short, at the cost of speed in exactly the locale handling the extensions exist to get right. The build itself uses meson-python as the backend, and a setup.cfg setting can switch the native extensions on for every build_ext invocation.

## Formatting and commit checks in the contributor workflow

Contributing to Portage means formatting your code with black before you open a pull request, since the project says it will probably reject a pull request that has not been run through it. The simplest enforcement is a git hook in your own checkout:

```bash
# .git/hooks/pre-commit (don't forget to chmod +x)

#!/bin/bash
black --check --diff .
```

The alternative, and the one the project points at for speed, is pre-commit, because it runs the linter over only the changed files:

```bash
emerge dev-vcs/pre-commit
pre-commit install
```

Both of those commands are Gentoo commands, which is a reminder that Portage is developed inside the distribution it ships. There is one more piece of housekeeping, aimed at repositories that adopted black after the fact. Commit 1bb64ff452 was a massive commit that simply formatted the code base, so the project suggests recording it in a blame ignore file:

```bash
git config blame.ignoreRevsFile .git-blame-ignore-revs
```

The repository already ships a .git-blame-ignore-revs file and a .pre-commit-config.yaml, so the configuration for this workflow is present in the tree.

## Where the real documentation lives, and what is missing

The README is short and points at five files in the repository root for the rest. DEVELOPING contains the code guidelines, LICENSE contains the GNU General Public License version 2, NEWS contains new features and major bug fixes for each version, RELEASE NOTES contains mainly upgrade information for each version, and TEST-NOTES contains the unit test information. That split is the answer to a question newcomers ask, which is where to look when a version changes behaviour under you: RELEASE NOTES and NEWS, in that order of specificity, rather than a changelog on a hosting site. The repository publishes no GitHub releases at all, so there is no tag to diff against and no release notes in the web interface. The rest of the tree is conventional: bin/ for scripts, cnf/ for configuration, doc/ and man/ for documentation, lib/ for the library, src/ for the meson-built native extension, misc/ and testpath/ for the rest, and a tox.ini, pylintrc, run-pylint and pyproject.toml for the tooling. A .portage_not_installed marker file at the root keeps the tree from being mistaken for an installed system.

## Licensing, mirroring and what a fork would inherit

Portage is free software distributed under the GNU General Public License version 2, and the README spells out the usual redistribution terms along with the warranty disclaimer, which is worth reading if you plan to run a modified copy on a fleet of build hosts. Because the code is GPL-2.0, a fork that links or embeds it inherits copyleft obligations on the combined work, and that is a question for your own counsel rather than for this article. On the operational side, the GitHub copy is explicitly a mirror and the authoritative history is at gitweb.gentoo.org, so a contributor should clone the gitweb repository rather than this one to avoid pushing to a mirror that discards commits. The last push to the mirror was on 2026-10-20, and the tree carries a .builds/ directory and a .github/ directory with a CI workflow badge, so continuous integration runs against this copy even though changes flow the other way. There is also a .editorconfig and a .gitattributes, which are small things but the kind of thing a project that has had a continuous integration badge for years tends to have.

## Conclusion

Portage suits Gentoo users and developers who need the ebuild ecosystem to keep working, and teams that want to consume those ebuild repositories through their own tooling thanks to PMS. It is a poor fit for a machine that only needs binary packages, since Portage is built around building from source. Before depending on it, read the NEWS, RELEASE NOTES and TEST-NOTES files in the tree, since the repository publishes no GitHub releases and its upgrade information lives there, and remember that this GitHub copy is a mirror of gitweb.gentoo.org.

## FAQ

### What are the dependencies of Portage?

Python and Bash should be the only hard dependencies, and Python 3.9 is the minimum supported version. Native extensions for libc bindings are optional, and Portage falls back to ctypes when they are not built.

### What is PMS and why does it matter for Portage?

The Package Manager Specification Project standardises and documents the behaviour of Portage so that ebuild repositories can be used by other package managers. It is maintained separately at dev.gentoo.org and in its own git repository.

### How do I build Portage's native extensions?

Run python setup.py build_ext --inplace --portage-ext-modules in the source tree. The extensions are libc bindings used to validate LC_CTYPE and LC_COLLATE behaviour for EAPI 6, and a setup.cfg setting can enable them for every build_ext invocation.

### How is the Portage test suite organised?

The project configuration declares three pytest markers: ft for functional tests, stress for stress tests and unit for unit tests, each selectable with the -m flag. Details about the unit tests are kept in the TEST-NOTES file at the repository root.

## Sources

- [gentoo/portage on GitHub](https://github.com/gentoo/portage)
- [Issues](https://github.com/gentoo/portage/issues)
- [License: GPL-2.0](https://github.com/gentoo/portage/blob/master/LICENSE)
- [Project website](https://gitweb.gentoo.org/proj/portage.git)
- [README](https://github.com/gentoo/portage/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gentoo-portage
