Skip to content

feat(add): copy gitignored build artifacts from a source worktree on create #124

@lugassawan

Description

@lugassawan

Summary

Add a [copy_ignored] config section and corresponding copy logic so newly-created worktrees can inherit gitignored build artifacts (node_modules/, target/, .next/, dist/, vendor/) from a source worktree. Use reflinks/CoW where available to keep the copy instantaneous and disk-cheap.

Motivation

Currently copy_files handles a small, explicit list of tracked or config-adjacent files (.env, CLAUDE.md). It has no gitignore awareness — internal/fileutil/copy.go:93 skips symlinks but otherwise copies every entry passed to it.

Build artifacts are the biggest cold-start cost in a new worktree. For a Node monorepo, npm install takes minutes; for Rust, cargo build can take 10+ minutes. Rimba already has copy-on-write dependency cloning (internal/deps/) for lockfile-resolved deps, so the concept of sharing state across worktrees is in-bounds. This extends the pattern to arbitrary gitignored artifacts.

Worktrunk's wt step copy-ignored validates the primitive.

Config surface (.rimba/settings.toml)

[copy_ignored]
source = "main"   # "main" (default) | task name | branch name | "latest"
patterns = [
  "**/node_modules/",
  "**/target/",
  ".next/",
  "dist/",
  "vendor/",
]
strategy = "auto"   # auto | reflink | hardlink | copy

strategy = "auto" tries reflink → hardlink → plain copy per-entry.

CLI surface

rimba add feat/x                 # honours [copy_ignored] from config on create
rimba sync-ignored feat/x        # re-sync from source after source advances
rimba add feat/x --no-copy-ignored

Implementation

  • internal/config/config.go — add CopyIgnored section; validate patterns compile.
  • internal/fileutil/reflink.go (new, platform-gated) — ReflinkFile(src, dst) using ioctl(FICLONE) on Linux / clonefile on macOS. Fall through to os.Link (hardlink), then existing Copy as last resort.
  • internal/fileutil/ walker — match patterns against source worktree, preserve dir structure, skip destinations that already exist unless --force.
  • cmd/add.go — after worktree creation, if [copy_ignored] is configured and not --no-copy-ignored, resolve source worktree path and invoke the walker.
  • cmd/sync_ignored.go (new) — standalone command with --force to overwrite existing destinations.

Error handling

  • Source worktree missing → warn and continue worktree creation.
  • Reflink unsupported on filesystem → silently degrade to hardlink → copy.
  • Partial copy on failure → leave partial state; log a hint to re-run sync-ignored --force.

Out of scope

  • Watching source for changes and auto-syncing. Manual sync-ignored only.
  • Cross-filesystem deduplication (reflinks require same FS; document this).
  • GC/compaction of orphaned hardlinks.

Files likely touched

  • internal/config/config.go — new section.
  • internal/fileutil/reflink.go (new, + _linux.go, _darwin.go, _other.go build tags).
  • internal/fileutil/copy_ignored.go (new) — pattern walker.
  • cmd/add.go — invoke on create.
  • cmd/sync_ignored.go (new).
  • tests/e2e/copy_ignored_test.go (new).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions