Metadata-Version: 2.4
Name: git-third-party
Version: 0.0.1
Summary: Vendor third-party Git repositories into your own, with path filtering and local patches.
Project-URL: Homepage, https://github.com/khwstolle/git-third-party
Project-URL: Repository, https://github.com/khwstolle/git-third-party
Author: khwstolle
License: MIT License
        
        Copyright (c) 2026 Kurt Stolle
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: git,submodule,subtree,third-party,vendoring
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Go
Classifier: Topic :: Software Development :: Version Control :: Git
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# git-third-party

Vendor third-party git content into your repo as ordinary files — no submodules.

`third-party.toml` records each entry's source URL, the ref it tracks, and any filters applied. `third-party.lock` pins the resolved commits. `git-third-party update` re-fetches upstream and stages the changes.

## Why

Submodules need a second clone, complicate CI, and hide third-party code from grep, build, and IDE tooling. Subtree merges lose provenance. `git-third-party` keeps content in-tree and visible to every tool, with enough metadata to update in one command.

## Requirements

- `git`
- Go 1.21+ (build only)

## Install

Prebuilt wheels on PyPI cover `linux-amd64`, `linux-arm64`, `darwin-amd64`, `darwin-arm64`, and `windows-amd64`:

```sh
pipx install git-third-party
# or:
uvx git-third-party --version
# or:
pip install --user git-third-party
```

Build from source:

```sh
go build -o ~/.local/bin/git-third-party .
```

The binary's `git-` prefix lets you invoke it as either `git-third-party` or `git third-party`.

## Quick start

Vendor a directory tracking a remote branch:

```sh
git-third-party add third_party/zlib https://github.com/madler/zlib --follow master
git commit -m "Vendor zlib"
```

Pull updates:

```sh
git-third-party update                    # all entries
git-third-party update third_party/zlib   # one entry
git-third-party status                    # dry-run
git commit -m "Update vendored zlib"
```

List, rename, remove:

```sh
git-third-party list
git-third-party rename third_party/zlib vendor/zlib
git-third-party remove third_party/zlib
```

## Tracking a ref

Each entry tracks exactly one of:

