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

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

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

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


当前回答

最近我不得不将几个Git存储库迁移到SVN上,在尝试了我能找到的所有解决方案之后,最后对我有用的是Mercurial(是的,使用了第三种VCS)。根据这份指南,我提出了以下流程(适用于Linux,但基本思路也适用于Windows)。

The necessary packages: $ sudo apt-get install git subversion mercurial python-subversion Mercurial needs to be configured by adding the following to ~/.hgrc: [extensions] hgext.convert= Create some temporary working directories (I had several repositories to migrate so I created directories for the SVN and Git versions, to keep them separate): $ mkdir svn $ mkdir git Make an empty local SVN repository: $ svnadmin create svn/project Clone the existing Git repository: $ git clone server/path/project.git git/project Let Mercurial do its thing: $ hg convert --dest-type svn git/project svn/project Now the SVN repository should contain the full commit history, but not with original timestamps. If this is not an issue, skip over the next part to step 11. With a little work, the date and time of each commit can be changed. Since my repositories are fairly small, it was feasible for me to do it manually. First, create a pre-revprop-change hook in the SVN repository with the following contents, to allow the necessary property to be modified: #!/bin/bash exit 0; This script has to be made executable: $ chmod +x svn/project/hooks/pre-revprop-change Mercurial created a working copy of the SVN repository, named project-wc, so switch to it and edit the commit times: $ cd project-wc $ svn propedit svn:date --revprop -r 1 Enter the correct date and time (pay attention to timezones!) and save. You should get a message saying "Set new value for property svn:date on revision 1". Now rinse and repeat for every other revision. Optionally check the commit history to make sure everything looks OK: $ svn log -r 1:HEAD Then go back up one level: $ cd .. Dump the repository: $ svnadmin dump svn/project > project.dump And load the dump on your Subversion server. Done!

这个过程可能也可以直接在远程存储库之间工作,但是我发现与本地存储库一起工作更容易。修正提交时间需要做很多工作,但总的来说,这个过程比我发现的任何其他方法都要简单得多。

其他回答

您可以创建一个新的SVN存储库。导出您的Git项目(充实. Git文件)。将其添加到SVN存储库中(使用Git中现有的内容初始化存储库)。 然后使用在新的Git项目中导入SVN存储库的说明。

但是这会丢失之前的Git历史记录。

在我的例子中,我必须从SVN启动一个干净的项目

$ Project> git svn init protocol://path/to/repo -s
$ Project> git svn fetch

添加你所有的项目资源…

$ Project> git add .
$ Project> git commit -m "Importing project sources"
$ Project> git svn dcommit

这就是我要做的。假设我的本地分支名为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回购中。

还有一个有效的序列(每个步骤都有一些注释):

Install git-svn and subversion toolkits: sudo apt-get install git-svn subversion Switch inside the PROJECT_FOLDER cd PROJECT_FOLDER Create the project path on the Subversion server (unfortunately the current git-svn plugin has a defect in comparison with TortoiseSVN). It is unable to store source code directly into the PROJECT_FOLDER. Instead, by default, it will upload all the code into PROJECT_FOLDER/trunk. svn mkdir --parents protocol:///path/to/repo/PROJECT_FOLDER/trunk -m "creating git repo placeholder"

在这里,中继在路径的末端是强制性的

Initialize the git-svn plugin context inside the .git folder git svn init -s protocol:///path/to/repo/PROJECT_FOLDER This is the place where trunk at the end of the path is unnecessary Fetch an empty Subversion repository information git svn fetch This step is helping to synchronize the Subversion server with the git-svn plugin. This is the moment when git-svn plugin establishes remotes/origin path and associates it with the trunk subfolder on the server side. Rebase old Git commits happened before the git-svn plugin became involved in the process (this step is optional) git rebase origin/trunk Add new/modified files to commit (this step is regular for Git activities and is optional) git add . Commit freshly added files into the local Git repository (this step is optional and is only applicable if step 7 has been used): git commit -m "Importing Git repository" Pushing all the project changes history into the Subversion server: git svn dcommit

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

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

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