Skip to content

[build] document Bazel worktree output-base cleanup - #17689

Merged
titusfortner merged 1 commit into
trunkfrom
c/wizardly-hertz-11e165
Jul 13, 2026
Merged

[build] document Bazel worktree output-base cleanup#17689
titusfortner merged 1 commit into
trunkfrom
c/wizardly-hertz-11e165

Conversation

@titusfortner

Copy link
Copy Markdown
Member

🔗 Related Issues

💥 What does this PR do?

Documents that Bazel creates a per-checkout output base that, unlike the shared
--disk_cache/--repository_cache, is never garbage-collected when a worktree is deleted. In
worktree-heavy workflows these orphaned output bases accumulate and leak gigabytes. The README
"Using Worktrees" section and AGENTS.md "Agent workspace" now explain how to make a worktree
self-cleaning by pointing its output base inside the worktree (startup --output_base=.local/bazel-out),
with a Windows caveat preserving the existing --output_user_root guidance.

🔧 Implementation Notes

🤖 AI assistance

  • No substantial AI assistance used
  • AI assisted (complete below)
    • Tool(s): Claude Code
    • What was generated: Documentation wording in README.md and AGENTS.md
    • I reviewed all AI output and can explain the change

💡 Additional Considerations

🔄 Types of changes

  • Cleanup (formatting, renaming)

@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Document Bazel output-base cleanup for git worktrees
📝 Documentation 🕐 Less than 10 minutes

Grey Divider

Description

• Explain that Bazel output bases are per-checkout and persist after worktree deletion.
• Document a self-cleaning worktree setup via startup --output_base=.local/bazel-out.
• Add Windows guidance to keep using --output_user_root to avoid path-length issues.
Diagram

graph TD
  A["Git worktree"] --> B["Bazel build"] --> C["Set output_base in worktree?"]
  C -->|"Yes (macOS/Linux)"| D[".bazelrc.local: output_base=.local/bazel-out"] --> E["Worktree removal reclaims output"]
  C -->|"No (default)"| F["Output base keyed by path"] --> G["Orphaned output base (GB leak)"]
  H["Windows note: use output_user_root"] -.-> C
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Add a cleanup helper script / git alias
  • ➕ Automates cleanup; less reliance on developers reading/remembering docs
  • ➕ Can detect and remove orphaned output bases safely with confirmation prompts
  • ➖ More maintenance and platform-specific edge cases (Windows paths, permissions)
  • ➖ Risk of deleting active output bases if detection is wrong
2. Standardize repo-provided per-worktree Bazel rc include
  • ➕ Makes the safer default easy to adopt (drop-in config)
  • ➕ Reduces per-developer configuration drift
  • ➖ Harder to keep cross-platform behavior correct (Windows path-length constraints)
  • ➖ May be viewed as too opinionated for diverse contributor environments

Recommendation: The documentation-first approach in this PR is the right immediate fix: it’s low-risk, explains the root cause (output bases persist per checkout path), and provides an actionable, per-worktree configuration that prevents disk leaks. Consider a follow-up enhancement only if orphaned output bases remain a common pain point: a small cleanup helper (opt-in) could further reduce operational burden, but it adds ongoing maintenance and safety concerns.

Files changed (2) +25 / -2

Documentation (2) +25 / -2
AGENTS.mdDocument self-cleaning Bazel output bases for worktree-based agent workflows +6/-2

Document self-cleaning Bazel output bases for worktree-based agent workflows

• Expands the Agent workspace guidance to explain Bazel’s per-checkout output base behavior in worktrees. Adds recommended configuration to place '--output_base' under '.local/' so output is reclaimed when a worktree is removed, and references README for shared cache setup.

AGENTS.md

README.mdExplain Bazel output-base leakage with worktrees and how to avoid it +19/-0

Explain Bazel output-base leakage with worktrees and how to avoid it

• Adds an explanation that Bazel output bases are not garbage-collected when a worktree is deleted, causing disk leaks in worktree-heavy workflows. Documents configuring 'startup --output_base=.local/bazel-out' for macOS/Linux and includes a Windows caveat to keep using '--output_user_root' for path-length limits.

README.md

@qodo-code-review

qodo-code-review Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 11 rules

Grey Divider


Action required

1. Wrong output_base invocation ✓ Resolved 🐞 Bug ≡ Correctness
Description
AGENTS.md says users can “pass --output_base=.local/bazel-out”, but in this repo output_base is
handled as a Bazel startup option (via startup --...). Users following the docs may pass it as a
normal build/test flag and Bazel will reject it, breaking the worktree setup guidance.
Code

AGENTS.md[R43-44]

+  the worktree is removed: add `startup --output_base=.local/bazel-out` to the worktree's
+  `.bazelrc.local`, or pass `--output_base=.local/bazel-out`. By default Bazel keys the output base on
Evidence
The new AGENTS.md text explicitly offers passing --output_base directly, while the repo’s Bazel
configuration and README consistently treat these as startup options (indicating they are not
meant to be regular command flags). This inconsistency makes the AGENTS.md alternative instruction
unreliable.

