Files
PowerToys/tools/build/Worktree-Guidelines.md

95 lines
5.0 KiB
Markdown
Raw Permalink Normal View History

Introduce worktree helper scripts for faster multi-branch development in PowerToys (#42076) <!-- 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.
2025-10-09 21:11:28 -07:00
# 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 checkedout 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.