将Google Code的Subversion仓库分叉并同步到GitHub

131

我如何将一个我没有写权限的Google Code Subversion仓库fork并保持同步到GitHub仓库?

我想在我的Git仓库中开发自己的功能,但我也希望与Google Code Subversion仓库保持同步,以从Google Code项目方面获取修复。

我知道git-svn并曾经使用它来上下游到我完全控制的Subversion仓库。但我不知道如何与Google Code Subversion仓库保持同步。

7个回答

178

从git-svn的远程分支来看,它基本上与常规的Git远程分支相同。因此,在本地仓库中可以有你的git-svn克隆,并将更改推送到GitHub。Git并不在意。如果你创建了一个git-svn克隆并将完全相同的更改推送到GitHub,那么你就会拥有Google Code存储库的非官方镜像。其余都是普通的Git。

git svn clone http://example.googlecode.com/svn -s
git remote add origin git@github.com:example/example.git
git push origin master

现在您已经拥有了这个,偶尔需要将Subversion存储库与Git同步。它会看起来像这样:

git svn rebase
git push
在gitk或类似工具中,它看起来像这样:

o [master][remotes/trunk][remotes/origin/master]
|
o
|
o

当你运行 git svn rebase 时,会出现以下情况:

o [master][remotes/trunk]
|
o
|
o [remotes/origin/master]
|
o
|
o

现在运行git push命令将提交推送到GitHub,其中包括那些在那里的[remotes/origin/master]分支。然后您将回到第一个ASCII示意图中的情况。

问题是,如何将您的更改加入到混合中?想法是,您不要在正在进行git-svn-rebase和git-push的同一分支上提交。您需要为自己的更改创建一个单独的分支。否则,您的更改将被重新基于Subversion的更改,这可能会使克隆您的Git存储库的任何人感到不适。明白了吗?好的,所以您创建一个名为“features”的分支。您进行提交并将其推送到GitHub的“features”分支。您的gitk看起来应该像这样:

o [features][remotes/origin/features]
|
o
|
o [master][remotes/trunk][remotes/origin/master]
|
o

你现在有一个特性分支,它比Google Code分支多了几个提交。那么当你想要将新的内容从Google Code合并进来时会发生什么?你需要首先运行git svn rebase,然后得到这样的结果:

                           o [features][remotes/origin/features]
[master][remotes/trunk] o  |
                        |  o
                        o /
                        |/
                        o[remotes/origin/master]
                        |
                        o

如果你git push master out,你可以想象[remotes/origin/master]与主分支相同。但是你的特性分支没有这些更改。现在你有两种选择,要么将主分支合并到特性分支,要么将特性分支重新设置基础。合并将会是这样:

git checkout features
git merge master 

            o [features]
           /|
          / o [remotes/origin/features]
[master] o  |
         |  o
         o /
         |/
         o
         |
         o

然后你将功能推送到GitHub。我省略了主分支的远程引用,以节省空间,它们应该与 [master] 处于同一点。

变基方法略微更加恶劣 - 你需要使用 --force 参数进行推送,因为你的推送不会是快进合并(你会从已经克隆过的某人那里拉取功能分支)。虽然这样做并不被认为是正确的,但如果你决心这样做,没有人能阻止你。它也使一些事情变得更容易,例如当补丁以稍微修改的形式被上游接受时。这将避免处理冲突,只需通过 rebase --skip 命令跳过上游补丁即可。无论如何,一个变基会像这样:

git rebase master features

         o [features]
         |
         o
         |  o [remotes/origin/features]
[master] o  |
         |  o
         o /
         |/
         o
         |
         o

然后你需要用git push --force来强制推送。你可以看到为什么需要强制,因为历史记录从[remotes/origin/features]到新的当前后置基础上存在着一个很大的分裂。

所有这些都有效,但需要付出很多努力。如果你要成为一名常规贡献者,最好的方法是像这样工作一段时间,将一些补丁发送到上游,并尝试获得对Subversion的提交访问权限。如果失败了,也许不要将您的更改推送到GitHub上。保持本地并尝试在上游获得它们的接受。


感谢您提供的出色指导。(我是一个git新手。)我有一个快速问题。我对一个大型SVN仓库进行了操作,结果大小约为141兆字节。我将其推送到github上,然后再次克隆,大小变成了130兆字节。我在两个版本上都运行了“git gc”。这种差异可能是由什么引起的? - mpontillo
我想通了。我需要使用 git push origin --mirror - mpontillo
运行得非常好,现在我只需要告诉原始的googlecode开发人员与我一起使用github :D - electblake
在使用git svn clone命令的-s选项时,这对我无效,但是如果不用该选项,则其余部分完全可以正常工作。 - user1027169

15

svn2github 服务

http://svn2github.com/ 网站提供了一项服务,可以将任何公开访问的 SVN 仓库复制到 Github 上(在 https://github.com/svn2github/projectname)。我尝试了它;点击“Make a mirror”按钮后,它似乎没做任何事情,显示“error”消息,但实际上它确实起作用了。新仓库已被创建,其中包含 SVN 仓库中的代码。

然后,您可以 fork 它创建的仓库并在自己的 fork 上工作。您可以使用他们的 bugtracker 将更改提交给上游项目。

查看服务的 Github 用户下的现有存储库(例如“svn2github pushed to master at svn2github/haxe 5 hours ago”),它似乎定期从 SVN 仓库中拉取更改。网站上没有关于谁运行该服务的信息,因此我不确定它是否会无限期运行,但它现在是可用的(如果它停止运行,您仍然可以手动更新您的 fork)。

Launchpad

如果你不想使用 Git 和 Github,则另一个选择是使用 Launchpad.net。 Launchpad 可以自动将 SVN(还有 CVS)仓库导入到个人的 bzr 分支中。为此,请创建一个 Launchpad 项目,然后转到新的导入页面,选择 Subversion 并输入 URL(例如 http://projectname.googlecode.com/svn/trunk/)。根据项目大小,初始导入可能需要几个小时。随后的导入将定期运行。

有关更多文档,请参阅Launchpad 帮助上的 VCS Imports


10

一份将代码从Google Code同步到GitHub的指南可在fnokd.com找到。作者使用一台始终开启的远程服务器和定时任务来自动化同步,并将SVN主干保留在名为“vendor”的GitHub分支中。


2

GitHub现在支持直接导入Subversion项目(参见http://help.github.com/import-from-subversion/)。只需创建一个新的repo,然后在“下一步”屏幕上点击“从Subversion导入”。但是它不支持进一步同步 :/。


该方法不再存在 - magnetik
现在请使用 https://import.github.com/new。请参阅 https://help.github.com/articles/importing-from-subversion/。 - Chris Arndt

1
嗯...在我的公司里,我做的几乎一样。只是将.svn和.git存储库放在同一个目录中(您检出svn存储库并在此工作副本中创建git存储库)。
然后使用svn up和git push完成了这件事。当然,如果您分歧很大,就必须手动合并东西。

没错,但我想避免使用 .svn 元数据,并希望 Git 能够将 SVN 存储库用作下游主存储库。 - optixx
那么,使用git-svn检出repo并将其推送到github不可能吗? - Marcin Gil

0
我在Yu-Jie Lin的博客上找到了以下指示:
首先克隆Subversion存储库并推送到Git:
git svn clone https://foo.googlecode.com/svn/ git-foo 
cd git-foo
git remote add git-foo git@github.com:username/foo.git 
git push git-foo master

提交到Subversion仓库后,运行:
cd /path/to/git-foo
git svn fetch 
git svn rebase 
git push git-foo master

0

我不太确定你想要什么,但是当然可以从一个子版本库中拉取并将其推送到Git存储库的同一工作副本中。您还可以使用git svn dcommit将其提交回子版本库。但是,您无法使GitHub存储库与子版本库同步。此外,如果您的工作副本中有尚未在子版本库中的提交,则需要对其进行变基,如果子版本库已更新,则需要强制执行git push --force将“新”提交推送到GitHub。


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