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:
memtrace index /path/to/notes --allow-non-git
MEMTRACE_ALLOW_NON_GIT=1 memtrace start --headless
| Flag | Description |
|---|---|
--allow-non-git | Accepted by any subcommand. Permits discovery and indexing of roots with no .git directory. |
| Variable | Default | Description |
|---|---|---|
MEMTRACE_ALLOW_NON_GIT | unset | Set 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.
| Capability | Works on a non-git root? |
|---|---|
find_symbol | Yes |
find_code | Yes |
get_symbol_context | Yes — callers, callees, references |
get_impact | Yes — blast radius from the graph |
find_dead_code | Yes — graph reachability |
get_repository_stats | Yes |
| Dashboard graph view | Yes |
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:
| Tool | Why it is empty |
|---|---|
get_evolution | Needs commits to diff a symbol across |
get_timeline | Needs git_commit episodes |
get_cochange_context | Needs commits to correlate files across |
replay_history | Nothing to replay |
get_arc | Needs the commit series behind a decision |
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.
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.