From 8c95a45c6a23b57b42a62c3bcc6b8f3a9a97feb1 Mon Sep 17 00:00:00 2001 From: Quanyi Ma Date: Mon, 27 Oct 2025 16:10:51 +0800 Subject: [PATCH] Update git protocol doc and reformat core.rs Signed-off-by: Quanyi Ma --- docs/GIT_PROTOCOL_GUIDE.md | 120 +++++++++++++++++++++++++++++++++++++ src/protocol/core.rs | 10 ++-- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/docs/GIT_PROTOCOL_GUIDE.md b/docs/GIT_PROTOCOL_GUIDE.md index 40264aa6..727d1fcf 100644 --- a/docs/GIT_PROTOCOL_GUIDE.md +++ b/docs/GIT_PROTOCOL_GUIDE.md @@ -173,6 +173,126 @@ Each transport layer is responsible for mapping protocol errors to appropriate t - Progress reporting - Reference update validation +### 9.3 Protocol Evolution: v0 / v1 / v2 Comparison + +#### Version Overview + +Git Smart Protocol has evolved through three major versions. +Each version refines how the client and server exchange repository data, +especially for large-scale or latency-sensitive environments. + +| Feature | v0 (Legacy) | v1 (Mainstream) | v2 (Modern) | +|----------|--------------|----------------|-------------| +| Capability Negotiation | ❌ None | ✅ Introduced | ✅ Refined command-based negotiation | +| Protocol Framing | Raw Stream | pkt-line framing | pkt-line with structured commands | +| HTTP Support | Partial | Full | Optimized and proxy-friendly | +| Extensibility | Limited | Basic | Modular and command-oriented | +| Command Granularity | Combined flow | Sequential phases | Independent commands | +| Performance | Low | Medium | High (fewer RTTs, less data transfer) | +| Server Complexity | Simple | Moderate | Structured and modular | +| Status in Git Ecosystem | Deprecated | Widely used | Supported in modern Git servers (>=2.18) | + +#### Version Highlights + +##### **v0 (Legacy Smart Protocol)** +- Early “smart” mode over TCP or SSH before capability negotiation existed. +- Used simple request/response sequences (`upload-pack` / `receive-pack`) + without flexible negotiation or side-band streaming. +- Now considered obsolete and unsupported in most Git servers. + +##### **v1 (Current Mainstream)** +- Introduced in Git 1.7+. +- Added capability negotiation, side-band multiplexing, and better error mapping. +- Enables features such as: + - `multi_ack_detailed`, `side-band-64k`, `ofs-delta`, `report-status`, `no-done` +- Currently the most widely deployed version (e.g., GitHub, GitLab, Gitea). + +##### **v2 (Command-Based Modern Protocol)** +- Introduced in Git 2.18 (2018), designed for extensibility and performance. +- Transforms the protocol from stream-based negotiation to a **command-driven request model**: + - Client sends specific commands instead of phase-based state machines. + - Server replies with structured sections per command. +- Ideal for HTTP(S) transports and proxy environments. + + +### 9.4 Protocol v2 Negotiation and Commands + +#### 1. Initial Capability Exchange + +The client initiates a request with: +``` +GET /info/refs?service=git-upload-pack +Git-Protocol: version=2 +``` + +Server responds with a list of supported capabilities and commands: +``` +version 2 +ls-refs +fetch=filter +server-option +session-id=deadbeef +agent=git/2.45.0 +``` + +#### 2. Supported v2 Commands + +| Command | Purpose | Description | +|----------|----------|-------------| +| `ls-refs` | List references | Returns branches, tags, and HEAD information with filtering. | +| `fetch` | Clone / fetch data | Supports partial and shallow clones; incremental packfile delivery. | +| `push` | Push updates | Negotiates reference updates and receives new objects. | +| `server-option` | Custom server parameters | Allows additional server-side settings before command execution. | +| `agent` | Version identification | Reports client/server version for debugging and analytics. | + +#### 3. Example: v2 Fetch Flow + +``` +C: command=ls-refs +C: agent=git/2.45.0 +C: end +S: ref refs/heads/main 1234abcd +S: symref=HEAD refs/heads/main +S: end + +C: command=fetch +C: want 1234abcd +C: filter blob:none +C: done +S: packfile data... +S: end +``` + +### 9.5 Migration and Upgrade Recommendations + +#### For Protocol Implementers +- Maintain backward compatibility: support v1 and v2 simultaneously. +- Allow version negotiation via the `Git-Protocol` header or SSH command environment. +- Gradually deprecate v0 handling to reduce code complexity. + +#### For System Integrators +- Use v2 for large-scale repositories or latency-sensitive deployments. +- v2’s `ls-refs` and `fetch=filter` reduce bandwidth and server CPU usage. +- Implement adaptive fallback to v1 for older Git clients. + +#### For `git-internal` Library +- Current status: **Full v1 compliance** +- Recommended next steps: + 1. Introduce protocol negotiation layer detecting `Git-Protocol: version=2` + 2. Implement minimal `ls-refs` and `fetch` command handlers + 3. Extend `RepositoryAccess` and `GitProtocol` traits to support v2 command flow + 4. Add benchmark suite comparing v1 vs v2 RTT and bandwidth efficiency + +### 9.6 Summary + +| Category | v1 | v2 | +|-----------|----|----| +| Negotiation | Capabilities exchange via `info/refs` | Explicit version header (`Git-Protocol: version=2`) | +| Command Model | Sequential phase-based | Independent modular commands | +| Extensibility | Limited (capability list) | Open-ended (new commands possible) | +| Efficiency | Moderate | High (fewer round trips, less data) | +| Implementation Complexity | Medium | Higher but cleaner abstraction | + ## 10. Integration Guide ### 10.1 Implementation Steps diff --git a/src/protocol/core.rs b/src/protocol/core.rs index c99ef8c3..685c4fa8 100644 --- a/src/protocol/core.rs +++ b/src/protocol/core.rs @@ -2,18 +2,18 @@ //! //! This module provides the main `GitProtocol` struct and `RepositoryAccess` trait //! that form the core interface of the git-internal library. +use std::str::FromStr; +use std::collections::HashMap; -use async_trait::async_trait; use bytes::Bytes; +use async_trait::async_trait; use futures::stream::StreamExt; -use std::collections::HashMap; -use std::str::FromStr; use crate::hash::SHA1; use crate::internal::object::ObjectTrait; -use super::smart::SmartProtocol; -use super::types::{ProtocolError, ProtocolStream, ServiceType}; +use crate::protocol::smart::SmartProtocol; +use crate::protocol::types::{ProtocolError, ProtocolStream, ServiceType}; /// Repository access trait for storage operations ///