mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-02-24 20:20:38 +01:00
<!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request This pull request introduces a new suite of helper scripts for managing Git worktrees in the `tools/build` directory, along with comprehensive documentation. The scripts streamline common workflows such as creating, reusing, and deleting worktrees for feature branches, forks, and issue-based development, making it easier for developers to work on multiple changes in parallel without duplicating the repository. Each script is provided as both a PowerShell (`.ps1`) and Windows batch (`.cmd`) wrapper for convenience. A detailed markdown guide explains usage patterns, scenarios, and best practices. **New worktree management scripts:** * Added `New-WorktreeFromFork.ps1`/`.cmd` to create a worktree from a branch in a personal fork, handling remote creation and branch tracking automatically. [[1]](diffhunk://#diff-ea4d43777029cdde7fb9fda8ee6a0ed3dcfd75b22ed6ae566c6a77797c8bef54R1-R111) [[2]](diffhunk://#diff-1314b08f84ac8c2e7d020e5584d9f2f19dbf116bbc13c14de0de432006912cfeR1-R4) * Added `New-WorktreeFromBranch.ps1`/`.cmd` to create or reuse a worktree for an existing local or remote branch, with logic to fetch and track branches as needed. [[1]](diffhunk://#diff-07c08acfb570e1b54647370cae17e663e76ee8cb09614cac7a23a9367f625a3eR1-R69) [[2]](diffhunk://#diff-6297be534792c3e6d1bc377b84bcd20b2eb5b3de84d4376a2592b25fc9a88a88R1-R4) * Added `New-WorktreeFromIssue.ps1`/`.cmd` to create a new issue branch from a base ref (default `origin/main`), slugifying the issue title for branch naming. [[1]](diffhunk://#diff-36cb35f3b814759c60f770fc9cc1cc9fa10ceee53811d95a85881d8e69c1ab07R1-R67) [[2]](diffhunk://#diff-890880241ffc24b5d29ddb69ce4c19697a2fce6be6861d0a24d02ebf65b35694R1-R4) * Added `Delete-Worktree.ps1`/`.cmd` to safely remove a worktree, with options to force removal, keep the local branch, or retain orphan fork remotes. Includes robust error handling and manual recovery guidance. [[1]](diffhunk://#diff-8a335544864c1630d7f9bec6f4113c10d84b8e26054996735da41516ad93e173R1-R120) [[2]](diffhunk://#diff-19a810e57f8b82e1dc2476f35d051eb43f2d31e4f68ca7c011c89fd297718020R1-R4) **Documentation:** * Introduced `Wokrtree-Guidelines.md`, a comprehensive guide covering the purpose, usage, flows, naming conventions, troubleshooting, and best practices for the new worktree scripts.
95 lines
5.0 KiB
Markdown
95 lines
5.0 KiB
Markdown
# PowerToys Worktree Helper Scripts
|
||
|
||
This folder contains helper scripts to create and manage parallel Git worktree for developing multiple changes (including Copilot suggestions) concurrently without cloning the full repository each time.
|
||
|
||
## Why worktree?
|
||
Git worktree let you have several checked‑out branches sharing a single `.git` object store. Benefits:
|
||
- Fast context switching: no re-clone, no duplicate large binary/object downloads.
|
||
- Lower disk usage versus multiple full clones.
|
||
- Keeps each change isolated in its own folder so you can run builds/tests independently.
|
||
- Enables working in parallel with Copilot generated branches (e.g., feature + quick fix + perf experiment) while the main clone stays clean.
|
||
|
||
Recommended: keep active parallel worktree(s) to **≤ 3** per developer to reduce cognitive load and avoid excessive incremental build invalidations.
|
||
|
||
## Scripts Overview
|
||
| Script | Purpose |
|
||
|--------|---------|
|
||
| `New-WorktreeFromFork.ps1/.cmd` | Create a worktree from a branch in a personal fork (`<User>:<branch>` spec). Adds a temporary unique remote (e.g. `fork-abc12`). |
|
||
| `New-WorktreeFromBranch.ps1/.cmd` | Create/reuse a worktree for an existing local or remote (origin) branch. Can normalize `origin/branch` to `branch`. |
|
||
| `New-WorktreeFromIssue.ps1/.cmd` | Start a new issue branch from a base (default `origin/main`) using naming `issue/<number>-<slug>`. |
|
||
| `Delete-Worktree.ps1/.cmd` | Remove a worktree and optionally its local branch / orphan fork remote. |
|
||
| `WorktreeLib.ps1` | Shared helpers: unique folder naming, worktree listing, upstream setup, summary output, logging helpers. |
|
||
|
||
## Typical Flows
|
||
### 1. Create from a fork branch
|
||
```
|
||
./New-WorktreeFromFork.ps1 -Spec alice:feature/perf-tweak
|
||
```
|
||
Creates remote `fork-xxxxx`, fetches just that branch, creates local branch `fork-alice-feature-perf-tweak`, makes a new worktree beside the repo root.
|
||
|
||
### 2. Create from an existing or remote branch
|
||
```
|
||
./New-WorktreeFromBranch.ps1 -Branch origin/feature/new-ui
|
||
```
|
||
Fetches if needed and creates a tracking branch if missing, then creates/reuses the worktree.
|
||
|
||
### 3. Start a new issue branch
|
||
```
|
||
./New-WorktreeFromIssue.ps1 -Number 1234 -Title "Crash on launch"
|
||
```
|
||
Creates branch `issue/1234-crash-on-launch` off `origin/main` (or `-Base`), then worktree.
|
||
|
||
### 4. Delete a worktree when done
|
||
```
|
||
./Delete-Worktree.ps1 -Pattern feature/perf-tweak
|
||
```
|
||
If only one match, removes the worktree directory. Add `-Force` to discard local changes. Use `-KeepBranch` if you still need the branch, `-KeepRemote` to retain a fork remote.
|
||
|
||
## After Creating a Worktree
|
||
Inside the new worktree directory:
|
||
1. Run the minimal build bootstrap in VSCode terminal:
|
||
```
|
||
tools\build\build-essentials.cmd
|
||
```
|
||
2. Build only the module(s) you need (e.g., open solution filter or run targeted project build) instead of a full PowerToys build. This speeds iteration and reduces noise.
|
||
3. Make changes, commit, push.
|
||
4. Finally delete the worktree when done.
|
||
|
||
## Naming & Locations
|
||
- Worktree is created as sibling folders of the repo root (e.g., `PowerToys` + `PowerToys-ab12`), using a hash/short pattern to avoid collisions.
|
||
- Fork-based branches get local names `fork-<user>-<sanitized-branch>`.
|
||
- Issue branches: `issue/<number>` or `issue/<number>-<slug>`.
|
||
|
||
## Scenarios Covered / Limitations
|
||
Covered scenarios:
|
||
1. From a fork branch (personal fork on GitHub).
|
||
2. From an existing local or origin remote branch.
|
||
3. Creating a new branch for an issue.
|
||
|
||
Not covered (manual steps needed):
|
||
- Creating from a non-origin upstream other than a fork (add remote manually then use branch script).
|
||
- Batch creation of multiple worktree in one command.
|
||
- Automatic rebase / sync of many worktree at once (do that manually or script separately).
|
||
|
||
## Best Practices
|
||
- Keep ≤ 3 active parallel worktree(s) (e.g., main dev, a long-lived feature, a quick fix / experiment) plus the root clone.
|
||
- Delete stale worktree early; each adds file watchers & potential incremental build churn.
|
||
- Avoid editing the same file across multiple worktree simultaneously to reduce merge friction.
|
||
- Run `git fetch --all --prune` periodically in the primary repo, not in every worktree.
|
||
|
||
## Troubleshooting
|
||
| Symptom | Hint |
|
||
|---------|------|
|
||
| Fetch failed for fork remote | Branch name typo or fork private without auth. Try manual `git fetch <remote> <branch>`.
|
||
| Cannot lock ref *.lock | Stale lock: run `git worktree prune` or manually delete the `.lock` file then retry.
|
||
| Worktree already exists error | Use `git worktree list` to locate existing path; open that folder instead of creating a duplicate.
|
||
| Local branch missing for remote | Use `git branch --track <name> origin/<name>` then re-run the branch script.
|
||
|
||
## Security & Safety Notes
|
||
- Scripts avoid force-deleting unless you pass `-Force` (Delete script).
|
||
- No network credentials are stored; they rely on your existing Git credential helper.
|
||
- Always review a new fork remote URL before pushing.
|
||
|
||
---
|
||
Maintainers: Keep the scripts lean; avoid adding heavy dependencies or global state. Update this doc if parameters or flows change.
|