pvc <cmd>: patch version control command line utility.

NOTICE: currently re-writing, not functional.

About

pvc is a version control system similar to git or mercurial, but is ultra simple: branches are simply a base followed by a set of unix patches with incrementing id. The only fundamental disadvantage (or advantage) of using pvc instead of git is that pvc supports only fast-forward merges, which are the cleanest and simplest to understand.

Basic Operation

The pvc command works very similar to git. Use pvc --help to get a full list of available commands. Below are the major ones:

pvcignore

The .pvcignore file should contain a line-separated list of #string.find patterns that should be ignored. Items ending in / will apply to whole directories. A common pvc ignore file might look like:

# directories
%.git/
%.out/

# extensions
%.so$

# binary files
%./path/to/some_binary

Architecture

As the name implies, pvc is patch-based version control.

A branch is a @branch/ dir inside the local .pvc/ with a base and a series of numbered patch files in rev/, e.g 01.p, 02.p, etc. A branch also has a tip file with the current tip id.

Commits are performed by diffing from the previous snapshot, creating the patch file.

Snapshots are created by applying patch files in either forward/reverse order to an existing snapshot, with the "zero" snapshot being an empty directory.

Any other modification to a branch (e.g squash, rebase, etc) use a simple state machine:

For an example of the above, to rebase (change the base), the .branch's base will have the new re-based id and the ops file will be a series of cherry picks from the original branch's id 1 to it's tip. To perform a split, the ops file just cherry cherry pick specific files, dropping a commit simply means skipping a cherry picks, inserting a commit is cherry picking between two commits, etc. Any merge conflicts stop the process, which the user needs to fix and commit and then run pvc fix again. However, the user can fix any problems later and work on another branch.

Finally, the entire .pvc directory is tracked by a hidden @.META branch as a single series of patches, allowing the user to (soft) reset to a previous repo state at any time.

Command pvc

Usage: pvc <subcmd> --help
This is the pvc command-line tool which can also be called directly from Lua.

pvc uses rev (revision) semantics of 'branch@id' where "branch" is a branch name (e.g "main") and id is an incrementing patch id, where later ids are always later patches.

Special branch names include:

Special id names include:

Subcmd init

Usage: pvc init dir --branch=main
Initialize the current directory as a pvc directory. This will create .pvc/ and .pvcpaths Arguments:

Subcmd diff

Usage: pvc diff rev1::rev2 paths...
Show the difference between rev1 and rev2. With no args, this shows the difference between at::local, or the changes from the current commit to the work_tree. Arguments:

Subcmd apply

Usage: pvc apply path/to/patch.p... Apply a series of patches Arguments:

Subcmd commit

Usage: pvc commit 'message' -- specific/paths to/commit
Commit local changes to the current branch, creating a new id.

The message is prepended to anything in the file ./PATCH. The ./PATCH file is deleted after the commit is complete. Arguments:

Subcmd at

Usage: pvc at [rev] --force
If rev is not given, just returns current branch#id.

Otherwise, sets the active branch@id, causing the local directory to be updated to be that snapshot.

If any local changes would be overwritten this will fail unless force=true.

at branch@id is called a "checkout" in other version control systems.
Arguments:

Subcmd upload

Usage: pvc upload branchName path/to/dir Backs up the branch to the directory, making a complete copy of the rev/ and metadata files but not copying snapshots.
TODO: support upload to remote repo. Arguments:

Subcmd pull

Usage: pvc pull branchName path/to/dir Restore the branch from path/to/dir.
TODO: support pulling from remote repo. Arguments:

Subcmd tip

Usage: pvc tip [branch]
Get the tip id of branch. Arguments:

Subcmd branch

Usage: pvc branch name [from]
Start new branch name branching off of from. Arguments:

Subcmd show

Usage: pvc show [branch#id] --before=10
Show the commits before/after branch#id.

If branch#id is not given, print all branches. Arguments:

Subcmd desc

Usage: pvc desc branch#id=current [$to/new.cxt]
Get or set the description for a single branch id.

The new description can be passed via to/new.cxt or after -- (like commit). Arguments:

Subcmd squash

Usage: pvc squash [name#id]
Combine changes and descriptions from branch id -> endId (inclusive) into a single commit. You can then edit the description using pvc desc branch#id.

This enables making lots of small commits and then "squashing" them into a single commit once they are in a good state. Arguments:

Subcmd rebase

Usage: rebase [branch=current] --id=10
Change the base of branch to id.

Rebase is a fundamental operation. It allows you to make or accept changes on your "main" branch while you work on development branches which are behind the main. See #basic for more details. Arguments:

Subcmd grow

Usage: grow --branch=current [from]
Copy changes in from onto branch.
In other version control systems this is called a "fast forward merge"
Arguments:

Subcmd prune

Usage: prune branch#id Arguments:

Subcmd export

Usage: export branch to/
Copy all patch files in the branch to to/.
The resulting directory is commonly sent to tar -zcvf branch.tar.gz path/ and then branch.tar.gz sent to a maintainer to be merged.
Arguments:

Subcmd snap

Usage: snap [branch#id=current]
Get the snapshot directory of branch#id.

The snapshot contains a copy of files at that commit. Arguments:

Mod pvc.repo

pvc submodule containing most logic for managing the pvc repository.

Types: Repo

Functions

Record Repo

A .pvc/ repo with branches, snapshots and a current state.

Fields:

Methods

Mod pvc.snap

pvc submodule containing logic for snapshots, aka complete directories of

files.

Types: Path Snap Diff

Functions

Record Path

Object in index files in form (+-x)(mtime):(id)/p

Fields:

Methods

Record Snap

A snapshot with a set of indexed paths.

Fields:

Methods

Record Diff

Diff:of(dir1, dir2) returns what changed between two pvc dirs.

Fields:

Methods

Mod pvc.unix

Functions