git svn rebase报invalid upstream、SVN上游信息识别错误求助
故障本质是本地故障分支丢失了git svn运行必需的上游关联元数据。git svn rebase依赖两个核心条件:一是本地存在正确的SVN远程追踪ref,二是当前分支的提交历史能追溯到带git-svn-id标记的SVN原生提交。
你之前手动执行git update-ref refs/remotes/git-svn refs/remotes/gitlab/trunk-svn的操作完全错误:GitLab上的分支是纯Git镜像,提交里的SVN标识大概率在同步时被过滤,根本无法被git-svn识别为合法上游。你之前尝试的删缓存、加rewriteRoot/rewriteUUID方案针对的是SVN服务器地址变更、UUID不匹配的场景,和当前问题不匹配,自然没有效果。
1. 重置正确的SVN远程追踪ref
先清除之前错误设置的git-svn ref,重新指向正确的SVN上游追踪分支:
# 先确认本地SVN trunk的ref存在 git show-ref refs/remotes/origin/trunk # 如果上面命令有输出,执行重置 git update-ref -d refs/remotes/git-svn git update-ref refs/remotes/git-svn refs/remotes/origin/trunk
如果执行git show-ref refs/remotes/origin/trunk无输出,说明本地SVN远程追踪ref丢失,先拉取一次SVN元数据再执行上述重置操作:
git svn fetch
2. 将本地分支提交重新嫁接回SVN追踪链
当前故障分支的提交历史已经和SVN元数据断链,才会触发"Unable to determine upstream SVN information"报错,通过rebase嫁接即可恢复关联,不会丢失本地未合并的工作内容:
- 切换到出问题的分支,以
trunk-svn为例:git checkout trunk-svn - 找到分支上最后一个携带合法
git-svn-id标记的提交hash,记为<last-good-svn-commit>:git log --grep="git-svn-id:" -1 --format=%H如果当前分支遍历不到带
git-svn-id的提交,可以切到之前新建的、能正常执行git svn rebase的分支上,找到两个分支的共同祖先提交,该提交就是带合法SVN元数据的断点。 - 获取SVN trunk当前最新的提交hash,记为
<svn-trunk-head>:git rev-parse refs/remotes/origin/trunk - 执行变基,将断点之后的所有本地提交重新挂载到最新的SVN上游提交之上:
git rebase --onto <svn-trunk-head> <last-good-svn-commit> trunk-svn
3. 验证修复
变基完成后直接执行拉取命令验证:
git svn rebase
正常会提示分支与上游SVN已同步,不会再出现invalid upstream或找不到上游信息的报错。
bugfix-svn等其他故障分支的修复逻辑完全一致:
- 找到分支最后一个带
git-svn-id标记的断点提交 - 找到该分支对应的SVN上游追踪分支(比如对应
refs/remotes/origin/bugfix/xxx)的最新hash - 执行相同的
git rebase --onto操作,将本地提交嫁接回正确的SVN追踪链即可
- 操作前建议先给故障分支打备份标签,避免rebase失误丢失本地改动:
git tag trunk-svn-bak trunk-svn,确认修复正常后再删除备份标签即可 - 不要将git-svn相关的追踪ref指向GitLab等纯Git远程的分支,这类镜像分支通常会过滤掉提交中的
git-svn-id元数据,无法被git-svn识别为合法上游 - 全新拉取的分支之所以正常,是因为新分支直接基于本地已有的SVN追踪ref创建,提交链上的元数据是完整的
内容的提问来源于stack exchange,提问作者Sam R

