> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vers.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Commits

> Immutable, content-addressable snapshots of a VM. The thing you restore, branch from, and tag.

A **commit** is an immutable snapshot of a VM's full state — filesystem, memory, CPU registers — captured at the moment you ran `vers commit`. Commits have a content-addressable id (e.g. `c123456789abcdef`) that uniquely identifies that exact state.

Commits are the currency of sharing, reuse, and reproducibility in Vers. Everything that "starts from somewhere" starts from a commit.

## What a commit captures

| Captured                                   | Not captured                                                                                     |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| Full root filesystem                       | External connections (TCP sessions survive memory but won't recover if the network peer is gone) |
| Memory (every running process)             | IP address (new VMs get new IPs)                                                                 |
| CPU registers                              | SSH keys that weren't on disk at commit time                                                     |
| Environment variables in running processes | Account-level `vers env` settings (those are injected at boot, not baked in)                     |

In practice: if your work is in memory or on disk, it's in the commit. If it depends on the outside world, you'll need to re-establish that.

## Creating a commit

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
vers commit              # Commit HEAD
vers commit my-vm        # Commit a specific VM
```

<Warning>
  Committing **pauses** the VM. Run `vers resume` afterward if you want to keep working with it.
</Warning>

The output is a commit id. You can pipe it straight into other commands:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
COMMIT=$(vers commit --format json | jq -r .commit_id)
vers tag create stable "$COMMIT"
```

## Restoring from a commit

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
vers run-commit <commit-id>
```

This boots a fresh VM from the saved state. It doesn't "resume" the original VM — it creates a new one, identical to the moment of the commit, with its own id and IP.

You can restore the same commit any number of times. Each call produces an independent VM.

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
# Three independent VMs, all starting from the same commit
vers run-commit "$COMMIT" --vm-alias a
vers run-commit "$COMMIT" --vm-alias b
vers run-commit "$COMMIT" --vm-alias c
```

## Commits vs branches vs forks

These words get muddled — a quick disambiguation:

| Operation                  | Input        | Output                                                      |
| -------------------------- | ------------ | ----------------------------------------------------------- |
| `vers commit`              | A running VM | A new commit id                                             |
| `vers branch <vm>`         | A running VM | A new VM (plus a fresh commit, created internally)          |
| `vers branch <commit>`     | A commit     | A new VM                                                    |
| `vers run-commit <commit>` | A commit     | A new VM (conceptually identical to `vers branch <commit>`) |

Branches always produce a running VM. Commits always produce a frozen state. Restores always produce a running VM from a frozen state.

## Lifetime and deletion

Commits persist until you explicitly delete them with `vers commit delete`. They survive:

* The deletion of the VM that produced them
* The deletion of the child VMs they created
* Your CLI logging out and back in

This makes commits the right place to stash "I might need this later" state. A VM is ephemeral; a commit is durable.

## Tagging commits

Commit ids are long and unmemorable. Tags fix that:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
vers tag create production <commit-id>
vers tag create v1.2 <commit-id> -d "release candidate"
```

Tags are mutable — you can move them with `vers tag update` — and cheap. Deleting a tag doesn't touch the commit it pointed at.

Anywhere a commit id is accepted (`vers run-commit`, `vers branch`, `vers build`'s `FROM`), you can pass a tag name instead.

## Repositories

For structured naming, tags can live inside **repositories**: `my-app:latest`, `my-app:v1.2`, etc. A repo is a namespace for a related group of commits. Repos can be public (other orgs can fork them) or private.

See [`vers repo`](/cli-reference/repo) for the full workflow; most users can get away with plain tags until they need the structure.

## A typical workflow

<Steps>
  <Step title="Prepare">
    Boot a VM, install dependencies, configure things.

    ```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
    vers run --vm-alias prep
    vers connect prep
    # apt install ... ; configure ... ; exit
    ```
  </Step>

  <Step title="Freeze">
    ```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
    COMMIT=$(vers commit prep --format json | jq -r .commit_id)
    vers tag create base "$COMMIT"
    ```
  </Step>

  <Step title="Fan out">
    Every future VM starts from this known-good base.

    ```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
    vers run-commit base --vm-alias worker-1
    vers run-commit base --vm-alias worker-2
    ```
  </Step>
</Steps>

## See also

* [VMs](/concepts/vms) — what you commit *from*
* [vers commit](/cli-reference/commit), [vers run-commit](/cli-reference/run-commit), [vers tag](/cli-reference/tag)
* [Dockerfile support](/concepts/dockerfile) — build commits declaratively
