我一直在用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
如果你不小心git svn init
使用错误的URL 运行,并且你不够聪明,无法对你的工作进行备份(不要问......),你不能再次运行相同的命令.但是,您可以通过发出以下命令撤消更改
rm -rf .git/svn edit .git/config
并删除部分[svn-remote "svn"]
部分.
然后你可以重新运行git svn init
.
以下是我们如何运作:
在您的计算机上的某个位置克隆您的Git存储库.
打开.git/config并添加以下内容(从维护Git存储库的只读SVN镜像):
[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>> .git/info/grafts
现在,"gitk"应该显示svn/trunk
为主分支所基于的第一个提交.
使移植物永久化:
git filter-branch -- ^svn/trunk --all
放下移植物:
rm .git/info/grafts
gitk应该仍然显示svn/trunk
在master的祖先中.
在树干上线性化您的历史记录:
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.这就是我制作它的方式,保留了整个提交历史.唯一丢失的是原始提交时间,因为libSVN将设置本地时间git svn dcommit
.
如何:
有一个SVN存储库,我们想要将我们的东西导入并使用git-svn克隆它:
git svn clone https://path.to/svn/repository repo.git-svn`
去那里:
cd repo.git-svn
添加Git存储库的远程(在本例中我使用的是C:/Projects/repo.git).你想推送到SVN并给它命名为old-git:
git remote add old-git file:///C/Projects/repo.git/
从master-branch存储库中获取主分支中的信息到当前存储库:
git fetch old-git master
将old-git远程的master分支签出到当前存储库中名为old的新分支中:
git checkout -b old old-git/master`
Rebase将HEAD置于old-git/master之上.这将保留您的所有提交.这基本上是在Git中完成所有工作并将其放在您从SVN访问的工作之上.
git rebase master
现在回到你的主分支:
git checkout master
你可以看到你有一个干净的提交历史.这就是你想要推向SVN的.
将你的工作推向SVN:
git svn dcommit
就这样.这是非常干净,没有黑客攻击,一切都完美开箱即用.请享用.