使用git filter-branch修改历史后,如何协调Git与活跃SVN仓库?
SVN迁移Git后修改历史与SVN同步的解决方案
兄弟,我太懂你这种既要迁移又要清理历史还要兼顾旧SVN的痛苦了,先给你点透核心问题:git svn是靠SVN版本号和Git提交哈希的一一对应来同步的,一旦你用filter类命令修改了Git历史,所有提交的哈希全变了,原来的同步关联直接就断了。下面给你两个可行的方案,看你需求选:
方案1:彻底切到Git(强烈推荐,省心省力)
这是最稳妥的路子,毕竟迁移就是为了换Git,没必要拖着旧SVN不放:
- 先把Git历史彻底清理干净:别用老旧的
git filter-branch了,官方都弃用了,用git filter-repo才靠谱。比如要替换历史里的密码,就用:
如果要直接删掉某个存敏感信息的文件,就用:git filter-repo --replace-text <(echo '你的明文密码==>REDACTED')git filter-repo --path 敏感文件名.txt --invert-paths - 反复验证清理后的历史,确保没有漏网的敏感数据,然后把这个清理后的Git仓库设为团队的官方仓库
- 通知所有成员放弃原来的SVN和旧Git克隆,全部改用新仓库
- 最后把SVN仓库设为只读,彻底封死旧提交路径,避免有人误操作
方案2:必须保留SVN同步(操作复杂,谨慎选择)
如果因为某些原因还得和SVN双向同步,那得做个"同步桥"来隔离修改后的Git历史和SVN:
- 保留你最开始那个没修改过历史的git svn克隆,把它当成专门的同步工具,只用来拉取和推送SVN的提交,别在上面做任何历史修改
- 把清理后的Git仓库作为你的日常工作仓库,每次要同步SVN的新提交时:
- 先在同步桥仓库执行
git svn fetch拉取SVN最新内容,再git svn rebase同步到本地分支 - 然后在工作仓库把同步桥加为远程仓库:
git remote add sync-bridge /path/to/你的同步桥仓库路径 - 拉取同步桥的更新后,用
git rebase sync-bridge/trunk把SVN的新提交接到你清理后的历史后面(这里大概率会有冲突,得耐心解决)
- 先在同步桥仓库执行
- 如果要把工作仓库的修改推回SVN:
- 在工作仓库把需要推的提交用
git cherry-pick挑到一个临时分支 - 把这个临时分支推到同步桥仓库,然后在同步桥仓库执行
git svn dcommit推回SVN
- 在工作仓库把需要推的提交用
必记的踩坑提醒
- 绝对绝对不要在修改过历史的Git仓库上执行
git svn dcommit!这会把SVN的历史彻底搅乱,到时候哭都来不及 - 只要你修改了Git历史,所有团队成员都必须重新克隆新仓库,旧的本地仓库和新仓库的历史完全不兼容,强行拉取会出大问题
git filter-repo需要你先把仓库的远程链接去掉,或者用--force参数,执行前最好先备份仓库,以防万一
内容的提问来源于stack exchange,提问作者Greg Sandstrom
相关产品推荐
相关产品推荐

