lane README

The project's README from github.com/lukeed/lane. As one markdown file: README.md.

lane CI

Copy-on-write Git worktrees with memory that survives them.

Lane creates isolated worktrees without leaving behind the ignored build caches that make a checkout fast. It can also attach durable notes to a file or symbol, then flag them when the relevant code changes. Lane never calls a model.

[!TIP] Why another worktree tool?

When you run git worktree add, it creates a clean checkout but leaves behind everything Git ignores: target/, node_modules/, virtual environments, generated files, and local .env files. This means you must reinstall and/or build from scratch, despite already having all your caches warm on disk. On a reflink filesystem, lane clones those entries by reference. The new lane starts warm while allocating new storage only for the blocks it changes.

Lane uses clonefile(2) on APFS and FICLONE on Linux filesystems that support it, including btrfs and XFS with reflink enabled. If reflinks are unavailable, lane creates a normal worktree and does not byte-copy ignored caches. When desired, lane new --dirty also carries tracked edits and untracked, non-ignored files; without reflinks, those changed files are copied normally.

Lanes live under .lane/trees/ and are excluded through .git/info/exclude, so the worktrees themselves are never committed.

Lane can also attach durable notes/memories to a file or symbol, then flag them when the relevant code changes.

Lane never calls a model.

Install

Prebuilt binaries are available for macOS and Linux on arm64 and x86_64:

$ curl -fsSL https://lane.lukeed.com | sh

The installer writes to ~/.local/bin by default. Set LANE_INSTALL to choose another directory, or LANE_VERSION to pin a release.

You may also install with Cargo:

$ cargo binstall --git https://github.com/lukeed/lane lane
# or
$ cargo install --git https://github.com/lukeed/lane

Lane requires Rust 1.85 or newer when building from source.

Setup

For each new shell, install the lane shellenv wrapper to automatically cd into and out of lanes. Add this to .zshrc or .bashrc:

eval "$(lane shellenv)"

Or add the Fish wrapper to ~/.config/fish/config.fish:

lane shellenv fish | source

The wrapper completes lane names for lane rm, lane push, lane enter, and lane merge.

While not necessary, this is more convenient than manually running cd .lane/trees/<new lane> repeatedly.

Then initialize each repository:

$ cd yourrepo
$ lane init
$ git add .lane AGENTS.md
$ git commit -m 'initialize lane'

This creates the memory store, adds a short agent protocol to AGENTS.md, and reports whether the filesystem supports reflinks.

Optional tooling can capture Why: commit trailers or install the fuller agent workflow:

$ lane install hooks  # capture targeted Why: trailers from commits
$ lane install skill  # install the fuller workflow for coding agents

Usage

$ lane new fix-login
$ lane why src/auth.rs
$ lane note add src/auth.rs -a 'fn verify' \
    'must stay constant-time; early return leaks token length'

# edit and commit as usual
$ lane check
$ lane merge
# or
$ lane push

lane new creates a branch and worktree under .lane/trees/. On APFS, btrfs, and reflink-enabled XFS, ignored files are cloned by reference. Otherwise, Lane creates a normal Git worktree and skips ignored files.

Notes record what must stay true, not what a commit changed. They are stored as Markdown under .lane/memory/ and anchored to a declaration, Markdown section, component block, or whole file.

For repositories with protected branches, use lane push instead of lane merge. After the pull request lands, run lane prune.

Run lane --help for the command list, or visit the usage guide for the full workflow. See Audit for how to review existing memories before landing.

Memory

Memory is ordinary Markdown committed with the repository:

.lane/
  memory/<path>/<ulid>-<slug>.md   live notes and confirmed fingerprints
  attic/<path>/<ulid>-<slug>.md    retired notes, still recoverable
  trees/<name>/                    local worktrees, never committed

New notes use distinct files, so parallel lanes can annotate the same code without editing the same bytes. lane note confirm <id> re-vouches for a drifted note by updating its confirmed fingerprint. Pin and unpin likewise update retention metadata. If two branches make conflicting judgments about the same note, Git makes that disagreement visible.

Notes are written directly to .lane/memory/ without a baseline. The next audit baselines them after any rebase, follows source-file renames, and moves superseded, unpinned missing, or unpinned over-budget notes to .lane/attic/ rather than deleting them.

