Skip to content

Strategies

Each vendored target has a strategy. The default is subtree because it gives the project a portable, reviewable copy of upstream source.

Use subtree when the source is small enough to commit and you want every clone of your project to include it.

Terminal window
ingraft add effect --strategy subtree

Use submodule when the upstream repository is large or you want a pinned git relationship without copying its contents into your own history.

Terminal window
ingraft add rust-lang/rust --strategy submodule

Submodules are also the preferred strategy when the vendor is meant to be edited. Use a fork URL and a branch in that fork so vendor patches live as normal commits that can be pushed and upstreamed:

Terminal window
ingraft add your-org/effect --strategy submodule --ref vendor-patches

See Editable Vendors for the full workflow.

Use clone-ignore when source should exist locally for agents and LSPs but should not be committed.

Terminal window
ingraft add Effect-TS/effect --strategy clone-ignore

If the project has a colocated jj repository, the CLI falls back to clone-ignore because jj does not yet support git subtree and submodule workflows directly.

Large or irrelevant files can be filtered during vendoring when the strategy supports it:

Terminal window
ingraft add Effect-TS/effect \
--exclude "**/*.png" \
--exclude-dir docs/generated \
--max-file-size 1MB

This keeps non-source artifacts out of the vendor tree when they do not help the coding workflow.

Ownership modelRecommended strategy
Read-only reference sourcesubtree
Editable vendor with a fork or upstream PR pathsubmodule
Local scratch checkoutclone-ignore

The default subtree path optimizes for agent visibility. The fork-backed submodule path optimizes for patch ownership.