概述

本文档详细介绍了 Xget 对 Git 协议的全面支持,包括 HTTP/HTTPS、SSH、Git 协议等各种 Git 传输协议的加速方案。通过 Xget,开发者可以显著提升 Git 操作的速度和稳定性。

Git 协议基础

Git 传输协议

Git 支持多种传输协议:

  1. HTTP/HTTPS 协议

    • 最常用的协议
    • 支持代理和缓存
    • 适合防火墙环境
  2. SSH 协议

    • 加密传输
    • 支持认证
    • 适合安全要求高的场景
  3. Git 协议

    • 最快的协议
    • 无加密
    • 适合内网环境
  4. Git 协议 (SSH)

    • 结合了 Git 协议和 SSH
    • 速度快且安全

Git 操作类型

Git 操作主要分为以下类型:

  1. Clone

    • 克隆完整仓库
    • 浅克隆(shallow clone)
    • 单分支克隆
  2. Fetch

    • 获取远程更新
    • 获取特定分支
    • 获取特定标签
  3. Pull

    • 拉取并合并
    • 拉取并变基
  4. Push

    • 推送提交
    • 推送标签
    • 强制推送
  5. 其他操作

    • LFS 操作
    • Submodule 操作
    • Archive 操作

HTTP/HTTPS 协议支持

基本原理

Xget 通过 HTTP/HTTPS 协议代理 Git 操作,实现以下功能:

  1. URL 转换

    • 将原始 Git URL 转换为 Xget 加速 URL
    • 自动识别 Git 仓库地址
  2. 请求代理

    • 代理 Git HTTP 请求
    • 处理 Git 特定的请求头
  3. 响应缓存

    • 缓存 Git 对象
    • 减少重复请求

URL 转换规则

// GitHub URL 转换
function convertGitHubUrl(url) {
  // 原始 URL: https://github.com/user/repo.git
  // 加速 URL: https://xget.xi-xu.me/gh/user/repo.git
  
  const pattern = /^https?:\/\/github\.com\/(.+?)\/(.+?)(\.git)?$/;
  const match = url.match(pattern);
  
  if (match) {
    const [, user, repo] = match;
    return `https://xget.xi-xu.me/gh/${user}/${repo}.git`;
  }
  
  return url;
}

// GitLab URL 转换
function convertGitLabUrl(url) {
  // 原始 URL: https://gitlab.com/user/repo.git
  // 加速 URL: https://xget.xi-xu.me/gl/user/repo.git
  
  const pattern = /^https?:\/\/gitlab\.com\/(.+?)\/(.+?)(\.git)?$/;
  const match = url.match(pattern);
  
  if (match) {
    const [, user, repo] = match;
    return `https://xget.xi-xu.me/gl/${user}/${repo}.git`;
  }
  
  return url;
}

// 通用 URL 转换
function convertGitUrl(url) {
  const converters = [
    convertGitHubUrl,
    convertGitLabUrl,
    // 添加其他平台的转换函数
  ];
  
  for (const converter of converters) {
    const converted = converter(url);
    if (converted !== url) {
      return converted;
    }
  }
  
  return url;
}

Git HTTP 请求处理

// Git HTTP 请求处理器
async function handleGitHttpRequest(request) {
  const url = new URL(request.url);
  const path = url.pathname;
  
  // Git 智能协议请求
  if (path.endsWith('/info/refs')) {
    return await handleInfoRefs(request);
  }
  
  // Git 对象请求
  if (path.includes('/objects/')) {
    return await handleGitObject(request);
  }
  
  // Git 上传包请求
  if (path.includes('/git-upload-pack')) {
    return await handleUploadPack(request);
  }
  
  // Git 接收包请求
  if (path.includes('/git-receive-pack')) {
    return await handleReceivePack(request);
  }
  
  // 默认处理
  return await fetch(request);
}

// 处理 info/refs 请求
async function handleInfoRefs(request) {
  const url = new URL(request.url);
  const service = url.searchParams.get('service');
  
  // 构建目标 URL
  const targetUrl = buildTargetUrl(url);
  
  // 添加 Git 特定的请求头
  const headers = new Headers(request.headers);
  headers.set('Git-Protocol', 'version=2');
  
  // 发送请求
  const response = await fetch(targetUrl, {
    method: request.method,
    headers: headers
  });
  
  return response;
}

