branch/work

The bw tool

One small binary that turns the commits on your machine into a stack of reviewable changes.

Installing

bw is a single static binary with no runtime to install. See the tool page for the package manager commands. To build it from a checkout of the repository:

$ go build -o bw ./cli/cmd/bw
$ mv bw /usr/local/bin/

Check it works:

$ bw version
bw 1.0.0

Signing in

bw never asks for your password, because there is not one. It uses a device authorization flow: the tool shows a short code, you approve it in a browser, and the tool collects a token afterwards. The token never appears in your shell history and is never typed into the terminal.

$ bw auth login

  Your code is KRPT-8N2W
  Approve it at https://branchwork.info/device

  Waiting for you to approve. Press Ctrl-C to stop.

ok Signed in as yourhandle.
Token saved to ~/.config/branchwork/config.json

Check that the code in your browser matches the code in your terminal. That is what the code is for: it proves the browser is approving the terminal in front of you and not somebody else's.

The token is written with owner-only permissions. Each machine gets its own, and you can revoke any of them under Settings, Devices.

Other auth commands

$ bw auth status      Who you are and which server you are pointed at
$ bw auth logout      Forget the token on this machine

logout clears the local file. To make the token itself stop working everywhere, revoke it in Settings.

Stacks

bw stack create

$ bw stack create "Search pipeline"
$ bw stack create "Search pipeline" --repo yourhandle/project --base develop
$ bw stack create "Search pipeline" --description "Parser, planner, ranker"

Creates a stack and links your current branch to it. The repository name is guessed from your origin remote. The base defaults to main and is the branch your commits are measured against.

The link is stored in .git/branchwork/stack.json, inside the repository rather than in your global config, because one machine can have many checkouts.

bw stack list

Every stack you can see, with its id, name, repository and owner.

bw stack status

The most useful command in the tool. It compares the commits on your branch against what the server has:

$ bw stack status

Search pipeline  yourhandle/project onto main
https://branchwork.info/stack/stk_8f56e965

COMMIT    CHANGE            STATE     SUBJECT
f12ead77  chg_b9d22681-753  r2 open   Tokenize search queries
96c3a08e  chg_7d2cab5c-a8e  r1 open   Plan index scans
8be9afe0  -                 new       Rank results by recency

new means submitting will create a change for that commit. Run this before submitting if you want to know what is about to happen.

bw stack link

$ bw stack link stk_8f56e965

Points the current branch at an existing stack. Use it after a fresh clone, or when somebody else created the stack.

bw submit

The command everything else supports.

$ bw submit
$ bw submit --dry-run

It runs in two passes:

  1. Every commit without a Change-Id trailer gets a change created for it, stacked in commit order. The trailers are then written into your branch in a single rewrite.
  2. Each commit's content is pushed as a revision of its change.

Splitting it that way is what makes submit safe to run repeatedly. After the first run every commit carries its id, so later runs create nothing and only push what actually differs.

About the rewrite

Adding a trailer to a commit that is not HEAD cannot be done by amending, so bw rebuilds the branch: each commit keeps its own tree, author, and dates, and gets a new message. The branch only moves once every new commit exists, so a failure part way through leaves your original branch untouched.

Your commit hashes change. That is inherent to adding anything to a commit message, and it is the same thing a rebase does. Run bw init to avoid it entirely.

--dry-run

Prints what would happen and sends nothing. Good for the first time.

bw sync

$ bw sync
$ bw sync --no-fetch

Fetches, rebases your branch onto its base, then submits whatever moved.

It refuses to run with uncommitted changes. There is no flag to override that. Commit or stash first.

If the rebase hits a conflict, it stops and tells you what to do:

error: the rebase stopped, most likely on a conflict.
  Resolve it, run git rebase --continue, then run bw submit.
  To abandon the rebase entirely, run git rebase --abort.

bw change

$ bw change list                    Changes in the linked stack
$ bw change list stk_8f56e965      Changes in any stack
$ bw change view chg_b9d22681      One change, its revisions and its reviews

bw review

$ bw review list                   What is waiting on you
$ bw review show chg_b9d22681      The incremental diff
$ bw review show chg_b9d22681 --full

review list shows open changes you did not write where your last review, if any, is older than the current head.

review show prints the same incremental scope the website opens on: only what landed since your last review of that change. Pass --full for everything.

You cannot submit a verdict from the terminal, by design. Notes and approvals belong somewhere you can see the code properly.

bw checkout

$ bw checkout chg_b9d22681
$ bw checkout chg_b9d22681 --branch review/parser

Creates a branch and writes the files from that change's head revision into your working tree, so you can actually run a teammate's work rather than only read it.

This is a snapshot of the head revision, not a fetch of the original commits. Branchwork stores file contents rather than git objects today, and the command says so rather than pretending otherwise.

bw init

$ bw init
ok Installed .git/hooks/commit-msg.

Installs a commit hook that adds a Change-Id trailer as you commit. Then bw submit never has to rewrite anything, and your commit hashes never change underneath you. Worth running in any repository you use regularly.

It refuses to overwrite an existing commit-msg hook. If you have one, look at it and combine them by hand.

Configuration

Config lives at ~/.config/branchwork/config.json on macOS and Linux, and under your profile's app data directory on Windows.

  • BRANCHWORK_SERVER - point at a different server.
  • BRANCHWORK_TOKEN - use a token without saving it. Useful in CI.
  • BRANCHWORK_CONFIG_DIR - put the config somewhere else.
  • NO_COLOR - turn off color. Color is off automatically when output is piped.

When things go wrong

you are not signed in

Run bw auth login. If it keeps happening, the token was probably revoked in Settings.

this branch is not linked to a stack

Run bw stack create, or bw stack link <stack-id> if the stack already exists.

that change already has something stacked on it

A stack is a line, so each change has at most one child. This usually means two branches are submitting into the same stack. Give the second one its own stack.

Only the change's author can push to it

Exactly what it says. To iterate on someone else's change, use bw checkout and put your version in your own change.

The rewrite failed part way

Your commits are intact - the branch only moves after every rebuilt commit exists. Fix whatever git complained about and run bw submit again.

Something unclear or wrong here? Tell us - that is a bug in the docs, and we treat it like one.