有没有可能将Subversion代码库作为Git子模块?

162
有没有办法将一个Subversion仓库作为Git子模块添加到我的Git仓库中?类似这样的操作:
git-svn submodule add https://svn.foo.com/svn/proj --stdlayout svn-project

https://svn.foo.com/svn/proj指向一个 Subversion 仓库。

我知道有一种名为git-svn的工具,可以让我们与 Subversion 仓库进行交互。因此我认为,也许可以使用 git-svn 检出一个 Subversion 仓库,然后将其作为子模块使用。

6个回答

132

不行。你最好是在一个专用的 Git 存储库中设置 SVN 仓库的镜像。

git svn clone -s http://subversion.example.com/ mysvnclone
cd mysvnclone
git remote add origin git@example.com:project.git
git push origin master

你可以将git仓库作为子模块添加到原始项目中

cd /path/to/gitproject
git submodule add git://example.com/project.git -- svn-project
git add svn-project
git commit -m "Add submodule"

svn:externals和git子模块之间存在一个概念上的区别,如果从subversion的角度来看这个问题可能会让你感到困惑。Git子模块被钉在你给它的版本上。如果“upstream”发生变化,则必须更新子模块的引用。

因此,当我们与上游的Subversion进行重新同步时:

cd /path/to/mysvnclone
git svn rebase
git push

...这个git项目仍然会使用我们之前提交的原始版本。要更新到svn HEAD,您需要使用

cd /path/to/gitproject/svn-project
git checkout master
git pull
cd ..
git add svn-project
git commit -m"Update submodule"

1
你在发布这些代码之前尝试过吗?子模块在git svn中无法正常工作。 - xhan
4
@xhan 是的,我并不主张在同一个代码库中混合使用 git-svn 和子模块。使用 git-svn 创建的克隆仅是将 svn 仓库转换为本地 git 克隆的桥梁。 - richq
这可能不是默认设置,但你可以像 Git 子模块一样将 svn:externals 绑定到特定的版本。 - MarcH
我收到了有关第一个命令缺少--prefix标志的投诉(警告)。我应该在意吗? - bobbaluba
@bobbaluba 看这里 http://blog.tfnico.com/2013/08/always-use-git-svn-with-prefix.html - robingrindrod
显示剩余6条评论

8

我刚刚经历了这个过程。我正在做类似于rq的事情,但是略有不同。 我设置了其中一台服务器来托管我需要的svn存储库的git克隆。在我的情况下,我只想要只读版本,并且需要在服务器上使用裸库。

在服务器上运行:

GIT_DIR=<projectname>.git git init
cd <projectname>.git/
GIT_DIR=. git svn init svn://example.com/trunk
GIT_DIR=. git svn fetch
git gc

这将设置我的裸仓库,然后我有一个定时脚本来更新它:
#!/usr/bin/python

import os, glob

GIT_HOME='/var/www/git'

os.chdir(GIT_HOME)
os.environ['GIT_DIR']='.'
gits = glob.glob('*.git')
for git in gits:
  if not os.path.isdir(git):
    continue
  os.chdir(os.path.join(GIT_HOME, git))
  if not os.path.isdir('svn/git-svn'):
    #Not a git-svn repo
    continue

  #Pull in svn updates
  os.system('git svn fetch && git gc --quiet')
  #fix-svn-refs.sh makes all the svn branches/tags pullable
  os.system('fix-svn-refs.sh')
  #Update the master branch
  os.system('git fetch . +svn/git-svn:master && git gc --quiet')`

这还需要来自http://www.shatow.net/fix-svn-refs.sh的fix-svn-refs.sh。 这主要是受到了http://gsocblog.jsharpe.net/archives/12的启发。
我不确定为什么需要执行git gc,但没有它我无法执行git pull
所以在完成所有这些步骤后,您可以按照rq的说明使用git子模块。

有人可能认为,你甚至可以将这个作为一个提交前钩子来实现。 - Andres Jaan Tack

6

目前git-svn不支持svn:externals。但是有两个其他工具可以帮助你:

  1. SubGit

    SubGit 是一种服务器端解决方案,它使得 Git 可以访问 Subversion 仓库,反之亦然。您可以参考文档了解更多细节,但总的来说,使用 SubGit 相当容易:

    $ subgit configure --layout auto $SVN_URL $GIT_REPO
    

    上述命令将检测 SVN 项目中的分支布局,然后创建一个空的裸 Git 仓库,准备镜像 SVN 项目。除非这些凭据已经存储在 ~/.subversion 目录下的 SVN 凭据缓存中,否则可能会要求您提供凭据。您还可以调整 $GIT_REPO/subgit/authors.txt 来将 SVN 作者名称映射到 Git 身份。

    $ subgit install $GIT_REPO
    $ ... 让初始翻译完成 ...
    $ 翻译成功
    

    此时,您已经将 Subversion 仓库连接到新创建的 Git 仓库。SubGit 在每次 svn commit 时将 SVN 版本转换为 Git 提交,并在每次 git push 时将 Git 提交转换为 SVN 版本。

你需要做的就是让Git仓库对提交者可用。可以查看git-http-backend了解更多信息。然后,您可以将创建的Git仓库添加为常规子模块。

SubGit也可作为Bitbucket Server的附加组件使用,欲了解更多信息,请查看此处

因此,无需使用任何外部工具,如git-svn或其他工具。

SubGit是专有软件,但对于小型公司(最多10个提交者)、学术和开源项目是免费的。

  • SmartGit

    SmartGit 取代了客户端的 git-svn。您可以在 这里 找到更多有关其功能的信息。

    特别是,SmartGit 支持 git 子模块svn:externals,您可以在您的代码库中混合使用它们。

    SmartGit 是专有软件,但非商业用途免费。


  • subgit (https://subgit.com/documentation/config-options.html#translate.externals) 和 smartgit 都通过在工作副本中显式添加 .gitsvnextmodules 文件的方式支持 svn:externals。这意味着您仍然需要使用这些软件来检出外部依赖项,而不能直接从外部 git hub 服务器(如 githubgitlab)使用基本的 git 工具来检出这些外部依赖项。因此,与 svn:externals 相关的源在外部 git hub 服务器上将无法被观察和下载,这仍然是一个重要问题。 - Andry

    4
    除了rq所说的方法外,另一种方法是使用第三方"externals"项目(http://nopugs.com/ext-tutorial),它更好地模拟了svn外部引用的工作方式。使用externals,您可以跟踪git或svn存储库,并且似乎更容易将更改推送到这些存储库中。但是,它需要项目成员下载和安装单独的软件包。
    我还没有使用子模块或externals;但是,我花了几个小时阅读了所有替代方案,看起来externals更适合我的需求。 Jon Loeliger在《Git版本控制》第15章中有关于这些和其他自定义方法的优秀讨论(http://oreilly.com/catalog/9780596520120),我强烈推荐阅读。

    0

    嗯,有 git-remote-testsvn,所以我猜应该是这样的

    git submodule add testsvn::http://www.telegraphics.com.au/svn/bzquips/trunk/ \
        module/bzquips
    

    应该可以工作。它能吗?


    0

    Piston正在进行重写以支持此功能,包括反向操作,同时还支持Subversion存储库中的现有Subversion URL和git+git。

    请查看Piston Github存储库

    不幸的是,它似乎尚未发布。


    3
    尽管活塞很可能会在你最需要它的时候失败,但我不建议使用它,此外也没有对活塞进行任何错误修复。 - Henrik

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接