Skip to content

Playbooks for g

Story-style workflows—solo, team, and on-call. Jump into the full Use cases page anytime.

Workspaces

Git worktrees with friendly names, interactive switching, container layouts, and file-copy support.

Workspaces wrap git worktree: each workspace is a separate directory on disk with its own checkout, but they all share a single Git object database. You keep multiple branches alive at once — no stashing, no second clone, no lost context.

The main repo folder stays on `main`; `g workspace create` adds sibling (or container-child) directories that share the same Git object database but check out independent branches.

When to use workspaces

SituationWithout workspacesWith g workspace
Urgent hotfix arrives while you’re mid-featuregit stash, switch, fix, pop stash, prayOpen a second directory on main, fix there, come back
Two long-running tracks at onceClone the repo a second timeOne object store, two named directories
Review a teammate’s branch locallyAbandon your current stateCreate a workspace for their branch, switch in seconds
Work on a feature that needs .env tweaksManually copy files each time--copy brings your untracked files along
Onboarding a fresh repogit clone, settle for flat layoutgit clone then g workspace init, container layout from day one

Two directory layouts

Sibling layout (default)

Each workspace lives next to the repo root, joined by a configurable separator:

~/projects/myapp                    ← main repo      (main branch)
~/projects/myapp--feature-auth      ← workspace      (feat/auth branch)
~/projects/myapp--hotfix            ← workspace      (fix/oauth branch)

Container layout

Enabled by g workspace init. The original repo path becomes a container directory; each workspace is a child:

~/projects/myapp/                   ← container
~/projects/myapp/main/              ← primary workspace   (main branch)
~/projects/myapp/feature-auth/      ← workspace           (feat/auth branch)
~/projects/myapp/hotfix/            ← workspace           (fix/oauth branch)

Once in container layout, every future g workspace create places new worktrees inside the container automatically — no configuration needed.


Use cases

Fix a production bug without touching your feature branch

Who: You are halfway through feat/notifications. A login bug just hit production. It needs a patch on main now.

Goal: Produce a fix commit and PR without abandoning or stashing your current work.

What to do

  1. From anywhere in your repo, create a hotfix workspace branching off main:

    g workspace create hotfix -b fix/oauth-token

    g creates myapp--hotfix (sibling) or myapp/hotfix (container) and checks out a new fix/oauth-token branch there. Your current directory is untouched.

  2. Switch into it:

    g workspace switch hotfix
    # A subshell opens inside myapp--hotfix
  3. Fix, test, commit, push, open PR — exactly as normal:

    # ... edit files ...
    g commit -m "fix(auth): refresh token expiry window"
    g push origin fix/oauth-token
  4. Exit the shell when you are done. Your feature branch is right where you left it:

    exit
    # back in myapp on feat/notifications
  5. Once the hotfix is merged, clean up:

    g workspace delete hotfix

Run two long-lived features in parallel

Who: You own both the search redesign and the billing refactor. Each takes weeks. Switching between them with git switch means rebuilding caches, restarting dev servers, and losing IDE state every time.

Goal: Keep both tracks alive on disk at the same time.

What to do

  1. Set up both workspaces once:

    g workspace create search-v2 --description "Elasticsearch rollout"
    g workspace create billing-ui -b feat/billing-shell --description "Stripe v3 migration"
  2. See what is running:

    g workspace list
      ◉ main        main          ~/projects/myapp/main          abc1234  —
      ◯ search-v2   feat/search   ~/projects/myapp/search-v2     def5678  3 hours ago
      ◯ billing-ui  feat/billing  ~/projects/myapp/billing-ui    9ab0123  1 day ago
  3. Jump between them as needed:

    g workspace switch        # interactive fuzzy picker — type to filter
    g workspace switch search-v2   # or directly by name
  4. Each workspace gets its own node_modules, build cache, and editor window. Switching is opening a shell tab — not a git switch.


Pick up a teammate’s branch for local testing

Who: You are reviewing a PR for feat/new-dashboard. You want to run it locally without leaving your current branch.

Goal: Check out their branch in a separate directory while staying on your own work.

What to do

  1. Their branch exists on origin but not locally. g tracks it automatically:

    g workspace create dashboard-review -b feat/new-dashboard
    # → finds origin/feat/new-dashboard, creates a local tracking branch
  2. Switch in, run their dev server on a different port, test:

    g workspace switch dashboard-review
    npm run dev -- --port 3001
  3. Leave feedback, exit, delete:

    exit
    g workspace delete dashboard-review

Start a new project with workspace layout from day one

Who: You are cloning a repo for a new engagement. You know you will work on multiple branches over time and want the container layout from the start.

Goal: Clone and be workspace-ready before writing a single line of code.

What to do

git clone https://github.com/org/api-service.git
cd api-service
g workspace init
cd ../api-service/main

What happened:

~/projects/api-service/         ← container created
~/projects/api-service/main/    ← repo moved here

From now on, g workspace create feature-x places the worktree at api-service/feature-x/.


Convert an existing repo to container layout

Who: You cloned the repo months ago the normal way. You have started hitting the “too many stashes” problem and want to switch to worktrees properly.

Goal: Reorganise the existing clone in place without losing any work.

