Skip to main content

atomic view

Manage views (filtered perspectives on the repository graph).

Synopsis​

atomic view <SUBCOMMAND>
atomic view create <NAME> [OPTIONS]
atomic view split <NAME> [CHANGES]... [OPTIONS]
atomic view switch <NAME>
atomic view list [--short] [--remote [<REMOTE>]]
atomic view delete <NAME> [--force]
atomic view promote [NAME]

Description​

Views in Atomic are change-set filters on a single canonical graph. Every edge in the repository is written to one global GRAPH immediately — views determine which subset of that graph is visible by tracking which changes belong to them in VIEW_CHANGES.

This is fundamentally different from Git branches. A Git branch is a pointer to a commit; an Atomic view is an ordered set of change references that filters the ambient graph into a coherent perspective.

View Scopes​

ScopeEdge VisibilityLifecycleUse Case
SharedFiltered from canonical GRAPHPermanent (cannot be deleted)dev, release, main
DraftFiltered from canonical GRAPHEphemeral (deletable)features, bugs, experiments

Both scopes read from and write to the same canonical GRAPH. The difference is lifecycle: draft views can be deleted (their VIEW_CHANGES entries are removed; orphaned edges are cleaned by GC), while shared views are permanent collaborative history.

How It Works​

Views form a parent hierarchy that defines the filter chain for graph traversal:

  main  (Shared, parent=None — the only true root)
│
release (Shared, parent=main)
│
dev (Shared, parent=release)
│
├── service-auth (Draft, parent=dev)
│ ├── feature-login (Draft, parent=service-auth)
│ └── feature-logout (Draft, parent=service-auth)
│
└── service-payments (Draft, parent=dev)
└── bug-checkout (Draft, parent=service-payments)

A view's effective filter is the union of its own VIEW_CHANGES and all ancestor views' VIEW_CHANGES, plus the transitive dependency closure:

feature-login filter = VIEW_CHANGES[feature-login]
∪ VIEW_CHANGES[service-auth] (parent, Draft)
∪ VIEW_CHANGES[dev] (ancestor, Shared)
∪ VIEW_CHANGES[release] (ancestor, Shared)
∪ VIEW_CHANGES[main] (root)
∪ dependency closure

During graph traversal, an edge is visible if the change that introduced it is in the view's effective filter. All edges live in the single GRAPH table; the view just decides which ones to follow.

This means a team working on service-payments automatically sees infrastructure changes that were inserted into dev from service-auth — no sync, no rebase, no manual intervention.

Key Differences from Git Branches​

AspectGit BranchesAtomic Views
Data ModelPointer to a commitOrdered set of change references
StorageDuplicates historySingle GRAPH, per-view change filters
"Merging"3-way merge with conflictsInsert change references (with dependency closure)
StateHEAD commit hashMerkle hash of change sequence
CleanupManual git branch -D + orphaned objectsDelete VIEW_CHANGES entries; GC orphaned edges
CollaborationIsolated snapshotsFiltered perspectives, real-time sharing

Subcommands​

view create — Create a New View​

Synopsis​

atomic view create <NAME> [OPTIONS]

Arguments​

<NAME> — Name for the new view.

Options​

OptionDescription
--draft, -dCreate a draft view (ephemeral, deletable)
--parent <VIEW>Set the parent view (defaults to current view)
--from <VIEW>Fork from an existing view (copies its change log)
--switch, -sSwitch to the new view after creation

Examples​

# Create a draft feature view (most common workflow)
atomic view create feature-auth --draft

# Create a draft view with an explicit parent
atomic view create feature-login --draft --parent service-auth

# Create a shared view (permanent, like a release line)
atomic view create release-2.0

# Fork from an existing view (copies change history)
atomic view create hotfix --from release-1.0

# Create and switch in one command
atomic view create feature-api --draft --switch

View Scopes​

Without --draft (default): Creates a shared view. The view is permanent and visible to all collaborators. Use for long-lived integration points like dev, release, main.

With --draft: Creates a draft view. The view can be deleted when no longer needed — deletion removes its VIEW_CHANGES entries, and orphaned edges are cleaned by GC. Use for features, bugs, experiments, and service-level work.

Parent Chain​

The --parent option sets where this view sits in the filter hierarchy. When you're working in a view, graph traversal filters edges through your view's changes, then your parent's, all the way up to the root.

