feat: add e worktree for additional gclient working directories#836
Open
MarshallOfSound wants to merge 1 commit intomainfrom
Open
feat: add e worktree for additional gclient working directories#836MarshallOfSound wants to merge 1 commit intomainfrom
e worktree for additional gclient working directories#836MarshallOfSound wants to merge 1 commit intomainfrom
Conversation
8610adf to
f5e38c3
Compare
e59a2b8 to
4a55cd5
Compare
f5e38c3 to
54952a6
Compare
VerteDinde
approved these changes
Apr 6, 2026
Adds `e worktree add <name> <dir>` and `e worktree clean <name>`. `add` wraps depot_tools' gclient-new-workdir.py to create a second working tree that shares git object stores with an existing checkout, clones the source build config with the new root/buildtools path, and runs `e sync` so the worktree is immediately buildable. `clean` removes the worktree directory and its config. It refuses to touch a directory unless `.gclient` and `src/.git/objects` are symlinks, so it can never delete a primary checkout. Not supported on Windows (gclient-new-workdir.py requires symlinks).
4a55cd5 to
d7a234e
Compare
codebytere
reviewed
Apr 8, 2026
Comment on lines
+160
to
+164
| evmConfig.remove(name); | ||
| console.log(`Removed config ${color.config(name)}`); | ||
|
|
||
| console.log(`Deleting ${color.path(root)}...`); | ||
| deleteDir(root); |
Member
There was a problem hiding this comment.
If deleteDir fails we've already nuked the config, so now you've got an orphaned worktree directory with no config pointing at it. Can we flip the order here?
Comment on lines
+27
to
+36
| function isDerivedWorktree(root: string): boolean { | ||
| const gclient = path.join(root, '.gclient'); | ||
| const gitObjects = path.join(root, 'src', '.git', 'objects'); | ||
| return ( | ||
| fs.existsSync(gclient) && | ||
| fs.lstatSync(gclient).isSymbolicLink() && | ||
| fs.existsSync(gitObjects) && | ||
| fs.lstatSync(gitObjects).isSymbolicLink() | ||
| ); | ||
| } |
Member
There was a problem hiding this comment.
If somebody runs git gc in the worktree, the .git/objects symlink can get replaced with a real directory, so this check would fail and they'd be unable to clean up via e worktree clean. Maybe add a --force escape hatch on clean?
| console.log( | ||
| `Running ${color.cmd('e sync')} to fetch toolchains and apply patches in the new worktree...`, | ||
| ); | ||
| const e = path.resolve(__dirname, 'e'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #834.
Summary
e worktree add <name> <dir>wrapsgclient-new-workdir.pyto create a second working tree that shares git objects with an existing checkout, writes a matching build config (cloned from--source, default current), and runse syncso it's immediately buildable.--no-sync/-o <out>/-favailable.e worktree clean <name> --yesremoves the worktree directory and its build config. Guarded: refuses unless.gclientandsrc/.git/objectsare symlinks (so a primary checkout can never be deleted), refuses if the config is currently active, and requires--yes.gclient-new-workdir.pyrequires symlinks.Pairs well with per-shell active configs:
Test plan
yarn buildcleanyarn lint:tscleanyarn test(63 passing)e worktree add testing2 ~/src/electron2 --no-synccreates an 18G workdir with symlinked.git/{objects,refs,config}, writesevm.testing2.json, switches to ite syncin the new workdir fetches gn/clang/node ande build --gen-onlyproducesbuild.ninjae worktree clean testing --yesrefuses (primary checkout)e worktree clean <active> --yesrefuses (config in use)e worktree clean testing2 --yesremoves dir + config