Collaborate with Branches¶
A branch is an isolated line of work. This guide covers the day-to-day loop of taking a piece of work onto its own branch, sharing it, moving between branches, and closing it out when you are done.
If you are coming from Git or Perforce, Comparing with Other Source Control Tools maps those workflows onto FlexVault's model. This guide assumes you have a workspace connected to a repository and are logged in, as covered in Getting Started with the CLI.
Everyone starts on main¶
A new repository has one branch, main, and a new workspace starts on that branch by default. Work there is private until you publish it: as you edit, the FlexVault Agent records draft revisions in your workspace, and nobody else sees them.
$ fxv status
Current branch: main
Local snapshot: main.456.3
Branch head: main.456
Workspace is up to date with published branch
For a small team working on one line of development, that is the whole workflow. Branches become useful when a piece of work needs to be shared before it is ready to go onto main, or when it should proceed separately from it.
Start a piece of work on its own branch¶
fxv branch new creates a branch and moves your workspace onto it:
$ fxv branch new fix-water-shaders
Created branch alice/fix-water-shaders at alice/fix-water-shaders.-.1 (from main.456).
Didn't mean to create a user branch? To make it global, run `fxv branch promote alice/fix-water-shaders`.
Workspace is now on alice/fix-water-shaders. Local changes were left as they are.
IMPORTANT: This branch is a draft, local to this workspace. Run `fxv publish` to share it.
That output covers three things.
The branch you asked for as fix-water-shaders was created as alice/fix-water-shaders. A branch created without --global is a user branch, owned by you and written with your username as a prefix. Every other command refers to it by that full name. A global branch, like main, has a bare name and belongs to nobody, and is created with fxv branch new --global.
A branch name is what the rest of your team sees in a listing if they look through branches, so it's generally helpful to use descriptive names. fix-water-shaders or bug-fxv-112 says what the branch is for, where shaders or wip is not as helpful. You do you though. A name is up to 64 characters of letters, digits, _, -, or spaces.
After this operation, your working directory was not touched. Uncommitted edits stay exactly where they are on disk and become local changes on the new branch, so you can work first and decide it deserves a branch afterwards. This is the usual way to start: notice that what you are doing has grown, and move it.
The branch is local to your workspace until you publish it. Nobody else can see it, list it, or sync to it, and fxv branch list marks it accordingly:
$ fxv branch list
Branch Revision
main main.456
* alice/fix-water-shaders alice/fix-water-shaders.-.1 (local only)
The - in alice/fix-water-shaders.-.1 sits where a published revision number would go. The branch has nothing published on it yet, so there is no published revision for the draft to be numbered against.
Choosing between a user branch and a global branch
A user branch suits one person's piece of work, such as a fix, a feature, or an experiment, though it is not private and can be shared once published. A global branch suits work that many people publish to from the start, or that outlives any single task, such as release stabilization or a hotfix line against a live release.
Both are suggestions rather than rules. FlexVault does not enforce a workflow, so use whatever fits your team and the work in front of you.
Note
fxv branch promote, offered in the hint above, is not available yet. Until it is, a branch that should be global has to be created that way with fxv branch new --global.
Share the branch¶
fxv publish publishes your current draft to the branch you are on. The first publish is also what makes the branch itself visible to everyone else:
In a brand new repository
A branch's first publish records the published revision its history descends from. If nothing in the repository has been published yet, there is nothing to record and the publish fails. Publish once on main first, then publish the branch.
From here, a teammate can find it in a listing and can move onto it themselves:
$ fxv branch list --all
Branch Revision
* main main.456
alice/fix-water-shaders alice/fix-water-shaders.0
Without --all, a listing shows the global branches and your own. --all widens it to every user's branches, and --owner alice narrows it to one person's.
The owner prefix records who created a branch, not who may use it. Once published, a user branch is shared like any other: a teammate can switch onto it, pick up your later revisions with fxv sync, and publish their own work to it. Multiple people collaborating on alice/fix-water-shaders is supported as a normal workflow.
Switching between branches¶
fxv branch switch moves the workspace onto another branch, at whatever revision of it you hold: your latest draft revision there, or the branch's published head if you have no local work on it.
Switching is safe with edits in progress. They are snapshotted onto the branch you are leaving before the workspace moves, so they stay with that branch and are waiting for you when you switch back.
Which command you want depends on what you are trying to do:
fxv branch switch <branch>changes which branch you are working on, and takes your own work on that branch with it.fxv syncstays on the current branch and pulls in work published elsewhere, merging your unpublished drafts on top of it.fxv goto <revision>aligns the workspace with one existing revision, exactly as it was.
That last one is why a published revision ID is what you send to somebody else. fxv branch switch alice/fix-water-shaders leaves two people on two different revisions, because which revision of a branch you hold depends on your own unpublished work. A published revision is the same content in every workspace, so pasting one into a chat message puts a colleague on exactly what you are looking at:
Draft revisions do not work that way. Drafts are local, so your main.123.1 and a colleague's main.123.1 are unrelated pieces of work that happen to share an ID. A draft revision ID is only meaningful in the workspace that made it, and fxv goto main.123.1 sends each of you somewhere different.
Keep your branch up to date¶
fxv sync brings your workspace to the latest published revision of the branch you are on, merging your unpublished drafts on top of it. On a shared branch, that is how you take in what other people have published, and any of their changes that collide with your drafts are flagged as conflicts for fxv resolve to settle:
Sync works within one branch. It does not bring main's newer revisions onto alice/fix-water-shaders, and it will not take alice/fix-water-shaders back to main.
Combining two branches is not available yet
fxv merge is planned but not implemented, and there is no other command that combines two branches. A branch cannot currently be brought back into main, and main cannot be brought forward into a branch that was created from an earlier revision of it.
Until it exists, plan branches around that limitation. Work destined for main is simplest to do on main, publishing as you go. Branches suit work that will stay separate, or that will be published and consumed on the branch itself.
Rename a branch¶
A name chosen early does not have to be permanent. fxv branch rename changes it, and the branch keeps its history, its revisions, and its owner:
$ fxv branch rename alice/fix-water-shaders fix-water
Renamed branch alice/fix-water-shaders to alice/fix-water.
Its history and revisions are unchanged.
Give the new name on its own, as above, or with your own <username>/ prefix. Someone else's prefix is rejected, because a rename does not hand the branch to another owner.
A revision ID starts with a branch name, so a rename invalidates the IDs people wrote down under the old one. alice/fix-water-shaders.0 stops resolving, and that same revision becomes alice/fix-water.0. If you have already shared an ID and then rename, send the new one.
Renaming a global branch changes what everybody types, so it requires --force. The repository's default branch cannot be renamed at all.
Finish with a branch¶
Everything in FlexVault is preserved, even when you're done with a branch. To indicate that you are finished with a branch, and to hide it from general view, you retire it:
Retiring does two things. It takes the branch out of default listings, so a repository accumulates finished branches without them getting in the way, and it blocks publishing to the branch.
Everything else still works. The branch's history is readable, fxv branch switch still moves onto it, a new branch can be created from any of its revisions, and you can still snapshot local work there. A snapshot on a retired branch tells you that publishing is blocked and saves the work anyway, so nothing is lost if you edit a retired branch by accident.
Retiring a global branch affects everyone, so it requires --force:
If the work turns out not to be finished, fxv branch restore reverses the retirement and the branch is publishable again:
Note
Ownership and retirement are advisory. FlexVault has no authentication yet, so they record who a branch belongs to and whether it is finished, rather than restricting who can act on it. Anyone connected to the repository can retire or restore any branch.