# Draft views for team-level organization
atomic view create service-auth --draft --parent dev
atomic view create feature-login --draft --parent service-auth
atomic view create feature-oauth --draft --parent service-auth

# feature-login sees:
# VIEW_CHANGES[feature-login] ← my changes
# ∪ VIEW_CHANGES[service-auth] ← parent's changes
# ∪ VIEW_CHANGES[dev] ← grandparent's changes (and up)

view split — Split Changes into a New Draft View​

Requires Atomic CLI >= 0.15.3

atomic view split was added in Atomic 0.15.3. On earlier versions the subcommand is unavailable — check yours with atomic --version.

Pull a set of changes out of a view and into a new draft view. Because changes are content-addressed and every edge already lives in the canonical GRAPH, split is a pure metadata operation: no change is re-applied, no hash is rewritten, and the changes that stay behind are left byte-identical.

The new view is created as a draft parented on the source, so it inherits the source's state and holds the split-out changes in its own VIEW_CHANGES. The source keeps everything else.

This is the inverse of atomic insert: insert brings a change's dependency closure into a view; split lifts a change and its dependents out.

Synopsis​

atomic view split <NAME> [CHANGES]... [OPTIONS]

Arguments​

<NAME> — Name for the new draft view.

[CHANGES]... — One or more change hashes (or unambiguous prefixes) to split out. Mutually exclusive with --last.

Options​

OptionDescription
--from <VIEW>Source view to split out of (defaults to the current view)
--last <N>Split the last N changes of the source view instead of naming them
--cascadeAlso move any changes that depend on the split-out set
--dry-run, -nPreview the split (and any blocking dependents) without performing it
--switch, -sSwitch to the new draft after creating it
--confirmAcknowledge the orphaning risk and skip the confirmation prompt (required for non-interactive use)

Confirmation​

A real split (not --dry-run) moves the changes out of the source view, so deleting the new draft later can leave them orphaned — referenced by no view and invisible everywhere. Atomic therefore previews the split, prints what will move, and asks you to confirm before performing it. In scripts and agent sessions (no terminal), pass --confirm to acknowledge the same risks non-interactively; without it the command refuses.

$ atomic view split wip --last 1
⚠ This removes 1 change(s) from 'dev' into draft 'wip' (0 dependent change(s) included).
⚠ Deleting that draft without inserting its changes elsewhere may leave them orphaned, invisible in every view. They will not return to the source automatically.
? Split 1 change(s) from 'dev' into 'wip'? I understand deleting the draft may orphan them [y/N]

Dependency safety​

Before moving anything, Atomic computes the reverse-dependency closure of the requested changes within the source view: does any change that stays behind depend on one you're pulling out?

  • Nothing depends on them → clean split.
  • Something depends on them → the split is refused unless you pass --cascade, which moves the dependents along too. Preview it with --dry-run.

This guarantees the source view is never left with a dangling reference, and the changes that remain are provably independent of what left.

Working copy​

When you split out of the current view, Atomic reconciles the working copy to the source's new state (files whose only remaining change left are removed; reverted files are rewritten). With --switch, the working copy is materialized to the new draft instead.

Examples​

# Split two specific changes out of the current view into a new draft "wip"
atomic view split wip ABCDEF12 34567890

# Split the last 3 changes of dev, previewing first
atomic view split wip --from dev --last 3 --dry-run

# Pull out a change and everything that depends on it, then switch to it
atomic view split experiment 9F3C21AA --cascade --switch
$ atomic view split wip --from dev --last 2
✓ Split 2 change(s) out of dev into draft wip
ℹ 'dev' now has 5 change(s); draft 'wip' has 2 own change(s).

view switch — Switch to a Different View​

Synopsis​

atomic view switch <NAME>

Arguments​

<NAME> — Name of the view to switch to.

Examples​

# Switch to main
atomic view switch main

# Switch to a feature view
atomic view switch feature-auth

# Switch to a service view
atomic view switch service-auth

When you switch views:

  1. The working copy is updated to match the target view's state
  2. Files are created, updated, or removed to reflect the new view's graph filter
  3. The new view becomes the current view

Note: Switching views updates your working copy files. Unrecorded changes may be affected.

view list — List Views​

Lists views locally by default, or on a remote with --remote.

Synopsis​

atomic view list [OPTIONS]

Options​

