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

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

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

我将是唯一一个致力于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存储库,该怎么办?如果您只想有选择地向管道发送提交,该怎么办?我有个更好的办法。

我保留了一个本地Git存储库,我所做的一切都是从SVN中获取和合并。通过这种方式,我可以确保包括所有与SVN相同的更改,但我将提交历史与SVN完全分开。

然后,我在一个单独的文件夹中保存一个单独的SVN本地工作副本。这就是我提交回SVN的文件,我只使用SVN命令行实用程序。

当我准备将本地Git存储库的状态提交到SVN时,我只需将所有乱七八糟的文件复制到本地SVN工作副本中,然后从那里使用SVN而不是Git提交它。

这样我就不需要做任何重基,因为重基就像冻结。

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

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

直接使用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

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

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

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

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";
}

这解决了我的问题。