// 处理 Git 对象请求
async function handleGitObject(request) {
  const url = new URL(request.url);
  const targetUrl = buildTargetUrl(url);
  
  // 检查缓存
  const cacheKey = `git-object:${url.pathname}`;
  const cached = await CACHE.get(cacheKey);
  
  if (cached) {
    return new Response(cached, {
      headers: {
        'X-Cache': 'HIT',
        'Content-Type': 'application/x-git-loose-object'
      }
    });
  }
  
  // 发送请求
  const response = await fetch(targetUrl, {
    method: request.method,
    headers: request.headers
  });
  
  // 缓存响应
  if (response.ok) {
    const clonedResponse = response.clone();
    const buffer = await clonedResponse.arrayBuffer();
    await CACHE.put(cacheKey, buffer, {
      expirationTtl: 86400 // 缓存 24 小时
    });
  }
  
  return response;
}

// 处理 git-upload-pack 请求
async function handleUploadPack(request) {
  const url = new URL(request.url);
  const targetUrl = buildTargetUrl(url);
  
  // 处理 POST 请求体
  const body = await request.arrayBuffer();
  
  // 发送请求
  const response = await fetch(targetUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-git-upload-pack-request',
      'Accept': 'application/x-git-upload-pack-result'
    },
    body: body
  });
  
  return response;
}

// 处理 git-receive-pack 请求
async function handleReceivePack(request) {
  const url = new URL(request.url);
  const targetUrl = buildTargetUrl(url);
  
  // 处理 POST 请求体
  const body = await request.arrayBuffer();
  
  // 发送请求
  const response = await fetch(targetUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-git-receive-pack-request',
      'Accept': 'application/x-git-receive-pack-result'
    },
    body: body
  });
  
  // 失效相关缓存
  await invalidateGitCache(url.pathname);
  
  return response;
}

// 构建目标 URL
function buildTargetUrl(url) {
  // 移除 Xget 前缀
  const path = url.pathname.replace(/^\/(gh|gl|gitea)\//, '');
  
  // 构建目标 URL
  const platform = url.pathname.split('/')[1];
  const baseUrl = getPlatformBaseUrl(platform);
  
  return `${baseUrl}/${path}`;
}

// 获取平台基础 URL
function getPlatformBaseUrl(platform) {
  const platforms = {
    'gh': 'https://github.com',
    'gl': 'https://gitlab.com',
    'gitea': 'https://gitea.com'
  };
  
  return platforms[platform] || 'https://github.com';
}

Git LFS 支持

// Git LFS 请求处理
async function handleGitLfsRequest(request) {
  const url = new URL(request.url);
  const path = url.pathname;
  
  // LFS 对象下载
  if (path.includes('/objects/')) {
    return await handleLFSObject(request);
  }
  
  // LFS 批量操作
  if (path.includes('/objects/batch')) {
    return await handleLFSBatch(request);
  }
  
  return await fetch(request);
}

// 处理 LFS 对象请求
async function handleLFSObject(request) {
  const url = new URL(request.url);
  const targetUrl = buildTargetUrl(url);
  
  // 检查缓存
  const cacheKey = `lfs-object:${url.pathname}`;
  const cached = await CACHE.get(cacheKey);
  
  if (cached) {
    return new Response(cached, {
      headers: {
        'X-Cache': 'HIT',
        'Content-Type': 'application/vnd.git-lfs'
      }
    });
  }
  
  // 发送请求
  const response = await fetch(targetUrl, {
    method: request.method,
    headers: request.headers
  });
  
  // 缓存响应
  if (response.ok) {
    const clonedResponse = response.clone();
    const buffer = await clonedResponse.arrayBuffer();
    await CACHE.put(cacheKey, buffer, {
      expirationTtl: 604800 // 缓存 7 天
    });
  }
  
  return response;
}

// 处理 LFS 批量操作
async function handleLFSBatch(request) {
  const url = new URL(request.url);
  const targetUrl = buildTargetUrl(url);
  
  // 处理 POST 请求体
  const body = await request.json();
  
  // 发送请求
  const response = await fetch(targetUrl, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/vnd.git-lfs+json',
      'Accept': 'application/vnd.git-lfs+json'
    },
    body: JSON.stringify(body)
  });
  
  return response;
}

SSH 协议支持

SSH 代理原理

Xget 通过 SSH 代理实现 Git SSH 协议的加速:

  1. SSH 连接代理

    • 代理 SSH 连接
    • 处理 SSH 认证
  2. 数据传输优化

    • 压缩传输数据
    • 缓存传输内容
  3. 连接复用

    • 复用 SSH 连接
    • 减少连接开销

SSH URL 转换

// SSH URL 转换
function convertSSHUrl(url) {
  // 原始 URL: git@github.com:user/repo.git
  // 加速 URL: ssh://git@xget.xi-xu.me:22/gh/user/repo.git
  
  const sshPattern = /^git@([^:]+):(.+)$/;
  const match = url.match(sshPattern);
  
  if (match) {
    const [, host, repoPath] = match;
    const platform = getPlatformFromHost(host);
    
    return `ssh://git@xget.xi-xu.me:22/${platform}/${repoPath}`;
  }
  
  return url;
}