OptionDescription
--short, -sShow only view names (no metadata)
--remote [<REMOTE>]List views on a remote instead of locally. Pass --remote alone to use the default remote, or --remote <name|url> to target a specific one
--identity <IDENTITY>Identity to authenticate to the remote (only with --remote)
--insecure, -kSkip TLS verification when querying a remote (only with --remote)

Examples​

# Simple list (current view marked with *)
$ atomic view list
dev
* feature-auth
release-1.0
service-auth
# Detailed list (scope, change count, state hash) — the default output
$ atomic view list
* dev [shared] (12 changes) state: 2AAAAAAAA...
feature-auth [draft] (3 changes) state: XYZABCDEF... parent: dev
release-1.0 [shared] (8 changes) state: QRSTUVWXY... parent: main
service-auth [draft] (15 changes) state: 123456789... parent: dev

# Names only
$ atomic view list --short
dev
feature-auth
release-1.0
service-auth
# List the views available on a remote (default remote)
$ atomic view list --remote
Views on origin (https://acme.atomic.storage/workspaces/demos/projects/app/code)
dev [shared] (12 changes) state: 2AAAAAAAA...
feature-auth [draft] (3 changes) state: XYZABCDEF... parent: dev
release-1.0 [shared] (8 changes) state: QRSTUVWXY... parent: main

# Target a specific remote by name or URL
atomic view list --remote origin
atomic view list --remote https://acme.atomic.storage/workspaces/demos/projects/app/code
Remote views preserve their scope and parent

The server records each pushed view with its scope and parent, so remote listings report the real [shared] / [draft] scope and the parent chain, matching how the view was scoped locally. Use atomic clone --all-views to reconstruct the full set of remote views locally.

view delete — Delete a View​

Synopsis​

atomic view delete <NAME> [OPTIONS]

Arguments​

<NAME> — Name of the view to delete.

Options​

OptionDescription
--force, -fDelete without the orphan-confirmation prompt (also the non-interactive escape hatch)

Rules​

  • Shared views cannot be deleted — they represent permanent collaborative history.
  • Views with children cannot be deleted — delete or reparent children first.
  • The current view cannot be deleted — switch to a different view first.
  • Draft views have their VIEW_CHANGES entries removed. Orphaned edges (not referenced by any other view) are cleaned by background GC.
  • Orphan preview: before deleting, Atomic lists the changes that would lose their last view reference (no remaining view references them, directly or via dependencies). If any would be orphaned, it warns, prints the hashes, and asks for confirmation. Their data is not erased — the change objects stay in the content-addressed store — but they disappear from every view and do not return to the source automatically. Insert them into another view first to keep them referenced, or pass --force to proceed knowingly. In non-interactive contexts (scripts, agents) the prompt fails closed: only --force proceeds.

Examples​

# Delete an abandoned feature view (all its changes are still referenced
# elsewhere, or it is empty — no prompt, straight through)
atomic view delete feature-old
# ✓ Deleted view: feature-old

# Deleting a view whose changes would be orphaned warns and prompts
atomic view delete wip
# ⚠ Deleting 'wip' would orphan 1 change(s): no remaining view references them.
# 7A5F89A98F14B025...
# ⚠ Their data is not erased by view deletion, but they will disappear from all views and will not return to the source automatically.
# ℹ Insert these changes into another view before deleting this one to keep them referenced.
# ? I understand these changes will be orphaned; delete the view [y/N]

# Non-interactive: --force acknowledges the warning without a prompt
atomic view delete experiment --force
# ✓ Deleted view: experiment

What Happens to Inserted Changes?​

When you insert changes from a draft view into a shared view (like dev), those change references are added to the target view's VIEW_CHANGES. If you then delete the source draft view:

  • VIEW_CHANGES entries for the draft view → removed
  • Change references already inserted into other views → preserved
  • Edges in the canonical GRAPH → preserved (as long as any view references them)
  • Edges referenced only by the deleted view → cleaned by GC

This is the clean lifecycle:

# Create and work
atomic view create feature --draft --switch
atomic record -m "add login"
atomic record -m "add logout"
atomic record -m "add session mgmt"

# Insert some changes into dev
atomic insert <login-hash> --view dev
atomic insert <session-hash> --view dev

# Abandon the rest and clean up
atomic view switch dev
atomic view delete feature
# ✓ "logout" change reference removed (never inserted anywhere else)
# ✓ "login" and "session" references preserved in dev
# ✓ Orphaned edges from "logout" cleaned by GC

view promote — Promote a View to Shared Root Scope​

Synopsis​

atomic view promote [NAME]

Arguments​

[NAME] — Name of the view to promote. Defaults to the current view.

Description​

Promotes a draft view to shared root scope: the view becomes permanent (like main or dev) and can no longer be deleted. Use this when a draft has proven itself — for example, graduating a long-lived service view into shared collaborative history.

Examples​

# Promote the current draft view to shared scope
atomic view promote

# Promote a named view
atomic view promote service-auth

View Types in Practice​

Short-Lived Feature Work​

# Create a draft view for a quick bug fix
atomic view create bugfix-123 --draft --switch
atomic record -m "Fix null pointer in auth"
atomic insert <hash> --view dev
atomic view switch dev
atomic view delete bugfix-123

Long-Lived Service Work (Monorepo)​

# Team A: service-level view that lives for months
atomic view create service-auth --draft --parent dev

# Individual features stacked on the service view
atomic view create feature-oauth --draft --parent service-auth --switch
atomic record -m "Add OAuth provider"
atomic record -m "Add token refresh"

# Insert shared infrastructure into dev (visible to all teams)
atomic insert <oauth-provider-hash> --view dev

# Team B sees it immediately via their filter chain
# (service-payments is also parented on dev)

Release Management​

# Create a shared release view
atomic view create release-2.0 --parent main

# Insert specific changes from dev
atomic insert <feature-hash> --view release-2.0
atomic insert <bugfix-hash> --view release-2.0

# Tag the release
atomic tag create v2.0.0 --view release-2.0 -m "Release 2.0"

Inserting Changes Between Views​

When you insert a change into another view, Atomic automatically resolves the full dependency closure — it's not a cherry-pick of a single change, it pulls in every change the target depends on to remain mathematically consistent:

# feature has changes: C1, C2, C3, C4, C5
# C5 depends on C1 → C2 → C3

atomic insert C5 --view dev
# Atomic computes: deps(C5) = {C1, C2, C3}
# dev already has: {C1}
# Missing: {C2, C3, C5} → inserted in dependency order

Because all edges are already in the canonical GRAPH, insert is an O(1) metadata operation per change — it only writes entries to VIEW_CHANGES. No edge copying is needed.

This ensures the target view is always in a mathematically consistent state. You never get a "missing dependency" error after inserting.

See atomic insert for the full insert command reference.

Comparing Views​

# Preview what would be inserted (dry run)
atomic insert view feature --to-view dev --dry-run

# See the change-level diff between two views
# (which changes exist in one but not the other)

View Properties​

Each view maintains:

PropertyDescription
NameHuman-readable identifier
ScopeShared (permanent) or Draft (deletable)
ParentThe view this one is based on (None for root)
Change sequenceOrdered list of change references in VIEW_CHANGES
Merkle stateCryptographic hash of the change sequence
Change countNumber of changes referenced

Merkle State​

Each view maintains an incremental Merkle hash representing its complete state:

state_0 = Hash(empty)
state_1 = Hash(state_0 || change_hash_1)
state_2 = Hash(state_1 || change_hash_2)
...

This enables efficient sync (compare Merkle states to find divergence), integrity verification, and deterministic state identification.

Default View​

When you initialize a repository, a default shared view is created:

atomic init
# Creates "dev" view (shared, root)

# Or specify a custom name
atomic init --view main

Performance​

View operations are fast because they only manipulate metadata (VIEW_CHANGES entries), not graph edges:

OperationTimeNotes
Create< 10msWrites view metadata
SplitO(n)Metadata move; recomputes the source view's Merkle + reverse-dependency closure
Switch100ms–5sDepends on working copy size (materializing the view)
List< 10msScans VIEWS table
Delete (draft)< 50msRemoves VIEW_CHANGES entries; GC cleans orphaned edges
Delete (shared)BlockedShared views are permanent
Insert (per change)O(1)Metadata write to VIEW_CHANGES (no edge copying)
Graph traversalO(edges)Filtered by introduced_by ∈ visible_changes

Configuration​

# .atomic/config.toml

[repository]
default_view = "dev"

[view.main]
protected = true # Prevent accidental deletion

[view.release]
protected = true

See Also​