drift

module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 14, 2026 License: MIT

README

drift logo

drift

中文文档 · GitHub · Roadmap


Version control for creators — a content-addressed, chunk-deduplicated version control system designed for writers, illustrators, and designers. Unlike Git, which treats every file as opaque bytes, drift recognizes image and video formats, shows meaningful metadata in diffs, and stores only what actually changed through content-defined chunking.

Status: Phase 1–3.5 complete (local core + branches + filetype engines + remote sync). GUI desktop app is a planned phase; see docs/roadmap.md.

Why drift?

Pain point with Git drift answer
200 MB file changes by a small part → store the whole file again FastCDC content-defined chunking stores only the changed blocks
Staging area / commits / merge — a programmer's mental model save captures all changes automatically; no staging, no merge
Diff shows raw bytes for binary files Pluggable filetype engines (text/image/video/binary): text gets unified diff, images/videos show format and dimension changes
No visual timeline CLI stage shows history in tables; GUI visual timeline is Phase 4
Branches mean merge conflicts Branches are pure forks for experimentation; user merges manually

Features

  • Content-addressed storage — BLAKE3 hashes verify integrity and dedupe automatically across snapshots and branches.
  • CDC chunking — FastCDC for variable-size content-defined chunks, with a fixed-size fallback for very large files (>100 MB). zstd compression on top.
  • No staging areadrift save captures the working tree as-is. Authors think about their work, not about indexes.
  • Branches without merge — create experimental branches, switch freely, restore from anywhere. No merge conflicts, ever.
  • Filetype engines — text (unified diff), image (format/dimension/size comparison, supports PNG/JPEG/GIF/WebP/BMP/TIFF), video (format detection + dimension parsing, supports MP4/MOV/AVI/MKV/WebM), binary (fallback). New engines plug in via a registry.
  • Automatic watchesdrift watch on periodically scans the workspace and auto-saves when changes are detected (default interval 300s), with auto-saves hidden from log by default.
  • Remote sync — push/pull to remote storage via WebDAV or SMB, with incremental transfer and branch-scoped sync.
  • Single binary — one static Go binary for macOS / Windows / Linux. No runtime, no daemons to install.

Install

go install github.com/Alei-001/drift/cmd/drift@latest

Or build from source (with version metadata injected via ldflags):

git clone https://github.com/Alei-001/drift.git
cd drift
go build -ldflags "-X github.com/Alei-001/drift/internal/version.Version=v0.1.0" -o drift ./cmd/drift

Requires Go 1.25+.

Upgrade

Once a GitHub release is published, self-upgrade to the latest version:

drift upgrade          # download and replace the current binary
drift upgrade --check  # only check for a newer release

Release assets follow the naming convention drift_<version>_<os>_<arch>.{zip|tar.gz} with an optional drift_<version>_checksums.txt (SHA-256) that is verified when present.

Quick start

# Initialize a project
cd my-novel
drift init

# Save a snapshot
drift save -m "Chapter 1 draft"

# See what changed since the last save
drift status

# Browse history (current branch chain)
drift log

# Try an experimental direction
drift branch create rewrite-ending
drift switch rewrite-ending
# ... edit files ...
drift save -m "Alt ending v1"

# Switch back; the rewrite is preserved on its own branch
drift switch main

# Inspect a specific snapshot's file changes
drift log --detail id:12ab

# Restore the workspace to a previous snapshot (auto-backs up first)
drift restore id:12ab

# Undo the last save
drift undo

# Configure a remote and sync
drift remote add origin --url https://example.com/dav/my-novel --user <user>
drift push origin            # push local data to remote
drift pull origin            # pull latest data from remote
drift clone https://example.com/dav/my-novel my-novel  # clone a remote repo

Commands

