MemtraceDOCS

Indexing directories without git

Index a plain directory that is not a git repository as a point-in-time snapshot, what you get, and the temporal features that are unavailable by construction.

By default Memtrace only indexes directories that are git working trees. A directory with no .git is skipped during discovery, and pointing memtrace index at one does nothing. Enabling non-git indexing lets Memtrace map a plain directory as a point-in-time snapshot: the symbol graph, relationships, and search all work; everything derived from commit history does not exist.

Enabling it#

Either a flag or an environment variable — the flag for a one-off run, the variable for a service:

One-off
memtrace index /path/to/notes --allow-non-git
For a long-running daemon
MEMTRACE_ALLOW_NON_GIT=1 memtrace start --headless
FlagDescription
--allow-non-gitAccepted by any subcommand. Permits discovery and indexing of roots with no .git directory.
VariableDefaultDescription
MEMTRACE_ALLOW_NON_GITunsetSet to 1 for the same effect as --allow-non-git. Useful where only the environment can be set — a systemd unit, a launchd plist, or a container.

What you get#

A non-git root is indexed under the same repository identity a git repository would get: the canonicalised directory name. Nothing about identity or scoping is synthetic.

CapabilityWorks on a non-git root?
find_symbolYes
find_codeYes
get_symbol_contextYes — callers, callees, references
get_impactYes — blast radius from the graph
find_dead_codeYes — graph reachability
get_repository_statsYes
Dashboard graph viewYes

Because everything downstream is branch-scoped, a non-git root is recorded under the reserved branch name (no-vcs). Parentheses are not legal in a git ref name, so this can never collide with a branch you actually have. Pass it explicitly when a tool asks for a branch.

What is unavailable#

Every temporal feature is derived from commit history. Without commits there is nothing to derive them from, so these return empty for a (no-vcs) scope:

ToolWhy it is empty
get_evolutionNeeds commits to diff a symbol across
get_timelineNeeds git_commit episodes
get_cochange_contextNeeds commits to correlate files across
replay_historyNothing to replay
get_arcNeeds the commit series behind a decision
NOTE

These do not fail silently. A temporal answer for a (no-vcs) scope carries history_available: false and a no_history_reason explaining that an empty result means there is no history to read, not that the code never changed. An agent reading the response can tell the two apart.

Scoping with .memtraceignore#

.memtraceignore is applied by the ingestion layer, not the git layer, so it works on a non-git root exactly as it does on a repository. Without .gitignore to lean on, it is usually worth writing one — a plain directory often contains build output or vendored trees that a repository would have excluded.

.memtraceignore
node_modules/
dist/
*.min.js
vendor/

Why it is opt-in#

Indexing a directory is cheap; silently indexing one is not. Discovery walks parent directories, and defaulting to "any directory is a repository" would pull in home directories, mounted volumes, and download folders that a user never meant to index. Requiring the flag keeps discovery predictable.

The second reason is honesty about the result. Someone pointing Memtrace at a directory reasonably expects the product they read about, and roughly a third of the tool surface is temporal. Asking for the flag makes the trade explicit at the point of choosing it, rather than leaving it to be discovered when get_evolution comes back empty.