gitlink-cli/doc/CODE_SYNC_STRATEGY.md

483 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# GitLink-GitHub 代码双向同步方案
**版本**: v1.0
**日期**: 2026-04-02
**状态**: 已确认
---
## 1 概述
实现 GitHub主仓和 GitLink镜像仓的代码双向同步确保两个平台的代码始终一致。通过 Git hooks 在关键操作点进行同步检查,自动解决冲突或提示用户手动处理。
### 1.1 核心原则
- **GitHub 为主仓**GitHub 是代码的唯一真实来源
- **GitLink 为镜像仓**GitLink 作为备份和协作平台
- **Hook 控制在 GitLink**:所有同步逻辑通过 GitLink 本地 hooks 实现
- **GitHub 完全被动**GitHub 不需要任何 hook 操作
- **冲突自动解决**:优先自动 rebase 解决,无法解决时提示用户
---
## 2 同步触发点
### 2.1 四个关键触发点
| 触发点 | Hook | 检查内容 | 动作 |
|--------|------|---------|------|
| **直接 commit** | `pre-commit` | GitLink HEAD vs GitHub HEAD | 不同步则阻止 commit |
| **直接 push** | `pre-push` | GitLink HEAD vs GitHub HEAD | 不同步则阻止 push |
| **创建 PR** | Webhook | 拉取最新 GitHub 代码 | 自动 rebase 到最新 GitHub 代码 |
| **Merge PR** | Webhook | 拉取最新 GitHub 代码 + 自动 rebase | 解决冲突后 merge并推送到 GitHub |
### 2.2 触发点详解
#### 2.2.1 Pre-commit Hook直接 commit
**场景**:用户在 GitLink 本地修改代码后执行 `git commit`
**流程**
```
1. 用户执行: git commit -m "..."
2. pre-commit hook 触发
3. 检查: GitLink HEAD == GitHub HEAD?
- 是 → 允许 commit
- 否 → 阻止 commit提示用户执行 rebase
```
**实现**
```bash
#!/bin/bash
# .git/hooks/pre-commit
GITHUB_HEAD=$(git ls-remote https://github.com/owner/repo HEAD | awk '{print $1}')
GITLINK_HEAD=$(git rev-parse HEAD)
if [ "$GITHUB_HEAD" != "$GITLINK_HEAD" ]; then
echo "❌ Error: GitLink HEAD 不同步 GitHub"
echo "请执行: git fetch github && git rebase github/main"
exit 1
fi
exit 0
```
#### 2.2.2 Pre-push Hook直接 push
**场景**:用户在 GitLink 本地修改代码后执行 `git push`
**流程**
```
1. 用户执行: git push origin main
2. pre-push hook 触发
3. 检查: GitLink HEAD == GitHub HEAD?
- 是 → 允许 push
- 否 → 阻止 push提示用户执行 rebase
```
**实现**
```bash
#!/bin/bash
# .git/hooks/pre-push
GITHUB_HEAD=$(git ls-remote https://github.com/owner/repo HEAD | awk '{print $1}')
GITLINK_HEAD=$(git rev-parse HEAD)
if [ "$GITHUB_HEAD" != "$GITLINK_HEAD" ]; then
echo "❌ Error: GitLink HEAD 不同步 GitHub"
echo "请执行: git fetch github && git rebase github/main"
exit 1
fi
exit 0
```
#### 2.2.3 创建 PR 时同步Webhook
**场景**:用户在 GitLink 创建 PR
**流程**
```
1. 用户在 GitLink 创建 PR: feature → main
2. GitLink webhook 触发
3. 拉取最新 GitHub 代码到 GitLink
4. 自动 rebase PR 分支到最新 GitHub main
5. 如果冲突可自动解决 → 直接解决
6. 如果冲突无法自动解决 → 提示用户手动解决
```
**实现逻辑**
```
POST /webhook/pr-created
├─ 获取 PR 信息 (source_branch, target_branch)
├─ git fetch github main
├─ git checkout source_branch
├─ git rebase github/main
│ ├─ 冲突可解决 → 自动解决 + git rebase --continue
│ └─ 冲突无法解决 → 提示用户PR 标记为 "需要手动 rebase"
└─ 更新 PR 状态
```
#### 2.2.4 Merge PR 时同步Webhook
**场景**:用户在 GitLink 合并 PR
**流程**
```
1. 用户在 GitLink 点击 "Merge PR"
2. GitLink webhook 触发
3. 拉取最新 GitHub 代码到 GitLink
4. 自动 rebase PR 分支到最新 GitHub main
5. 如果冲突可自动解决 → 直接解决 + merge
6. 如果冲突无法自动解决 → 停止 merge提示用户
7. Merge 成功后,自动 push 到 GitHub
```
**实现逻辑**
```
POST /webhook/pr-merge
├─ 获取 PR 信息 (source_branch, target_branch)
├─ git fetch github main
├─ git checkout source_branch
├─ git rebase github/main
│ ├─ 冲突可解决 → 自动解决 + git rebase --continue
│ └─ 冲突无法解决 → 停止 merge返回错误
├─ git checkout target_branch
├─ git merge source_branch
├─ git push github target_branch
└─ 更新 PR 状态为 "已合并"
```
---
## 3 冲突处理策略
### 3.1 冲突类型与解决方案
| 冲突类型 | 原因 | 解决方案 |
|---------|------|--------|
| **文件内容冲突** | 同一文件同一行被修改 | 自动 rebaseGit 尝试自动合并) |
| **文件删除冲突** | 一边删除,一边修改 | 提示用户手动选择 |
| **文件重命名冲突** | 同一文件被重命名为不同名称 | 提示用户手动选择 |
| **二进制文件冲突** | 二进制文件被修改 | 提示用户手动选择 |
### 3.2 自动解决策略
**可自动解决的冲突**
- 不同文件的修改
- 同一文件不同行的修改
- 简单的文本冲突Git 能自动合并)
**实现**
```bash
git rebase github/main --no-edit
# 如果有冲突,尝试自动解决
if [ $? -ne 0 ]; then
# 尝试使用 ours 或 theirs 策略
git rebase --continue --strategy=recursive -X ours
fi
```
### 3.3 无法自动解决时的处理
**流程**
```
1. Rebase 失败,存在冲突
2. 返回错误信息给用户
3. PR 标记为 "冲突" 状态
4. 用户本地手动解决冲突
5. 用户执行: git rebase --continue
6. 用户 push 到 GitLink
7. Pre-push hook 检查 → 通过
8. 用户重新点击 "Merge PR"
```
---
## 4 实现架构
### 4.1 组件清单
| 组件 | 位置 | 职责 |
|------|------|------|
| **Pre-commit Hook** | `.git/hooks/pre-commit` | 检查 commit 前的同步状态 |
| **Pre-push Hook** | `.git/hooks/pre-push` | 检查 push 前的同步状态 |
| **PR Created Webhook** | GitLink 服务端 | 创建 PR 时自动 rebase |
| **PR Merged Webhook** | GitLink 服务端 | Merge PR 时自动 rebase + push GitHub |
| **Sync CLI Command** | `gitlink-cli sync` | 手动触发同步(可选) |
### 4.2 数据流
```
GitHub (主仓)
↓ (git fetch)
GitLink 本地仓库
├─ pre-commit hook (检查同步)
├─ pre-push hook (检查同步)
└─ webhook (创建/合并 PR 时自动 rebase)
↓ (git push)
GitLink 远程仓库
↓ (webhook)
GitHub (推送更新)
```
---
## 5 用户工作流
### 5.1 场景 1直接 commit 到 GitLink
```bash
# 1. 用户在 GitLink 本地修改代码
cd gitlink-cli
echo "new code" >> file.txt
# 2. 执行 commit
git commit -m "feat: add new feature"
# 3. Pre-commit hook 检查
# ✅ 如果 HEAD 同步 → commit 成功
# ❌ 如果 HEAD 不同步 → commit 失败,提示 rebase
# 4. 如果失败,用户手动 rebase
git fetch github
git rebase github/main
# 5. 重新 commit
git commit -m "feat: add new feature"
```
### 5.2 场景 2创建 PR
```bash
# 1. 用户创建 feature 分支
git checkout -b feature/new-feature
# 2. 修改代码并 commit
git commit -m "feat: implement feature"
# 3. Push 到 GitLink
git push origin feature/new-feature
# 4. 在 GitLink 创建 PR: feature/new-feature → main
# GitLink webhook 自动触发:
# - 拉取最新 GitHub 代码
# - 自动 rebase feature 分支到最新 GitHub main
# - 如果冲突可解决 → 自动解决
# - 如果冲突无法解决 → PR 标记为 "需要手动 rebase"
```
### 5.3 场景 3Merge PR
```bash
# 1. 用户在 GitLink 点击 "Merge PR"
# GitLink webhook 自动触发:
# - 拉取最新 GitHub 代码
# - 自动 rebase PR 分支到最新 GitHub main
# - 如果冲突可解决 → 自动解决 + merge
# - 如果冲突无法解决 → merge 失败,提示用户
# 2. Merge 成功后,自动 push 到 GitHub
# GitHub 代码自动更新
```
### 5.4 场景 4直接 push 到 GitLink
```bash
# 1. 用户本地修改代码并 commit
git commit -m "fix: bug fix"
# 2. 执行 push
git push origin main
# 3. Pre-push hook 检查
# ✅ 如果 HEAD 同步 → push 成功
# ❌ 如果 HEAD 不同步 → push 失败,提示 rebase
# 4. 如果失败,用户手动 rebase
git fetch github
git rebase github/main
git push origin main
```
---
## 6 配置与部署
### 6.1 Hook 安装
在 gitlink-cli 项目中创建 hooks
```bash
# 创建 hooks 目录
mkdir -p .githooks
# 创建 pre-commit hook
cat > .githooks/pre-commit << 'EOF'
#!/bin/bash
GITHUB_HEAD=$(git ls-remote https://github.com/owner/repo HEAD | awk '{print $1}')
GITLINK_HEAD=$(git rev-parse HEAD)
if [ "$GITHUB_HEAD" != "$GITLINK_HEAD" ]; then
echo "❌ Error: GitLink HEAD 不同步 GitHub"
echo "请执行: git fetch github && git rebase github/main"
exit 1
fi
exit 0
EOF
# 创建 pre-push hook
cat > .githooks/pre-push << 'EOF'
#!/bin/bash
GITHUB_HEAD=$(git ls-remote https://github.com/owner/repo HEAD | awk '{print $1}')
GITLINK_HEAD=$(git rev-parse HEAD)
if [ "$GITHUB_HEAD" != "$GITLINK_HEAD" ]; then
echo "❌ Error: GitLink HEAD 不同步 GitHub"
echo "请执行: git fetch github && git rebase github/main"
exit 1
fi
exit 0
EOF
# 设置权限
chmod +x .githooks/pre-commit .githooks/pre-push
# 配置 Git 使用这些 hooks
git config core.hooksPath .githooks
```
### 6.2 Webhook 配置
在 GitLink 项目设置中配置 webhooks
**PR Created Webhook**
- URL: `https://your-server/webhook/pr-created`
- 事件: Pull Request Created
- 负载: PR 信息source_branch, target_branch, pr_id
**PR Merged Webhook**
- URL: `https://your-server/webhook/pr-merged`
- 事件: Pull Request Merged
- 负载: PR 信息source_branch, target_branch, pr_id
---
## 7 风险与缓解
### 7.1 潜在风险
| 风险 | 影响 | 缓解措施 |
|------|------|--------|
| **Rebase 失败** | PR 无法合并 | 提示用户手动解决PR 标记为冲突 |
| **GitHub 网络不可达** | Hook 超时 | 设置超时时间,失败时提示用户 |
| **Webhook 失败** | 同步不及时 | 重试机制 + 手动同步命令 |
| **并发 merge** | 数据不一致 | 使用分布式锁或队列 |
### 7.2 缓解方案
**Hook 超时处理**
```bash
timeout 5 git ls-remote https://github.com/owner/repo HEAD
if [ $? -eq 124 ]; then
echo "⚠️ Warning: GitHub 网络超时,跳过同步检查"
exit 0 # 允许操作继续
fi
```
**Webhook 重试**
```
失败 → 等待 5 秒 → 重试
失败 → 等待 10 秒 → 重试
失败 → 等待 30 秒 → 重试
失败 → 记录日志,通知管理员
```
---
## 8 手动同步命令(可选)
提供 CLI 命令供用户手动触发同步:
```bash
# 手动同步 GitLink 到最新 GitHub 代码
gitlink-cli sync --from github --to gitlink
# 手动同步 GitHub 到最新 GitLink 代码(不推荐)
gitlink-cli sync --from gitlink --to github
# 查看同步状态
gitlink-cli sync status
```
---
## 9 验证与测试
### 9.1 测试场景
| 场景 | 预期结果 | 验证方法 |
|------|---------|--------|
| GitHub 有新代码GitLink 直接 commit | Commit 失败,提示 rebase | 执行 commit检查错误信息 |
| GitHub 有新代码GitLink 直接 push | Push 失败,提示 rebase | 执行 push检查错误信息 |
| 创建 PR 时 GitHub 有新代码 | 自动 rebasePR 创建成功 | 创建 PR检查 PR 状态 |
| Merge PR 时 GitHub 有新代码 | 自动 rebase + merge推送 GitHub | Merge PR检查 GitHub 代码 |
| 冲突无法自动解决 | PR 标记为<E8AEB0><E4B8BA>提示用户 | 创建冲突 PR检查状态 |
### 9.2 测试命令
```bash
# 1. 测试 pre-commit hook
git commit -m "test"
# 2. 测试 pre-push hook
git push origin main
# 3. 测试 PR 创建同步
# 在 GitLink 创建 PR检查是否自动 rebase
# 4. 测试 PR 合并同步
# 在 GitLink 合并 PR检查 GitHub 是否更新
```
---
## 10 后续优化
### 10.1 短期1-2 周)
- [ ] 实现 pre-commit 和 pre-push hooks
- [ ] 实现 PR Created 和 PR Merged webhooks
- [ ] 编写测试用例
- [ ] 文档完善
### 10.2 中期2-4 周)
- [ ] 实现手动同步 CLI 命令
- [ ] 添加同步状态监控
- [ ] 优化冲突自动解决策略
- [ ] 添加日志和告警
### 10.3 长期1 个月+
- [ ] Issue 和 PR 元数据同步
- [ ] 评论和 Review 同步
- [ ] 自动化测试和 CI/CD 集成
- [ ] 性能优化和扩展性改进
---
## 11 总结
本方案通过 **Git hooks + Webhooks** 的组合,实现了 GitHub 和 GitLink 的代码双向同步。核心特点:
**GitHub 为主仓**:确保代码唯一真实来源
**自动冲突解决**:优先自动 rebase无法解决时提示用户
**多触发点**commit、push、PR 创建、PR 合并都有同步检查
**用户友好**:清晰的错误提示和恢复指导
**低风险**:失败时提示用户,不会自动破坏代码
---
**审批人**: [待确认]
**实施日期**: [待定]
**联系人**: [待定]