来自 git-svn 的远程分支与普通的 Git 远程分支几乎相同。因此,在您的本地存储库中,您可以克隆 git-svn 并将更改推送到 GitHub。吉特不在乎。如果您创建 git-svn 克隆并将完全相同的更改推送到 GitHub,您将拥有 Google 代码存储库的非官方镜像。剩下的就是普通的 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-ing 和 git-pushing 的同一个分支上。您需要一个单独的分支来进行更改。否则,您最终会在 Subversion 的基础上重新调整您的更改,这可能会让克隆您的 Git 存储库的任何人感到不安。跟着我?好的,所以你创建了一个分支,我们称之为“功能”。然后你做出一个提交并将其推送到 GitHub 的功能分支。你的 gitk 看起来像这样:
o [features][remotes/origin/features]
|
o
|
o [master][remotes/trunk][remotes/origin/master]
|
o
在这里,您的功能分支在 Google 代码分支之前有几个提交,对吧?那么,当您想从 Google 代码中整合新内容时会发生什么?你会先运行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] 与 master 在同一点。但是您的功能分支没有更改。您现在的选择是将 master 合并到 features 中,或者 rebase features。合并看起来像这样
git checkout features
git merge master
o [features]
/|
/ o [remotes/origin/features]
[master] o |
| o
o /
|/
o
|
o
然后您将功能推送到 GitHub。为了节省空间,我已经把遥控器留给主人了,它们会和 [master] 处于同一位置。
rebase 方法稍微有点邪恶——你必须用 --force 推动,因为你的推动不会是快进合并(你会从克隆它的人那里拉出特性分支)。这样做并不被认为是可以的,但如果你下定决心,没有人可以阻止你。它确实也让一些事情变得更容易,例如当补丁以略微修改的形式被上游接受时。它可以省去处理冲突的麻烦,你可以 rebase --skip 上游补丁。无论如何,rebase 应该是这样的:
git rebase master features
o [features]
|
o
| o [remotes/origin/features]
[master] o |
| o
o /
|/
o
|
o
然后你必须git push --force 那。你可以看到为什么你需要强制它,历史从 [remotes/origin/features] 到新的当前 post-rebase [features] 之间存在很大的分歧.
这一切都有效,但需要付出很多努力。如果你打算成为一名普通的贡献者,最好的办法是像这样工作一段时间,向上游发送一些补丁,看看你是否可以获得对 Subversion 的提交访问权限。如果做不到这一点,也许不要将您的更改推送到 GitHub。将它们保留在本地并尝试让它们在上游被接受。