Spheroman / Spheroman/newgit

Render targets as real worktree files: git clean/smudge filters instead of --skip-worktree

Open
#64 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Rust
Stars
0
Forks
0
Avg merge
1h 58m
Merged PRs (30d)
48

Description

Summary

Replace --skip-worktree on source-owned render targets with a per-workspace
git clean/smudge filter, so rendered files are ordinary files in the
worktree and the substitution is reversed on every git operation instead of
the file being hidden from git entirely.

Both halves already exist: render::substitute is the smudge,
render::reverse is the clean (crates/newgit-core/src/render.rs).

Why this fits

newgit-v1-mvp.md:599"A render reads the committed content of the path,
substitutes, and writes the result. It never reads what is currently on
disk."

A smudge filter receives exactly the committed blob on stdin. The purity rule
that was derived to make render idempotent is precisely the filter contract.
Checkout becomes render.

This is also the interposition point git actually provides, rather than a
git shim — consistent with interpose or intercept commands, don't emulate,
and it avoids the command shims that v1 deliberately defers.

Mechanism

Installed per-workspace, the same shape as the .git/info/exclude handling
for tracker paths (crates/newgit-core/src/materializer.rs:72). Both files
are untracked and per-clone, so nothing lands in the repo:

# <workspace>/.git/info/attributes
packages/db/supabase/config.toml filter=newgit-render
# <workspace>/.git/config
[filter "newgit-render"]
    clean  = newgit render-clean  --workspace . -- %f
    smudge = newgit render-smudge --workspace . -- %f
    required = true

required = true is not optional: a missing or erroring newgit binary must
fail the git command loudly rather than silently committing this instance's
ports.

What this deletes

Not additive — it removes machinery:

  • --skip-worktree on source paths (crates/newgit-core/src/source.rs:213)
    and with it the whole What it costs, and saying so section
    (newgit-v1-mvp.md:661). Hand edits to a rendered source file round-trip
    and commit cleanly, because git only ever sees cleaned content. "To edit a
    rendered file for real, edit it in the store repo"
    stops being a
    limitation.
  • Drift detection — the recompute-and-compare at checkpoint and before
    re-render. It exists only to warn that an edit is about to be lost. Under
    filters the edit isn't lost.
  • The throwaway-index skip-worktree re-set
    (crates/newgit-core/src/source.rs:236) — the leak where a fresh
    GIT_INDEX_FILE doesn't carry skip-worktree bits and git add -A sweeps
    rendered ports into a checkpoint. git add -A against that index now cleans
    the content itself.

newgit export reading from HEAD stays correct either way.

What has to be gotten right

  • Round-trip must be exact. If clean(smudge(blob)) != blob byte-for-byte,
    git shows a permanent phantom modification on that file forever. The
    rendered value is already required to be unique in both directions; this
    makes it worth actually running the round-trip at bind and failing the
    bind — same class of failure as a find that matches zero times.

    Note render::reverse is deliberately lenient about counts
    (crates/newgit-core/src/render.rs:229), which is right for a clean filter
    running over a file someone edited — so the guarantee has to come from the
    bind-time check, not from the filter.

  • Value collisions now bite constantly. If allocated port 54400 happens
    to appear in the committed file for an unrelated reason, clean rewrites it
    too. Today that is a capture-time problem; under filters it is every
    git status.

  • Not everything runs filters. libgit2-based tools (JetBrains, some
    editors) and jj don't — jj has no smudge/clean support. There is no jj
    in the workspace path today (workspaces are plain clones), but given the
    project is nominally built on jj, this constrains the direction. The v2 FUSE
    projection is filter-independent and remains the real answer; this is a
    better v1 stand-in than skip-worktree, and the [[render]] declaration
    outlives both.

  • Performance: one process spawn per rendered file per git op. Only
    declared render paths, so small. filter.<name>.process (the long-running
    filter protocol) is the escape hatch if it ever shows up.

  • Not a security boundary. git -c filter.newgit-render.clean= add
    bypasses it — the same hole --skip-worktree had. Consistent with do not
    simulate security
    , but it should be stated explicitly in the spec rather
    than left implied.

Work

  • newgit render-clean / newgit render-smudge subcommands reading the
    binding record by workspace path
  • Install .git/info/attributes + .git/config filter config at bind;
    tear down alongside the existing exclude/skip-worktree teardown
  • Bind-time clean(smudge(blob)) == blob round-trip check, failing the
    bind with the file and string named
  • Remove skip-worktree for source-owned render paths, the throwaway-index
    re-set, and drift detection
  • Rewrite the render section of newgit-v1-mvp.md: fold Keeping instance
    values out of everything downstream
    down to export + capture, drop
    What it costs, and state the bypass hole

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with crates/newgit-core/src/render.rs, then inspect bind setup in crates/newgit-core/src/materializer.rs:72 and source handling around crates/newgit-core/src/source.rs:213 and :236. Trace the existing render, binding, exclude, teardown, and drift paths before implementing the listed filter subcommands and configuration. Done means bind installs and removes the filters, round-trip validation fails clearly, obsolete skip-worktree machinery is removed, and newgit-v1-mvp.md reflects the behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
git, rust
Domain
cli, documentation, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.