# How code-review-graph Handles Different Git Hosting Platforms: A Deep Dive into Multi-Platform Support

> Discover how code-review-graph supports GitHub GitLab Bitbucket and more by normalizing URLs and using platform adapters for seamless multi-platform Git analysis.

- Repository: [Tirth Kanani/code-review-graph](https://github.com/tirth8205/code-review-graph)
- Tags: deep-dive
- Published: 2026-08-17

---

**code-review-graph normalizes remote URLs, detects the host type via `PlatformFactory`, and delegates to platform-specific adapters (GitHub, GitLab, Bitbucket) or a generic Git CLI fallback, enabling seamless repository analysis across any Git hosting service.**

The `code-review-graph` tool is designed to analyze code review patterns across diverse Git repositories without locking you into a single vendor. By abstracting platform differences behind a unified adapter interface, it allows developers to generate review graphs from GitHub, GitLab, Bitbucket, or even self-hosted Git instances using the same command-line interface.

## The Three-Step Platform Abstraction Strategy

The repository handles multi-platform support through a pipeline that separates remote detection from data retrieval. This architecture lives primarily in two core modules: [`code_review_graph/git_utils.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/git_utils.py) for URL parsing and [`code_review_graph/platform.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/platform.py) for adapter dispatch.

### Step 1: Remote URL Normalization

Before any API calls occur, the tool extracts the `origin` remote from the local repository and canonicalizes it. In [`code_review_graph/git_utils.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/git_utils.py), the `normalize_remote_url` function strips protocol prefixes (https://, git@), authentication segments, and `.git` suffixes to produce a clean `host/owner/repo` string.

This normalization ensures that `https://github.com/user/repo.git`, `git@github.com:user/repo.git`, and `https://token@github.com/user/repo` all resolve to the same identifier, allowing downstream logic to focus on host detection rather than URL parsing edge cases.

### Step 2: Host Detection and Adapter Selection

Once normalized, the URL flows into [`code_review_graph/platform.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/platform.py) where the `PlatformFactory` class inspects the host segment against known patterns (`github.com`, `gitlab.com`, `bitbucket.org`). The factory maintains an internal registry mapping host regexes to adapter classes.

If a match is found, the factory instantiates the corresponding platform-specific adapter. If no match occurs—such as with self-hosted GitLab instances or private Gitea servers—the factory defaults to the `GitCLIAdapter`, ensuring the tool never fails solely due to unrecognized hosting providers.

### Step 3: Platform-Specific Implementation

Each adapter implements a common interface defining methods like `list_pull_requests()`, `fetch_pr_details()`, and `post_comment()`. This contract allows the core graph-building engine to remain agnostic about whether it is talking to the GitHub REST API, GitLab GraphQL endpoints, or local Git binaries.

## Platform-Specific Implementation Details

The concrete adapters handle authentication, pagination, and API quirks while exposing a uniform Python interface.

### GitHub Adapter

Located in [`code_review_graph/github_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/github_adapter.py), this implementation targets the official GitHub REST API at `https://api.github.com/`. It reads authentication tokens from the `GITHUB_TOKEN` environment variable, falling back to unauthenticated requests (subject to rate limits) if the variable is unset.

The adapter supports PR review comments, status checks, and automatic pagination handling for large repositories. It also implements specialized logic for fetching review threads and dismissal states, which are critical for accurate graph construction.

### GitLab Adapter

The [`code_review_graph/gitlab_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/gitlab_adapter.py) module interfaces with GitLab's API v4 at `https://gitlab.com/api/v4/` (or custom self-hosted URLs). Authentication uses the `GITLAB_TOKEN` environment variable passed as a private-token header.

This adapter handles both project-level and group-level repositories and respects GitLab's offset-based pagination model. It maps GitLab's "merge requests" nomenclature to the generic "pull request" interface expected by the core engine.

### Bitbucket Adapter

In [`code_review_graph/bitbucket_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/bitbucket_adapter.py), the tool supports both Bitbucket Cloud (`https://api.bitbucket.org/2.0/`) and Bitbucket Server instances. It expects `BITBUCKET_TOKEN` as an OAuth 2 bearer token for Cloud operations.

When encountering Bitbucket Server deployments or authentication failures, the adapter automatically falls back to the generic Git CLI adapter, ensuring read-only graph generation remains possible even without API access.

### Generic Git CLI Fallback

The [`code_review_graph/git_cli_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/git_cli_adapter.py) serves as the universal fallback when no hosted API is available. Using subprocess calls to `git ls-remote`, `git log`, and `git fetch`, it synthesizes PR-like data from commit messages and branch naming conventions (e.g., `feature-branch -> main`).

While this adapter provides read-only access and cannot post comments or fetch PR metadata like review states, it enables code-review-graph to function with any Git repository, including private corporate mirrors or offline archives.

## Extending Support for New Platforms

The platform abstraction is deliberately plugin-friendly. To add support for a new hosting service like Azure DevOps or Gitea:

1. Create a new module implementing the `BasePlatformAdapter` abstract base class (following the pattern in [`github_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/github_adapter.py)).
2. Register the adapter in `PlatformFactory._registry` with a host-matching regex.
3. The core engine automatically selects the new adapter the next time a matching remote URL is detected.

This design requires no modifications to the graph-construction pipeline, keeping the codebase maintainable as the Git hosting ecosystem evolves.

## Practical Usage Example

The following snippet, adapted from [`docs/USAGE.md`](https://github.com/tirth8205/code-review-graph/blob/main/docs/USAGE.md), demonstrates how the platform detection works transparently:

```python
from code_review_graph.platform import PlatformFactory

# Path to any local Git repository

repo_path = "/path/to/my/repo"

# Factory automatically detects GitHub, GitLab, Bitbucket, or generic Git

adapter = PlatformFactory.from_repo_path(repo_path)

# Uniform interface regardless of underlying platform

pull_requests = adapter.list_pull_requests()
for pr in pull_requests:
    details = adapter.fetch_pr_details(pr.id)
    print(f"{details.title} by {details.author}")

```

The `PlatformFactory.from_repo_path()` method handles the remote extraction, URL normalization, and adapter instantiation internally, returning a ready-to-use client that abstracts away platform differences.

## Summary

- **URL Normalization**: The `normalize_remote_url` function in [`code_review_graph/git_utils.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/git_utils.py) canonicalizes remote URLs to remove protocol and authentication variations.
- **Host Detection**: `PlatformFactory` in [`code_review_graph/platform.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/platform.py) matches normalized URLs against known hosts and selects the appropriate adapter.
- **Platform Adapters**: Dedicated modules ([`github_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/github_adapter.py), [`gitlab_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/gitlab_adapter.py), [`bitbucket_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/bitbucket_adapter.py)) implement API-specific logic for the three major hosted platforms.
- **Universal Fallback**: [`git_cli_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/git_cli_adapter.py) provides read-only access for any Git repository using local Git commands.
- **Environment-Based Auth**: Each hosted adapter reads tokens from `GITHUB_TOKEN`, `GITLAB_TOKEN`, or `BITBUCKET_TOKEN` respectively.
- **Extensible Design**: New platforms require only a new adapter class and registry entry, leaving core logic unchanged.

## Frequently Asked Questions

### How does code-review-graph authenticate with different Git hosting platforms?

The tool uses environment variables for each platform: `GITHUB_TOKEN` for GitHub, `GITLAB_TOKEN` for GitLab, and `BITBUCKET_TOKEN` for Bitbucket. These tokens are read by their respective adapter classes in [`code_review_graph/github_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/github_adapter.py), [`code_review_graph/gitlab_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/gitlab_adapter.py), and [`code_review_graph/bitbucket_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/bitbucket_adapter.py). If no token is provided, the GitHub adapter falls back to unauthenticated requests (with lower rate limits), while GitLab and Bitbucket adapters will fail gracefully to the generic Git CLI adapter.

### Can code-review-graph work with self-hosted GitLab or Bitbucket Server instances?

Yes. The `PlatformFactory` detects the host from the remote URL, and if it matches `gitlab.com` or `bitbucket.org`, it uses the hosted adapters. For self-hosted instances with different domains, the factory defaults to `GitCLIAdapter` from [`code_review_graph/git_cli_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/git_cli_adapter.py), which uses standard Git commands to analyze the repository. You can also extend the factory to register custom adapters for internal hosting domains by modifying the registry in [`code_review_graph/platform.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/platform.py).

### What happens if my Git hosting platform is not supported?

The tool falls back to the generic Git CLI adapter implemented in [`code_review_graph/git_cli_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/git_cli_adapter.py). This adapter uses local Git commands (`git log`, `git ls-remote`) to build a read-only review graph based on commit history and branch structures. While you lose access to PR comments and review states, you can still generate basic code review visualizations for any Git repository.

### Is it possible to add support for Azure DevOps or other platforms without modifying core code?

Yes. The architecture supports this through the adapter pattern. You would create a new module (e.g., [`azure_adapter.py`](https://github.com/tirth8205/code-review-graph/blob/main/azure_adapter.py)) implementing the `BasePlatformAdapter` interface, then register it in `PlatformFactory._registry` within [`code_review_graph/platform.py`](https://github.com/tirth8205/code-review-graph/blob/main/code_review_graph/platform.py) with a regex matching `dev.azure.com`. The core graph-building engine treats all adapters identically, so no other files require changes.