How Codex Plugin CC Handles Review Target Resolution: Branch vs Working Tree

Codex Plugin CC resolves review targets through the resolveReviewTarget function in plugins/codex/scripts/lib/git.mjs, which automatically selects between branch diffs and working-tree changes based on repository cleanliness, explicit --base or --scope flags, or falls back to branch mode when the working tree is clean.

Understanding review target resolution is essential when using the openai/codex-plugin-cc repository to generate code reviews. The system must determine whether to analyze changes against a specific branch reference or against the current working directory's staged and unstaged modifications. This decision logic is implemented in the Git utility module and consumed by the main companion script.

The Core Resolution Function

The entire review target resolution process centers on the resolveReviewTarget function located in plugins/codex/scripts/lib/git.mjs (lines 34-90). This async function accepts a repository path and an optional options object, then returns a deterministic target configuration that tells the review engine exactly what changes to analyze.

The function begins by ensuring the environment is valid through ensureGitRepository and capturing the current state via getWorkingTreeState before applying a cascading decision tree to select the appropriate mode.

Decision Flow for Target Resolution

The resolution logic follows a strict priority order, checking explicit overrides before falling back to automatic detection.

Pre-flight Validation

Before any mode selection occurs, the function validates that the current directory resides within a Git repository and gathers the working tree state. This initial check at lines 34-40 ensures that subsequent operations have a valid Git context to work with.

Explicit Base Reference (--base)

When the caller provides a base option (e.g., --base v1.2.0), the function immediately forces branch mode (lines 42-48). In this scenario, the review will compare the current state against the specified reference, regardless of working tree cleanliness. The returned object sets mode: "branch" and uses the provided ref as the baseRef.

Explicit Scope Selection (--scope)

The --scope flag allows users to override automatic detection with specific behaviors:

  • working-tree: Forces the review to analyze staged, unstaged, and untracked files in the working directory (lines 51-57). The function returns mode: "working-tree" and sets explicit: true.

  • branch: Forces branch comparison mode. When specified without a --base flag, the function calls detectDefaultBranch (lines 65-73) to identify the appropriate comparison branch (typically main, master, or whatever origin/HEAD points to).

Automatic Mode Detection

When no explicit flags are provided, the function enters auto mode (lines 75-89):

  1. Dirty working tree: If state.isDirty returns true (indicating staged, unstaged, or untracked files exist), the function selects working-tree mode (lines 75-81). This ensures that local modifications are reviewed even if they haven't been committed.

  2. Clean repository: When the working tree is clean, the function defaults to branch mode using the detected default branch as the comparison base (lines 83-89).

Target Object Return Structure

Regardless of which path is taken, resolveReviewTarget returns a standardized object containing:

Property Description
mode Either "branch" or "working-tree"
label Human-readable description (e.g., "branch diff against main")
baseRef The branch name for comparison (only present in branch mode)
explicit Boolean indicating whether the mode was forced via flags

This structure allows the calling code in codex-companion.mjs to consistently handle both review types without additional conditional logic.

Helper Functions Supporting Resolution

Several utility functions within git.mjs provide the data necessary for these decisions:

detectDefaultBranch

Located at lines 93-114, this function inspects origin/HEAD to determine the remote default branch. If that reference isn't available, it falls back to checking common branch names including main, master, and trunk. This ensures that branch-mode reviews always have a sensible comparison target even when the user hasn't specified one explicitly.

getWorkingTreeState

This function gathers the repository status to determine if the working tree is dirty. It checks for staged changes, unstaged modifications, and untracked files, returning a boolean isDirty flag that drives the automatic mode selection at line 75.

getCurrentBranch

Called at line 117, this utility reports the current branch name for inclusion in review summaries and metadata, though it doesn't affect the target resolution logic directly.

Practical Usage Examples

Here are three common patterns for invoking the resolution logic:

import { resolveReviewTarget } from "./plugins/codex/scripts/lib/git.mjs";

// 1. Automatic mode on a clean repository → branch diff
const target1 = await resolveReviewTarget("/path/to/repo");
console.log(target1.mode);   // "branch"
console.log(target1.label); // "branch diff against main"

// 2. Force working-tree review of local changes
const target2 = await resolveReviewTarget("/path/to/repo", { scope: "working-tree" });
console.log(target2.mode);   // "working-tree"
console.log(target2.explicit); // true

// 3. Compare against a specific tag or commit
const target3 = await resolveReviewTarget("/path/to/repo", { base: "v1.2.0" });
console.log(target3.mode);   // "branch"
console.log(target3.baseRef); // "v1.2.0"

These examples demonstrate how the function adapts to different workflows while maintaining consistent return types.

Integration with the Codex Companion

The resolution logic connects to the main application in plugins/codex/scripts/codex-companion.mjs at lines 369-371. Here, the validateNativeReviewRequest function calls resolveReviewTarget to prepare the review context before invoking the AI code review engine.

This integration point ensures that by the time the review starts, the system has already determined whether to analyze a branch diff (using baseRef) or the working tree changes, and has gathered the appropriate file lists accordingly.

Summary

  • Review target resolution occurs in plugins/codex/scripts/lib/git.mjs via the resolveReviewTarget function (lines 34-90).
  • The function prioritizes explicit user input: --base forces branch mode, while --scope forces either branch or working-tree mode.
  • In automatic mode, a dirty working tree triggers working-tree review, while a clean repository defaults to branch comparison against the detected default branch.
  • Helper functions detectDefaultBranch (lines 93-114) and getWorkingTreeState provide the underlying Git intelligence for these decisions.
  • The entry point at codex-companion.mjs (lines 369-371) consumes this logic to configure the review context.

Frequently Asked Questions

How does automatic mode decide between branch and working-tree review?

When running in automatic mode (no --scope or --base flags provided), the function checks state.isDirty at line 75. If the working tree contains any staged, unstaged, or untracked files, it selects working-tree mode to capture local modifications. If the repository is clean, it defaults to branch mode and compares against the detected default branch (lines 83-89).

What happens if I specify both --base and --scope?

The --base flag takes precedence in the implementation order. At lines 42-48, the function checks for the base option before evaluating the scope option. Providing a base reference automatically forces branch mode, regardless of any --scope value provided, because the explicit base reference inherently defines a branch comparison.

Which files contain the review target resolution logic?

The primary logic resides in plugins/codex/scripts/lib/git.mjs, specifically the resolveReviewTarget function (lines 34-90) and its helper functions detectDefaultBranch (lines 93-114) and getWorkingTreeState. The entry point that invokes this logic is plugins/codex/scripts/codex-companion.mjs (lines 369-371), and unit tests verifying this behavior are in tests/git.test.mjs.

How is the default branch detected when using branch mode?

The detectDefaultBranch function (lines 93-114) first attempts to resolve origin/HEAD to determine the remote default branch. If that reference is unavailable, it iterates through common branch names including main, master, and trunk, returning the first existing match. This ensures branch comparisons always have a valid reference point even without explicit configuration.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →