推送一个现有的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上工作)。
-
必要的软件包:
$ sudo apt-get install git subversion mercurial python-subversion
-
Mercurial需要通过将以下内容添加到
~/.hgrc
来进行configuration:[extensions] hgext.convert=
-
创build一些临时工作目录(我有几个回购迁移,所以我创build了SVN和Git版本的目录,以保持它们分开):
$ mkdir svn $ mkdir git
-
创build一个空的本地SVN仓库:
$ svnadmin create svn/project
-
克隆现有的Git仓库:
$ git clone server/path/project.git git/project
-
让Mercurial做它的事情:
$ hg convert --dest-type svn git/project svn/project
-
现在,SVN回购应该包含完整的提交历史logging,但不包含原始时间戳记。 如果这不是问题,请跳过下一部分到第11步。
-
通过一些工作, 每个提交的date和时间都可以改变 。 由于我的回购是相当小的,这是可行的,我做手动。 首先,在SVN
pre-revprop-change
创build一个pre-revprop-change
钩子,其内容如下:允许修改必要的属性:#!/bin/bash exit 0;
这个脚本必须是可执行的:
$ chmod +x svn/project/hooks/pre-revprop-change
-
Mercurial创build了一个名为project -wc的SVN仓库的工作副本,因此切换到它并编辑提交时间:
$ cd project-wc $ svn propedit svn:date --revprop -r 1
input正确的date和时间(注意时区!)并保存,你应该会收到一条消息:“为属性svn设置新值:在修订版本1上的date”。
现在冲洗,并重复其他修订。 -
(可选)检查提交历史logging以确保一切正常:
$ svn log -r 1:HEAD
然后回到一个级别:
$ cd ..
-
转储存储库:
$ svnadmin dump svn/project > project.dump
-
并在您的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。