Compare to git
Git's verbs keep git's names. Here is each common git command next to the seam command that does its job, and then what works differently.
Commands side by side
| git | seam | Notes |
|---|---|---|
git init | seam quilts new <slug> | main starts at an empty root commit. |
git clone | seam checkout <rev> --quilt <q> --dir <folder> [-- paths] | Writes files only, no history. Name paths for a sparse checkout. |
git switch -c <branch> | seam square open "<title>" --quilt <q> [--dir <folder>] | A square starts at the tip of main. |
git switch <branch> | seam checkout sq:<id> | Inside a block folder with nothing uncommitted. |
git branch | seam square list [--mine] [--all] | Open squares, or every square with --all. |
git status | seam status | In a block folder. Also says what merged under you. |
git add + git commit | seam commit -m "<message>" [paths] | No staging area. |
git push | (nothing) | A commit is on the server when it is made. |
git pull --rebase | seam rebase | Moves the square onto the tip and updates the folder. |
git diff | seam diff | Your uncommitted changes, in a block folder. |
git diff a b | seam diff a b, seam diff a..b | Also --stat and --name-only. |
git log | seam log [rev] [-n 20] [--oneline] [-- paths] | Newest first. Ranges like main~5..main work. |
git show | seam show <rev> [--stat | --name-only] | |
git blame | seam blame <path>[@rev] | Computed by the server, with the patch of each line. |
git show rev:path | seam cat <path>@<rev> | Writes the file's bytes to stdout. |
git ls-tree -r | seam ls [rev] [paths] | |
git merge + push to main | seam merge [sq:<id>] --into main | Rebased onto the tip as one patch, on the server. |
git merge <other> | seam merge sq:<other> | In your block: a two-parent commit in your square. |
git rebase [--onto] | seam rebase [--onto <rev>] | Conflicts are kept in the square; it never stops halfway. |
git cherry-pick | seam cherry-pick <rev> | Into your square, as a new commit. |
git revert | seam revert patch:<n> | Opens a new square that undoes the patch; merge it. |
git checkout --ours | seam resolve <path> --ours | Also --theirs, --base, --suggestion, --side n, --delete. |
git branch -D | seam square abandon | Kept and readable; seam square reopen brings it back. |
git merge --squash a b | seam square fold --into sq:<id> | One square's work becomes one commit in another. |
git add -p into two branches | seam square split <paths,...> <paths,...> | Each group of paths moves to a new square. |
git fast-import | seam import git <path> | Once, into a new quilt. |
git fast-export | seam export git <dir> | One way, to a branch of a plain git repo. |
Inside a block folder the quilt and the square come from the folder. Anywhere else, name them with --quilt <slug> and --square sq:<id>.
What is different
No local history
A git clone carries every commit. A block folder carries only files, plus .seam/block.json saying which quilt, square and commit they came from. log, show, blame and diffs between revisions are answered by the server. That keeps a checkout small and never stale, and it means you need to be online.
The server merges
Merging into main is one call. The server replays your square onto the current tip, combines changes to different parts of the same file, writes one commit and moves main with a compare-and-swap. If another merge won the race, it retries by itself, up to five attempts in all; after three lost races the merge waits its turn for the line, so it does land. There is no merge queue and nothing to pull first.
Because each square lands as one commit, main is a straight line of patches. Two-parent commits only happen inside squares.
Squares instead of branches
A square is not a name pointing at a commit. It is a record with an id, a title, a state and a holder: the one member who may commit to it. You hand it to someone else with seam square handoff. Abandoning a square does not delete its commits; they stay readable by id.
Patch numbers
Each merge into main gets the next number. patch:412 always names the same change, and main~3 is three patches back. seam log --oneline shows the number beside each commit: [main:412].
Conflicts are data
Git stops a merge with conflicts and waits for --continue or --abort. Quilt never stops halfway. A clash is stored in the commit as a conflict: each side, its base, and who made each side. The square carries it and keeps working; you can commit, rebase and hand it off. Only merging into main waits until it is settled. Read a conflicted file in the form you like: seam cat <path>@sq:<id> --format diff (the default), snapshot or git (classic <<<<<<< markers, two sides only).
Authors are members
There is no --author. Each commit records the signed-in member, with the AI tool it came through (Author: builder <agent:5c1e…> via claude) and, for an agent, the person it works for.
What git has that Seam does not
Some of these are left out on purpose. Others are in the design and not built yet.
Left out
- Push, pull, fetch and remotes. There is one server and it has every commit when it is made.
- The staging area and stash. Commit names paths when you want only some files; uncommitted work stays in its folder.
- Merge commits on main. Every square merges as one rebased patch.
- Hand-written authors and dates. The server records who you are and when.
Import and export
Import
$ seam import git ./my-app [--into <slug>] [--validate]- Reads the repo on your computer and makes a new quilt. Each commit on
HEAD's first-parent chain becomes a patch onmain. - The side commits of a merge become the commits of that patch's square. A square from a merge commit like
Merge pull request #12 from ada/fixtakes the branch name as its title. - Authors become stub members,
stub:<email>, so blame and log keep their names. - Each imported commit remembers its git sha:
seam show git:4d5bb0ffinds it. --validatecompares every patch's files with its git commit when the import is done.- Only
HEAD's history is imported. Other branches, tags and submodules are not.
Export
$ seam export git ../my-app-git --quilt my-app [--line main] [--branch <name>]- Writes each patch of the line as one commit on a branch (named after the line unless you pass
--branch). A folder that does not exist yet becomes a new bare repo. - Run it again to add the patches merged since. It keeps its place in
quilt-export.jsoninside the git directory. - The same patch always gives the same git commit id, on any machine.
- Each commit message ends with trailers:
Quilt-Commit,Quilt-Square,Quilt-PatchandQuilt-Author, plusQuilt-On-Behalf-OfandQuilt-Taskwhen they apply. - Authors keep the email from a git import; everyone else gets a noreply address such as
<name>@agents.noreply.heyquilt.com. - It is one way. If the branch moved since the last export, the export refuses and asks for a new branch or repo. It never merges or forces.
Ready to try it? Get started walks through an import from the beginning.