How the Codex Plugin Collects Git Repository Context for Reviews

The Codex plugin collects git repository context through a three-stage pipeline in plugins/codex/scripts/lib/git.mjs: resolving the review target, gathering raw diff data with size limits, and enriching with untracked files to produce a structured JSON payload for the language model.

When you run codex review, the openai/codex-plugin-cc repository needs to feed the Codex language model a complete yet concise snapshot of your changes. This review context is built by the collectReviewContext function and follows a predictable pipeline from detection to delivery. Understanding how this works helps you interpret review behavior, debug missing files, or tune performance for large repositories.

The Three Stages of Context Collection

The collectReviewContext routine in plugins/codex/scripts/lib/git.mjs breaks the work into modular stages that each handle a specific concern.

Stage 1: Resolve the Review Target with resolveReviewTarget

The plugin first determines what to diff. The resolveReviewTarget(cwd, options) function (starting at line 135 in git.mjs) inspects repository state and returns a target descriptor:

  • Dirty working tree: If git status --porcelain shows uncommitted changes, it prepares a working-tree diff.
  • Clean state: Falls back to a branch-range diff using the default branch (git symbolic-ref refs/remotes/origin/HEAD).
  • Explicit overrides: Respects options.base, options.head, or options.scope when provided.

The function ensures the current directory is a Git repository via ensureGitRepository (line 80) before proceeding.

Stage 2: Gather Raw Diff Data

With the target resolved, the plugin executes git diff commands (around lines 320-350 in git.mjs):

  • Uses --binary to preserve file renames and binary changes.
  • Runs git diff --shortstat for a human-readable summary.
  • Applies maxInlineDiffBytes (default 256 KB) to prevent oversized payloads.

When the diff exceeds this limit, the function switches to a lightweight context containing only filenames and short-stat rather than full patch text.

Stage 3: Enrich with Untracked Files and File Contents

The final enrichment step (lines 380-420 in git.mjs) handles edge cases:

  • Untracked files: Discovered via git ls-files --others --exclude-standard, then read via fs.readFile and added to context.files with path and content.
  • Symlink safety: Broken symlinks are skipped without crashing (verified in tests/git.test.mjs).
  • Size pruning: Individual file reads respect the same size limits as diffs.

The resulting context object follows the schema defined in plugins/codex/schemas/review-output.schema.json:

{
  "base": "origin/main",
  "head": "HEAD",
  "diff": "…patch text…",
  "files": [
    { "path": "src/app.js", "content": "…" }
  ],
  "stats": "3 files changed, 45 insertions(+), 12 deletions(-)"
}

Practical Example: Using the Git Utilities Directly

The codex-companion.mjs script (line 409) demonstrates the standard integration pattern. You can also use these utilities in custom workflows:

import {
  ensureGitRepository,
  resolveReviewTarget,
  collectReviewContext,
} from "./lib/git.mjs";

// Validate repository presence
await ensureGitRepository(process.cwd());

// Auto-detect target (dirty working tree vs. branch range)
const target = resolveReviewTarget(process.cwd());

// Build context with custom size limits
const reviewContext = await collectReviewContext(process.cwd(), target, {
  maxInlineDiffBytes: 200 * 1024, // 200 KB limit
});

// Submit to Codex
await codex.submitReview(reviewContext);

Key Source Files and Their Roles

File Purpose Critical Functions
plugins/codex/scripts/lib/git.mjs Core Git operations ensureGitRepository, resolveReviewTarget, collectReviewContext
plugins/codex/scripts/codex-companion.mjs CLI orchestration Calls collectReviewContext at line 409
plugins/codex/schemas/review-output.schema.json Payload validation Defines context object shape
tests/git.test.mjs Behavior verification Tests dirty repos, untracked directories, broken symlinks
tests/commands.test.mjs CLI integration Verifies git diff --shortstat output format

Summary

  • Target resolution uses resolveReviewTarget to choose between working-tree and branch-range diffs based on repository state and explicit options.
  • Diff collection runs git diff --binary with configurable size limits via maxInlineDiffBytes, falling back to lightweight context when exceeded.
  • Content enrichment adds untracked files through git ls-files --others and fs.readFile, safely handling symlinks and size constraints.
  • Final packaging produces a JSON payload conforming to review-output.schema.json with base, head, diff, files, and stats fields.

Frequently Asked Questions

How does the plugin decide between reviewing unstaged changes or comparing branches?

The resolveReviewTarget function runs git status --porcelain first. If output exists (uncommitted changes), it targets the working tree. Otherwise it uses the default remote branch for a branch-range comparison. You can override this with options.base, options.head, or options.scope.

What happens when a repository has very large diffs?

When collectReviewContext encounters a diff larger than maxInlineDiffBytes (default 256 KB), it truncates the patch text and returns a lightweight context containing only file paths and git diff --shortstat output. This prevents token limit exhaustion in the language model.

Are untracked files included in reviews?

Yes. The plugin runs git ls-files --others --exclude-standard to find untracked files, reads their contents up to the size limit, and includes them in the files array with path and content. Broken symlinks are detected and skipped to prevent crashes.

Can I use the git utilities outside the standard CLI workflow?

Yes. The module exports ensureGitRepository, resolveReviewTarget, and collectReviewContext from plugins/codex/scripts/lib/git.mjs. Import these in custom scripts to build review contexts with your own configuration, then submit via codex.submitReview(context).

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 →