How OpenCodeReview Handles File Bundling for Related Files: A Deep Dive into the Diff Resolution Pipeline
OpenCodeReview bundles related files by detecting logical relationships—such as renamed, moved, or module-linked files—and grouping them into context units that preserve full semantic context for LLM analysis, even when individual files are filtered out by user rules.
The alibaba/open-code-review project implements a sophisticated file bundling mechanism in its diff-processing layer. This system ensures that large language models (LLMs) receive complete contextual information when reviewing code changes, particularly when files have been renamed, moved, or belong to the same logical module. The bundling logic is centralized in the internal/diff package and orchestrated through a clean pipeline from workspace creation to LLM query execution.
The File Bundling Architecture
OpenCodeReview's approach to file bundling for related files rests on three core components that work together to preserve cross-file context.
Workspace Creation and File Discovery
The bundling process begins with building a comprehensive view of the repository. In internal/diff/workspace_file.go, the system creates a workspace structure that maps the entire codebase.
// Build the workspace for the repository
ws, err := diff.NewWorkspace(repoRoot)
if err != nil {
// Handle workspace initialization failure
}
This workspace serves as the foundation for all subsequent file resolution operations, enabling quick lookups of file locations and metadata.
Relocation Detection for Relationship Mapping
The internal/diff/relocation.go file implements Git history analysis to identify logically linked files. This component detects:
- Files that were renamed or moved in the same commit
- Files that share common ancestry or modification patterns
- Module-level groupings based on directory structure and import relationships
The relocation layer maintains an internal graph of file relationships that the resolver queries during bundle construction.
Bundle Resolution and Assembly
The core file bundling logic lives in internal/diff/resolver.go. The ResolveBundle method (or equivalent internal function) assembles the final bundle by:
- Accepting a primary file path as input
- Querying the relocation layer for related files
- Returning a
bundlestructure containing all interconnected files
// Resolve a file and get its bundle of related files
resolver, _ := rules.NewResolver(repoRoot, "")
bundle, err := resolver.ResolveBundle("src/main.go")
if err != nil {
// Handle resolution failure
}
This bundling step is critical—it guarantees that the LLM receives semantically complete context rather than isolated file fragments.
Loading Diffs for Complete Bundles
Once a bundle is constructed, the loadDiffs function (in internal/diff/resolver.go or related files) processes every member of the bundle. A key design decision here: diffs are loaded even for files that were excluded by user-specified include/exclude filters.
This behavior solves a common problem in code review tools. When a user filters to see only .go files, they might miss that a referenced .proto file changed in the same commit. OpenCodeReview's bundling overrides these filters for related files, ensuring the LLM can answer questions like "what changed in the module this file belongs to?"
// Load diffs for the whole bundle (even if some files are filtered)
diffs, err := diff.LoadDiffs(bundle, ws)
if err != nil {
// Handle diff loading failure
}
LLM Integration and Context Formatting
The final stage transforms bundled diffs into LLM-ready input. The FormatForLLM function (or equivalent in the diff package) serializes the bundle into a structured context block.
// Pass the bundled diffs to the LLM
llmInput := diff.FormatForLLM(diffs)
response, _ := llmClient.Query(llmInput)
By receiving related files as a single context unit, the LLM can perform cross-file reasoning—identifying breaking changes across renamed files, detecting interface mismatches between coupled modules, or understanding architectural shifts that span multiple files.
Key Source Files and Their Roles
| File | Purpose |
|---|---|
internal/diff/workspace_file.go |
Creates the repository workspace for file discovery |
internal/diff/relocation.go |
Analyzes Git history to detect moved/renamed/linked files |
internal/diff/resolver.go |
Implements ResolveBundle and loadDiffs for bundle construction and diff loading |
cmd/opencodereview/shared.go |
Wires the resolver into CLI command infrastructure |
cmd/opencodereview/agent.go |
Orchestrates review runs and feeds bundled diffs to the LLM |
Summary
- File bundling in OpenCodeReview groups logically related files to preserve LLM context across renames, moves, and module boundaries
- The relocation detector in
internal/diff/relocation.goidentifies file relationships through Git history analysis - Bundle resolution in
internal/diff/resolver.goassembles related files even when filtered out by user rules - Diff loading operates on complete bundles, ensuring no essential context is lost to file filters
- The LLM receives bundled context as unified blocks, enabling sophisticated cross-file reasoning
Frequently Asked Questions
What problem does file bundling solve in OpenCodeReview?
File bundling solves context fragmentation. Without it, file filters would strip away related files that the LLM needs for accurate analysis—renamed files would appear as deletions, module-level changes would be invisible, and cross-file dependencies would go unanalyzed. The bundling mechanism guarantees semantic completeness regardless of user filter settings.
How does OpenCodeReview detect that two files are "related"?
The system uses Git history analysis via internal/diff/relocation.go to identify files that were renamed, moved, or modified together. It also considers module structure—files in the same directory or with shared import relationships—to build a relationship graph that the resolver queries during bundle construction.
Can I disable file bundling or configure which relationships are detected?
The source analysis does not reveal explicit configuration options for bundling behavior. The bundling appears to be core architectural behavior wired through cmd/opencodereview/shared.go. Users can influence which files enter the pipeline through include/exclude filters, but related files that are filtered out will still be bundled if the relocation layer identifies them as linked.
Where does the actual LLM query with bundled files happen?
The orchestration occurs in cmd/opencodereview/agent.go, which coordinates the review run. This file creates the resolver, triggers bundle resolution, loads diffs via loadDiffs, formats the output through FormatForLLM, and submits the bundled context to the LLM client.
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 →