Einmal indiziert, in jedem Worktree bereit
Was du davon hast
Du arbeitest in mehreren Git-Worktrees oder lässt Agenten parallel laufen. Graph und Embeddings entstehen einmal, im ersten Checkout. Jeder weitere Worktree übernimmt sie, mit vollem Graph und semantischer Suche, und indiziert nur, was bei ihm anders ist.
Vorher und nachher
serde 1.0.229 liegt in vier verknüpften Git-Worktrees (git worktree add), jeder mit vollem Graph und semantischer Suche. Die Zeiten stammen von einem Apple M5, der erste Index lief mit leerem Inferenz-Cache.
Ohne geteilten Index
Der erste Checkout baut alles selbst: den Graph aus 219 Dateien und die Embeddings für 2.443 Code-Spans, jeder einmal durch das Modell.
$ greppy index .
…
indexed 219 files (120 unsupported, 0 unreadable, 0 oversize, 0 file-limit, 0 time-budget); 4571 nodes extracted; generation 1 (project: serde)
embedded 2443 code spans (0 local-store reused, 0 global-cache hits, 2443 inference misses, 4573 considered, 2150 non-definition skipped, 0 missing-file, 0 invalid-span, 0 oversize, 0 failed, 0 stale pruned)
Mit geteiltem Index
Jeder weitere Worktree übernimmt die gemeinsame Base und indiziert nur sein Delta.
$ greppy index .
…
greppy index: linked worktree uses shared Base 61d1f6b54eac at 7fc3b4c30c94f73a96ebd1553f2b090d928fc3a8 (reused); only the Git/dirty Delta will be indexed
indexed Delta generation 1: 0 changed/deleted paths, 0 private nodes (project: serde)
Im dritten Worktree kommt eine neue Funktion demo_format_count in serde/src/lib.rs dazu. Indiziert wird genau diese eine Datei, und die semantische Suche findet die Funktion direkt danach. Im vierten Worktree gibt es sie nicht.
$ greppy index .
…
indexed Delta generation 2: 1 changed/deleted paths, 1 private nodes (project: serde)
$ greppy search "how many formats are supported" --limit 3
serde/src/lib.rs:288 demo_format_count — returns a fixed count of 3
…
$ greppy search-symbol demo_format_count
status: no_matches
…
| Zeit | Spans durchs Modell | |
|---|---|---|
| Erster Checkout | 91,8 s | 2.443 |
| Worktree 1, legt die Base an | 22,0 s | 0 |
| Worktree 2 | 3,2 s | 0 |
| Worktree 3 | 3,1 s | 0 |
| Worktree 4 | 2,4 s | 0 |
| Worktree 3 nach der neuen Funktion | 5,1 s | 1 |
Agent-Workspace (greppy index --agent-worktree) |
2,8 s | 0 |
Der Checkout hat einen eigenen Store von 28,7 MB. Jeder Worktree hält nur ein Delta von 0,28 bis 0,35 MB und liest die gemeinsame Base mit. Alle Worktrees sehen denselben Graph wie der Checkout: 339 Dateien, 4.573 Knoten, 9.427 Kanten, im dritten Worktree dazu die neue Funktion.
Bei großen Repositories wächst der Abstand. Seit 0.4.1 nutzt auch der Aufbau der Base den Inferenz-Cache: Auf einem Mac mit M-Chip brauchte ein Worktree mit 41.012 Spans 161 s statt 1.520 s.
So funktioniert es
Der erste verknüpfte Worktree legt eine unveränderliche Base an: Graph und Embeddings des Git-Stands, identifiziert über Git-Tree, Store-Schema, Indexer- und Modellversionen. Die Embeddings kommen dabei aus dem nutzerweiten Inferenz-Cache, den der erste Index gefüllt hat; ein unveränderter Span geht nur einmal durch das Modell. Jeder Worktree und jeder Agent bekommt dazu ein privates Delta mit genau den Pfaden, die bei ihm anders sind: geändert, gelöscht, umbenannt oder neu, committet oder nicht. Abfragen sehen Base und Delta zusammen. Nur ein Prozess baut eine Base, alle anderen warten und übernehmen sie. Die Bindung eines Worktrees an seine Base bleibt fest, auch wenn der Haupt-Checkout weiterzieht.
Die Befehle
| Befehl | was er tut |
|---|---|
greppy index . |
im ersten verknüpften Worktree: Base anlegen; in jedem weiteren: Base übernehmen und nur das Delta indizieren |
greppy index --agent-worktree |
den Workspace des eingebauten Agenten samt Base vorab anlegen |
greppy index status --json |
Phase, Fortschritt und Bereitschaft, Modus (overlay oder single), Base und Delta; blockiert nie |
greppy cache status --json |
Stores, Bases, Modelle und ihre Größen |
greppy cache clear --root . --yes |
den Store dieses Worktrees und die geteilten Bases des Repositorys löschen |
Mehr in der Doku
- Worktrees und geteilter Index: Base und Delta, geteilte Inferenz, Speicherort, Aufräumen
- So funktioniert greppy: der Lebenszyklus des Index
- Eingebauter Agent: der Workspace, in dem jeder Agent arbeitet