workler branch-sync
Sync local branches between the main project and every workspace — no remote involved.
workler branch-syncBehavior
Where workler sync deals with origin, branch-sync deals with branches that exist only on your machine. It works in both directions:
Root → workspaces.
- Ensures every workspace has a
workler-rootremote pointing at the main project (added even when there is noorigin, fixed if the URL is wrong). - Creates the root's local branches in each workspace where missing.
- Fast-forwards workspace branches that are strictly behind the root's version.
Never touched, each skipped with a note:
- the branch currently checked out in a workspace
- a branch with local-only or diverged commits
Workspaces → root. Each workspace's local branches are mirrored into the root as read-only refs under refs/workler/<workspace>/<branch> — no local branches are created in the root. Stale mirrors of removed workspaces are pruned. Workler reports every workspace, then exits non-zero if any fetch, ref update, mirror, or prune operation failed.
Output
workspace feature-a
main up-to-date
develop fast-forwarded
spike created
wip skipped (checked out)
workspace review-1
main up-to-date
root refs (read-only, refs/workler/<workspace>/<branch>)
feature-a 4 branches -> refs/workler/feature-a/
review-1 1 branch -> refs/workler/review-1/
pruned refs/workler/old-ws/ (workspace removed)In a project group
A project group has no repository of its own, so the same two directions run between every member clone and the source repository it was cloned from: the source's local branches are created or fast-forwarded in the clone, and the clone's branches are mirrored into the source under refs/workler-group/<group>/<workspace>/<branch>, where <group> is the group folder's name plus a short hash of its path. That namespace is separate from refs/workler/, so a repository's own workspace named feat and the group workspace feat never prune each other, and a repository that belongs to two groups keeps one namespace per group: pruning in one never touches the other's mirrors. Rows are labelled <workspace>/<project>. The group's lock and every usable source repository's lock are held for the duration, so a branch-sync run inside a source repository at the same time fails with LOCKED.
workspace feat/projects/api
main up-to-date
from-root created
workspace feat/tools
main up-to-date
project refs (read-only, refs/workler-group/root-3f2a1b4c5d6e/<workspace>/<branch> in each source repository)
feat/projects/api 4 branches -> refs/workler-group/root-3f2a1b4c5d6e/feat/
feat/tools 2 branches -> refs/workler-group/root-3f2a1b4c5d6e/feat/Working with the mirrored refs
git for-each-ref refs/workler/ # what did every workspace produce?
git log refs/workler/feature-a/spike # inspect a workspace's branch
git diff main...refs/workler/feature-a/spike # review it against main
git branch spike refs/workler/feature-a/spike # adopt it as a real branchThis is the review flow for nested/agent workspaces: agents commit on branches in their own clones, branch-sync makes those visible in the root without letting any workspace move your branches.
Examples
workler branch-sync # both directions, all workspaces
workler branch-sync && workler remove exp # preserve exp's branches, then delete it