Skip to main content
Inspect and modify repositories using a subset of the Git command line. Mirage routes repository files through the workspace dispatcher, so the same commands can operate on RAM, disk or another backend with the required filesystem operations. The Python implementation uses Dulwich; the TypeScript implementation uses isomorphic-git. Mirage supplies the command grammar, output and VFS integration on both hosts. The compatibility target is native Git’s supported behavior, with the differences below. These libraries are implementation dependencies; their own command interfaces do not define Mirage’s supported commands.

Setup

git has no account config. It needs an existing repository to inspect, or a writable mount on which to initialize or clone one.
For YAML registration, see the CLI overview.

Supported commands

Run git <command> --help for the supported flags and operands. This list is generated from Mirage’s registered command tree.

Create and inspect a repository

-C selects a workspace directory and defaults to the session’s working directory. Repository discovery walks upward, so commands also work from subdirectories. Loose objects, packs, refs, the index and working files all use the same VFS operations as the shell. init supports -b, --bare and reinitialization. The default branch is master unless -b chooses another. commit requires -m and records mirage <mirage@localhost> unless --author 'Name <email>' overrides it. fsck checks the object database without modifying it.

Stage and change files

Continue from the initial commit above. Record a second version before using HEAD~1 to restore the original:
restore can discard changes in the selected destination. Use -- before a path beginning with -. Permission and read-only refusals go through the workspace dispatcher and are reported in Git’s command-specific wording.

Branches, tags and history

Annotated tags need -m; lightweight tags can point to any object. Revision expressions include parent/ancestor operators (^, ~), typed peels such as HEAD^{tree}, and paths such as HEAD:hello.txt. Operators apply left to right. Invalid suffixes are refused as part of the whole revision. log, show, rev-list, diff-tree, shortlog, cat-file, hash-object and ls-tree provide inspection without a host Git process. Run each command’s --help for supported formatting, filtering, path and diff options.

Clone, fetch and repository configuration

Clone and fetch can read another workspace repository or a smart-HTTP remote. Destinations must be writable mounts. There is no push or pull command. A path git refuses to check out is refused by checkout, switch, restore and reset as git refuses it; git clone then exits 128 and keeps the repository with an empty work tree. Reading the entries of a tree that holds an entry with an empty name exits 128 with git’s empty filename in tree entry. For authenticated GitHub clones, gh repo clone supplies its configured token, and only to its configured GitHub origin. --git-dir and --work-tree override GIT_DIR and GIT_WORK_TREE and resolve against -C. Repository core.worktree and core.bare affect discovery; linked worktrees use their recorded layout. Working-tree commands refuse bare repositories. No repository operation opens a host path behind the VFS.

Limits and intentional differences

  • Only the listed command subset is implemented. Merge, rebase, push, pull, reset --hard and switch - are absent; stash supports inspection only.
  • Commits accept no path operands and do not create merge commits. An unmerged index blocks commits and branch moves. checkout is stricter than Git about staged changes; switch can carry compatible staged changes but refuses file/directory collisions that would discard them.
  • Host templates, hooks, editors and Git’s initial-branch advisory are absent. Per-worktree config.worktree is not read. With conflicting core.bare and core.worktree, Mirage keeps the repository bare without Git’s warning.
  • Working-tree replacements preserve executable modes and symlink semantics. They do not follow a symlink out of a directory being replaced. Nested mounts block removals or replacements that would consume their contents; destinations are checked before writes begin. Renames preserve namespace metadata and cannot cross mount boundaries at either end.
  • Gitlinks create or retain directory placeholders. Mirage does not check out submodule content or compare a submodule’s HEAD; files inside a submodule directory can still appear as untracked. Removing a nonempty gitlink directory warns and leaves it in place.
  • Diff hunk bodies and diffstat counts can differ from native Git because the line-diff algorithm differs from xdiff. Headers, ordering and supported formatting match Git. Pretty formats email, mboxrd and reference are refused.
  • History searches use ASCII case folding. --since and --until accept ISO-8601 or epoch seconds; relative date phrases are refused.
  • tag -l/-d conflict wording uses a fixed option order. Tag deletion uses a ref transaction: duplicate updates are refused atomically, while missing names are reported and skipped.
These boundaries are exercised by the shared Git integration corpus on RAM and disk mounts. The VFS determines which filesystem operations are available; registering git does not make a read-only mount writable.

Upstream and dependency licenses

Dulwich offers an Apache-2.0 option; using it does not require choosing its GPL alternative. Matching Git behavior does not relicense Git, Dulwich or isomorphic-git. Copied or ported source and redistributed dependencies still carry their applicable terms and notices; see compatibility and licenses.