首页 文章

将现有的Git存储库推送到SVN

提问于
浏览
370

我一直在Git中完成所有工作并推送到GitHub . 我对软件和网站都非常满意,我不想在此时改变我的工作方式 .

我的博士生顾问要求所有学生将他们的工作保存在大学托管的SVN存储库中 . 我发现了大量关于将现有SVN存储库下载到Git中的文档和教程,但没有关于将Git存储库推送到新的SVN存储库 . 我希望必须有一些方法可以通过git-svn和一个新的分支和rebasing以及所有那些精彩的术语组合来实现这一点,但我是一个Git新手并且对它们中的任何一个都没有信心 .

然后我想在我选择时运行几个命令将提交推送到该SVN存储库 . 我希望继续使用Git,只是拥有SVN存储库镜像Git中的内容 .

如果这有任何区别,我将成为唯一一个承诺进入SVN的人 .

16 回答

  • 0

    如果您不必使用任何特定SVN并且您使用的是GitHub,则可以使用其SVN连接器 .

    更多信息请访问:Collaborating on GitHub with Subversion

  • 1

    就我而言,我不得不从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
    
  • 4

    直接使用 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"这样的远程跟踪分支,这很好,因为如果你只调用本地分支"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
    
  • 0

    我最近不得不将几个Git存储库迁移到SVN,在尝试了我能找到的所有解决方案之后,最终对我有用的是Mercurial(是的,使用第三个VCS) . 使用this guide,我提出了以下过程(在Linux上,但基本思想也适用于Windows) .

    • 必要的包裹:
    $ sudo apt-get install git subversion mercurial python-subversion
    
    • 需要通过将以下内容添加到 ~/.hgrc 来配置Mercurial:
    [extensions]
    hgext.convert=
    
    • 创建一些临时工作目录(我有几个要迁移的存储库,所以我为SVN和Git版本创建了目录,以使它们分开):
    $ mkdir svn
    $ mkdir git
    
    • 创建一个空的本地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存储库应包含完整的提交历史记录,但不包含原始时间戳 . 如果这不是问题,请跳过下一部分到第11步 .

    • 做了一点工作,the date and time of each commit can be changed . 由于我的存储库相当小,我可以手动完成 . 首先,在SVN存储库中创建一个带有以下内容的 pre-revprop-change 钩子,以允许修改必要的属性:

    #!/bin/bash
    exit 0;
    

    必须使此脚本可执行:

    $ chmod +x svn/project/hooks/pre-revprop-change
    
    • Mercurial创建了SVN存储库的工作副本,名为project-wc,因此切换到它并编辑提交时间:
    $ cd project-wc
    $ svn propedit svn:date --revprop -r 1
    

    输入正确的日期和时间(注意时区!)并保存 . 你应该收到一条消息,说"Set new value for property svn:date on revision 1" .
    现在冲洗并重复每次其他修订 .

    • (可选)检查提交历史记录以确保一切正常:
    $ svn log -r 1:HEAD
    

    然后回到一个级别:

    $ cd ..
    
    • 转储存储库:
    $ svnadmin dump svn/project > project.dump
    
    • 并在Subversion服务器上加载转储 . 完成!

    这个过程可能也会直接在远程存储库之间工作,但我发现使用本地存储库更容易 . 修复提交时间是很多工作,但整体而言,这个过程比我发现的任何其他方法都简单得多 .

  • 0

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

    但这将失去你以前的Git历史 .

  • 0

    我想分享一个名为Scatter的WordPress社区中使用的一个很棒的工具

    Git WordPress plugins and a bit of sanity scatter

    这使用户能够自动将他们的Git存储库发送到wordpress.org SVN . 理论上,此代码可以应用于任何SVN存储库 .

  • 390

    如果您不想将您在Git中提交的每个提交提交到SVN存储库,该怎么办?如果您只是想有选择地向管道发送提交怎么办?好吧,我有一个更好的解决方案 .

    我保留了一个本地Git存储库,我所做的就是从SVN获取和合并 . 这样我可以确保我包含与SVN相同的所有更改,但我将提交历史与SVN完全分开 .

    然后我保留一个单独的SVN本地工作副本,该副本位于单独的文件夹中 . 那是我提交给SVN的那个,我只是使用SVN命令行实用程序那 .

    当我准备将我的本地Git存储库状态提交给SVN时,我只需将整个文件复制到本地SVN工作副本中,然后使用SVN而不是Git从那里提交它 .

    这样我就不必做任何变基,因为变基就像自由基 .

  • 29

    我只想分享一些我接受的答案的经验 . 我做了所有步骤,在我完成最后一步之前一切都很好:

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

    这解决了我的问题 .

  • 27

    Git -> SVN with complete commit history

    我有一个Git项目,不得不把它移到SVN . 这就是我制作它的方式,保留了整个提交历史 . 唯一丢失的是原始提交时间,因为当我们执行 git svn dcommit 时,libSVN将设置本地时间 .

    Howto:

    • 有一个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-git存储库中获取主分支中的信息到当前存储库:
    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
    

    就这样 . 它非常干净,没有黑客攻击,一切都完美无缺 . 请享用 .

  • 8

    另一个有效的序列(每个步骤都有一些评论):

    • 安装 git-svnsubversion 工具包:
    sudo apt-get install git-svn subversion
    
    • 切换 PROJECT_FOLDER
    cd PROJECT_FOLDER
    
    • 在Subversion服务器上创建项目路径(遗憾的是,当前的 git-svn 插件与TortoiseSVN相比存在缺陷) . 它无法将源代码直接存储到 PROJECT_FOLDER 中 . 相反,默认情况下,它会将所有代码上传到 PROJECT_FOLDER/trunk .

    svn mkdir --parents protocol:/// path / to / repo / PROJECT_FOLDER / trunk -m“创建git repo占位符”

    这是路径末端 trunk 的地方 mandatory

    • 初始化 .git 文件夹中的 git-svn 插件上下文
    git svn init -s protocol:///path/to/repo/PROJECT_FOLDER
    

    这是路径末尾 trunk 的地方 unnecessary

    • 获取空的 Subversion 存储库信息
    git svn fetch
    

    此步骤有助于将Subversion服务器与 git-svn 插件同步 . 这是 git-svn 插件 Build remotes/origin 路径并将其与服务器端的 trunk 子文件夹关联的时刻 .

    • Rebase旧Git提交发生在 git-svn 插件参与该进程之前(此步骤为 optional
    git rebase origin/trunk
    
    • 添加要提交的新/已修改文件(此步骤对于Git活动是常规的,并且是 optional
    git add .
    
    • 将新添加的文件提交到本地Git存储库(此步骤为 optional ,仅在使用步骤7时适用):
    git commit -m "Importing Git repository"
    
    • 将所有项目更改历史记录推送到Subversion服务器:
    git svn dcommit
    
  • 7

    我需要将现有的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 属性 .

  • 3

    如果你想继续使用Git作为你的主存储库并且需要不时地修改SVN的修订版,你可以使用Tailor来保持SVN存储库同步 . 它可以复制不同源代码控制系统之间的修订版本,并使用您在Git中所做的更改来更新SVN .

    我没有尝试过Git-to-SVN转换,但是对于SVN - > SVN示例,请参见this answer .

  • 2

    在项目的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 ,你应该完成 . 但是,它会严重搞乱你的提交日期 .

  • 1

    我建议很短使用SubGit在4个命令中的指令 . 有关详细信息,请参阅post .

  • 0

    我也需要这个,并且在Bombe的答案帮助下摆弄一些,我开始工作了 . 这是食谱:

    导入Git - > Subversion

    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 .

  • -1

    以下是我们如何运作:

    在您的计算机上的某个位置克隆您的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
    

    注意:之后我总是废弃该文件夹 .

相关问题