Skip to content

bkarli/patchwork

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

161 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Patchwork

Patchwork is a peer-to-peer version control system inspired by Git.
Repositories synchronize directly between peers without using a central server.

Patchwork is used through a command-line interface and follows a Git-like workflow.


Usage

All commands are executed inside a project directory or any of its subdirectories.
Patchwork automatically finds the repository by locating a .patch directory in parent folders.


Initialize a Repository

patchwork init <name>

Initializes a new Patchwork repository in the current directory.

When this command is executed, Patchwork first checks whether a .patch directory already exists in the current directory or any parent directory. If a repository is found, initialization is aborted to prevent overwriting an existing repository.

If no repository exists, the command performs the following steps:

  • Creates a .patch directory in the current project root.
  • Creates the object store directories .patch/objects/blobs, .patch/objects/trees, and .patch/objects/commits.
  • Initializes a new repository configuration using the provided name as the author identity.
  • Generates a new cryptographic peer identity and derives a peer endpoint from it.
  • Stores the generated secret key and endpoint identifier in the repository configuration.
  • Writes the initial configuration to .patch/patchwork.toml.

After successful initialization, the directory is ready to be used as a Patchwork repository and can immediately participate in peer-to-peer synchronization.

patchwork clone <peer-public-key>

Initializes a new local Patchwork repository by connecting to an existing peer and bootstrapping collaboration.

When this command is executed, Patchwork performs the following steps:

  • Verifies that no .patch directory exists in the current directory or any parent directory to avoid overwriting an existing repository.
  • Creates a new .patch directory and initializes the local object store, including subdirectories for blobs, trees, and commits.
  • Initializes a fresh local configuration and generates a new cryptographic peer identity.
  • Derives a local peer endpoint from the generated secret key.
  • Connects to the remote peer specified by <peer-public-key> (endpoint of a peer) using the clone protocol.
  • Receives a redacted repository configuration from the remote peer, containing repository metadata and collaborator information while excluding private key material.
  • Registers the remote peer as a collaborator in the local configuration.
  • Sends an explicit acknowledgment (ACK) to complete the clone handshake.
  • Writes the initialized configuration to .patch/patchwork.toml.

The clone command only bootstraps metadata and peer relationships. No commits, trees, or blobs are transferred during cloning. Repository contents are synchronized later using pull and push commands.

Creating a Commit (Add & Commit)

patchwork add <paths...>

Stages files for the next commit by creating content-addressed blob objects.

The add command prepares files to be included in the next commit. It reads file contents, stores them as immutable blob objects, and records their hashes in the staging area.

When patchwork add (path) is executed, Patchwork performs the following steps:

  • Locates the Patchwork repository.
  • Loads the repository configuration.
  • Resolves paths relative to the project root.
  • Processes all provided file paths.

For each file path, Patchwork:

  • Checks that the path exists and refers to a regular file
    (directories are not supported yet).
  • Reads the complete file content into memory.
  • Computes a SHA-256 content hash using a Git-style blob header consisting of:
    • the object type (blob),
    • the file size,
    • a null separator,
    • the raw file bytes.
  • Stores the file content as a blob object at
    .patch/objects/blobs/<hash>.
  • Skips writing the blob if an identical blob already exists (content-based deduplication).
  • Converts the absolute file path into a path relative to the project root.
  • Adds an entry to the staging area mapping
    relative/path/to/file -> blob hash.

After all files have been processed, the updated staging area is written back to patchwork.toml.

Files staged with patchwork add become part of the next snapshot when patchwork commit is executed.

patchwork commit "<message>"

Creates a new commit representing a complete snapshot of the project state.

The commit command takes the files prepared with patchwork add and produces an immutable snapshot of the repository. While commits are built incrementally from previous ones, each commit fully describes the project state via its root tree.

When patchwork commit is executed, Patchwork performs the following steps:

  • Loads the repository configuration.
  • Verifies that the staging area is not empty.
  • Resolves the parent commit (if one exists).
  • Reconstructs the previous root tree from the parent commit.
  • Applies the staged file changes onto that tree.
  • Writes a new root tree object representing the full project snapshot.
  • Creates a commit object containing:
    • the new root tree hash,
    • the parent commit hash (if any),
    • the author name,
    • the commit message,
    • a timestamp.
  • Stores the commit as a content-addressed object.
  • Updates last_commit to reference the new commit.
  • Clears the staging area.
  • Persists the updated configuration to patchwork.toml.

Although a commit is derived by applying changes to the previous tree, the resulting commit always represents a complete snapshot and can be reconstructed independently using its root tree hash.

Run the Peer Server


patchwork start

Starts the local Patchwork peer server.

This command is used to enable peer-to-peer collaboration. It loads the existing repository configuration and starts listening for incoming connections from other peers.

When running patchwork start:

  • The repository configuration is loaded from .patch/patchwork.toml.
  • The stored peer identity is used to initialize the local peer.
  • The peer server is started and listens for incoming clone, pull, and push requests.
  • The process keeps running until it is manually stopped.

The peer server must be running in order for other peers to clone the repository or exchange updates via pull and push.

Synchronizing Changes


patchwork pull [peer-public-key]

Fetches and integrates missing commits and objects from one or more peers.

The pull command synchronizes the local repository with remote peers using an incremental, history-based protocol. It compares commit histories and transfers only the data that is not already present locally.

When patchwork pull is executed, the following steps are performed:

  • Loads the local repository configuration and verifies that a peer endpoint is configured.
  • Determines which peers to pull from:
    • If a <peer-public-key> (endpoint of a peer) is provided, only that peer is contacted.
    • If no peer is specified, all known collaborators are contacted.
  • Checks whether each peer is reachable using a lightweight handshake.
  • Initiates a pull connection to each reachable peer.

For each connected peer, Patchwork performs an incremental synchronization:

  • The remote peer sends its latest commit hash.
  • The local peer replies with:
    • yay if the commit already exists locally, or
    • nay if the commit is missing.
  • If the commit is missing, the remote peer walks backwards through its parent commits until a common ancestor is found.
  • Only the commits that are missing locally are selected for transfer.
  • For each missing commit:
    • The commit object is transferred.
    • All tree objects required to reconstruct the directory snapshot are transferred.
    • All referenced blob objects (file contents) are requested and transferred.

After receiving all objects:

  • The commit, tree, and blob objects are written into the local object store.
  • The local last_commit pointer is updated to the newest received commit.
  • The updated configuration is persisted to patchwork.toml.

If no new commits are found, the pull operation terminates without modifying the repository.

The pull command allows Patchwork repositories to stay synchronized while minimizing network traffic by transferring only missing history and objects.

patchwork push

Sends local commits and objects to all known collaborators.

The push command propagates the local repository state to remote peers. It uses an incremental protocol to ensure that only commits and objects missing on the remote side are transferred.

When patchwork push is executed, Patchwork performs the following steps:

  • Locates the Patchwork repository and loads the configuration from .patch/patchwork.toml.
  • Collects all configured collaborators from the repository configuration.
  • Excludes the local peer from the list of push targets.
  • Connects to each collaborator using the push protocol.

For each connected peer, Patchwork performs an incremental push:

  • Sends the hash of the local latest commit.
  • The remote peer replies with:
    • yay if the commit already exists, or
    • nay if the commit is missing.
  • If the commit is missing, Patchwork walks backwards through the local commit history until a common ancestor is found.
  • Only the commits that the remote peer does not yet have are selected for transfer.
  • For each selected commit:
    • The commit object is sent.
    • All tree objects required to reconstruct the directory snapshot are sent.
    • All referenced blob objects (file contents) are transferred on demand.

After the transfer completes:

  • The remote peer updates its last_commit pointer.
  • The local peer prints a per-collaborator push result, including success or error information.

If no collaborators are configured, or if all peers are already up to date, the push operation terminates without transferring data.

The push command ensures efficient peer-to-peer synchronization by avoiding redundant data transfer and only pushing missing repository history.

Restoring Snapshots into the Working Directory

patchwork checkout [<commit-hash>]

Restores the working directory to the state of a specific commit snapshot.

The checkout command reconstructs the working directory from the tree referenced by a commit. Each checkout fully rebuilds the file hierarchy from stored tree and blob objects, ensuring the working directory matches the exact snapshot recorded in the commit.

If no commit hash is provided, Patchwork checks out the current last_commit.

When patchwork checkout is executed, Patchwork performs the following steps:

  • Loads the repository configuration.
  • Resolves the target commit:
    • uses the provided commit hash, or
    • falls back to last_commit if none is given.
  • Verifies that the commit exists locally.
  • Reads the root tree hash from the commit object.
  • Reconstructs the full tree structure from stored tree objects.
  • Recursively restores the working directory by:
    • creating directories for tree entries,
    • writing files by copying blob contents from the object store.
  • Writes all files relative to the project root.

The checkout process does not apply diffs or incremental changes. Instead, the working directory is rebuilt directly from the commit’s root tree, guaranteeing an exact and reproducible snapshot of the project state.

Branch-based checkout is not yet implemented.

Example: Two Peers Using Patchwork

cargo install --path ./

Peer 1:

patchwork init alice

mkdir src

echo 'fn main() { println!("Hello from Patchwork"); }' > src/main.rs

patchwork add src/main.rs

patchwork commit "Add initial main file"

patchwork start

Peer 2:

patchwork clone

patchwork pull

patchwork checkout

echo '// change by peer 2' >> src/main.rs

patchwork add src/main.rs

patchwork commit "Update main file from peer 2"

patchwork push

Peer 1:

patchwork checkout

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •