git-sprout 0.1.1

A drop-in git worktree add that materialises the tree with filesystem copy-on-write clones
Documentation

git-sprout

Stop paying for the same tree twice. A drop-in replacement for git worktree add that doesn't copy your tree.

Website · Repository · Sponsor

Every worktree you create is a second full copy of your repository on disk. git-sprout materialises the new worktree with filesystem copy-on-write clones of a checkout you already have, instead of inflating every blob out of the object store into fresh blocks. The clone shares disk blocks with the source until something writes to them, so the second worktree costs almost nothing until it diverges.

The pitch is disk, not speed. One worktree of the Linux kernel —

meaningful difference in wall clock. That is

time anyone creates one.

Install

cargo install git-sprout

Or brew install alltuner/tap/git-sprout, or a binary from the releases page.

That puts git-sprout and git-worktree-fast on your PATH, where git picks them up as subcommands:

git sprout add ../myrepo-feature -b feature     # or: git worktree-fast add

What has to be true

The filesystem needs block cloning: APFS on macOS; btrfs, XFS with reflinks, or bcachefs on Linux; a ReFS volume or a Windows 11 Dev Drive on Windows. Everywhere else, ext4 and NTFS included, it runs plain git worktree add.

And the repository has to be one that does not convert files on checkout, because a file can only be shared when checking it out would not rewrite its bytes. core.autocrlf, which Git for Windows turns on by default, and * text=auto eol=crlf on any platform both leave nothing to share. Repositories with no conversion attributes clone everything, which is the common case on macOS and Linux, the kernel included.

Measuring it yourself

One property will otherwise waste your afternoon. A repository that arrives as a copy accelerates nothing until its stat cache is rebuilt. git sprout add clones a file only when git already considers the source's copy unmodified, which it decides from the inode, size and mtime recorded in the index. A cp -r, an rsync, a container image layer, a restored CI cache or an unpacked tarball gives every file a new inode and a fresh mtime, so every entry looks modified even though every byte is identical. The plan comes back empty, the worktree is still correct, and nothing is shared.

Run this once in the source repository first, and the numbers appear:

git update-index --refresh

Ask for the counts if you want to be certain a run actually cloned:

SPROUT_STATS=1 git sprout add ../wt -b feature   # cloned=… on stderr

Compatibility

git sprout add is meant to be indistinguishable from git worktree add in every observable way except time and disk. Same flags, same stdout, same exit codes, same hooks in the same order, same files and modes and index. Your repository's configuration is never modified, and any flag it does not fully understand is handed to git rather than refused.

That contract is compared against real git worktree add on every commit, across a matrix of repository fixtures and argument shapes, on macOS, Linux (btrfs, XFS, ext4) and Windows (NTFS, ReFS), plus the Linux kernel on two filesystems. The two deliberate differences, and the reasoning behind the whole design, are written out in the repository README and at sprout.alltuner.com.

License

MIT.

Built by David Poblador i Garcia with the support of All Tuner Labs. If this was useful to you, consider supporting its development.