Anchors include declarations such as fn verify, Markdown headings such as ## Rate limiting, component blocks such as #script, and @file for a whole file. Run lane anchors src/auth.rs to list the canonical values and their line ranges. A unique bare name such as verify is stored as its canonical value; a name shared by multiple declaration kinds is refused with the available choices. Comments and whitespace are normalized out of fingerprints.

Audit

Run lane check to get the status report for existing memories:

$ lane check

Freshness is computed for the anchored span, not the whole file:

result meaning
fresh the anchored span is unchanged
content-changed its implementation changed
contract-changed its declaration changed
anchor-missing the symbol no longer resolves
unverifiable lane has no grammar for that anchor

Resolve drift with exactly one of these actions:

$ lane note confirm <id>                  # still true
$ lane note replace <id> '<replacement>'  # needs an update
$ lane note retire <id>                   # no longer applies

Run lane note edit <id> for a guided terminal menu over the same actions, including pinning or unpinning the note.

Replacement inherits the live note's path and anchor. Retire and restore move bytes unchanged between live memory and the attic; pin and unpin control eviction. For a new note, supplied text never prompts and defaults to @file without -a; omit text to use the interactive anchor selector and one-line prompt.

Development

$ ./scripts/build.sh          # release-build and install the local lane binary
$ cargo fmt --all --check
$ cargo clippy --workspace --all-targets -- -D warnings
$ cargo test --workspace
$ ./scripts/test.sh           # end to end against temporary Git repositories
$ ./scripts/check-linux.sh    # run the same gates without reflink support
$ ./scripts/release.ts patch  # bump the version, then tag and push the release

License

MIT © Luke Edwards

lane (lukeed/lane)

Searching Database…

160 ·GitHub
这是什么?Lane 是一个 CLI 工具,创建写时复制的 Git worktree,让新的检出直接继承热构建缓存而不是从空开始;它还能把持久的 Markdown 笔记附着到代码上,当被标注的代码变化时会发出标记。
这是个 CLI 工具,还是配合 git 一起运行的东西?它是一个单二进制命令行工具,不是库或 GUI 应用;你在正常的 git 工作流之外运行 `lane` 命令。
怎么让 lane 跑起来?安装预编译二进制(macOS/Linux,arm64/x86_64)或运行 `cargo install`,把 lane 的 shell 包装脚本加进你的 .zshrc/.bashrc 或 Fish 配置,然后在每个仓库里运行 `lane init` 来建立记忆存储和 AGENTS.md。
需要先装 Rust 或特殊的文件系统吗?从源码构建需要 Rust 1.85 或更新版本;要获得写时复制的速度优势,需要支持 reflink 的文件系统,比如启用了 reflink 的 APFS、btrfs 或 XFS。
如果我的文件系统不支持 reflink 会怎样?Lane 会退回普通的 git worktree,并跳过对被忽略缓存的字节复制,因此你拿不到热缓存加速;此外它只提供 macOS 和 Linux 二进制,没有 Windows 版本。
预编译二进制支持哪些平台?macOS 和 Linux,arm64 和 x86_64 都有;不提供 Windows 版本。
lane 会调用 AI 模型吗?不会——README 声明 lane 从不调用模型;它是一个确定性的 worktree 和笔记跟踪工具,不是 AI 功能。
lane 怎么知道一条笔记已经过时?笔记锚定在某个声明、Markdown 标题、组件块或整个文件上,`lane check` 会根据锚定的那段代码是否变化,报告「最新」「内容已变」「契约已变」「锚点缺失」或「无法验证」。
旧的或被取代的笔记会怎样?Lane 不会删除被取代的、未固定但缺失的、或未固定但超预算的笔记——审计时它们会被移到 .lane/attic/,之后还能恢复。
两个分支可以对同一条笔记有分歧吗?可以——新笔记写入各自独立的文件,并行的 lane 不会相互冲突;如果两个分支对同一条笔记做出相互矛盾的判断,Git 会像其他任何合并一样把这个冲突呈现出来。
What are similar projects?turbocrypt, eza, diff-so-fancy, cz-cli, git-ai, difftastic, gitui, tatr
Creator
lukeed
Size
1.2 MB
Stars
160
Age
1mo
Commits · 90 Days