推送一个现有的git仓库到SVN

我一直在Git中做所有的工作,然后推到GitHub上。 我对软件和网站都非常满意,现在我不想改变我的工作方式。

我的博士顾问要求所有学生保持在大学托pipe的SVN存储库中工作。 我已经发现了大量的文档和教程,将现有的SVN回购下拉到git中,但没有关于推送一个新的SVN回购的git回购。 我希望有一个办法可以做到这一点,git-svn和一个新的分支和重新装订和所有这些美好的条件的组合,但我是一个git新手,并没有任何他们的信心。

然后,我想运行一些命令,以便在我select时向SVN回购提交提交,我希望继续使用Git,并且让SVN回购镜像Git中的内容。

如果这有什么不同,我将成为唯一一个承诺SVN的人。

任何指示如何做到这一点将非常感激!

我也需要这个,并且在Bombe的回答+一些摆弄的帮助下,我得到了它的工作。 这是配方:

导入git – > svn

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-repo。 就这样。

保持回购同步

您现在可以使用以下命令从svn – > git进行同步:

 git svn fetch git rebase trunk 

并从git – > svn同步,请使用:

 git svn dcommit 

最后的笔记

您可能想要在本地副本上尝试此操作,然后再应用到实时回购。 你可以把你的git-repo复制到一个临时的地方,只需使用cp -r ,因为所有的数据都在repo本身。 然后你可以设置一个基于文件的testing回购,使用:

 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 

并删除部分[svn-remote "svn"]部分。

然后你可以重新运行git svn init

以下是我们的工作原理:

在你的机器上克隆你的git仓库。 打开.git / config并添加以下内容(从http://www.kerrybuckley.org/2009/10/06/maintaining-a-read-only-svn-mirror-of-a-git-repository/ ):

 [svn-remote "svn"] url = https://your.svn.repo fetch = :refs/remotes/git-svn 

现在,从控制台窗口input以下内容:

 git svn fetch svn git checkout -b svn git-svn git merge master 

现在,如果出于任何原因在这里打破,请input以下3行:

 git checkout --theirs . git add . git commit -m "some message" 

最后,你可以承诺svn

 git svn dcommit 

注意:我总是在之后取消该文件夹。

欢呼!

直接使用git rebase会失去第一次提交。 Git认为它不同,不能重新设定它。

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

我将在这里抄录解决scheme,但Björn的学分。

初始化git-svn:

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

–prefix给你远程跟踪分支,比如“svn / trunk”,这很好,因为如果你打电话给你的本地分支只是“trunk”,那么你不会得到不明确的名字。 而-s是标准中继/标签/分支布局的快捷方式。

从svn获取最初的东西:

 git svn fetch 

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

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

然后得到空的中继提交的散列:

 git rev-parse svn/trunk 

创build嫁接:

 echo <root-commit-hash> <svn-trunk-commit-hash> >> .git/info/grafts 

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

使移植永久:

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

放下移植物:

 rm .git/info/grafts 

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

在主干顶部线性化历史logging:

 git svn rebase 

现在“git svn dcommit -n”应该告诉你它将会提交给trunk。

 git svn dcommit 

在您的项目的Subversion存储库中创build一个新的目录。

 # svn mkdir --parents svn://ip/path/project/trunk 

转到你的Git托pipe项目并初始化git-svn。

 # git svn init svn://ip/path/project -s # git svn fetch 

这将创build一个提交,因为你的svn项目目录仍然是空的。 现在重新提交一切,提交, git svn dcommit ,你应该完成。 尽pipe如此,它会严重搞砸你的提交date。

Git – >具有完整提交历史的SVN

我有一个git项目,并不得不将其移动到SVN。 这就是我所做的,保持了整个提交历史。 唯一会丢失的是原来的提交时间,因为libSVN会在我们git svn dcommit时设置当地时间。

如何:

1)有一个svn仓库,我们想要导入我们的东西,并用git-svn克隆它:

git svn clone https://path.to/svn/repository repo.git-svn

2)去那里:

cd repo.git-svn

3)添加git仓库的远程(在这个例子中,使用C:/Projects/repo.git )你要推送给svn,并给它的名字old-git:

git remote add old-git file:///C/Projects/repo.git/

4)从主分支从old-git仓库获取信息到当前的仓库:

git fetch old-git master

5)将旧git远程主分支签出到当前回购中名为old的新分支中:

git checkout -b old old-git/master

6)重新把HEAD放在old-git / master上面。 这将保持你所有的提交。 这基本上是把你所有的工作都在git中完成,并把它放在你从svn访问的工作上面。

git rebase master

7)现在回到你的主分支:

git checkout master

你可以看到你有一个干净的提交历史logging。 这是你想推到svn。

8)推动你的工作svn:

git svn dcommit

就这样。 非常干净,没有黑客入侵,所有的东西都是完美的。 请享用。

我会使用SubGit在4个命令中提出一个非常短的指令。 详情请看这个post 。

我需要将我现有的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回购(我的来源使用私人/公钥authentication),我不得不使用–username属性。

如果你想继续使用git作为你的主版本库,只需要将版本“导出”到svn,你可以使用裁剪来保持svn版本库的同步。 它可以复制不同的源代码控制系统之间的修订版本,并会更新您在git中所做的更改。

我还没有尝试过一个git – > svn转换,但对于一个svn – > svn示例看到这个答案 。

如果你不需要使用任何特定的svn,而且你正在使用Github,你可以使用他们的svn连接器。

更多信息在这里https://github.com/blog/1178-collaborating-on-github-with-subversion

我想分享一个名为Scatter的WordPress社区使用的一个伟大的工具

http://evansolomon.me/notes/git-wordpress-plugins-and-a-bit-of-sanity-scatter/

这使用户能够自动发送他们的git仓库到WordPress.org SVN。 理论上,这个代码可以应用于任何SVN仓库。

你可以做一个新的SVN回购。 导出你的git项目(丰富.git文件)。 把它添加到svn回购(用你到目前为止在git中初始化回购)。 然后使用说明在新的git项目中导入svn repos。

但是,这将放弃你以前的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 

我知道这是一个非常古老的问题,但是我最近不得不将一些Git版本迁移到SVN,并且在尝试了所有可以find的解决scheme之后, Mercurial (是的,使用了第三个 VCS)才终于为我工作。 使用本指南 ,我提出了以下过程(在Linux上,但基本概念也应该在Windows上工作)。

  1. 必要的软件包:

     $ sudo apt-get install git subversion mercurial python-subversion 
  2. Mercurial需要通过将以下内容添加到~/.hgrc来进行configuration:

     [extensions] hgext.convert= 
  3. 创build一些临时工作目录(我有几个回购迁移,所以我创build了SVN和Git版本的目录,以保持它们分开):

     $ mkdir svn $ mkdir git 
  4. 创build一个空的本地SVN仓库:

     $ svnadmin create svn/project 
  5. 克隆现有的Git仓库:

     $ git clone server/path/project.git git/project 
  6. 让Mercurial做它的事情:

     $ hg convert --dest-type svn git/project svn/project 
  7. 现在,SVN回购应该包含完整的提交历史logging,但不包含原始时间戳记。 如果这不是问题,请跳过下一部分到第11步。

  8. 通过一些工作, 每个提交的date和时间都可以改变 。 由于我的回购是相当小的,这是可行的,我做手动。 首先,在SVN pre-revprop-change创build一个pre-revprop-change钩子,其内容如下:允许修改必要的属性:

     #!/bin/bash exit 0; 

    这个脚本必须是可执行的:

     $ chmod +x svn/project/hooks/pre-revprop-change 
  9. Mercurial创build了一个名为project -wc的SVN仓库的工作副本,因此切换到它并编辑提交时间:

     $ cd project-wc $ svn propedit svn:date --revprop -r 1 

    input正确的date和时间(注意时区!)并保存,你应该会收到一条消息:“为属性svn设置新值:在修订版本1上的date”。
    现在冲洗,并重复其他修订。

  10. (可选)检查提交历史logging以确保一切正常:

     $ svn log -r 1:HEAD 

    然后回到一个级别:

     $ cd .. 
  11. 转储存储库:

     $ svnadmin dump svn/project > project.dump 
  12. 并在您的Subversion服务器上加载转储。 完成!

这个过程也可能直接在远程仓库之间工作,但是我发现使用本地仓库更容易。 确定提交时间是很多工作,但总的来说,这个过程比我发现的其他方法要简单得多。

只是想分享一些我接受答案的经验。 我做了所有的步骤,一切都很好,然后我跑了最后一步

 git svn dcommit 

$ git svn dcommit

在/usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm第101行的replace(s ///)中使用未初始化的值$ u。

在串联(。)中使用未初始化值$ u或在/usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm第101行使用string。refs / remotes / origin / HEAD:' https : //192.168.2.101/ svn / PROJECT_NAME '找不到''

我发现这个线程https://github.com/nirvdrum/svn2git/issues/50

最后是我在第101行的以下文件中应用的解决scheme/usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm

我replace了

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

我replace

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

这解决了我的问题

如果您不想在Git中提交每个提交到SVN存储库的内容? 如果你只是想有select地发送提交pipe道? 好。 我有一个更好的解决scheme。

我保留了一个本地git回购,我所做的一切都是从SVN获取和合并的。 这样,我可以确保包含所有与SVN相同的更改,但是我将提交历史与SVN完全分开。

然后我保持一个单独的文件夹中的一个单独的SVN本地工作副本。 这是我从SVN提交的,我只是使用SVN命令行工具。

当我准备好将本地的git repo的状态提交给SVN的时候,我简单地将整个文件拷贝到本地的SVN工作副本中,并使用SVN而不是git从那里提交。

这样我永远不必做任何重组,因为重新绑定就像是freebasing。