Skip to content

V2 fails to honor **/target/ Git ignore rules in FFF indexing #43987

Closed

Description

@altendky

Description

OpenCode V2's FFF index fails to honor valid anchored, directory-only wildcard rules such as **/target/ from a repository's root .gitignore.

Git correctly excludes matching paths, but OpenCode/FFF still indexes and returns them from /api/fs/find. On Linux, FFF consequently registers inotify watches throughout the excluded tree, causing unnecessary watch and memory usage.

Expected: Files and directories matching **/target/ are absent from FFF search results and are not watched.

Actual: In one reproduction, FFF indexed at least 11,160 files and 864 directories under rust/target. The server's FFF inotify descriptor contained 1,164 directory watches, including 867 under that excluded tree.

OpenCode currently pins both FFF packages to 0.10.1:

"@ff-labs/fff-bun": "0.10.1",
"@ff-labs/fff-node": "0.10.1",

FFF is initialized for eligible Git-backed locations with content indexing disabled and live watching left enabled:

export const fffLayer = Layer.effect(
Service,
Effect.gen(function* () {
const location = yield* Location.Service
const result = yield* Effect.try({
try: () =>
Fff.create({
basePath: location.directory,
aiMode: true,
disableMmapCache: true,
disableContentIndexing: true,
}),
catch: (cause) => cause,
}).pipe(
Effect.catch((error) => Effect.logWarning("failed to initialize fff", { error }).pipe(Effect.as(undefined))),
)
if (!result?.ok) {
if (result) yield* Effect.logWarning("failed to initialize fff", { error: result.error })
return Service.of({
find: () => Effect.succeed([]),
})
}
yield* Effect.addFinalizer(() => Effect.sync(() => result.value.destroy()).pipe(Effect.ignore))

export const layer = (options?: Options) =>
Layer.unwrap(
Effect.gen(function* () {
if (options?.fff === false || (options?.fff === undefined && process.platform === "win32") || !Fff.available())
return ripgrepLayer
const location = yield* Location.Service
// Non-VCS locations can contain many repositories, so avoid eagerly content-indexing the entire aggregate tree.
return location.vcs && !Protected.isHome(location.directory) ? fffLayer : ripgrepLayer
}),

Root cause: FFF 0.10.1 uses zlob 1.6.1. Its fast matcher treats the anchored, directory-only **/target/ pattern as a literal prefix comparison and returns before wildcard segment matching. zlob 1.6.2 fixes this, and FFF 0.10.3 is the first stable FFF release containing that upgrade. FFF 0.10.4 and 0.10.5 retain the fix.

FFF PR #742 concerns separate global/info-exclude parity work and is not the cause of this root .gitignore failure.

Proposed resolution: Upgrade @ff-labs/fff-bun and @ff-labs/fff-node together to at least 0.10.3, preferably the selected current stable compatible release. Add a regression test proving nested files and directories matching **/target/ are absent from FFF results, and verify that a fresh V2 server does not watch the excluded tree. The upstream release lineage is established, but the upgrade has not yet been smoke-tested in OpenCode.

Workaround: OPENCODE_DISABLE_FFF=1 selects ripgrep behavior, but loses FFF incremental search performance. Post-filtering results would not remove the underlying scanning, index memory, or watch overhead.

Plugins

None required.

OpenCode version

V2 at commit b3d60633293d14310084dbb9abd919c1243319ba.

Steps to reproduce

  1. On Linux, create or use a Git repository containing a nested target directory, such as rust/target/debug/deps.

  2. Add this rule to the root .gitignore:

    **/target/
  3. Confirm Git applies the rule:

    git check-ignore -v rust/target rust/target/debug rust/target/debug/deps
  4. Launch OpenCode V2 with --standalone. This is only to isolate the server process being measured.

  5. Query that server's /api/fs/find endpoint for paths beneath rust/target.

  6. Observe that excluded files and directories are returned.

  7. Inspect the server's inotify descriptor and observe watches beneath rust/target.

Screenshot and/or share link

Not applicable. This is reproducible through filesystem search results and the server's inotify descriptors.

Operating System

Linux.

Terminal

Terminal-independent.

Activity

  1. github-actions commented on Aug 21, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    These are distinct bugs with different root causes, so this issue may still warrant its own fix (upgrading fff to pick up the zlob 1.6.2 fix), but the linked issues share context and the inotify watch overhead symptom.

  2. altendky commented on Aug 21, 2026

    @altendky
    ContributorAuthor

    i just verified the excessive watches are gone. thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions