源码导入式 fork 同步上游更新 (Syncing Upstream into a Source-Imported Fork)
1. 一句话
上游源码是以压缩包/整份拷贝导入进自己仓库时(而不是先 clone 上游再改),这个 fork 与上游没有共同祖先(unrelated histories),git merge upstream/main 必然失败。同步只能走内容差异补丁,不能走 merge。
2. 触发条件
- 仓库历史里有一次性导入提交,如
Import Gemini Web2API Go source、baseline。 - 本地在此基础上加了自有特性,现在想跟上上游的后续版本。
3. 症状与报错
$ git merge v4.20.1
fatal: refusing to merge unrelated histories加 --allow-unrelated-histories 后不再报错,但问题更大:merge base(共同祖先)为空,凡双方内容有差异的文件全部冲突,等于逐文件手工"二选一"。
4. 根因
Git 的三方合并(three-way merge)依赖 merge base 来判定"谁改了什么"。没有共同祖先时,双方所有差异都被视为"各自新增",自动合并的判定依据根本不存在。
5. 正确做法:补丁同步
前提:能拿到上游当前基线版本与目标版本两份源码。
- 确定基线版本:把本地树与上游各 tag 逐一二进制 diff,差异最小者即基线。
git diff --no-index --stat <tag目录> <本地目录> - 两份源码解压到同一父目录下的同级目录(保证
a/、b/两侧路径深度一致)。 - 在父目录用相对路径生成补丁:
git diff --no-index --binary -- "up415/<v4.15.0目录>" "upstream/<v4.20.1目录>" > up.patch
用绝对路径会让 patch 的a/、b/前缀变成绝对路径,后续git apply直接找不到文件。 - 先空跑:
git apply --check -pN up.patchN=a/+ 父目录名 + 解压目录名 的层数(两侧层数相同,本例各 1 段,故-p3)。 - 真打补丁 → 编译 → 跑测试 → 提交前人工核对 diff,确认自有改动没被冲掉。
6. 边界(补丁法何时不成立)
- 本地改动与上游改动落在同一文件:hunk 会 reject(
Hunk #N FAILED)。改用git apply -3借 index 里的 blob 做三方合并,仍失败再手工合。 - 上游重命名/移动了目录:
--no-index的 rename 检测弱,会表现为"删一个 + 加一个",需人工判断。 - 上游动了依赖清单:同步后必须重新
go build/go mod tidy(或等价命令)验证。
7. 实例(2026-09-18,google-search-mcp-gemini-web2api)
- 本地 fork 基线为上游
zexadev/gemini-web2api-go的 v4.15.0,上游已发到 v4.20.1(落后 5 个版本)。 - 本地自有改动集中在
apikey.go/mcp.go/mcp_test.go/app.go;上游 4.15→4.20.1 改的是rotate.go/cookie_pool.go/gemini.go/admin_ui等。两侧文件集不相交,因此补丁干净应用。 - 验证链:
git apply --check -p3通过 → 真打 →go build产出 25.5 MB 单二进制 →go test ./...全绿。 - 结论:此类 fork 的"升级"是打补丁,且改动文件集是否相交决定要不要人工介入。
8. 下次如何快速识别
- 历史里见到一次性导入提交,就默认它是 unrelated histories,不要先试 merge。
- 判断落后多少:GitHub compare
v<当前版本>...main,返回status: identical说明该 tag 就是 main 最新;再用git diff --no-index --stat看具体落后内容。 - 判断"本地是不是最新"最快的办法是直接比
const Version/pyproject.toml等版本常量与上游最新 release,而不是读 CHANGELOG。
9. 相关
- Gemini Web 反代并发与带宽容量上限 (Gemini Web2API Relay Concurrency & Bandwidth Capacity Limits)
- 本地工具脱敏发布到 GitHub Public (Sanitized Public Release)
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Programming