Memory
Not everything Elegant Git knows fits into git config. Workspaces are shared between repositories, the repository registry has to survive a mv, and the pipes need a scratch pad. So, Elegant Git keeps its own state in two JSON files — shared memory for everything user-wide and per-repo memory for everything that belongs to one repository. Anything that does land in git config is on the configuration page instead.
You never have to open these files. git elegant memory status summarizes them, git elegant memory workspaces and git elegant memory repositories list their contents, and git elegant repo status shows what the current repository resolved to.
Shared memory
The file is state.json inside the user configuration directory your OS defines:
| OS | Path |
|---|---|
| macOS | ~/Library/Application Support/elegant-git/state.json |
| Linux | $XDG_CONFIG_HOME/elegant-git/state.json, or ~/.config/elegant-git/state.json when that variable is unset |
| Windows | %AppData%\elegant-git\state.json |
Set ELEGANT_GIT_STATE_FILE to an absolute path to override it — handy for tests and for keeping work and personal setups apart.
The document holds four things:
schema_version— currently2acquired_version— the Elegant Git version that applied the global configuration; its presence is whatgit elegant git configurechecks forworkspaces— each keyed by id, withname,user_name,user_email, and the optionalsigning_key,editor,gpg_program,namespaces, andlinked_reposrepositories— the registry of managed repositories, each keyed by id, withname,workspace_id,current_path, and the optionalpath_historyandorigin_url
The id of a repository is also written into its .git/config as elegant-git.repo-id (a UUIDv7), which is how a repository recognizes itself after you move it. path_history keeps the paths it used to live at.
Per-repo memory
The file is <repo>/.git/elegant-git/state.json, and ELEGANT_GIT_REPO_STATE_FILE overrides it. It holds schema_version, repo_id, workspace_id, default_branch, protected_branches, and branch_sources — the last one records which branch each branch was started from, so work can tell your unique commits from the ones you inherited.
When nothing is recorded yet, Elegant Git falls back to main for both the default development branch and the protected branches, and to origin for the remote.
Next to it sits <repo>/.git/elegant-git/commands.json, the per-repo command memory. That is where the pipes park the stash message and the branch name they have to restore, which is why an interrupted command can be rerun without losing your work.
Schema migration
Both files are versioned, and both migrate themselves on load. The one migration that exists so far renames the version 1 vocabulary — profiles becomes workspaces and profile_id becomes workspace_id — and it runs like this: a backup is written next to the file as state.json.bak, the file is rewritten in the current schema, and a line naming the backup is printed to stderr. If the result surprises you, mv state.json.bak state.json puts you back.
A file whose schema_version is newer than the one your binary supports is never rewritten. The command fails and asks you to upgrade Elegant Git, so an older installation cannot quietly downgrade state a newer one wrote.
How memory gets filled
git elegant repo configure is what links a repository to a workspace. It writes user.name and user.email into .git/config, and prompts before applying the optional workspace fields (signing_key, editor, gpg_program). Values that already match the workspace are skipped without prompts, and every git config set or unset is printed before it runs. Branch settings that belong to Elegant Git live only in per-repo memory; the legacy elegant-git.default-branch and elegant-git.protected-branches keys are removed from .git/config after migration, and those unsets are printed too. When the origin URL yields a namespace not yet on the workspace, repo configure — and workspace new when it applies to the current repository — asks to remember it, recording it silently in non-interactive mode.
Workspaces can be created three ways:
git configureoffers to create one from your global values after the global setuprepo configureshows a picker with the existing workspaces,[Create new], and[Use settings from this repository]when the repository already hasuser.nameanduser.emailworkspace newcreates one by hand, suggesting values from the local and then the globalgit config
repo clone may omit the workspace argument altogether and suggest one from a matching namespace. And workspace edit is transactional — it collects the field edits and the per-repository apply decisions, shows one summary, confirms once, and only then writes shared memory and touches the selected repositories.