hav
Getting started

hav for git users

hav has a different core model from git, and a few git instincts actively mislead. This page gives you the translation table, then the habits to unlearn.

The rosetta table

You want to…githav
Create a repogit inithav init
See what's changedgit status + git diffhav st
Record workgit add + git commit -mhav describe -m names it; the snapshot already happened
Publish onto a branchgit merge / git rebase + pushhav tie
Start the next unit of workgit checkout -bhav new, or keep editing and let tie start a fresh knot
Throw away WIPgit reset --hard / git stash drophav discard (undoable)
A branchbranchbuoy, a named pointer that never holds checkout state
Work on two things at oncegit worktree add (one checkout per branch)hav ws new (any number per buoy)
Bring in upstream changesgit pull / git rebasehav sync, explicit, into your workspace
Look at historygit loghav log
Inspect one commitgit showhav show
Amend / rewritegit commit --amend, git rebase -ihav edit, hav squash, hav split, hav absorb; descendants auto-rebase
Fix up earlier commitsgit absorb / manual fixup dancehav absorb
Undo a mistakereflog spelunkinghav undo (files included)
Sharegit push / git pullhav push / hav pull (fast-forward-only; reconcile with tie)
A bare repo to push togit init --barehav init --bare
Serve repos over HTTPgit daemon / a forgehav harbor serve
Ignore files.gitignore.havignore (same syntax)

Habits to unlearn

Stop staging

There is no index. Every hav command begins by capturing the working tree into your current knot, so by the time you type hav st, the snapshot exists. describe names it and tie lands it. The one thing the staging area gave you, committing part of your tree, is hav split (by file or by hunk), a curation step you run after the work.

Stop thinking of branches as places

A buoy is a pointer to a knot, and that is all it is. You are never "on" a buoy; your workspace tracks one. Checking out doesn't exist, and switching doesn't exist. If you need to work on something else, make another workspace (hav ws new). Workspaces are cheap database rows, and any number can track the same buoy.

Stop fearing history rewrites

In git, editing an old commit orphans every descendant and hands you the pieces. In hav, edit an old knot and every tied descendant re-merges automatically. Conflicts, if any, are stored as data in the descendants, and buoy heads keep their ids. Squash, split, and absorb are everyday moves.

Stop expecting merges to stop you

tie and sync always complete. If content collides, the conflict is recorded inside the resulting snapshot and materialized as markers in the tree of whoever needs to resolve it. Nothing is "in progress", and there is no --continue or --abort. Fix the file (or run hav resolve --take ours|theirs) whenever you like, and the next command's capture notices.

Stop expecting pull to touch your files

hav pull moves history between repos and fast-forwards the local buoy. It never merges and never touches a working tree. Your workspace then says behind main — hav sync, and files move only when you run it. Nothing ever rewrites a tree that an agent or a build might be using.

Push is fast-forward-only

Divergence is reconciled locally. There is no force-push and no merge-on-push. If the remote moved, pull fetches it, tells you the histories diverged, and prints the recipe: tie the remote head into your buoy (an ordinary merge, conflicts as data), then push.

Things git doesn't have

  • Untied knots. Work that hasn't landed has no parents yet, only a base. History is written at land time (tie), so the everyday flow yields linear history without rebase ceremony. See The model.
  • The op journal. Every mutation records a full before/after view, and hav undo restores state and disk. It is the reflog, if the reflog covered everything and included your files. See Undo.
  • Sealed crews. Encrypted lines of work inside a shared repo, revealed by an ordinary tie --reveal with ids unchanged. See Sealed crews.

Things hav deliberately lacks

  • No git bridge. No import, no export. The way in is files; the way out is files.
  • No hooks. Nothing runs code on your behalf during a command.
  • No force-push, no --hard, no destructive flags. Destruction is scoped to two explicit verbs (op limit, sweep) with consent gates.
  • No hosted service. Remotes are paths, or harbors you run yourself.

On this page