我在一个SVN商店工作,但是为了给我的工作注入一点理智,我使用了git-svn。越来越多的同事也看到了曙光,现在我们希望在某些情况下完全避开SVN。目前我们每个人都有自己的git-svn仓库,但由于哈希值的差异很大,除了普通的补丁或通过SVN,我们不能真正共享任何东西。我们应该如何组织我们的仓库以允许直接共享(通过git-remote)?
我能想到的唯一方法是一个单一的,共享的git-svn的仓库,我们使用它作为SVN的网关,但这可能有点麻烦——如果我们都能直接从我们自己的git-svn仓库推送到SVN,那就更好了。
Edit:不幸的是,我没有SVN服务器的管理员访问权限,所以像subgit这样的解决方案目前用处不大,尽管它们很有趣。
您可以查看subgit:
SubGit是一个平稳、无压力的Svn到Git迁移工具。在服务器端安装一次,只要你喜欢,可以同时使用Subversion和Git。
SubGit允许建立一个双向的Subversion到Git的复制(可写镜像)。
:
SubGit是公司范围内从Svn迁移到Git的解决方案,即:
Much better than git-svn (see comparison); Requires no changes of the infrastructure that is already in place; Allows one to use all Git and all Subversion features; Provides genuine stress-free migration experience.
两个不同版本控制系统之间的双向网关早于git。大约10年前,我就已经在CVS和Arch之间用手做了。如果您不想购买subgit,您可以手动维护网关,甚至尝试编写脚本。工作流程很简单:
- 有
trunk
和master
两个分支。trunk
镜像subversion,master
是加上git 中开发的更改。 - 每当有新的变化在subversion:
-
$ git svn fetch
-
master$ git merge trunk
-
- 当中继被推送时:
-
trunk$ git merge master
-
trunk$ git svn dcommit
-
master$ git merge trunk
-
- 你应该自动执行这两个序列,即一次只执行一个操作。
- 你可以考虑设置git-svn,这样它就不会用subversion版本信息重写提交,从而减少git中合并提交的数量。
- 这可以在多个分支中完成,但我不认为在git中合并单独的subversion分支可以工作。
我们的情况完全相同。我们得到的是(警告,一些伪代码!):
- 远程git repo,脚本化(使用bash脚本),不能是——bare
-
一个预接收钩子,检查用户名,然后每个收到的ref和所有svn映射的分支:(git -> svn):
-
git checkout -f <branch>
-
git reset HEAD --hard
-
git clean -fdx
-
git merge -n $newrev
-
git svn dcommit
-
如果失败,恢复所有,
-
然后,在所有循环之后-更新所有SVN分支(使用脚本,见下文)
-
-
a cronjob用最新的svn变更更新git-svn分支:
-
git checkout --orphan svn-update <random-branch-name>
-
git svn fetch --all
- 所有git-svn分支:
git branch -D <branch> && git branch --track <svn-branch> refs/remotes/<svn-branch>
,
-
-
git认证的ssh密钥
- 用户管理的SVN认证(基于git用户名,这取决于你的设置)
这样就没有人直接使用SVN,与纯git的唯一区别是你不能修改git- SVN的分支历史(因为SVN不会让你提交)。
如果我们都能直接从我们自己的git-svn仓库推送到SVN,那就更好了。
git svn dcommit
命令不是用来做什么的吗?
使用git svn rebase
将你的git克隆版本重新定位到svn的中央仓库,然后使用git svn dcommit
将你的本地提交推送到svn。
我每天使用git svn和GCC git镜像,它工作得很好。也许这是因为有一个中央只读镜像,它会自动从svn的提交中更新,所以每个使用git-svn的人都会从git镜像中看到相同的历史记录和相同的提交id集。这样就可以从只读镜像获取和合并,然后通过git svn rebase和git svn dcommit将更改推送到svn repo。然后,这些更改将同步到只读镜像,并由具有相同id的其他人获取。
我也处于类似的设置中,这里有一个对我和我的同事有效的过程:
-
一个人使用
git svn clone
和朋友创建Git存储库 -
其他人使用常规的Git命令克隆第一个Git存储库,然后复制第一个存储库的
.git/config
的svn-remote.{name}
位。在git help svn
的示例中有这样做的说明。
现在,每个人都有一个git-svn
设置,可以用来与Subversion存储库交互。
更重要的是,每个人都有一个具有相同分支和提交历史的git-svn
设置,这意味着git svn fetch
和朋友创建的提交将是相同的,包括哈希值。在这一点上,除了推拉到Subversion存储库之外,您还可以在自己之间使用所有Git的高级分布式特性。
不像普通的Git,你需要小心共享配置——如果你的分支结构发散,你的哈希值也会发散。有时事情会出错,需要修复(我曾经有两个git svn fetch
同时运行,它们以一种微妙的方式相互攻击;我不得不用git svn reset
倒带我的历史并重新取回,以保持我的哈希值与其他人的哈希值相匹配)。但这是将两种工具混在一起的限制。