AGENTS.md[41-46]
README.md[161-166]
.bazelrc[1-2]
.bazelrc[16-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AGENTS.md` suggests users can alternatively “pass `--output_base=.local/bazel-out`”, but `--output_base` is a Bazel *startup* option (as shown elsewhere in the repo). This phrasing can lead users to pass it in the wrong position (as a command option), which Bazel will reject.

### Issue Context
The repo already documents `output_base` correctly as a `startup` option in `README.md`, and `.bazelrc` uses `startup` stanzas for startup-only flags.

### Fix Focus Areas
- AGENTS.md[42-46]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Unanchored output_base path 🐞 Bug ≡ Correctness ⭐ New
Description
README recommends startup --output_base=.local/bazel-out, which is a relative path and can resolve
differently depending on where Bazel is invoked from (e.g., from a subdirectory), creating multiple
output bases and breaking the stated “output base lives under root .local/” cleanup behavior. This
also means the output directory may not be covered by the repo’s .bazelignore entry (which only
ignores the root .local).
Code

README.md[R161-166]

+On macOS/Linux, make a worktree self-cleaning by pointing its output base inside the worktree. Add
+this to that worktree's `.bazelrc.local`:
+
+```
+startup --output_base=.local/bazel-out
+```
Evidence
The README’s recommendation uses a relative --output_base, while the repo’s own guidance and
configuration show that output_base should be anchored to the workspace root and that %workspace%
is available for path anchoring. Additionally, .bazelignore only ignores the root .local, so a
non-root-resolved output base would not be ignored as the README claims.

README.md[157-174]
AGENTS.md[25-29]
.bazelignore[13-19]
.bazelrc.remote[44-49]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`README.md` documents `startup --output_base=.local/bazel-out` for per-worktree cleanup. Because it’s a relative path, it may not consistently point at the workspace-root `.local/` directory, undermining the stated cleanup behavior and the repo’s `.bazelignore` assumptions.

## Issue Context
The repo already uses Bazel’s `%workspace%` expansion in `.bazelrc*` files, which provides a stable, workspace-root anchored path.

## Fix Focus Areas
- README.md[161-174]

## Proposed fix
Update the README snippet to use an anchored path, e.g.:

```
startup --output_base=%workspace%/.local/bazel-out
```

(Alternatively, explicitly state that Bazel must be invoked from the repo root for the relative path to work as intended, but the anchored form is more robust.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Previous review results

Review updated until commit 97cd919

Results up to commit cb95346


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required
1. Wrong output_base invocation ✓ Resolved 🐞 Bug ≡ Correctness
Description
AGENTS.md says users can “pass --output_base=.local/bazel-out”, but in this repo output_base is
handled as a Bazel startup option (via startup --...). Users following the docs may pass it as a
normal build/test flag and Bazel will reject it, breaking the worktree setup guidance.
Code

AGENTS.md[R43-44]

+  the worktree is removed: add `startup --output_base=.local/bazel-out` to the worktree's
+  `.bazelrc.local`, or pass `--output_base=.local/bazel-out`. By default Bazel keys the output base on
Evidence
The new AGENTS.md text explicitly offers passing --output_base directly, while the repo’s Bazel
configuration and README consistently treat these as startup options (indicating they are not
meant to be regular command flags). This inconsistency makes the AGENTS.md alternative instruction
unreliable.

AGENTS.md[41-46]
README.md[161-166]
.bazelrc[1-2]
.bazelrc[16-18]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AGENTS.md` suggests users can alternatively “pass `--output_base=.local/bazel-out`”, but `--output_base` is a Bazel *startup* option (as shown elsewhere in the repo). This phrasing can lead users to pass it in the wrong position (as a command option), which Bazel will reject.

### Issue Context
The repo already documents `output_base` correctly as a `startup` option in `README.md`, and `.bazelrc` uses `startup` stanzas for startup-only flags.

### Fix Focus Areas
- AGENTS.md[42-46]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

Comment thread AGENTS.md Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit a9b4d83

@AutomatedTester

Copy link
Copy Markdown
Member

This would be better in the bazelrc file so that everyone benefits

@titusfortner

Copy link
Copy Markdown
Member Author

I like the idea, but I don't think we want to force this on everyone all the time. The output-base leak is specific to temporary worktrees on Mac/Linux. It would break things for Windows, and using a relative path can cause weird behaviors unless you always run bazel from top level directory.

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 95c82b3

@titusfortner
titusfortner force-pushed the c/wizardly-hertz-11e165 branch from 95c82b3 to 97cd919 Compare July 13, 2026 16:12
@titusfortner

Copy link
Copy Markdown
Member Author

merged part of this with #17756 because my memory is bad, this becomes just a readme update.

@titusfortner
titusfortner merged commit 7d15848 into trunk Jul 13, 2026
15 checks passed
@titusfortner
titusfortner deleted the c/wizardly-hertz-11e165 branch July 13, 2026 16:13
Comment thread README.md
Comment on lines +161 to +166
On macOS/Linux, make a worktree self-cleaning by pointing its output base inside the worktree. Add
this to that worktree's `.bazelrc.local`:

```
startup --output_base=.local/bazel-out
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Unanchored output_base path 🐞 Bug ≡ Correctness

README recommends startup --output_base=.local/bazel-out, which is a relative path and can resolve
differently depending on where Bazel is invoked from (e.g., from a subdirectory), creating multiple
output bases and breaking the stated “output base lives under root .local/” cleanup behavior. This
also means the output directory may not be covered by the repo’s .bazelignore entry (which only
ignores the root .local).
Agent Prompt
## Issue description
`README.md` documents `startup --output_base=.local/bazel-out` for per-worktree cleanup. Because it’s a relative path, it may not consistently point at the workspace-root `.local/` directory, undermining the stated cleanup behavior and the repo’s `.bazelignore` assumptions.

## Issue Context
The repo already uses Bazel’s `%workspace%` expansion in `.bazelrc*` files, which provides a stable, workspace-root anchored path.

## Fix Focus Areas
- README.md[161-174]

## Proposed fix
Update the README snippet to use an anchored path, e.g.:

```
startup --output_base=%workspace%/.local/bazel-out
```

(Alternatively, explicitly state that Bazel must be invoked from the repo root for the relative path to work as intended, but the anchored form is more robust.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 97cd919

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants