Git SVN指定非标准SVN仓库布局中的分支和标签

3
布局是:
Branches\
    Project1/
        Branch11/
        ...
        Branch1N/
    Project2/
        Branch21/
    ProjectX/   # not anywhere else
Excluded1\
Excluded2\
Excluded3\
Excluded4\
Programs\
    Excluded11\
    ...
    Excluded1N\
    Project1/   # the main one
    Project2/
    ...
    ProjectN/
Tags\
    Project1/
        Release1/
        ...
        Release69/

排除 我已经排除了 - 但我完全不知道如何将分支/标签映射到git分支/标签 - 最好是在事后(每个克隆需要约5小时)。

请记住,我是SVN的新手 - 我不知道也不理解分支/标记系统。

我在windoz上 - svn2git不是选项(无论如何,我对如何在克隆后或最坏情况下仅使用vanilla git进行此操作感兴趣)
此外,我不打算将其作为永久迁移,它将作为SVN和用于开发的新git存储库之间的桥梁运行 - 因此我希望尽可能保留信息 - 但不超过所需。 在某些时候,它可能会变成永久性 - 那时我将需要过滤掉空提交(对于被排除的项目),我猜是这样的(?)

Repo

命令:

$ git svn clone --ignore-paths="^(?:Releases|Projects|Scripts|Games|)/|^Programs/(?:Nif Scanner|Nif Viewer|Raziel23x's Oblivion Toolset|Shader Disasm|Shader Editor)/" --authors-file=authors_with_emails.txt svn://svn.code.sf.net/p/oblivionworks/code/ .

克隆后,我有:

$ git branch -r
  git-svn
$ git branch
* master


概述:我已经克隆了这件事,排除了我想排除的东西 - 现在我想告诉git“为这些svn分支创建一个git分支 - 一个真正的git分支,计算增量并压缩它们并删除Branches文件夹 - 并跟踪它们 - 这个(700 mb)标签目录只是标签 - 你能做些什么(它们不对应提交)?”
我没有看到邪恶的主干

我的config