- `--follow <branch>` — follows the branch tip, re-resolving on every `update`. Default when neither flag is set (resolved from the remote's `HEAD`).
- `--pin <tag-or-sha>` — pins to a tag (resolved once, then cached) or a commit SHA (used as-is). 40-hex-char strings count as SHAs.

Switch with `git-third-party set <dir> --pin v1.3.1` (or `--follow master`).

## Filtering content

Vendor part of an upstream repo:

```sh
git-third-party add vendor/foo https://example.com/foo.git \
    --subdir src \
    --include '*.c' --include '*.h' \
    --exclude 'tests/'
```

- `--subdir` — start from a subdirectory of the upstream repo.
- `--include` — keep only matching paths (repeatable; default keeps everything).
- `--exclude` — drop matching paths (repeatable; always wins over `--include`).

Patterns follow `gitignore` rules with documented deviations; see `git-third-party add --help` for the spec. Submodules in the upstream repo are recursively inlined unless excluded.

## Configuration files

Two files live at the repo root, both committed:

- `third-party.toml` — hand-editable intent. Each `[[third_party]]` table is one vendored directory. Each `add`/`set`/`rename`/`remove` rewrites the file, dropping any user comments.
- `third-party.lock` — generated. Records the resolved commit and any saved `tree-patch` per entry. Sorted by `dir` for stable diffs. Do not edit by hand.

Example `third-party.toml`:

```toml
# git-third-party — vendored content config.

[[third_party]]
dir = "third_party/zlib"
url = "https://github.com/madler/zlib"
follow = "master"

[[third_party]]
dir = "vendor/foo"
url = "https://example.com/foo.git"
pin = "v1.3.1"
subdir = "src"
include = ["*.c", "*.h"]
exclude = ["tests/"]
```

Corresponding `third-party.lock`:

```toml
# git-third-party lockfile — generated; do not edit by hand.
version = 1

[[third_party]]
dir = "third_party/zlib"
commit = "abc123..."

[[third_party]]
dir = "vendor/foo"
commit = "def456..."
```

## Commands

| Command | Aliases | Purpose |
| --- | --- | --- |
| `init` | | Create an empty `third-party.toml` (most users skip this — `add` creates it). |
| `add DIR URL` | | Register a new entry and download it. |
| `set DIR …` | `edit` | Change URL, ref, or filters for an existing entry. |
| `unset DIR FIELD…` | | Clear `subdir`, `include`, or `exclude`. |
| `update [DIR]` | `up` | Re-fetch and stage updates. |
| `status [DIR]` | `st` | `update --dry-run`. |
| `list [DIR]` | `ls` | Show entries and their tracking mode. |
| `info DIR` | `show` | Print full details for one entry. |
| `rename DIR NEW_DIR` | `mv` | Move a vendored directory and update the config. |
| `remove DIR` | `rm` | Unregister a directory and `git rm -r` its content. |
| `patch save DIR` | | (unstable) Record local edits as a tree-patch. |
| `patch diff DIR` | | (unstable) Show the saved tree-patch via `git diff`. |
| `completion SHELL` | | Print a `bash`/`zsh`/`fish`/`powershell` completion script. |

### Common flags

- `-v`, `-vv`, `-q` — debug, trace, or warn-only logging.
- `--log-level=trace|debug|info|warn|error` — explicit level.
- `--log-format=text|json` — switch the stderr handler to JSON.
- `--color=auto|always|never` — honors `NO_COLOR`.
- `--dry-run` — plan without staging.
- `-f`, `--allow-dir-exists` — let `add`/`rename` write into a non-empty target.
- `--profile <path>` — write a CPU profile.
- `--json` — emit a structured `entryResult` (or array) on stdout instead of human text. Schema lives in `output.go`.
- `--commit MSG` — run `git commit -m MSG` after the command stages changes.
- `--check` (on `update`/`status`) — exit non-zero if any entry would change. Useful in CI and pre-commit hooks.

### Exit codes

| Code | Meaning |
| --- | --- |
| 0 | success |
| 1 | generic failure |
| 2 | configuration invalid (TOML parse, validation, lockfile schema mismatch) |
| 3 | network, fetch, or ref-resolution failure |
| 4 | unresolvable merge conflict during `update` |
| 5 | `--check` detected a pending change |

## Settings

Settings resolve through five layers, each overriding the previous:

1. Built-in defaults.
2. Per-user: `git config --global third-party.<key>`.
3. Per-repo: a `[settings]` table in `third-party.toml`.
4. Environment variables.
5. CLI flags.

Environment variables:

- `GIT_THIRD_PARTY_LOG_LEVEL` (`trace`/`debug`/`info`/`warn`/`error`) — same as `--log-level`.
- `GIT_THIRD_PARTY_LOG_FORMAT` (`text`/`json`) — same as `--log-format`.
- `GIT_THIRD_PARTY_COLOR` (`auto`/`always`/`never`) — same as `--color`.
- `GIT_THIRD_PARTY_UNSTABLE` — comma-separated feature names; same as `--unstable`.
- `NO_COLOR` — standard cross-tool convention; disables ANSI color even when `--color=auto`.

Unstable commands (currently the `patch` subtree) need explicit opt-in: `--unstable=patch` (`-Z patch`), `unstable = ["patch"]` under `[settings]`, or `git config --global third-party.unstable patch`.

## Shell completions

```sh
# bash
source <(git-third-party completion bash)

# zsh
git-third-party completion zsh > "${fpath[1]}/_git-third-party"

# fish
git-third-party completion fish > ~/.config/fish/completions/git-third-party.fish
```

## Editing vendored content (unstable)

Enable with `--unstable=patch` (or set the equivalent in `[settings]` or git-config — see [Settings](#settings)):

- `git-third-party --unstable=patch patch save <dir>` — record local modifications as a tree-level patch in `third-party.lock`. The patch reapplies on every `update` via a 3-way merge.
- `git-third-party --unstable=patch patch diff <dir>` — show the saved patch.

If `update` produces conflicts, the patch is stored with a `-conflicts` suffix; resolve with `git add` followed by another `patch save`. Review the resulting commits carefully — the feature is unstable for a reason.

## License

MIT — see [LICENSE](LICENSE).
