我一直在用Git完成所有工作并推送到GitHub。我对软件和网站都非常满意,我不想在此时改变我的工作方式。
我的博士生顾问要求所有学生将他们的工作保存在大学托管的SVN存储库中。我已经找到大量关于将现有SVN存储库下载到Git中的文档和教程,但没有关于将Git存储库推送到新的SVN存储库。我希望必须有一些方法来实现这一点,结合使用git-svn和一个新的分支和变基所以及所有那些精彩的术语,但我是一个Git新手并且对它们中的任何一个都没有信心。
然后我想在我选择时运行几个命令将提交推送到该SVN存储库。我希望继续使用Git,只是拥有SVN存储库镜像Git中的内容。
如果这有任何不同,我将是唯一一个承诺进入SVN的人。
我也需要这个,并且在Bombe的回答+一些摆弄的帮助下,我得到了它的工作。这是食谱:
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
并删除部分[svn-remote "svn"]
部分。
然后你可以重新运行git svn init
。
我想分享一个名为Scatter的WordPress社区中使用的很棒的工具
Git WordPress plugins and a bit of sanity scatter
这使用户能够自动将他们的Git存储库发送到wordpress.org SVN。理论上,此代码可以应用于任何SVN存储库。
就我而言,我不得不从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
您可以创建一个新的SVN存储库。导出你的Git项目(充实.git文件)。将其添加到SVN存储库(使用您在Git中的内容初始化存储库)。然后使用说明在新的Git项目中导入SVN存储库。
但这将失去你以前的Git历史。
我只想分享一些我接受的答案的经验。我做了所有步骤,在我完成最后一步之前一切都很好:
git svn dcommit
$ git svn dcommit
在/usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm第101行使用未初始化的值$ u代替(s ///)。
在连接(。)中使用未初始化的值$ u或在/usr/lib/perl5/vendor_perl/5.22/Git/SVN.pm第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
同
if (!$u) {
$u = $pathname;
}
else {
$u =~ s!^\Q$url\E(/|$)!! or die
"$refname: '$url' not found in '$u'\n";
}
这解决了我的问题。
另一个有效的序列(每个步骤都有一些评论):
git-svn
和subversion
工具包:
sudo apt-get install git-svn subversion
PROJECT_FOLDER
cd PROJECT_FOLDER
git-svn
插件与TortoiseSVN相比存在缺陷)。它无法将源代码直接存储到PROJECT_FOLDER
中。相反,默认情况下,它会将所有代码上传到PROJECT_FOLDER/trunk
。
svn mkdir --parents protocol:/// path / to / repo / PROJECT_FOLDER / trunk -m“创建git repo占位符”这是路径尽头的trunk
必修的地方
git-svn
文件夹中初始化.git
插件上下文
git svn init -s protocol:///path/to/repo/PROJECT_FOLDER
这是路径尽头的trunk
不需要的地方Subversion
存储库信息
git svn fetch
此步骤有助于将Subversion服务器与git-svn
插件同步。这是git-svn
插件建立remotes/origin
路径并将其与服务器端的trunk
子文件夹关联的时刻。git-svn
插件参与该过程之前(此步骤是可选的)
git rebase origin/trunk
git add .
git commit -m "Importing Git repository"
git svn dcommit
我最近不得不将几个Git存储库迁移到SVN,在尝试了我能找到的所有解决方案之后,最终对我有用的是Mercurial(是的,使用第三个VCS)。使用this guide,我提出了以下过程(在Linux上,但基本的想法也适用于Windows)。
$ sudo apt-get install git subversion mercurial python-subversion
~/.hgrc
来配置Mercurial:
[extensions]
hgext.convert=
$ mkdir svn
$ mkdir git
$ svnadmin create svn/project
$ git clone server/path/project.git git/project
$ hg convert --dest-type svn git/project svn/project
pre-revprop-change
钩子,其中包含以下内容,以允许修改必要的属性:
#!/bin/bash
exit 0;
必须使此脚本可执行:
$ chmod +x svn/project/hooks/pre-revprop-change
$ cd project-wc
$ svn propedit svn:date --revprop -r 1
输入正确的日期和时间(注意时区!)并保存。您应该收到一条消息“为属性svn设置新值:修订版本1上的日期”。
现在冲洗并重复每次其他修订。$ svn log -r 1:HEAD
然后回到一个级别:
$ cd ..
$ svnadmin dump svn/project > project.dump
这个过程可能也会直接在远程存储库之间工作,但我发现使用本地存储库更容易。修复提交时间是很多工作,但总的来说,这个过程比我找到的任何其他方法都要简单得多。
有三种方法:
echo "git_id svn_id}" > .git/info/grafts
then git svn dcommit
bash demo:github demo
v1.x:使用rebase和commit id
v2.x:使用copy文件,然后使用svn commit
如果您不想将您在Git中提交的每个提交提交到SVN存储库,该怎么办?如果您只是想有选择地向管道发送提交怎么办?好吧,我有一个更好的解决方案。
我保留了一个本地Git存储库,我所做的就是从SVN获取和合并。这样我可以确保我包含与SVN相同的所有更改,但是我将提交历史与SVN完全分开。
然后我保留一个单独的SVN本地工作副本,该副本位于单独的文件夹中。那是我做的那个提交回SVN,我只是使用SVN命令行实用程序。
当我准备将我的本地Git存储库状态提交给SVN时,我只需将整个文件复制到本地SVN工作副本中,然后使用SVN而不是Git从那里提交它。
这样我就不必做任何变基,因为变基就像自由基。
以下是我们如何运作:
在您的计算机上的某个位置克隆您的Git存储库。
打开.git / config并添加以下内容(来自Maintaining a read-only SVN mirror of a Git repository):
[svn-remote "svn"]
url = https://your.svn.repo
fetch = :refs/remotes/git-svn
现在,从控制台窗口中键入以下内容:
git svn fetch svn
git checkout -b svn git-svn
git merge master
现在,如果它因任何原因而在这里打破,请输入以下三行:
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
我将在这里转录解决方案,但是Björn的学分。
初始化git-svn:
git svn init -s --prefix=svn/ https://svn/svn/SANDBOX/warren/test2
--prefix为您提供远程跟踪分支,如“svn / trunk”,这很好,因为如果您只是将“本地分支”称为“主干”,则不会出现含糊不清的名称。而-s
是标准主干/标签/分支布局的快捷方式。
从SVN获取最初的东西:
git svn fetch
现在查找根提交的哈希值(应显示单个提交):
git rev-list --parents master | grep '^.\{40\}$'
然后获取空中继提交的哈希:
git rev-parse svn/trunk
创建移植物:
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
。
在树干上线性化您的历史记录:
git svn rebase
现在“git svn dcommit -n”应该告诉你它将提交到trunk。
git svn dcommit
在项目的Subversion存储库中创建一个新目录。
# svn mkdir --parents svn://ip/path/project/trunk
更改为您的Git托管项目并初始化git-svn。
# git svn init svn://ip/path/project -s
# git svn fetch
这将创建一个提交,因为您的SVN项目目录仍为空。现在重新定义该提交的所有内容,git svn dcommit
,你应该完成。但是,它会严重影响您的提交日期。
Git - >具有完整提交历史的SVN
我有一个Git项目,不得不把它移到SVN。这就是我制作它的方式,保留了整个提交历史。唯一丢失的是原始提交时间,因为当我们执行git svn dcommit
时,libSVN将设置本地时间。
如何:
git svn clone https://path.to/svn/repository repo.git-svn`
cd repo.git-svn
git remote add old-git file:///C/Projects/repo.git/
git fetch old-git master
git checkout -b old old-git/master`
git rebase master
git checkout master
你可以看到你有一个干净的提交历史。这就是你想要推向SVN的。git svn dcommit
就这样。这是非常干净,没有黑客攻击,一切都完美开箱即用。请享用。
我需要将现有的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存储库(我的origin
使用私钥/公钥认证),我不得不使用--username
属性。
如果您希望继续使用Git作为主存储库并且只需要不时“导出”SVN的修订版,则可以使用Tailor来保持SVN存储库同步。它可以复制不同源代码控制系统之间的修订版本,并使用您在Git中进行的更改来更新SVN。
我没有尝试过Git-to-SVN转换,但对于SVN - > SVN示例,请参阅this answer。
如果您不必使用任何特定的SVN并且您使用的是GitHub,则可以使用其SVN连接器。