Git worktrees
A git worktree is a second checkout of the same repository, on another branch, in another folder. cornercase turns each one into a workspace, so every line of work has its own files, its own shells and its own agent, and none of them steps on the others: a build, a half-written change or an agent’s edits stay in their own folder.
When worktrees are available
Section titled “When worktrees are available”Worktrees are offered when the project folder is the root of a git repository, that is, it contains a .git folder. A project that is a subfolder of a repository, or a folder without git, gets plain workspaces instead.
Create a worktree workspace
Section titled “Create a worktree workspace”-
Click
+ Newunder the workspaces, then new workspace. -
Type the branch name. The dialog shows where the checkout will go.
-
Keep with its own worktree ticked (click it or press
Tabto toggle) and click create.
cornercase then, in the background:
- checks out the branch if it already exists, or creates it from the project’s current
HEADif it doesn’t; - runs
git worktree addinto<worktrees folder>/<repository>/<branch>; - copies the files listed in
.worktreeinclude; - opens the new workspace with a shell in the checkout, which first runs the project’s setup if it has one.
If something goes wrong, the reason appears in red in the dialog and no workspace is added: for example when the checkout folder already exists, when git doesn’t accept the branch name, or when the branch is already checked out in another worktree.
Where checkouts go
Section titled “Where checkouts go”By default, checkouts live in ~/.cornercase/worktrees, grouped by repository. The folder name is the branch made safe for a path: lowercase letters and digits are kept, anything else becomes a dash, and repeated or trailing dashes are dropped.
| Repository | Branch | Checkout |
|---|---|---|
~/code/web-shop |
feat/login |
~/.cornercase/worktrees/web-shop/feat-login |
~/code/web-shop |
fix//The Bug! |
~/.cornercase/worktrees/web-shop/fix-the-bug |
~/code/orders-api |
issue-482-returns-page |
~/.cornercase/worktrees/orders-api/issue-482-returns-page |
To keep them somewhere else, change settings → Worktrees → worktrees folder. Use an absolute path or one starting with ~/. The change applies to new worktrees; existing ones stay where they are.
Commits to pull
Section titled “Commits to pull”When a workspace’s branch is behind its upstream, the workspace row ends with the number of commits you don’t have yet, such as ↓3, so you know it’s time to pull. It goes away once you pull.
- It works with any remote, not only GitHub, for branches that have an upstream (
git push -uorgit branch --set-upstream-tosets one). A branch without an upstream, or a folder without git, shows nothing. - cornercase runs
git fetch --allin the background for each project every 5 minutes, and counts the commits every few seconds, so a pull shows right away. The first fetch happens as soon as the project is open. - The fetch never asks for a password or passphrase: if it needs one, or the network is down, it fails silently and the number stays as it was. Use an SSH agent or a credential helper so it can run unattended.
To fetch more or less often, change settings → Worktrees → fetch branches every, in minutes. 0 turns it off: nothing is fetched and no numbers are shown.
Pull requests and their checks
Section titled “Pull requests and their checks”When a workspace’s branch has a pull request on GitHub, its row ends with the pull request’s number, coloured by its checks, or marked when it has merge conflicts, so you see from the sidebar which line of work is green, still running or broken, without opening a browser:
| Mark | Means |
|---|---|
#486! in orange |
it has merge conflicts with its base branch: GitHub runs none of its pull_request workflows until they are resolved |
#485✗ in red |
a check failed |
#483• in yellow |
checks are still running |
#482✓ in green |
every check passed |
#482 in grey |
the pull request has no checks |
#482 in purple |
merged |
#482 crossed out |
closed without merging |
Click the number on the row, or click the row’s ⋯ (or right-click it) and pick pull request #485, to see each check, failed ones first, with the workflow it belongs to:
A flow run shows the same number at the end of its diagram, and a click on it opens the same dialog.
A pull request with merge conflicts says so at the top (open · conflicts with main · 1 passed). GitHub runs no pull_request workflows until the conflict is resolved, so its list of checks may be missing some, often all but an app’s commit status.
- copy link copies the pull request’s address, to open it in your browser.
- ask agent, shown when a check failed or the pull request has merge conflicts, pastes into the workspace’s agent that it has merge conflicts with its base and which checks failed and the links to their logs, so it can read them (with
gh run view, for example) and fix them. It is not sent: add what you want and pressEnter. Without an agent in the workspace, the text is copied instead.
With a prefix key, g p opens the dialog for the workspace on screen.
How it works:
- cornercase runs
gh, GitHub’s CLI, in each workspace’s folder:gh pr viewfinds the pull request of the branch checked out there, also one an agent opened withgh pr create.ghmust be installed and logged in (gh auth login); without it nothing shows, and settings → Worktrees → pull requests says why. - Only workspaces on a branch of a repository with a remote are asked, and not the default branch (
origin’sHEAD). A workspace is asked again every 20 seconds while its checks run and every minute otherwise; a merged or closed pull request, and a project whereghfailed, every 5 minutes. Opening the dialog asks at once. - GitHub works out whether a pull request can merge in the background. Right after a push to the branch or its base it may not know yet, so a new conflict can take up to a minute to show, and until then the row keeps what it showed.
- Turn it off in settings → Worktrees → pull requests; nothing is asked then. Scripts and agents find the same in
cornercase status --json, under each workspace’spull_request, withconflictsandbase.
Worktrees you made elsewhere
Section titled “Worktrees you made elsewhere”Every linked worktree of the repository shows up as a workspace, including the ones you create yourself with git worktree add or that another tool creates. cornercase looks for them about once a second, so they appear shortly after they exist. A worktree workspace with no tabs disappears when its folder is removed.
Bring your ignored files along
Section titled “Bring your ignored files along”A fresh checkout only contains what git tracks. Files that git ignores, such as .env files with local secrets, are missing. List the ones you want in every new worktree in a .worktreeinclude file at the root of the repository, using .gitignore patterns:
.env.envs/.env.localA file is copied into a new worktree only when it matches .worktreeinclude and is ignored by git. Tracked files are already in the checkout, and untracked files that git doesn’t ignore are left out on purpose. The matching is done by git itself, so it follows the same rules as .gitignore.
For example, with this .gitignore:
.env.envs/secret.txt| File | Copied? | Why |
|---|---|---|
.env |
Yes | Listed and ignored. |
.envs/.env.local |
Yes | Listed and ignored. |
secret.txt |
No | Ignored, but not listed. |
notes.md (untracked) |
No | Listed or not, git doesn’t ignore it. |
Files keep their place in the tree. If a file can’t be copied, the worktree is still created and the reason is written to the server log.
Set up each new worktree
Section titled “Set up each new worktree”A fresh checkout has no node_modules, no build and no local configuration. Give a project the commands that fix that and they run in every worktree cornercase creates: click ⋯ (or right-click) on the project and choose project settings. It is offered for projects whose folder is a repository root.
The dialog has two fields, setup and teardown; Enter adds a line, Tab moves between them, and save stores them in config.json under projects.
npm cicp "$CORNERCASE_ROOT/.env.local" .env.localThe order in a new worktree is: git worktree add, the .worktreeinclude files, the setup in the workspace’s first tab, then the agent. The setup runs visibly in that tab, so progress bars, colours and prompts work and the output stays in the scrollback; when it ends, the same tab becomes your shell. Commands run with /bin/sh -e (the first failing command stops the script) in the worktree, with three variables set: CORNERCASE_ROOT (the project folder), CORNERCASE_WORKTREE (the new worktree) and CORNERCASE_BRANCH. To use your own shell’s functions, call it: zsh -lic 'nvm use && npm ci'.
An agent that starts there (from an issue, cornercase start --worktree, the queue, a chat app or a flow) waits for the setup and starts only if it succeeded. If it fails, the tab shows a red !, a message says setup failed in project › workspace, nothing else starts and the output is there to read. Fix the cause and choose run setup in the workspace’s menu to run it again in a new tab. The setup runs only for worktrees cornercase just created, not for ones made elsewhere, workspaces reused on an existing branch, or after a restart. There is no time limit: press Ctrl+C in the tab to stop it. While it runs the workspace row shows setting up….
teardown runs before a worktree is removed, once its programs have stopped and before git deletes the folder, in the background with the same variables and a limit of five minutes. If it fails, the worktree is removed anyway and the message says removed <workspace>, but its teardown failed with the reason; cornercase close --remove-worktree prints it as a warning on stderr.
The commands are stored on your computer, not in the repository, so a cloned project cannot run anything until you have written it yourself; to share a setup with your team, commit a script and put one line, ./scripts/setup.sh, in the field. Cornercase’s log records sizes, exit statuses and timings, never the commands or their output; the only exception is a failed teardown, whose last output line (at most 160 characters) is logged at debug level.
Remove a worktree
Section titled “Remove a worktree”Hover the workspace and click its ×. Because removing the workspace also deletes its checkout, cornercase asks first (the message adds Its teardown runs first. when the project has a teardown):
While the dialog is open, cornercase checks the checkout for modified or untracked files, which git would refuse to delete. If it finds some, the dialog says so and the button becomes remove anyway, which runs git worktree remove --force and throws those changes away. Click cancel to keep the worktree and save your work first.
A worktree can also be locked with git worktree lock; Claude Code locks the worktrees it creates while its session runs. The dialog then shows the lock’s reason and, when the reason names a process, whether it still runs: a lock whose process is gone was left behind, for example when a restart ended the session. unlock and remove unlocks it and removes it. If the process still runs, cancel and end it first. From a script, cornercase close --worktree BRANCH --remove-worktree --check shows the same before anything stops, and --unlock does unlock and remove; see Scripts and agents.
remove closes the dialog at once, so you can go on working while the folder is deleted, which takes a while for a checkout with node_modules or build output. The workspace’s programs are ended first, and its row stays, dimmed, with removing… at its end until git has finished; meanwhile it can’t be opened. If it was the workspace on screen, the view moves to the nearest one, above it when there is one. When git is done, the row goes and a message says removed <workspace>. If git refuses after all, for example because a file changed in the meantime, the row comes back without its tabs and a message gives git’s reason; click its × again to remove anyway. You can remove several worktrees at once.
A run of a flow can give roles worktrees of their own: they go with the run’s workspace, which is checked, torn down and removed together with them (the message names how many), and one cannot be removed alone while its run lives. Their branches are kept.
Worktrees from issues
Section titled “Worktrees from issues”Starting an issue from the issue browser in a repository creates a worktree too, on a branch named after the issue, such as issue-482-returns-page-crashes-on-empty-address. Everything on this page applies to it.