Skip to content

Repository files navigation

Git third party

Patch third-party libraries without forking them.

standard-readme compliant License: GPL v3

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

About

Tool for patching third-party dependencies without need to fork them

Topics

Resources

Stars

Watchers

Forks

Releases

Contributors

Languages