// 从主机名获取平台
function getPlatformFromHost(host) {
  const platforms = {
    'github.com': 'gh',
    'gitlab.com': 'gl',
    'gitea.com': 'gitea'
  };
  
  return platforms[host] || 'gh';
}

SSH 配置

在 ~/.ssh/config 中配置 Xget SSH 代理:

# GitHub
Host github.com
    HostName xget.xi-xu.me
    Port 22
    User git
    IdentityFile ~/.ssh/id_rsa
    ProxyCommand ssh -W %h:%p git@xget.xi-xu.me

# GitLab
Host gitlab.com
    HostName xget.xi-xu.me
    Port 22
    User git
    IdentityFile ~/.ssh/id_rsa
    ProxyCommand ssh -W %h:%p git@xget.xi-xu.me

SSH 密钥管理

// SSH 密钥验证
async function verifySSHKey(publicKey) {
  // 验证 SSH 密钥格式
  const keyPattern = /^(ssh-rsa|ssh-ed25519|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521) /;
  
  if (!keyPattern.test(publicKey)) {
    throw new Error('Invalid SSH key format');
  }
  
  // 验证密钥长度
  const keyParts = publicKey.split(' ');
  if (keyParts.length < 2) {
    throw new Error('Invalid SSH key format');
  }
  
  return true;
}

// SSH 密钥存储
async function storeSSHKey(userId, publicKey) {
  const key = `ssh-key:${userId}`;
  
  await KV.put(key, publicKey, {
    expirationTtl: 2592000 // 30 天
  });
}

// SSH 密钥获取
async function getSSHKey(userId) {
  const key = `ssh-key:${userId}`;
  
  return await KV.get(key);
}

Git 协议支持

Git 协议原理

Git 协议是 Git 专用的传输协议,特点:

  1. 高效传输

    • 二进制协议
    • 最小化数据传输
  2. 无加密

    • 速度快
    • 不适合公网
  3. 简单实现

    • 协议简单
    • 易于实现

Git 协议 URL 转换

// Git 协议 URL 转换
function convertGitProtocolUrl(url) {
  // 原始 URL: git://github.com/user/repo.git
  // 加速 URL: git://xget.xi-xu.me/gh/user/repo.git
  
  const gitPattern = /^git:\/\/([^\/]+)\/(.+)$/;
  const match = url.match(gitPattern);
  
  if (match) {
    const [, host, repoPath] = match;
    const platform = getPlatformFromHost(host);
    
    return `git://xget.xi-xu.me/${platform}/${repoPath}`;
  }
  
  return url;
}

Git 协议处理

// Git 协议请求处理
async function handleGitProtocolRequest(request) {
  const url = new URL(request.url);
  const path = url.pathname;
  
  // Git 协议请求
  if (url.protocol === 'git:') {
    return await handleGitProtocol(request);
  }
  
  return await fetch(request);
}

// 处理 Git 协议
async function handleGitProtocol(request) {
  const url = new URL(request.url);
  const targetUrl = buildTargetUrl(url);
  
  // 创建 Git 协议连接
  const connection = await createGitConnection(targetUrl);
  
  // 处理 Git 协议握手
  await handleGitHandshake(connection);
  
  // 处理 Git 协议数据传输
  return await handleGitDataTransfer(connection, request);
}

// 创建 Git 协议连接
async function createGitConnection(url) {
  // 实现 Git 协议连接
  const connection = {
    url: url,
    socket: null,
    state: 'connected'
  };
  
  return connection;
}

// 处理 Git 协议握手
async function handleGitHandshake(connection) {
  // 实现 Git 协议握手
  const handshake = `git-upload-pack ${connection.url.pathname}\0host=${connection.url.hostname}\0`;
  
  connection.socket.send(handshake);
  
  const response = await connection.socket.receive();
  
  return response;
}

// 处理 Git 协议数据传输
async function handleGitDataTransfer(connection, request) {
  // 实现 Git 协议数据传输
  const data = await request.arrayBuffer();
  
  connection.socket.send(data);
  
  const response = await connection.socket.receive();
  
  return new Response(response, {
    headers: {
      'Content-Type': 'application/x-git-upload-pack-result'
    }
  });
}

Git 操作优化

Clone 操作优化

// Clone 操作优化
async function optimizeClone(url, options = {}) {
  const { depth = 0, singleBranch = false, branch = null } = options;
  
  // 构建优化后的 URL
  let optimizedUrl = convertGitUrl(url);
  
  // 添加查询参数
  const searchParams = new URLSearchParams();
  
  if (depth > 0) {
    searchParams.set('depth', depth.toString());
  }
  
  if (singleBranch) {
    searchParams.set('single-branch', 'true');
  }
  
  if (branch) {
    searchParams.set('branch', branch);
  }
  
  if (searchParams.toString()) {
    optimizedUrl += `?${searchParams.toString()}`;
  }
  
  return optimizedUrl;
}

