Git push 后生成 Changes 流程 18.5
重点
# app/workers/update_merge_requests_worker.rb
主要看看这个
生成 MR Changes(代码变更/diff) 的完整流程。
生成 Changes 的核心流程
1. UpdateMergeRequestsWorker (主要入口)
# app/workers/update_merge_requests_worker.rb
-
触发时机: 在
BranchPushService#enqueue_update_mrs中被调度 -
队列:
update_merge_requests - 功能: 当 push 影响到 MR 的分支时触发
2. MergeRequests::RefreshService (协调服务)
# app/services/merge_requests/refresh_service.rb
# 第 151-185 行:reload_merge_requests 方法
关键代码(第 164 和 175 行):
merge_request.reload_diff(current_user) # 重新加载 diff
3. MergeRequests::ReloadDiffsService (重载 Diff 服务)
# app/services/merge_requests/reload_diffs_service.rb
# 第 16 行
new_diff = merge_request.create_merge_request_diff(preload_gitaly: true)
- 创建新的
MergeRequestDiff记录 - 清除旧的缓存
- 更新讨论位置
4. MergeRequestDiff Model (核心模型)
# app/models/merge_request_diff.rb
关键回调(第 248 行):
after_create :save_git_content, unless: :importing?
save_git_content 方法(第 273-287 行):
def save_git_content
ensure_commit_shas # 确保 commit SHA
save_commits # 保存 commits
save_diffs # ⭐ 生成并保存 diff files
save
end
save_diffs 方法(第 918-945 行):
def save_diffs
# 1. 比较 commits
diff_collection = compare_diffs_preloaded
# 2. 构建 diff files
rows = build_merge_request_diff_files(diff_collection)
# 3. 批量创建 diff files 到数据库
create_merge_request_diff_files(rows)
# 4. 设置状态为 'collected' 或 'overflow'
new_attributes[:state] = :collected
end
完整的调用链
git push
↓
PostReceive Worker
↓
BranchPushService
↓
UpdateMergeRequestsWorker ⭐ (异步队列任务)
↓
MergeRequests::RefreshService
↓
merge_request.reload_diff(user)
↓
MergeRequests::ReloadDiffsService
↓
merge_request.create_merge_request_diff
↓
MergeRequestDiff.create! (触发 after_create 回调)
↓
save_git_content
↓
save_diffs ⭐ (生成 diff)
↓
create_merge_request_diff_files ⭐ (保存到数据库)
数据库表
生成的 Changes 数据主要存储在:
-
merge_request_diffs: diff 的元数据(head_commit_sha, base_commit_sha 等) -
merge_request_diff_files: 每个文件的具体变更内容 -
merge_request_diff_commits: 包含的 commits
总结
生成代码变更的核心任务是 UpdateMergeRequestsWorker,它通过调用一系列服务和模型方法,最终在 MergeRequestDiff 模型的 save_git_content 方法中:
- 从 Git 仓库获取 diff 数据
- 解析并构建 diff files
- 批量插入数据库
由 TianLu 编辑于