[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
    hideDotFiles = dotGitOnly
[svn-remote "svn"]
    ignore-paths = ^(?:Releases|Projects|Scripts|Games|)/|^Programs/(?:Nif Scanner|Nif Viewer|Raziel23x's Oblivion Toolset|Shader Disasm|Shader Editor)/
    url = svn://svn.code.sf.net/p/oblivionworks/code
    fetch = :refs/remotes/git-svn
[svn]
    authorsfile = authors_with_emails.txt
[gui]
    wmstate = zoomed
    geometry = 787x377+54+59 305 1127
[remote "github"]
    url = https://github.com/Utumno/wrye_bash_refactoring.git
    fetch = +refs/heads/*:refs/remotes/github/*
[branch "master"]
    remote = github
    merge = refs/heads/master
2个回答

2

对于分支:

在你的git配置文件中,可以控制svn分支的位置:

[svn-remote "svn"]
url = file:///some.url.to/svn/dir
fetch = trunk:refs/remotes/trunk
branches = Branches/*/*:refs/remotes/*

所以你可以设置不同的分支引用。

好的,对于标签也可以进行相同的操作 - 因为在svn中,标签和分支非常相似。

branches = Tags/*:refs/remotes/*

如果你想要“真正的”git标签,没有问题。一旦你将它们引用为分支,你可以再次修改你的git存储库,以便创建良好的git标签引用:

git-for-each-ref refs/remotes/origin/tags | cut -d / -f 5- |
while read ref
do
git tag -a "$ref" -m"say farewell to SVN" "refs/remotes/origin/tags/$ref"
git push origin ":refs/heads/tags/$ref"
git push origin tag "$ref"
done

显然,您需要稍微修改这些脚本以适应您的目的。

会尽快尝试这些 - 与此同时,您能否解释一下脚本实际上是做什么的 - 特别是 [svn-remote "svn"]?他们所指的主干是什么?_这会将“分支”实际压缩到git数据库中并从我的面前消失吗_?如果您查看实际存储库并提供一些示例代码,这将有所帮助(至少对我来说)。您还需要详细说明映射逻辑,我不理解 - 问题在于存储库的结构。添加了配置。 - Mr_and_Mrs_D
我需要在配置文件中创建一个新的部分吗?此外,是否有一种简单的方法可以为每个远程分支检出本地分支并在其上运行 git svn rebase?根据 这里 的说法,这就是我要做的。这会使我的分支“回到”树吗?另请参见这里 - 这些是 fetch 过程中报告的“发现可能的分支点”吗?请稍微更新一下您的答案 - 我将很乐意接受它,但仍然缺乏信息。 - Mr_and_Mrs_D
git与git不同,每个repo的克隆都是一个分叉,这意味着您有对远程存储库的引用,但要开始在本地工作,您必须创建每个分支-但您只需要更改的分支,因此您可以根据需要获取它们,您可以轻松地围绕分支创建命令编写循环以创建所有分支。我认为您想多了解一下git-rebase,除非您想要rebase当前工作分支,否则直接获取后不需要进行rebase。当您获取时,您只会获得引用。 - Michael
谢谢,我了解git - 我想做的是重新创建历史记录 - git足够聪明,可以生成这样的消息:Found possible branch point: svn://svn.code.sf.net/p/oblivionworks/code/Programs/Wrye%20Bash => svn://svn.code.sf.net/p/oblivionworks/code/Branches/Wrye%20Bash/295-fixes, 1667 Initializing parent: refs/remotes/svn-branches/Wrye Bash/295-fixes@1667,所以我正在尝试让其重新创建树。因为这些分支是“无根”的,我相信有一种方法可以将它们“变基”到主分支上。也许我需要重新克隆?当然,标签也是如此 - 目前大小为700 mb。 - Mr_and_Mrs_D
那么如何在克隆之后编辑配置文件,以便将分支映射到正确的项目 - 参见此链接 - Mr_and_Mrs_D
显示剩余6条评论

1

我最近也做了类似的事情。

首先,我不确定为什么您想在从svn转到git后重新排列所有内容。我怀疑这是不可能的。

其次,如果没有svn2git,我不会想过去做这个。我不确定您所提到的Windows问题是什么 - svn2git是用Ruby编写的。如果可以避免,我不会使用Windows,但是如果没有其他办法,肯定有一个适用于Windows的Ruby实现,通过Cygwin等方式。

第三,这是关键,我使用svndumpfilter将svn存储库完全按照我想要的方式(即以svn2git可以轻松消费的形式)获取,然后再进行转换。这需要一些尝试和错误,但最终效果非常好。

请参阅http://svnbook.red-bean.com/en/1.7/svn.reposadmin.maint.html#svn.reposadmin.maint.migratehttp://svnbook.red-bean.com/en/1.7/svn.reposadmin.maint.html#svn.reposadmin.maint.filtering(根据您的SVN版本调整链接)获取更多信息。
编辑:我原本想把这个作为评论,但是它太长了。我认为你能做到的最好的事情就是像这样。
[svn-remote "svn"]
    ignore-paths = ^(?:Releases|Projects|Scripts|Games|)/|^Programs/(?:Nif Scanner|Nif Viewer|Raziel23x's Oblivion Toolset|Shader Disasm|Shader Editor)/
    url = svn://svn.code.sf.net/p/oblivionworks/code
    fetch = Programs/Wrye Bash:refs/remotes/git-svn/Wrye Bash
    branches = Branches/Wrye Bash/*:refs/remotes/git-svn/Wrye Bash/branches/*
    fetch = Programs/Skyrim Viewer:refs/remotes/git-svn/Skyrim Viewer
    fetch = Programs/CBash:refs/remotes/git-svn/CBash
    branches = Branches/CBash/*:refs/remotes/git-svn/CBash/branches/*
# etc.

那就是,对于你感兴趣的每个程序,都需要进行一次fetch,并且如果适用的话,还需要有一个branches行。就像你链接到的答案中所示,你需要在执行git svn fetch之前清除.git/svn/.metadata文件。

但这对我的早期评论没有任何影响:你的git历史仍然是完全线性的,并不反映你项目的实际分支和合并历史。如果你将其作为永久迁移,那么这将不会是你想要的结果。


谢谢你,但3不是一个选项 - 我说过svn2git也不是一个选项 - 毕竟这不是核物理学 - 必须有一种方法可以在git中完成。但我想听听你对第一点的看法 - 为什么不能事后(即克隆后)?我肯定可以在事后添加新分支,那么为什么我不能说“嘿,git,这个branches文件夹只是分支 - 所以吸收它们到你的对象中”? - Mr_and_Mrs_D
谢谢 - 是的,我应该编辑一下问题 - 我的意思是我不想安装cygwin和ruby以及阅读svn2git文档等等 - 我只想通过git来完成。我知道它可以在Windows上完成,但这次我真的宁愿保持原始状态(除了其他原因外,因为我想确切地了解发生了什么)。 - Mr_and_Mrs_D
现在我完全理解git中的分支是什么。但是,看一下问题中的存储库结构-有可能告诉git“嘿,这些是分支,猜猜-它们对应于Programs/Project1/文件中的提交”。我想这涉及到1. @Michael所说的内容(加上...?)2.创建git分支并将它们指向远程和3.希望只运行git svn fetch(或git svn rebase或...)-请参见此处 - Mr_and_Mrs_D
目前的问题是,你得到的git历史记录完全是线性的。你没有告诉git svn clone去哪里查找分支,所以它完全忽略了任何分支或合并。我相当确定(绝对不是100%确定)这必须在git svn clone(或git svn init)时完成。请参阅git svn--follow-parent--trunk--tags--branches--stdlayout选项的文档。 - Steven Collins
那么这个怎么样?我的直觉告诉我肯定是可能的 - 如果不是的话,我就不会浪费我的声望了 - 无论如何,现在我后悔没有使用--prefix - 尽管对于这个也许还不算太晚。 - Mr_and_Mrs_D
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接