Command Purpose
drift init Create .drift/ repository
drift save [-m <msg>] [--tag <name>] Save a snapshot of all changes
drift status Show added / modified / deleted files
drift log [--branch <name>] [--all] [--limit <n>] Browse snapshot history
drift show <version> [<file>] List files in a snapshot, or display a file's content
drift diff <v1> <v2> Diff two snapshots (file list or unified diff)
drift restore <version> Restore the workspace to a snapshot (backs up first)
drift undo Undo the last save
drift branch {list,create,delete,rename} Manage branches
drift switch <branch> Switch to a branch (optionally create with -c)
drift tag {list,add,delete,rename} Manage tags
drift watch {on,off,status,pause,resume} Background auto-save daemon
drift ignore <pattern> Add ignore rules to .driftignore
drift resolve <version> Resolve a version reference to a snapshot ID
drift remote {add,list,remove,rename,set-url,show,test} Manage remote repository configuration
drift push <remote> [--branch <name>] [--dry-run] Push local data to remote
drift pull <remote> [--branch <name>] [--dry-run] Pull data from remote to local
drift clone <remote-url> <path> Clone a remote repository to local
drift ls-remote <remote> List branches and tags on a remote
drift check Verify .drift/ storage integrity
drift gc [--dry-run] Remove unreachable snapshots and chunks
drift config {get,set,list} View and modify configuration
drift version Show version, commit, and build info
drift upgrade [--check] [--force] Self-upgrade to the latest GitHub release

Version references

Commands that take a <version> accept:

  • head — current HEAD snapshot
  • id:<hash-prefix> — match by hash prefix (≥ 4 chars)
  • tag:<name> — resolve via tag
  • branch:<name> — resolve via branch head
  • <bare-name> — shorthand for branch:<bare-name>

Project layout

cmd/                  CLI entry points (cobra commands) — no business logic
  drift/              main binary
internal/             business implementation (not importable externally)
  porcelain/          business logic: snapshot, branch, restore, lock, watch, gc
  filetype/           pluggable type engines (text/image/video/binary)
  chunker/            FastCDC + fixed-size chunking
  storage/            Storer interface + shared helpers
    backends/         filesystem (prod) and memory (tests) implementations
    refname/          branch / tag name validation
    stream/           chunk streaming helpers
  remote/             remote sync: WebDAV/SMB protocols, push/pull transfer
  core/               domain types: Hash, Chunk, Snapshot, FileEntry, Config, ...
  util/               fsutil, glob, pathutil, format, cache
  version/            build-time version metadata + self-upgrade
docs/                 design and reference docs

See AGENTS.md for the full layering rules and conventions.

Documentation

Building and testing

go build ./...            # build all packages
go test ./...             # run all tests
go test -run TestFoo ./internal/porcelain/   # single test

No Makefile, no lint config — pure go toolchain. CI via GitHub Actions (see .github/workflows/).

Protobuf codegen

Generated files live in internal/core/*.pb.go. Regenerate with:

protoc --proto_path=internal/core --go_out=internal/core --go_opt=paths=source_relative internal/core/snapshot.proto
protoc --proto_path=internal/core --go_out=internal/core --go_opt=paths=source_relative internal/core/index.proto

The --go_opt=paths=source_relative flag is required (see AGENTS.md).

Key dependencies

License

MIT — see the LICENSE file for details.

Directories

Path Synopsis
cmd
drift command
internal
storage/refname
Package refname validates reference names (branch, tag, HEAD) for both storage backends.
Package refname validates reference names (branch, tag, HEAD) for both storage backends.
util/logutil
Package logutil configures the global slog logger to write structured logs to a file inside the .drift/ directory.
Package logutil configures the global slog logger to write structured logs to a file inside the .drift/ directory.
util/pathutil
Package pathutil provides cross-platform path utilities.
Package pathutil provides cross-platform path utilities.
version
Package version exposes the build-time version metadata of the drift binary and the self-upgrade workflow.
Package version exposes the build-time version metadata of the drift binary and the self-upgrade workflow.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL