In short: jj refuses an empty name, does nothing if the name is unchanged, and refuses if the current
workspace isn't in the view. It then starts a transaction, locks the working copy, renames the workspace
in the working-copy state, in the view (which moves its working-copy commit and Git HEAD to
the new name, refusing a name that's taken) and in the workspace store, commits the operation
Renamed workspace '<old>' to '<new>', and records it in the working copy.
The command is cmd_workspace_rename. It can only rename the
workspace it runs in. Workspaces are created by
jj workspace add; the name is what
NAME@ means in revsets and jj log.
1. Command-line surface
| Argument | Type | Default | Meaning |
|---|---|---|---|
NEW_WORKSPACE_NAME (positional) | workspace name | required | The new name for the current workspace (source). |
2. Configuration
None. The name has no config of its own.
3. End-to-end flow
The old name is read from the working copy itself, not from command arguments (source), which is why a forgotten workspace can't be renamed back into the repo: its working copy still has its name, but the view doesn't (test).
4. Core architecture touchpoints
- View:
View::rename_workspacemoves the working-copy commit ID and, if recorded, the GitHEADfrom the old name to the new one, throughMutableRepo::rename_workspace. See the view page. - Working copy: the working-copy state stores its workspace name, so it is renamed under the working-copy lock; see the working copy page.
- Workspace store: the entry's name changes and its path stays
(
rename), sojj workspace root --name NEWworks and the old name no longer does (test). - Commits: none change;
jj logshowsNEW@on the same commit.
5. Transaction and operation
- Transaction: a raw one (
into_inner), committed directly rather than throughfinish, because the working copy is updated by hand: the lock is taken before the view changes and released with the new operation ID (source). - Operation description:
Renamed workspace '<old>' to '<new>', unusually capitalized and in the past tense compared to other commands (source). - Outside the operation: the workspace store rename and the working-copy state are written to disk directly, not recorded in the operation.
6. Algorithm and invariants
Invariants: names stay unique in the view; no commit changes; the workspace's directory and working-copy commit are the same before and after.
7. Errors and edge cases
| Message | When | Source |
|---|---|---|
New workspace name cannot be empty | An empty name. | rename.rs, test |
Nothing changed. | The new name equals the current one. | rename.rs, test |
The current workspace '<name>' is not tracked in the repo. | The workspace was forgotten. | rename.rs, test |
Failed to rename a workspace, caused by Workspace <name> already exists | Another workspace has that name. | view.rs, test |
8. Worked example
From upstream's test_default and second (in ../secondary), running
jj workspace rename third in the secondary directory prints nothing. Afterwards
(source):
$ jj workspace list
default: . qpvuntsm e8849ae1 (empty) (no description set)
third: ../secondary uuqppmxq 94f41578 (empty) (no description set)
$ jj log # from the secondary directory
@ 94f41578a9e1 third@
│ ○ e8849ae12c70 default@
├─╯
◆ 000000000000
The commit IDs and the directory are unchanged; only the name moved, in all three places shown in §6.