我一直在用Git做我所有的工作,并将其推送到GitHub。我对软件和网站都很满意,我不希望在这一点上改变我的工作实践。

我的博士导师要求所有学生将作业保存在学校托管的SVN存储库中。我发现了大量关于将现有的SVN存储库下拉到Git中的文档和教程,但没有关于将Git存储库推到新的SVN存储库中的文档和教程。我希望通过结合Git -svn、一个新的分支和rebase以及所有这些美妙的术语来实现这一点,但我是Git新手,对其中任何一个都没有信心。

然后,当我选择时,我希望只运行几个命令将提交推到SVN存储库。我希望继续使用Git,让SVN存储库镜像Git中的内容。

我将是唯一一个致力于SVN的人,如果这有什么不同的话。


当前回答

我想分享一个在WordPress社区中使用的很棒的工具,叫做Scatter

Git WordPress插件和一点理智的分散

这使得用户能够自动将他们的Git存储库发送到wordpress.org SVN。理论上,这段代码可以应用于任何SVN存储库。

其他回答

直接使用git rebase将丢失第一次提交。Git以不同的方式对待它,并且不能对它进行重基。

有一个程序可以保存完整的历史记录:http://kerneltrap.org/mailarchive/git/2008/10/26/3815034

我将在这里转录解决方案,但学分是Björn。

初始化git-svn:

git svn init -s --prefix=svn/ https://svn/svn/SANDBOX/warren/test2

前缀为您提供了像“svn/trunk”这样的远程跟踪分支,这很好,因为如果您只将本地分支称为“trunk”,则不会得到模棱两可的名称。-s是标准trunk/tags/branches布局的快捷方式。

从SVN中获取初始的东西:

git svn fetch

现在查看你的根提交的散列(应该显示一个单独的提交):

git rev-list --parents master | grep '^.\{40\}$'

然后获取空trunk的哈希值commit:

git rev-parse svn/trunk

创建嫁接:

git replace --graft <root-commit-hash> <svn-trunk-commit-hash>

现在,“gitk”应该将svn/trunk显示为主分支所基于的第一个提交。

使移植物永久化:

git filter-branch -- ^svn/trunk --all

掉落移植物:

git replace -d <root-commit-hash>

Gitk应该仍然在master的祖先中显示svn/trunk。

在树干顶部线性化你的历史:

git svn rebase

现在"git svn dcommit -n"应该告诉你它将提交到trunk。

git svn dcommit

我只是想分享一些我的经验和公认的答案。我做了所有的步骤,在我运行最后一步之前,一切都很好:

git svn dcommit

$ git SVN dcommit 使用未初始化的值$u替换/usr/lib/perl5/vendor_perl/5.22/Git/SVN。下午101线。 在/usr/lib/perl5/vendor_perl/5.22/Git/SVN中使用未初始化的值$u(.)或字符串。下午101线。 refs/remotes/origin/HEAD:“https://192.168.2.101/svn/PROJECT_NAME”中没有找到

我找到了线程https://github.com/nirvdrum/svn2git/issues/50,最后我在101行下面的文件中应用了解决方案 /usr/lib/perl5/vendor_perl / 5.22 / Git / SVN.pm

我更换了

$u =~ s!^\Q$url\E(/|$)!! or die

with

if (!$u) {
    $u = $pathname;
} 
else {
       $u =~ s!^\Q$url\E(/|$)!! or die
      "$refname: '$url' not found in '$u'\n";
}

这解决了我的问题。

这就是我要做的。假设我的本地分支名为main。填补空白,因为我不记得确切的git svn命令,因为我已经有一段时间没有使用它了。

create in svn the branch that will be used for the project. use git svn to clone the svn repo you want (at least, the branch you want to use so that you do not have to fetch the other millions of revisions that we do not care about for this endeavor). checkout the svn branch in the new git repo. Add to this repository a remote that points to the original git repo you are using for the project. Let's say the remote is called the-real-stuff. git fetch the-real-stuff # so that we get to see what's in the real repo Given that this is the first time we will be pulling our code into the svn one, we have to trick git so that it can "merge" that code: git merge --allow-unrelated-histories the-real-stuff/main -m "Whatever comment I want in the svn revision". This will "merge" both branches locally. git svn dcommit so that you can push the content of the project as it is right now.

继续工作在原来的git回购。然后,当你想要推入svn时,去到git的svn clone,然后做:

git fetch the-real-stuff # get visibility to the changes in the original git repo
git merge the-real-stuff/main -m "Whatever comment I want to show on this svn revision"
git svn dcommit

这样就做完了。

我喜欢使用2个回购的想法,这样我们就不用用svn的东西来填充原始的回购,尽管有可能将整个东西保留在一个git回购中。

如果您希望继续使用Git作为您的主存储库,并且只需要不时地将修订“导出”到SVN,那么您可以使用Tailor来保持SVN存储库的同步。它可以在不同的源代码控制系统之间复制修订,并将您在Git中所做的更改更新到SVN。

我没有尝试过git到SVN的转换,但是对于一个SVN -> SVN示例,请参阅这个答案。

我需要将现有的Git存储库提交到一个空的SVN存储库。

我是这样做到的:

$ git checkout master
$ git branch svn
$ git svn init -s --prefix=svn/ --username <user> https://path.to.repo.com/svn/project/
$ git checkout svn
$ git svn fetch
$ git reset --hard remotes/svn/trunk
$ git merge master
$ git svn dcommit

它毫无问题地运行着。我希望这能帮助到一些人。

因为我必须使用不同的用户名向SVN存储库授权(我的源使用私钥/公钥身份验证),所以我必须使用——username属性。