Guides
Moving from a git-clone install
How to turn a Repolane folder you cloned from GitHub into a workspace run by the installed package, keeping every lane, branch, memory and note. With a preview, a backup and an undo.
On this page
In brief. If you set Repolane up by cloning its repo and running
./lane install, your work lives inside that clone.lane migrateturns the clone into a workspace, in place, keeping every lane, branch, memory and note. Three steps:lane upgradein the clone,pipx install repolane, thenlane migrate. It shows its plan first, writes a backup before it changes anything, andlane migrate --undoputs the clone back.
A git-clone install is a clone of the Repolane repo that is also where your work lives, with
registry/, memory/, knowledge/ and repos/ at its top and ~/.local/bin/lane pointing into it.
A workspace keeps the same things under .repolane/ and gets Repolane itself from the installed
package. See Install for the layout you end up with.
Until you move, the clone keeps working as it is. A clone that has been set up shows one line at
session start and in lane status saying that lane migrate converts it; migrate_reminder: false
in the clone’s registry/config.yml turns that line off.
The three steps
cd ~/repolane # your clone
lane upgrade # 1. take the last update the clone can get; its lane doctor then names the next two steps
pipx install repolane # 2. install the package (or: uv tool install repolane)
lane migrate # 3. run the installed lane: turn the clone into a workspace, in place
lane migrate ~/path/to/the/clone works from anywhere; with no folder it uses the current one.
The ~/.local/bin router. lane install wrote a small router to ~/.local/bin/lane, and pipx
links its own lane into the same folder. Until lane migrate removes the router, lane there may
still be the old one, which sends every call to the clone. If lane migrate says it “runs from the
installed package, not from the clone itself”, run the installed lane by its full path: pipx
prints where it put it, and pipx list shows it again. After the migration, run
pipx reinstall repolane if pipx skipped linking lane because the router was in the way. The
installed package has no lane install or lane use: it refuses both and points to lane init and
lane migrate.
Preview, confirm, backup
lane migrate shows everything it would do first and changes nothing until you confirm
(“Migrate now? [y/N]”, or --yes).
--dry-run | only show the plan. With no terminal and no --yes, that is all it does too |
--verbose | list every file in the plan, not one line per folder |
--yes | ask nothing: migrate, and accept the changes under ~/.claude and ~/.local/bin |
--git | start a fresh, empty git repo for the workspace afterwards (see Keep your workspace in your own git repo) |
--claude-home <dir> | Claude Code’s folder, if it is not ~/.claude |
It refuses while Claude Code is running inside the folder or one of its lanes: a running session’s
hooks point into the clone, and the migration removes those files. End those sessions (/exit), then
run it again from a plain terminal, not from a Claude Code shell.
Before the first change it writes a backup of everything it changes or removes to
~/.local/share/lane/backups/<folder>-<time>.tar.gz and prints the path.
What it does
- Your data moves under
.repolane/:registry/,memory/,knowledge/,repos/,.cache/(ascache/),registry/config.yml(asconfig.yml),scripts/env.sh(asenv.sh) andscripts/local/. Nothing in them is changed. The worktrees stay inlanes/and are repaired withgit worktree repair, so git keeps working in them, and their.envlinks follow the base clones. - Repolane’s own files are removed: only paths a release shipped, never anything else in the
folder. The clone’s
.gitis Repolane’s repo, so it goes too (it is in the backup). CLAUDE.mdbecomes yours: a short file that imports.repolane/REPOLANE.md, keeping every line you added. If you edited lines of Repolane’s own text, the old file is also kept asCLAUDE.md.pre-0.10..claude/settings.jsonrunslane hook …commands andlane statusline, keeping your own keys and hooks. Every lane’s settings are written again.- Outside the folder, each asked first: the memory links under
~/.claude/projectspoint into.repolane/memory(a base clone’s project folder is renamed, because its path changed), and the router in~/.local/bin/laneis removed when no other clone install uses it.planes.jsonrecords the workspace instead of the clone.
It ends with the backup path and the undo command. Then run lane doctor in the folder.
If it stops half way
Run lane migrate again. Each step is recorded, and it continues where it stopped. On a folder that
is already a workspace it says there is nothing to do and changes nothing.
Putting the clone back
lane migrate --undo ~/.local/share/lane/backups/<folder>-<time>.tar.gz
This restores the clone install as the backup holds it. Anything written in the workspace since the migration is kept aside, not deleted.
When a step refuses
The clone’s own lane upgrade refuses. It only fast-forwards. It refuses when tracked files
outside registry/, memory/, knowledge/, CLAUDE.md and .claude/settings*.json are dirty,
and when the clone has commits of its own. Keep your state in a commit, then merge:
git add registry knowledge memory CLAUDE.md && git commit -m "keep my state"
git pull
The usual conflict is .claude/settings.json: take upstream’s version
(git checkout --theirs .claude/settings.json, git add .claude/settings.json, git commit), then
lane doctor. git merge --abort returns you to where you were; none of this touches lanes/ or
repos/. If the refusal names .claude/settings.json as modified by lane init, run
git checkout -- .claude/settings.json, then lane upgrade, then lane init --yes.
“both X and Y exist”. The folder already has a .repolane/<name> next to the clone’s <name>,
from an earlier attempt or by hand. Move one aside, then run lane migrate again.
.claude/settings.json is not valid JSON. Mend it first; the migration only ever merges into it.
More recovery steps are on When something goes wrong.