解决失败的"git svn clone"(需要完整的历史记录)

Foo*_*ooF 26 svn git git-svn

我想将Subversion存储库子目录(module此处表示)转换为具有完整历史记录的git存储库.svn copy我的Subversion存储库的历史记录中有许多操作(Subversion人们称之为分支).发布策略是每次发布或其他分支创建后,旧URL保持未使用状态,新URL将替换旧URL以包含工作.

最好的是,通过我的阅读,似乎应该这样做:

$ git svn clone --username=mysvnusername --authors-file=authors.txt \
    --follow-parent \
    http://svnserver/svn/src/branches/x/y/apps/module module
Run Code Online (Sandbox Code Playgroud)

(其中branches/x/y/描绘了最新的分支).但我得到一个错误,看起来像这样:

W: Ignoring error from SVN, path probably does not exist: (160013): Filesystem has no item: '/svn/src/!svn/bc/100/branches/x/y/apps/module' path not found
W: Do not be alarmed at the above message git-svn is just searching aggressively for old history.
Run Code Online (Sandbox Code Playgroud)

(更新:添加--no-minimize-url上述选项不会删除错误消息.)

目录module被创建和填充,但是svn copy不会导入超过最新提交的Subversion历史记录(当我预期数百个时,创建的git存储库最终只有两次提交).

问题是,如何在出现这种情况的情况下导出完整的Subversion历史记录?

可能的原因

  1. 搜索错误消息,我发现:git-svn匿名结帐失败,其中-s 链接到此Subversion问题:http://subversion.tigris.org/issues/show_bug.cgi? id = 3242

    我通过阅读理解,Subversion 1.5中的内容改变了客户端如何访问存储库.对于较新的Subversion,如果没有对URL路径的某些超级目录的读访问权(对我来说是真的,svn ls http://svnserver/svn失败了403 Forbidden),那么我们就会失败并进行一些Subversion操作.

  2. Jeff Fairley在他的回答中指出Subversion URL中的空格也可能导致此错误消息(由用户Owen确认).看看他的解决方案,看看他git svn clone是如何解决这个问题,如果你失败了同样的resson.

  3. Dejay Clayton在他的回答中表明,如果branch和tag svn urls中最深的子目录组件具有相同的名称(例如.../tags/release/1.0.0.../branches/release-candidates/1.0.0),则可能会发生此错误.

Dej*_*ton 9

当我在分支或标签中有相同名称的子目录时,我遇到了这个问题.

例如,我有标签candidates/1.0.0releases/1.0.0,因为子目录这引起了记录错误1.0.0出现内都candidatesreleases.

每个git-svn文档:

当使用多个--branches或--tags时,git svn不会自动处理名称冲突(例如,如果来自不同路径的两个分支具有相同的名称,或者分支和标记具有相同的名称).在这些情况下,使用init设置Git存储库,然后在第一次获取之前编辑$ GIT_DIR/config文件,以便分支和标记与不同的名称空间相关联.

因此,由于类似的命名candidatesreleases标记,以下命令失败:

git svn clone --authors-file=../authors.txt --no-metadata \
    --trunk=/trunk --branches=/branches --tags=/candidates \
    --tags=/releases --tags=/tags -r 100:HEAD \
    --prefix=origin/ \
    svn://example.com:3692/my-repos/path/to/project/
Run Code Online (Sandbox Code Playgroud)

以下命令序列确实有效:

git svn init --no-metadata \
    --trunk=/trunk --branches=/branches --tags=/tags \
    --prefix=origin/ \
    'svn://example.com:3692/my-repos/path/to/project/'

git config --add svn-remote.svn.tags \
    'path/to/project/candidates/*:refs/remotes/origin/tags/Candidates/*'

git config --add svn-remote.svn.tags \
    'path/to/project/releases/*:refs/remotes/origin/tags/Releases/*'

git svn fetch --authors-file=../authors.txt -r100:HEAD
Run Code Online (Sandbox Code Playgroud)

请注意,这只能起作用,因为在branches和内部没有其他冲突tags.如果有,我将不得不同样解决它们.

在成功克隆SVN存储库之后,我执行了以下步骤以便:将SVN标记转换为GIT标记; 转trunkmaster; 将其他引用转换为分支; 并重新定位远程路径:

# Make tags into true tags
cp -Rf .git/refs/remotes/origin/tags/* .git/refs/tags/
rm -Rf .git/refs/remotes/origin/tags

# Make other references into branches
cp -Rf .git/refs/remotes/origin/* .git/refs/heads/
rm -Rf .git/refs/remotes/origin
cp -Rf .git/refs/remotes/* .git/refs/heads/ # May be missing; that's okay
rm -Rf .git/refs/remotes

# Change 'trunk' to 'master'
git checkout trunk
git branch -d master
git branch -m trunk master
Run Code Online (Sandbox Code Playgroud)


mli*_*elt 6

不是一个完整的答案,但也许你遗失的片段(我也有兴趣迁移,所以我发现了这个难题的一部分).

当您查看git-svn文档时,您将找到以下选项:

--no-minimize-url 
Run Code Online (Sandbox Code Playgroud)

当跟踪多个目录(使用--stdlayout, - blank或--tags选项)时,git svn将尝试连接到Subversion存储库的根目录(或允许的最高级别).如果整个项目在存储库中移动,则此默认设置允许更好地跟踪历史记录,但可能会导致读取访问限制到位的存储库出现问题.传递--no-minimize-url将允许git svn按原样接受URL,而不尝试连接到更高级别的目录.默认情况下,当仅跟踪一个URL /分支时,此选项处于关闭状态(这样做不太好).

这适合您的情况,因此git svn不会尝试读取更高级别的目录树(将被阻止).

至少你可以尝试一下......