# How open-code-review Handles Diff Viewing and Annotation: A Deep Dive into the Go Implementation

> Discover how open-code-review efficiently handles diff viewing and annotation through a four-stage pipeline in its Go implementation. Explore structured diff parsing and interactive inline comments.

- Repository: [Alibaba/open-code-review](https://github.com/alibaba/open-code-review)
- Tags: deep-dive
- Published: 2026-08-04

---

**open-code-review implements a four-stage pipeline that extracts raw Git diffs, parses them into structured `FileDiff` and `Hunk` objects, maps comment positions to exact diff coordinates, and serves an interactive HTTP viewer for inline annotation.**

The `alibaba/open-code-review` project provides a comprehensive solution for diff viewing and annotation across multiple code review platforms. By combining Git command execution with custom parsing logic, the tool transforms unified diff output into navigable data structures that enable precise inline commenting. Understanding how open-code-review handles diff viewing and annotation reveals the architectural patterns that support GitLab, Gerrit, and GitFlic integrations.

## The Four-Stage Diff Processing Pipeline

The architecture separates concerns into distinct phases: extraction, parsing, position mapping, and visualization. Each stage operates on concrete Go structs defined in the `internal/tool` package.

### Stage 1: Diff Extraction via Git Commands

The pipeline begins in [`internal/tool/file_read_diff.go`](https://github.com/alibaba/open-code-review/blob/main/internal/tool/file_read_diff.go) with the **`loadDiffsByPath`** function. This utility executes `git diff --no-ext-diff --no-textconv` against a specified revision range to obtain a raw unified diff. The function captures stdout and handles repository path resolution, ensuring that binary diffs and external diff drivers are excluded for consistent text parsing.

### Stage 2: Unified Diff Parsing

Once extracted, the raw diff string feeds into the **`parseDiff`** function within the same file. This parser segments the combined diff into per-file sections represented by the **`FileDiff`** struct, which tracks `OldPath` and `NewPath` metadata. Each `FileDiff` contains a slice of **`Hunk`** structs that record `oldStart`, `newStart`, line counts, and the actual text lines. These structures preserve the context lines required for accurate comment positioning.

### Stage 3: Annotation Position Mapping

When users create comments, the system must translate file paths and line numbers into platform-specific diff positions. The [`internal/tool/code_comment.go`](https://github.com/alibaba/open-code-review/blob/main/internal/tool/code_comment.go) file implements **`makeCommentPosition`**, which walks the parsed `FileDiff` and `Hunk` slices to compute the exact coordinates. This mapping accounts for added, removed, and context lines, generating position objects compatible with GitLab's diff position API or Gerrit's comment endpoints.

### Stage 4: Interactive Viewer Server

The final stage exposes a local HTTP server defined in [`internal/viewer/server.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/server.go) and [`internal/viewer/handler.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/handler.go). The **`opencodereview view`** command (entry point in [`cmd/opencodereview/viewer_cmd.go`](https://github.com/alibaba/open-code-review/blob/main/cmd/opencodereview/viewer_cmd.go)) launches this server, serving HTML diff pages at the `/diff` endpoint and handling comment submissions via `/comment`. The viewer renders the parsed hunks with clickable "Add comment" controls that invoke the position mapping logic.

## Core Implementation Details

### Loading and Parsing Diffs in file_read_diff.go

The `LoadDiffsByPath` function returns a `map[string]*FileDiff`, keyed by new file paths for O(1) lookup during annotation. Each `FileDiff` struct encapsulates the complete change set for a single file, while nested `Hunk` structs maintain the line-range metadata necessary for mapping absolute line numbers to relative hunk positions.

```go
// Load diffs for a specific revision range
diffsByPath, err := file_read_diff.LoadDiffsByPath("/path/to/repo", "main", "feature-branch")
if err != nil {
    log.Fatalf("diff extraction failed: %v", err)
}

// Inspect a specific file's hunks
fd := diffsByPath["src/main.go"]
fmt.Printf("File %s contains %d hunks\n", fd.NewPath, len(fd.Hunks))

```

### Computing Comment Positions in code_comment.go

The `MakeCommentPosition` function accepts a `Comment` struct (containing `Path` and `Line`) and the `diffsByPath` map. It iterates through the `Hunks` of the target `FileDiff` to locate which hunk contains the specified line number, then calculates the `oldLine` and `newLine` values required by the review platform's API.

```go
comment := tool.Comment{
    Path: "src/main.go",
    Line: 42, // Line number in the new version
}

pos, err := code_comment.MakeCommentPosition(comment, diffsByPath)
if err != nil {
    log.Fatalf("position mapping failed: %v", err)
}
fmt.Printf("Diff position: %+v\n", pos)

```

### Serving the Diff Viewer

The viewer server integrates the parsed diff structures with a lightweight HTTP interface. When a browser requests a diff, the handler retrieves the pre-computed `FileDiff` objects and renders them with line anchors. If a diff cannot be located—such as when a repository is stripped or the revision range is invalid—the system logs a warning and falls back to a plain-text summary, ensuring that no comment data is lost.

## Practical Usage Examples

Launch the interactive diff viewer from the command line to inspect changes before submitting a review:

```bash

# Start the local diff viewer server

$ opencodereview view --repo . --from origin/main --to HEAD

# Server available at http://localhost:8080/diff

```

Programmatically process diffs for custom CI integrations:

```go
package main

import (
    "log"
    "github.com/alibaba/open-code-review/internal/tool"
)

func main() {
    // Extract and parse
    diffs, err := tool.LoadDiffsByPath(".", "HEAD~1", "HEAD")
    if err != nil {
        log.Fatal(err)
    }
    
    // Process each file's hunks
    for path, fd := range diffs {
        log.Printf("Processing %s with %d hunks", path, len(fd.Hunks))
    }
}

```

## CI Integration and Fallback Handling

The repository includes [`examples/gitflic_ci/post_review.py`](https://github.com/alibaba/open-code-review/blob/main/examples/gitflic_ci/post_review.py), which demonstrates how Python-based CI systems can leverage the Go diff engine. When the diff is unavailable—perhaps due to shallow clones or missing merge-base references—the integration falls back to posting summary comments rather than inline annotations. This graceful degradation ensures that review feedback persists even when the full diff viewing pipeline cannot execute.

## Summary

- **Diff extraction** relies on [`internal/tool/file_read_diff.go`](https://github.com/alibaba/open-code-review/blob/main/internal/tool/file_read_diff.go) to execute Git commands and capture unified diff output.
- **Parsing logic** converts raw diffs into `FileDiff` and `Hunk` structs that preserve line-number metadata.
- **Annotation mapping** uses [`internal/tool/code_comment.go`](https://github.com/alibaba/open-code-review/blob/main/internal/tool/code_comment.go) to translate absolute line numbers into platform-specific diff positions.
- **Viewer server** provides an HTTP interface defined in [`internal/viewer/server.go`](https://github.com/alibaba/open-code-review/blob/main/internal/viewer/server.go) for interactive diff browsing and commenting.
- **Fallback mechanisms** ensure comments are posted as summaries when diff data is missing, as shown in the GitFlic CI example.

## Frequently Asked Questions

### How does open-code-review extract diffs from Git repositories?

The tool invokes `git diff --no-ext-diff --no-textconv` through the `LoadDiffsByPath` function in [`internal/tool/file_read_diff.go`](https://github.com/alibaba/open-code-review/blob/main/internal/tool/file_read_diff.go). This command generates a unified diff for the specified revision range while excluding binary files and external diff drivers, ensuring consistent text output for parsing.

### What data structures does open-code-review use to represent diff hunks?

The system defines a `FileDiff` struct for each changed file, containing `OldPath` and `NewPath` fields along with a slice of `Hunk` structs. Each `Hunk` records `oldStart`, `newStart`, and the line-by-line changes, preserving context lines necessary for accurate comment positioning.

### How are comment positions mapped to specific lines in a diff?

The `MakeCommentPosition` function in [`internal/tool/code_comment.go`](https://github.com/alibaba/open-code-review/blob/main/internal/tool/code_comment.go) accepts a file path and line number, then traverses the `Hunk` slices within the corresponding `FileDiff` to calculate the exact diff coordinates. This produces position objects that code review platforms like GitLab or Gerrit can render as inline annotations.

### Can open-code-review display diffs without a local Git repository?

No, the current implementation requires a local repository to execute `git diff` commands. However, if the diff cannot be generated—due to shallow clones or missing references—the system implements a fallback mechanism that posts comments as summary notes rather than inline annotations, ensuring feedback is not lost.