我一直在用Git做我所有的工作,并将其推送到GitHub。我对软件和网站都很满意,我不希望在这一点上改变我的工作实践。
我的博士导师要求所有学生将作业保存在学校托管的SVN存储库中。我发现了大量关于将现有的SVN存储库下拉到Git中的文档和教程,但没有关于将Git存储库推到新的SVN存储库中的文档和教程。我希望通过结合Git -svn、一个新的分支和rebase以及所有这些美妙的术语来实现这一点,但我是Git新手,对其中任何一个都没有信心。
然后,当我选择时,我希望只运行几个命令将提交推到SVN存储库。我希望继续使用Git,让SVN存储库镜像Git中的内容。
我将是唯一一个致力于SVN的人,如果这有什么不同的话。
这就是我要做的。假设我的本地分支名为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回购中。
我也需要这个,在Bombe的回答的帮助下,再加上一些摆弄,我让它工作了。下面是食谱:
导入Git -> Subversion
1. cd /path/to/git/localrepo
2. svn mkdir --parents protocol:///path/to/repo/PROJECT/trunk -m "Importing git repo"
3. git svn init protocol:///path/to/repo/PROJECT -s
4. git svn fetch
5. git rebase origin/trunk
5.1. git status
5.2. git add (conflicted-files)
5.3. git rebase --continue
5.4. (repeat 5.1.)
6. git svn dcommit
在第3条之后,你会收到这样一条神秘的消息:
使用更高级别的URL: protocol:///path/to/repo/PROJECT => protocol:///path/to/repo
忽略它。
当您运行#5时,您可能会遇到冲突。通过添加状态为“unmerged”的文件并恢复rebase来解决这些问题。最终,你会完成;然后使用dcommit同步回SVN存储库。这是所有。
保持存储库同步
您现在可以使用以下命令从SVN同步到Git:
git svn fetch
git rebase trunk
要从Git同步到SVN,请使用:
git svn dcommit
最后请注意
在应用到活动存储库之前,您可能希望在本地副本上尝试这一点。您可以将Git存储库复制到临时位置;只需使用cp -r,因为所有数据都在存储库本身中。然后你可以建立一个基于文件的测试存储库,使用:
svnadmin create /home/name/tmp/test-repo
并使用以下命令检查工作副本:
svn co file:///home/name/tmp/test-repo svn-working-copy
这样可以让你在做出任何持久的改变之前先玩一玩。
附录:如果你搞砸了git svn init
如果您不小心使用错误的URL运行了git svn init,并且您不够聪明,没有对您的工作进行备份(不要问…),那么您不能再次运行相同的命令。但是,您可以通过发出以下命令来撤销更改:
rm -rf .git/svn
edit .git/config
删除section [svn-remote "svn"] section。
然后可以重新运行git svn init。
我只是想分享一些我的经验和公认的答案。我做了所有的步骤,在我运行最后一步之前,一切都很好:
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";
}
这解决了我的问题。