如何在svn上镜像git,在Windows上,使用裸回购

  • 本文关键字:git svn 镜像 Windows git svn
  • 更新时间 :
  • 英文 :


有很多关于从SVN迁移到git的信息,但我正在寻找一种将git镜像到SVN的方法,在SVN中,git repo是预先存在的,SVN repo需要更新git repo的内容,然后保持最新。(这是一面镜子,我不需要双向同步(。

(为什么?因为dev已经迁移到git,但管理层只信任svn。这为我们争取了改变态度的时间…(

我发现最接近我想要的东西是在这里,但我遇到了与那里评论中的人相同的问题:SVN日志被合并消息污染了。

主要的问题是有两个完全独立的历史,没有办法将它们永久地结合在一起。gitsvn必须从现有的svn repo开始,因此初始提交就是从那里开始的。但我不想永久地重写我的git repo的历史,以使其基于SVN初始提交。

这个答案让我走了很多路,我认为我已经完成了,在第一次同步时,这很好,但问题是它试图将所有历史从git重新绑定到svn分支上,尽管该分支已经包含了大部分历史。这最终会尝试进行"向后"合并(将旧版本的文件合并到新版本(,这会产生无法解决的冲突(每次都必须再次进行(。

所以我改采樱桃。

无论如何,这里是设置:这是一个完整的遍历,它在本地创建所有内容。它可以适应你已经拥有的一切。

创建裸git回购

#(create and cd to a test folder)
git --bare init bare.git

创建本地git工作回购

#(cd to test folder)
mkdir gitrepo
cd gitrepo
echo 'First content' > file.txt
git add .
git commit -m "Initial git commit"
git remote add origin [absolute path to bare.git]
git push origin master

此时,添加到本地git工作repo的新文件已同步到裸repo。

创建空的subversion

svn mkdir --parents [path to desired svn repo including /trunk] -m "Initial commit"

将裸机克隆到镜像存储中

#(cd to test folder)
git clone [absolute path to bare.git] mirror
cd mirror
code .gitconfig # I'm using VSCode here: edit with whatever you want

将以下行添加到文件中:

[svn-remote "svn"]
url = [path to svn repo including /trunk]
fetch = :refs/remotes/git-svn

提交到svn

git svn fetch
git rebase --onto remotes/git-svn --root master 
git svn dcommit

这将从svn中获取空的"第一次提交",将从裸repo克隆的所有更改重新绑定到它上,然后将数据提交回svn。在这一点上,所有的回购都是同步的。

(请注意,对于具有大量历史的现有回购,如果master的过去历史中存在分支/合并,则可能需要进行一些手动合并(。

设置必要的分支

最初的设置让我们看到master指向svn。所以

git checkout -b svn
git checkout -B master origin/master
git checkout -b previous

其思想是svn分支跟踪svn远程,master跟踪原点/主节点,previous指向主节点/svn的最后一个同步。通过这种方式,我们可以使用从previousmaster的提交范围来确定要挑选的内容。

设置挂钩

要进行设置以使同步到svn步骤是自动的,请在裸repo的hooks文件夹中创建文件post-receive。内容如下:

#!/bin/sh
#
# After receiving pushed commits, move to Mirror and update to svn
unset GIT_DIR # weird but without this, cd doesn't influence execution directory
cd ..\mirror
git checkout master
git pull origin
git checkout svn
git cherry-pick previous..master
git svn dcommit
git checkout previous
git merge --ff master
exit

最新更新