diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index c5402b9..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,55 +0,0 @@ -# Blue Oak Model License - -Version 1.0.0 - -## Purpose - -This license gives everyone as much permission to work with -this software as possible, while protecting contributors -from liability. - -## Acceptance - -In order to receive this license, you must agree to its -rules. The rules of this license are both obligations -under that agreement and conditions to your license. -You must not do anything with this software that triggers -a rule that you cannot or will not follow. - -## Copyright - -Each contributor licenses you to do everything with this -software that would otherwise infringe that contributor's -copyright in it. - -## Notices - -You must ensure that everyone who gets a copy of -any part of this software from you, with or without -changes, also gets the text of this license or a link to -. - -## Excuse - -If anyone notifies you in writing that you have not -complied with [Notices](#notices), you can keep your -license by taking all practical steps to comply within 30 -days after the notice. If you do not do so, your license -ends immediately. - -## Patent - -Each contributor licenses you to do everything with this -software that would otherwise infringe any patent claims -they can license or become able to license. - -## Reliability - -No contributor can revoke this license. - -## No Liability - -***As far as the law allows, this software comes as is, -without any warranty or condition, and no contributor -will be liable to anyone for any damages related to this -software or this license, under any kind of legal claim.*** diff --git a/README.md b/README.md deleted file mode 100644 index 9ff9501..0000000 --- a/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# arc ![license] ![activity] - -[license]: https://badge.hanna.lol/license/BlueOak-1.0.0 -[activity]: https://badge.hanna.lol/activity/hanna/arc - -A delta-based version control system written in Rust. - -Unlike Git's snapshot-based model, Arc stores incremental deltas using -ZSTD-compressed MessagePack files. Changes are automatically tracked -without manual staging, and commits are immutable once created. - -Arc uses a **bookmark** system instead of branches, and bridges to Git -remotes for push, pull, clone, and sync operations via `libgit2`. - -## Features - -- Incremental delta storage (ZSTD + MessagePack) -- Automatic change tracking (no staging step) -- Bookmarks and immutable tags -- Named stashes -- Three-way merge and graft (cherrypick/rebase) -- Git bridge for remote operations (push, pull, clone, migrate, sync) -- Optional SSH commit signing -- Per-repo and global YAML configuration with aliases -- `.arcignore` / `.ignore` support - -## Building - -Arc builds exclusively through Nix: - -```sh -nix build -``` - -The flake uses `nixpkgs-unstable`, `flake-parts`, `fenix`, and `crane`. - -A dev shell is available for iterative work: - -```sh -nix develop -``` - -## Usage - -``` -arc init [path] Initialize a new repository -arc commit Commit current changes -arc status Show changes since last commit -arc diff [start..end] Show a diff of changes -arc log [start..end] Show commit history -arc show Show details of a ref or commit -arc history [start..end] Show per-line modification history - -arc switch Switch worktree to a bookmark or tag -arc merge Merge a bookmark or tag into the worktree -arc revert Revert a commit or range -arc reset [file...] Reset worktree to the last commit -arc graft --onto Cherrypick commits onto a bookmark - -arc mark add|rm|list|rename Manage bookmarks -arc tag add|rm|list Manage tags -arc stash create|use|push|pop|rm|list Manage named stashes - -arc push [-r remote] Push to a git remote -arc pull [-r remote] Pull from a git remote -arc clone [-b branch] [path] Clone a git remote as an arc repo -arc migrate Convert a git repo to an arc repo -arc sync [-p] Sync bookmarks and tags with remote - -arc remote add|rm|list Manage remotes -arc config set|get|show|unset [-g] Manage configuration -``` - -## Testing - -```sh -nix develop -c cargo test -nix develop -c cargo clippy -nix develop -c cargo fmt --check -``` - -## License - -[Blue Oak Model License 1.0.0](LICENSE.md) diff --git a/docs/architecture.md b/docs/architecture.md deleted file mode 100644 index 25c7ce1..0000000 --- a/docs/architecture.md +++ /dev/null @@ -1,120 +0,0 @@ -# Architecture - -Arc is a version control system with its own data model, storage format, and a -git bridge for interoperability. - -## Repository Layout - -An arc repository keeps all state in an `.arc/` directory at the worktree root: - -| Path | Format | Purpose | -|------|--------|---------| -| `HEAD` | YAML | Current state — one of three variants: **unborn** (no commits yet; has `bookmark`), **attached** (on a bookmark; has `bookmark` + `commit`), or **detached** (raw commit; has `commit`). | -| `config.yml` | YAML | Local repository configuration. | -| `commits/.zst` | Zstandard-compressed MessagePack | Commit objects. Each file contains a `CommitObject` that bundles a `Commit` and its `Delta`. | -| `bookmarks/.yml` | YAML | One file per bookmark. Contains a `RefTarget` with an optional `commit` field. | -| `tags/.yml` | YAML | Same format as bookmarks. | -| `stashes/state.yml` | YAML | Tracks the active stash. | -| `stashes/named/.yml` | YAML | Per-stash state files. | -| `remotes.yml` | YAML | Map of remote names to URLs. | -| `git/` | Bare git repo | Shadow repository used by the git bridge. | -| `git-map.yml` | YAML | Bidirectional mapping between arc commit IDs and git OIDs. | - -## Data Model (`src/model.rs`) - -`CommitId` and `DeltaId` are newtype wrappers around `String`, holding SHA-256 -hex hashes. - -**Commit** — `id`, `parents` (Vec), `delta` (DeltaId), `message`, -`author` (optional `Signature`), `timestamp` (i64 unix), -`ssh_signature` (optional PEM string). - -**Delta** — `id`, `base` (optional parent CommitId), `changes` (Vec of -`FileChange`). - -**FileChange** — `path` plus a `kind`: Add, Modify, Delete, or Rename. - -**FileContentDelta** — either `Full { bytes }` (complete snapshot) or -`Patch { format, data }` (incremental). - -**Head** — enum with variants Unborn, Attached, and Detached. - -## Storage (`src/store.rs`) - -`CommitObject` bundles a `Commit` and its `Delta` into a single unit that is -serialized as MessagePack, then compressed with Zstandard at level 3. Files are -written atomically (write to `.tmp`, then rename). IDs are computed by SHA-256 -hashing the MessagePack-serialized content-addressable data. - -## Tracking (`src/tracking.rs`) - -`FileTree` is a `BTreeMap>` mapping relative paths to file -content. - -- `scan_worktree` — recursively walks the working directory, respecting ignore - rules and skipping `.arc/` and `.git/`. -- `materialize_committed_tree` — rebuilds the full file tree by replaying the - linear delta chain from the root commit. -- `detect_changes` — compares the committed tree against the worktree to produce - a list of `FileChange` entries (adds, modifies, deletes). - -## Ignore System (`src/ignore.rs`) - -Reads `.arcignore` first, falling back to `.ignore`. Always ignores `.arc/` and -`.git/`. - -- `*` and `?` glob wildcards. -- `!` prefix for negation. -- Patterns without `/` match any path component; patterns with `/` match the - full relative path. -- Patterns ending with `/` match directories only. - -## Git Bridge (`src/bridge.rs`) - -Maintains a shadow bare git repository under `.arc/git/`. - -`GitMap` provides bidirectional mapping (`arc_to_git` / `git_to_arc`) persisted -in `.arc/git-map.yml`. - -- `arc_to_git` recursively converts arc commits to git commits, materializing - file trees as git tree objects. -- `git_to_arc` does the reverse, computing deltas from git tree diffs. -- SSH authentication via agent or key files (`~/.ssh/id_ed25519`, `id_rsa`, - `id_ecdsa`). - -## Merge (`src/merge.rs`) - -Full three-way merge with line-level merging for text files using Myers diff. -Conflicts are marked with `<<<<<<< ours` / `=======` / `>>>>>>> theirs`. -Binary files fall back to keeping the "ours" version on conflict. - -## Signing (`src/signing.rs`) - -Optional SSH key signing using the `ssh-key` crate. Signs with SHA-512 under -the `arc` namespace. Verification extracts the public key from the signature -itself. Supports `~` expansion in key paths. - -## Source Modules - -| Module | Responsibility | -|--------|----------------| -| `main.rs` | Entry point, macro definitions | -| `cli.rs` | Clap-based CLI parsing and command dispatch | -| `model.rs` | Core data types | -| `store.rs` | Commit/delta serialization and content-addressing | -| `tracking.rs` | Worktree scanning, change detection, commit logic | -| `repo.rs` | Repository init/open/discover, path validation | -| `config.rs` | YAML config loading, merging (local-first), effective config | -| `refs.rs` | Bookmark/tag CRUD, switch, worktree write/clean | -| `bridge.rs` | Git bridge (shadow repo, push, pull, clone, migrate, sync) | -| `diff.rs` | Unified diff rendering | -| `inspect.rs` | Log, show, history (blame), Myers diff | -| `merge.rs` | Three-way merge | -| `modify.rs` | Reset, revert, merge command, graft | -| `resolve.rs` | Target/range resolution (bookmarks, tags, prefixes, HEAD) | -| `ignore.rs` | Ignore file parsing and matching | -| `signing.rs` | SSH commit signing and verification | -| `stash.rs` | Named stash system | -| `remote.rs` | Remote management (remotes.yml) | -| `error.rs` | Error types | -| `ui.rs` | Colored output formatting | diff --git a/docs/commands.md b/docs/commands.md deleted file mode 100644 index c9df7a5..0000000 --- a/docs/commands.md +++ /dev/null @@ -1,180 +0,0 @@ -# Command Reference - -## Global Flags - -- `-v` / `--verbose` — Increase verbosity (up to `-vvv`). -- `--version` — Show version. -- `--help` / `help` — Show help. - -## Core - -### `arc init [path]` - -Initialize a new arc repository. Creates the `.arc/` directory structure including `commits/`, `bookmarks/`, `tags/`, `stashes/`, `config.yml`, and `HEAD`. The default bookmark is `main`. - -### `arc commit ` - -Commit all current changes. No staging area is needed — changes are detected automatically by comparing the worktree to the last commit. Creates a ZSTD-compressed MessagePack commit object in `.arc/commits/`. If a signing key is configured (`user.key`), the commit is signed with SSH. - -### `arc status` - -Show added, modified, and deleted files since the last commit. - -### `arc diff [start..end]` - -Show a unified diff of changes. Without arguments, shows uncommitted changes. With a range, shows the diff between two commits. - -### `arc log [start..end]` - -Show commit history. Without arguments, shows all commits. Supports ranges like `start..end` (inclusive, either side optional). Each entry shows commit ID, timestamp, author, message, and a `[signed]` tag if applicable. - -### `arc show ` - -Show full details of a commit including author, date, parent(s), signature verification status, and the diff it introduced. Resolves bookmarks, tags, commit IDs, and commit prefixes. - -### `arc history [start..end]` - -Show per-line blame/annotation for a file, showing which commit last modified each line. Uses the Myers diff algorithm. - -## Branching (Bookmarks) - -### `arc mark add [commit]` - -Create a bookmark at the given commit. Defaults to HEAD if no commit is specified. - -### `arc mark rm ` - -Remove a bookmark. Cannot remove the active bookmark. - -### `arc mark list` - -List all bookmarks, marking the active one. - -### `arc mark rename ` - -Rename a bookmark. Updates HEAD if the active bookmark is renamed. - -## Tags - -### `arc tag add [commit]` - -Create an immutable tag at the given commit. Defaults to HEAD if no commit is specified. Tags cannot be overwritten. - -### `arc tag rm ` - -Remove a tag. - -### `arc tag list` - -List all tags with their commit IDs. - -## Navigation - -### `arc switch ` - -Switch the worktree to a bookmark or tag. Switching to a bookmark attaches HEAD. Switching to a tag or raw commit detaches HEAD. Requires a clean worktree. - -### `arc merge ` - -Three-way merge from a bookmark or tag into the current worktree. Creates a merge commit with two parents. Reports conflicts with `<<<<<<< ours / ======= / >>>>>>> theirs` markers. - -## Undo & Modification - -### `arc revert ` - -Create a new commit that reverses the changes from a commit or range. Uses three-way merge. - -### `arc reset [file...]` - -Reset the worktree to match the last commit. Without arguments, resets all files. With file arguments, resets only those files. - -### `arc graft --onto ` - -Cherry-pick/rebase commit(s) onto a target. Uses three-way merge. If the target is a bookmark, updates the bookmark pointer. - -## Stash - -### `arc stash create ` - -Create a named stash and set it as active. - -### `arc stash use ` - -Switch the active stash. - -### `arc stash push` - -Push dirty changes onto the active stash and reset the worktree. - -### `arc stash pop` - -Pop the most recent entry from the active stash and apply it to the worktree. Requires a clean worktree and matching HEAD. - -### `arc stash rm ` - -Remove a named stash. - -### `arc stash list` - -List all named stashes with entry counts. - -## Configuration - -### `arc config set [-g] ` - -Set a config value. Use `-g` for global config. Keys use `section.field` format (e.g. `user.name`, `default.bookmark`, `aliases.c`). - -### `arc config get [-g] ` - -Get a config value. Without `-g`, resolves local first, then falls back to global. - -### `arc config show [-g]` - -Show full configuration as YAML. Without `-g`, shows effective (merged) config. - -### `arc config unset [-g] ` - -Remove a config key. - -### Valid Config Fields - -- `user.name` — Author name. -- `user.email` — Author email. -- `user.key` — SSH key path for commit signing. -- `default.bookmark` — Default bookmark name (default: `main`). -- `default.remote` — Default remote name (default: `origin`). -- `aliases.` — Command aliases, expanded at the CLI level. - -## Git Bridge & Remotes - -### `arc remote add ` - -Add a remote. Stored in `.arc/remotes.yml`. - -### `arc remote rm ` - -Remove a remote. - -### `arc remote list` - -List all configured remotes. - -### `arc push [-r remote]` - -Push to a git remote. Converts arc commits to git commits via a shadow git repo (`.arc/git/`), with the mapping stored in `.arc/git-map.yml`. - -### `arc pull [-r remote]` - -Pull from a git remote. Converts git commits to arc commits. Fast-forward only. - -### `arc clone [-b branch] [path]` - -Clone a git remote and convert it to an arc repository. - -### `arc migrate` - -Convert an existing git repository to an arc repository. Imports all branches as bookmarks and all tags. Preserves commit history. - -### `arc sync [-p]` - -Sync all bookmarks and tags to the shadow git repo. With `-p`, also pushes to the default remote. diff --git a/docs/configuration.md b/docs/configuration.md deleted file mode 100644 index 12f4ffc..0000000 --- a/docs/configuration.md +++ /dev/null @@ -1,64 +0,0 @@ -# Configuration - -Arc uses YAML configuration files. - -```yaml -user: - name: hanna - email: me@hanna.lol - key: ~/.ssh/id_ed25519 - -default: - bookmark: main - remote: origin - -aliases: - c: commit - p: push - l: pull -``` - -## File Locations - -- **Local config**: `.arc/config.yml` inside the repository. Created automatically on `arc init` with default bookmark/remote values. -- **Global config**: `$XDG_CONFIG_HOME/arc/config.yml`, or `~/.config/arc/config.yml` if `XDG_CONFIG_HOME` is not set. - -## Resolution Order - -Local config values take priority over global config values. For each field, the local value is checked first; if not set, the global value is used. Aliases from both configs are merged, with local aliases overriding global ones with the same name. - -## Sections - -### `user` - -| Key | Description | -|---|---| -| `user.name` | Author name for commits. | -| `user.email` | Author email for commits. Both name and email must be set for author info to appear on commits. | -| `user.key` | Path to an SSH private key for commit signing (e.g. `~/.ssh/id_ed25519`). Tilde expansion (`~`) is supported. When set, commits are automatically signed. | - -### `default` - -| Key | Description | -|---|---| -| `default.bookmark` | Default bookmark name (used on init). Defaults to `main`. | -| `default.remote` | Default remote name (used by push/pull/sync). Defaults to `origin`. | - -### `aliases` - -Maps short names to command names. For example, `aliases.c: commit` lets you run `arc c "message"` instead of `arc commit "message"`. Aliases are expanded at the CLI level before command dispatch. Any alias key is valid; the value should be a valid arc command name. - -## Commands - -``` -arc config set Set a local config value. -arc config set -g Set a global config value. -arc config get Get a value (local first, then global). -arc config get -g Get a value from global config only. -arc config show Show the effective (merged) configuration. -arc config show -g Show only the global configuration. -arc config unset Remove a key from local config. -arc config unset -g Remove a key from global config. -``` - -Keys use dot notation: `section.field` (e.g. `user.name`, `default.remote`, `aliases.st`). diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index 6b53f3b..0000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,70 +0,0 @@ -# Getting Started - -Arc is a delta-based version control system written in Rust. It builds exclusively through Nix. - -## Building - -Arc uses a Nix flake (nixpkgs-unstable, flake-parts, fenix, crane): - -```sh -nix build -``` - -Enter a dev shell with `nix develop` (provides rustc, cargo, clippy, rustfmt, git, pkg-config, cmake, perl). - -Run Arc with `nix run` or `result/bin/arc` after building. - -## Configuration - -```sh -arc config set user.name "yourname" -arc config set user.email "you@example.com" -``` - -Global config lives at `$XDG_CONFIG_HOME/arc/config.yml` (or `~/.config/arc/config.yml`). - -## Creating a Repository - -```sh -arc init [path] -``` - -This creates a `.arc/` directory containing: - -- `commits/` — commit storage -- `bookmarks/` — branches (default: `main`) -- `tags/` — tagged commits -- `stashes/` — stashed changes -- `config.yml` — repository config -- `HEAD` — current position - -The default remote is `origin`. - -## Tracking Changes - -Arc tracks changes automatically — there is no staging area. - -```sh -arc status # see what changed -arc commit # commit all changes -arc log # view history -arc diff # see diffs -``` - -## Ignoring Files - -Create a `.arcignore` or `.ignore` file with gitignore-like glob syntax. Prefix a pattern with `!` to negate it. - -## Working with Git Repositories - -Clone a git repo: - -```sh -arc clone [path] -``` - -Migrate an existing git repo (run inside the repo): - -```sh -arc migrate -``` diff --git a/docs/git-bridge.md b/docs/git-bridge.md deleted file mode 100644 index cd205fa..0000000 --- a/docs/git-bridge.md +++ /dev/null @@ -1,65 +0,0 @@ -# Git Bridge - -Arc uses an internal git bridge to interoperate with git remotes. Since Arc uses its own delta-based storage format (ZSTD-compressed MessagePack), it maintains a shadow bare git repository to translate between formats when communicating with git servers. - -## Shadow Repository - -- Located at `.arc/git/` — a bare git repository created automatically on first use. -- A bidirectional mapping between arc commit IDs and git OIDs is stored in `.arc/git-map.yml`. -- The map has two fields: `arc_to_git` and `git_to_arc`, both string-to-string mappings. - -## Commit Conversion - -**Arc → Git:** The bridge materializes the full file tree at each arc commit, writes it as a git tree object, and creates a git commit with the same message, author, and timestamp. Parents are recursively converted. Cached mappings are reused. - -**Git → Arc:** The bridge reads the git tree, computes deltas against the parent's tree using Arc's `detect_changes`, and creates arc `CommitObject` entries. Author info and timestamps are preserved from the git commit. - -## Authentication - -- SSH authentication is attempted first via the SSH agent, then by scanning `~/.ssh/` for key files (`id_ed25519`, `id_rsa`, `id_ecdsa`). -- Interactive/password authentication is not supported. -- Up to 4 authentication attempts are made before failing. - -## Commands - -### Push (`arc push [-r remote]`) - -- Converts all arc commits on the current bookmark to git commits. -- Pushes the current bookmark as a git branch to the remote. -- Only pushes the active bookmark's branch. -- Uses fast-forward only; diverged histories produce an error. -- Default remote is `origin` (configurable via `default.remote`). - -### Pull (`arc pull [-r remote]`) - -- Fetches from the remote into the shadow git repo. -- Converts new git commits to arc commits. -- Fast-forward only — if the local bookmark has diverged, an error is returned. -- Updates the bookmark pointer and worktree. - -### Clone (`arc clone [-b branch] [path]`) - -- Clones the git remote into a new arc repository. -- Imports all branches as bookmarks and tags. -- Checks out the specified branch (or the remote HEAD, or `main` by default). -- Writes the full worktree after import. - -### Migrate (`arc migrate`) - -- Converts an existing git repository (in the current directory) to an arc repository. -- Creates `.arc/` alongside the existing `.git/`. -- Imports all `refs/heads/*` as bookmarks and `refs/tags/*` as tags. -- Preserves remotes from the git config. -- Sets HEAD to the same branch as the git repo's HEAD. - -### Sync (`arc sync [-p]`) - -- Ensures the shadow git repo mirrors all arc bookmarks and tags. -- Converts any new arc commits to git commits and updates git refs. -- With `-p` (`--push`), also pushes all refs to the default remote. - -## Remotes - -- Stored in `.arc/remotes.yml` as a YAML map of name → URL. -- Managed with `arc remote add|rm|list`. -- When pushing to git, bookmarks become git branches and tags become git tags.