- Python 91.5%
- Nix 8.5%
|
Some checks failed
CI / ci (push) Has been cancelled
Patch files were named by their position in the series, so inserting a patch rewrote every file after it. The name is now the Crockford Base32 SHA-3 digest of the patch bytes and the order lives in the manifest; the legacy layout migrates in place on the next save or update. Rename `.git-third-party/config.json` to `manifest.json` in the same migration: nothing in that file is configuration. The old name is still read, and dropped once the new one is written -- unless it describes a repo the manifest does not, which is refused rather than deleted. `git am` is pinned against local config that would rewrite what a patch applies (`--keep-cr`, `--whitespace=nowarn`, `--no-3way`), and the tool now keeps a `.gitattributes` in `.git-third-party` so the enclosing repository can not normalize the bytes its patch names are derived from. |
||
|---|---|---|
| .github/workflows | ||
| docs/contributing | ||
| support/scripts | ||
| tests | ||
| .coveragerc | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| collect-sources.nix | ||
| flake.lock | ||
| flake.nix | ||
| git-third-party | ||
| LICENSE | ||
| LICENSE.lgpl | ||
| README.md | ||
| ruff.toml | ||
Git third party
Patch third-party libraries without forking them.
Background
git-third-party is a small zero-dependency utility that is an alternative to
git-submodules and
git-subtree.
It stores only the delta (your changes) inside your tree, not the full vendored
source.
It is not oriented for highly concurrent modification of third-party tools by multiple users.
Install
With Nix (flakes):
nix profile install github:kp2pml30/git-third-party
Or just drop the single script on your PATH — it needs only python3 and
git:
curl -o ~/.local/bin/git-third-party https://raw.githubusercontent.com/kp2pml30/git-third-party/main/git-third-party
chmod +x ~/.local/bin/git-third-party
Usage
# add a third-party repository
git-third-party add third-party/RustPython https://github.com/RustPython/RustPython.git a13b99642b0bc13ca89d01768a7ddbec18fe8219
# ^ git-third-party add <relative path> <repository url> <commit hash>
# now modify it as a regular repository, and commit your changes
# save patches to push to your origin
git-third-party save third-party/RustPython
# ^ git-third-party save <relative path>
# reapply patches (e.g. on a fresh checkout)
git-third-party update third-party/RustPython
# ^ git-third-party update <relative path>
Without installing, you can run it straight from the flake:
nix run github:kp2pml30/git-third-party -- add third-party/RustPython <url> <commit>
How it works
It stores a manifest under /.git-third-party/manifest.json that describes all
third-party repositories and their patches. save updates the patches, update
reapplies them. Older versions called that file config.json; it is still read,
and renamed the next time the tool writes.
Patch files are content addressed: the file name is the SHA-3 digest of the
patch bytes, in Crockford Base32 (case-insensitive and safe in paths). The order
of the series lives in manifest.json, so editing history in the middle of a
series renames nothing — only the patches that actually changed show up in a
diff. Repositories saved by an older version, which numbered patches 1, 2,
3, …, are migrated in place by the next save or update.
The .git-third-party directory must be tracked by git, while the third-party
working trees themselves should not be. The tool keeps a .gitattributes and a
.gitignore of its own in there: patch bytes are what their names are derived
from, so the enclosing repository must not normalize their line endings. Commit
those alongside the manifest.
Each managed checkout gets its push url disabled (origin fetches from
upstream, but pushing fails), so local patch commits can not accidentally be
pushed to the third-party project.
Best effort is made to keep patches deterministic and to strip metadata from them, including:
- git version
- commit hash (which depends on the committer)
- …
Contributing
See docs/contributing/.
License
GPL-3.0 (C) 2024-2026 Kira Prokopenko