Repository navigation
Make forks leave out what .gitignore files ignore - #6
Merged
Merged
Conversation
A fork is everything in the directory, so a directory with a large `node_modules` or `target` takes seconds to fork, twice over, as the fork and its base each clone every file in it. On APFS, 200,000 ignored files took about 5 seconds. With the new `--skip-ignored` option of `fsfork` and `confine`, what `.gitignore` files ignore and git does not track is left out of the fork and its base, which took about 0.1 seconds on the same directory. It is an option, because warm builds are why a fork has build output. Git says what is ignored, so that the rules are its own, and the same as `fsdiff` goes by. It runs on a repository of `fsfork`'s own with no configuration, as `fsdiff`'s does, because the directory could be a fork that a confined command changed, and `confine` forks outside the sandbox. It reads the directory's index, so that tracked files stay. Directories with nothing ignored in them are still cloned whole, at once.
A fork of a directory with a large `node_modules` or `target` should be quick without having to ask for it, so what `.gitignore` files ignore is now left out unless `--no-ignore` is given, named as in `rg` and `fd`. `--skip-ignored` is gone. As `fsfork` now needs git by default, it warns and forks everything if git is not there or cannot tell what is ignored: a fork with too much in it works, and refusing to make one would not.
This was referenced Oct 30, 2026
penberg
added a commit
that referenced
this pull request
Nov 3, 2026
A fork is otherwise named after the directory and the first number not taken, `turso.1`, which says nothing about what it is for. With `-n swebench`, it is `turso.swebench`, and its base `.turso.swebench.base`, so that forks made for different things can be told apart, and a script can know where its fork is without parsing `fsfork`'s output. A named fork takes no number. ```sh cd $(fsfork -n swebench) confine -n swebench -w ~/.claude claude ``` The name cannot be empty or have `/` in it, as the fork goes next to the directory, and cannot be given with a second argument, which says where the fork goes instead. In `confine`, it cannot be given with `-d`, which runs the command without a fork. Stacked on #6, as it builds on `Contents` and `--no-ignore` from there.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A fork was everything in the directory, so a large
node_modulesortargetmade forking slow. Now a fork and its base leave out what.gitignorefiles ignore and git does not track.--no-ignore, forfsforkandconfine, forks everything as before. The name is the onergandfduse.Measured on APFS with a debug build:
--no-ignorenode_modulestarget, about 6,000 files)Asking git adds a fixed cost, so a directory with very few files forks more slowly than before: about 0.15 s for a one-file directory.
Behaviour changes
--no-ignoreis given..env, which a command in the fork may need.How it works
.gitignorefiles, as infsdiff, not.git/info/excludeor a global excludes file. Tracked files stay even if a pattern matches them..gitignorefiles above it. A directory that is itself ignored goes by its own only.fsforkwarns on standard error and forks everything.Security
confineforks outside the sandbox, and the directory may be a fork that a confined command changed, so git must not use its configuration:core.fsmonitoralone would run a command. Git runs on a temporary repository with no configuration and reads only.gitignorefiles and the index. There is a test that a configuredcore.fsmonitordoes not run.Limitations
clonefilerejects a FIFO or socket on its own, though it takes them inside a directory. Next to something ignored, FIFOs are remade, and sockets and devices are left out.main, and will touch the same lines ofconfine.rsandconfine.1as Make confine run gh for the command, each time you allow it #5, so whichever lands second needs a small rebase.Testing
cargo test,cargo clippyandcargo fmtpass on macOS, and I checked by hand that repositories with a split or sparse index fork correctly. CI runs the same tests on Linux, where the path throughcpis exercised; speed there is unmeasured.