// 使用示例
const optimizedUrl = await optimizeClone('https://github.com/user/repo.git', {
  depth: 1,
  singleBranch: true,
  branch: 'main'
});

Fetch 操作优化

// Fetch 操作优化
async function optimizeFetch(url, options = {}) {
  const { depth = 0, prune = false, tags = true } = options;
  
  // 构建优化后的 URL
  let optimizedUrl = convertGitUrl(url);
  
  // 添加查询参数
  const searchParams = new URLSearchParams();
  
  if (depth > 0) {
    searchParams.set('depth', depth.toString());
  }
  
  if (prune) {
    searchParams.set('prune', 'true');
  }
  
  if (!tags) {
    searchParams.set('no-tags', 'true');
  }
  
  if (searchParams.toString()) {
    optimizedUrl += `?${searchParams.toString()}`;
  }
  
  return optimizedUrl;
}

// 使用示例
const optimizedUrl = await optimizeFetch('https://github.com/user/repo.git', {
  depth: 1,
  prune: true,
  tags: false
});

Push 操作优化

// Push 操作优化
async function optimizePush(url, options = {}) {
  const { force = false, forceWithLease = false, tags = false } = options;
  
  // 构建优化后的 URL
  let optimizedUrl = convertGitUrl(url);
  
  // 添加查询参数
  const searchParams = new URLSearchParams();
  
  if (force) {
    searchParams.set('force', 'true');
  }
  
  if (forceWithLease) {
    searchParams.set('force-with-lease', 'true');
  }
  
  if (tags) {
    searchParams.set('tags', 'true');
  }
  
  if (searchParams.toString()) {
    optimizedUrl += `?${searchParams.toString()}`;
  }
  
  return optimizedUrl;
}

// 使用示例
const optimizedUrl = await optimizePush('https://github.com/user/repo.git', {
  force: false,
  tags: true
});

Git 配置优化

全局配置

# 配置 Git 使用 Xget
git config --global url."https://xget.xi-xu.me/gh/".insteadOf "https://github.com/"
git config --global url."https://xget.xi-xu.me/gl/".insteadOf "https://gitlab.com/"
git config --global url."https://xget.xi-xu.me/gitea/".insteadOf "https://gitea.com/"

# 配置 Git 协议
git config --global http.proxy http://xget.xi-xu.me:8080
git config --global https.proxy https://xget.xi-xu.me:8443

# 配置缓存
git config --global http.cache 3600
git config --global https.cache 3600

# 配置压缩
git config --global core.compression 9
git config --global http.compression 9
git config --global https.com 9

仓库配置

# 进入仓库目录
cd your-repo

# 配置仓库使用 Xget
git config url."https://xget.xi-xu.me/gh/".insteadOf "https://github.com/"

# 配置 LFS
git config lfs.url https://xget.xi-xu.me/gh/user/repo.git/info/lfs
git config lfs.basictransfersonly true
git config lfs.concurrenttransfers 8

性能配置

# 配置并发
git config --global http.postBuffer 524288000
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999

# 配置超时
git config --global http.timeout 600
git config --global http.connectTimeout 30
git config --global http.readTimeout 600

# 配置重试
git config --global http.maxRetries 3
git config --global http.retryDelay 1000

常见问题

Q1: 如何验证 Git 加速是否生效?

A: 使用 time 命令测量操作时间:

# 测试 clone 速度
time git clone https://xget.xi-xu.me/gh/user/repo.git

# 测试 fetch 速度
time git fetch origin

Q2: Git LFS 如何使用 Xget 加速?

A: 配置 LFS 使用 Xget:

git config lfs.url https://xget.xi-xu.me/gh/user/repo.git/info/lfs
git lfs fetch

Q3: 如何处理 Git 认证问题?

A: 使用 Git 凭据存储:

# 配置凭据存储
git config --global credential.helper store

# 输入凭据
git push

Q4: Xget 支持哪些 Git 操作?

A: Xget 支持所有 Git 操作,包括 clone、fetch、pull、push、LFS 等。

Q5: 如何切换回原始 Git URL?

A: 移除 Git 配置:

git config --global --unset url."https://xget.xi-xu.me/gh/".insteadOf

总结

Xget 提供了全面的 Git 协议支持,包括 HTTP/HTTPS、SSH、Git 协议等各种传输协议。通过 URL 转换、请求代理、响应缓存等技术,Xget 显著提升了 Git 操作的速度和稳定性。

同时,Xget 对 Git LFS、Submodule 等高级功能也提供了完善的支持,确保开发者能够享受到完整的 Git 加速体验。