Force working-tree review
How the Codex Plugin Resolves Review Targets: Working Tree vs Branch Detection
The Codex plugin resolves review targets through a priority-based algorithm in resolveReviewTarget that first checks for explicit --base or --scope flags, then automatically selects working-tree mode when uncommitted changes exist or branch mode against the default branch when the repository is clean.
The openai/codex-plugin-cc repository implements intelligent target resolution to determine whether a code review should analyze your working directory changes or compare branches. Understanding how the plugin chooses between working-tree and branch modes helps you control exactly what gets reviewed when running codex review commands. The resolution logic lives in plugins/codex/scripts/lib/git.mjs and follows a strict priority order to balance explicit user intent with automatic detection.
The Core Resolution Function
The resolveReviewTarget function in plugins/codex/scripts/lib/git.mjs (lines 35-90) serves as the single source of truth for determining review scope. This function analyzes repository state and user-provided flags to return a structured target object that downstream components consume when building review requests.
The function examines three potential inputs in strict priority order:
- Explicit
--baseflag – Forces branch comparison against a specific reference - Explicit
--scopeflag – Directly selects either working-tree or branch mode - Automatic detection – Inspects repository cleanliness to choose intelligently
Priority 1: The --base Flag Override
When you supply --base <ref>, the plugin immediately enters branch mode. This flag takes precedence over all other options, diffing the current HEAD against your specified base reference.
codex review --base main
This returns a target object with mode: "branch", baseRef: "main", and explicit: true, bypassing all automatic detection logic.
Priority 2: The --scope Flag Selection
The --scope flag provides explicit mode selection without specifying a particular branch reference:
--scope working-tree→ Targets uncommitted changes in your working directory--scope branch→ Compares against the repository's default branch (detected viadetectDefaultBranch)
# Force working-tree review
codex review --scope working-tree
# Force branch review against default branch
codex review --scope branch
When using --scope branch without --base, the system calls detectDefaultBranch (also in git.mjs) to identify whether to diff against main, master, or another default reference.
Priority 3: Automatic Selection Logic
When no explicit flags are provided, the plugin enters auto mode and inspects repository state via the state.isDirty property. This boolean aggregates status across staged, unstaged, and untracked files.
If the repository contains any uncommitted changes, the function selects working-tree mode to review your active edits. If the repository is completely clean, it falls back to branch mode, comparing the current HEAD against the default branch.
This automatic behavior ensures that codex review without arguments does the right thing: reviewing your current work when you have edits, or reviewing branch divergence when you don't.
Return Value Structure
Regardless of how the mode is determined, resolveReviewTarget returns a standardized object consumed by plugins/codex/scripts/lib/codex.mjs and validated in plugins/codex/scripts/codex-companion.mjs:
{
mode: "working-tree" | "branch",
label: "working tree diff" | "branch diff against main",
baseRef: "main" | undefined, // Only present for branch mode
explicit: true | false // True if from --base or --scope
}
The explicit field allows the CLI to distinguish between user-intended overrides and automatic selections, which affects how results are displayed and cached.
Practical Usage Examples
Example 1: Default Behavior on Dirty Repository
When your working directory has unstaged modifications:
codex review
Resulting target object:
{
"mode": "working-tree",
"label": "working tree diff",
"explicit": false
}
The function detects state.isDirty === true and returns the working-tree target.
Example 2: Explicit Base Reference
codex review --base feature/123
Result:
{
"mode": "branch",
"label": "branch diff against feature/123",
"baseRef": "feature/123",
"explicit": true
}
Example 3: Explicit Scope to Branch with Default Detection
codex review --scope branch
Assuming the default branch is main:
{
"mode": "branch",
"label": "branch diff against main",
"baseRef": "main",
"explicit": true
}
Example 4: Explicit Scope to Working Tree
codex review --scope working-tree
Result:
{
"mode": "working-tree",
"label": "working tree diff",
"explicit": true
}
Summary
- The
resolveReviewTargetfunction inplugins/codex/scripts/lib/git.mjs(lines 35-90) implements a three-tier priority system for target resolution. - Explicit
--basealways wins, forcing branch mode against the specified reference. - Explicit
--scopeselects working-tree or branch mode, with branch mode usingdetectDefaultBranchto find the comparison target. - Automatic mode inspects
state.isDirty: uncommitted changes trigger working-tree review, while clean repositories trigger branch comparison against the default. - The function returns a structured object with
mode,label,baseRef, andexplicitproperties used bycodex.mjsto construct native review requests.
Frequently Asked Questions
What happens if I specify both --base and --scope?
The --base flag takes precedence over --scope according to the priority logic in git.mjs. If you provide both, the plugin ignores the --scope value and uses the explicit base reference for branch comparison.
How does the plugin detect whether to use main or master as the default branch?
The detectDefaultBranch function (located in plugins/codex/scripts/lib/git.mjs) interrogates the repository's symbolic refs and remote configuration to determine whether to diff against main, master, or another default branch when running in --scope branch mode or automatic branch fallback.
Can I review untracked files in working-tree mode?
Yes. The automatic state.isDirty detection includes untracked files alongside staged and unstaged changes. When the plugin detects any uncommitted content—including new untracked files—it selects working-tree mode to ensure those files appear in the review context.
Where are the tests for target resolution located?
Unit tests verifying resolveReviewTarget behavior live in tests/git.test.mjs, covering scenarios for dirty repositories, clean repositories, and explicit flag handling. Integration tests confirming CLI respect for chosen targets appear in tests/runtime.test.mjs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →