Keeping workspaces in sync
Because every workspace is an independent clone, each one has its own fetch/pull state and its own local branches. That isolation is the point — but it means clones drift apart. Four commands operate on the main project and all workspaces at once to manage the drift:
workler status
workler fetch
workler sync
workler branch-syncNone of them ever merges, rebases, or force-pushes. Everything is fast-forward-only, and anything unsafe is skipped with a note.
workler status — where is everything?
One line per workspace: current branch (or detached SHA), ahead/behind vs its upstream, and clean/dirty:
NAME BRANCH UPSTREAM STATE
main main up to date clean
feature-a feature-a ahead 2 dirty
review-1 main behind 3 clean
old-thing (detached 1a2b3c4) no upstream clean
broken - - broken: missing .git (not a clone)Directories under .worktrees/ that are not usable clones are flagged as broken rather than hidden. Untracked files (such as the ones created by copy rules) never count as dirty.
workler fetch — update everyone's view of the remote
Runs git fetch --prune origin in the main project and every workspace. Workspaces without an origin remote are skipped with a note; a failure in one workspace (network, auth) is reported and does not stop the others.
workler sync — fetch, then fast-forward
sync fetches everything, then fast-forwards each workspace's current branch where an upstream exists:
fetching:
main fetched origin
feature-a fetched origin
updating:
main up to date
feature-a fast-forwarded feature-a (2 commits)
review-1 skipped (uncommitted changes)
spike diverged, skipped (ahead 1, behind 3)What sync will never do:
- touch a workspace with uncommitted changes to tracked files (untracked files don't block a sync)
- merge or rebase a branch that has diverged from its upstream — it is reported
diverged, skipped - update anything whose fetch failed (that would fast-forward onto stale refs)
- move a detached
HEAD
workler branch-sync — share local branches between clones
fetch/sync deal with the remote. branch-sync deals with local branches that exist only on your machine, syncing them across clones in both directions:
Root → workspaces. Every workspace gets a workler-root remote pointing at the main project (added even when there is no origin, fixed if the URL is wrong). The root's local branches are created in each workspace if missing, and fast-forwarded when strictly behind. The branch currently checked out in a workspace is never moved, and neither is a branch with local-only or diverged commits — both are skipped with a note.
Workspaces → root. Each workspace's local branches are mirrored back into the root as read-only refs under refs/workler/<workspace>/<branch>. No local branches are created in the root — inspect the mirrors with:
git for-each-ref refs/workler/
git log refs/workler/feature-a/spikeStale mirrors for removed workspaces are pruned automatically.
workspace feature-a
main up-to-date
spike created
wip skipped (checked out)
root refs (read-only, refs/workler/<workspace>/<branch>)
feature-a 3 branches -> refs/workler/feature-a/A typical rhythm
workler status # morning: where is everything?
workler sync # pull what's safe everywhere
workler branch-sync # make yesterday's local branches visible everywhere