What to do

  1. Make sure your working tree is clean (commit or stash anything in progress):

    g status
  2. Run init from inside the repo:

    cd ~/projects/myapp
    g workspace init

    init prints its plan — exactly which directories will move — and asks for confirmation before touching anything:

      move  ~/projects/myapp  →  ~/projects/myapp--ws-tmp
      mkdir ~/projects/myapp
      move  ~/projects/myapp--ws-tmp  →  ~/projects/myapp/main
    
    Proceed? [y/N]
  3. Confirm, then navigate to the new inner location:

    cd ~/projects/myapp/main
  4. Create your first extra workspace:

    g workspace create feature-x
    # → placed at ~/projects/myapp/feature-x/

Bring your local config files along

Who: Your project needs .env, config/local.yml, and a self-signed cert that are gitignored and live only in your checkout. You branch off to work on a new feature but those files are missing from the fresh worktree.

Goal: Copy just the files you need into the new workspace without manual cp commands.

What to do

g workspace create feature-payments --copy

An interactive checklist appears listing every untracked and gitignored file in your current workspace:

Select files to copy into the new workspace (space to toggle, enter to confirm)
> [x] .env
  [ ] .env.test
  [x] config/local.yml
  [ ] certs/localhost.pem

Toggle with Space, confirm with Enter. Only the selected files are copied — directory structure is preserved.


Jump to any workspace from anywhere

Who: You have four workspaces open and lost track of which terminal is which.

Goal: Get into the right workspace without remembering the exact name.

What to do

Run switch with no argument:

g workspace switch

A fuzzy-searchable list opens:

Switch to workspace
> ◉ main         main          ~/projects/myapp/main
  ◯ feature-auth feat/auth     ~/projects/myapp/feature-auth
  ◯ hotfix        fix/oauth     ~/projects/myapp/hotfix
  ◯ billing-ui    feat/billing  ~/projects/myapp/billing-ui

Type any part of the name, branch, or path to filter. The workspace you are currently inside is pre-selected. Press Enter to open a shell there, Escape to cancel.


Command reference

g workspace init

Reorganise an existing repo into container layout. Shows a plan and asks for confirmation. On failure, rolls back to the original state.

g workspace init

g workspace list

Show all worktrees with metadata. The ◉ marker indicates the workspace your shell is currently inside.

g workspace list
     Name         Branch        Path                              HEAD     Created
─ ──────────── ─────────────  ──────────────────────────────────  ───────  ───────
◉ main         main          ~/projects/myapp/main               abc1234  —
◯ feature-auth feat/auth     ~/projects/myapp/feature-auth       def5678  2 days ago
◯ hotfix       fix/oauth     ~/projects/myapp/hotfix             9ab0123  4 hours ago

g workspace create

# New branch named after the workspace
g workspace create feature-auth

# New branch with a custom name
g workspace create hotfix -b fix/oauth-token

# New branch from a specific commit
g workspace create hotfix -b fix/oauth-token abc1234

# Existing local or remote branch (remote auto-tracked if not local)
g workspace create auth-review -b feat/auth

# With a description shown in list view
g workspace create search-v2 --description "Elasticsearch rollout"

# Copy untracked/gitignored files from the current workspace
g workspace create feature-payments --copy

# Combine flags
g workspace create feature-x -b feat/x --description "New feature" --copy

Branch resolution order:

  1. Exists locally → check out directly.
  2. Exists on origin only → create a local tracking branch.
  3. Neither → create a fresh branch (optionally from a start point).

g workspace switch

g workspace switch              # interactive fuzzy picker
g workspace switch feature-auth # direct by name (fuzzy matched)

Opens a subshell in the workspace directory. Exit with exit or Ctrl+D to return.

g workspace status

Show what workspace you are currently inside, its branch, path, creation time, and a change summary.

g workspace status

Run this from any linked worktree — useful when you forget which checkout you are in.

g workspace rename

Rename a workspace — moves the directory on disk and runs git worktree repair to update git’s internal tracking.

g workspace rename feature-auth auth-v2

g workspace delete

g workspace delete auth-v2
g workspace delete auth-v2 --force    # remove even with uncommitted changes

Remote branch auto-tracking

When you pass -b <branch> to create and that branch does not exist locally, g checks origin/<branch> before creating a fresh branch:

# origin/feat/payments exists locally
g workspace create payments -b feat/payments
# → git worktree add ... -b feat/payments --track origin/feat/payments

If neither local nor remote is found, a new branch is created from the current HEAD (or from start_point if given).


Configuration

[workspace]
separator = "--"    # sibling layout only: myapp--workspace-name

The separator has no effect in container layout — workspace names become directory names directly.


Under the hood

g workspace is a thin layer on top of standard git worktree commands:

git worktree add <path> <branch>                         # existing local branch
git worktree add -b <branch> --track origin/<b> <path>  # remote tracking branch
git worktree add -b <branch> <path> <start-point>        # new branch from commit
git worktree list --porcelain                             # list (for display)
git worktree remove [--force] <path>                     # delete
git worktree repair                                       # after rename or init
git ls-remote --symref <url> HEAD                        # clone: detect default branch

Metadata (friendly names, descriptions, creation timestamps, container root) is stored in ~/.config/g/workspaces.toml alongside the rest of your local developer state. It is not part of the repository and is not committed.


Tips

  • g workspace status tells you which checkout you are in from any linked worktree — useful when you have three terminals open on the same repo.
  • g workspace switch (no argument) is faster than list for navigating: just type a fragment of the name or branch.
  • One workspace per long-running branch beats stashing. Stashes accumulate; workspaces have names.
  • Preview destructive operations with g --dry-run workspace init to see exactly what will move before it moves.
  • See Git flows for how worktrees complement stack workflows — for example, fixing main in a hotfix workspace while a feature stack stays open in another directory.