使用reposurgeon将SVN存储库转换为git,而不创建.gitignore文件?

3
我使用reposurgeon将我的svn转换为git存储库,链接在这里:(如何使用reposurgeon将svn repo转换为git?)。
问题是,转换后的标签出现在创建标签的位置而不是它们所属的修订版本位置。在SVN中,无论我何时创建标签,它们都会显示在它们应该出现的日志右侧。
似乎这与reposurgeon在每个标签中添加一个.gitignore提交有关,看起来像这样:
# A simulation of Subversion default ignores, generated by reposurgeon.
*.o
*.lo
...
*.pyo
*.rej
*~
.#*
.*.swp
.DS_store
# The contents of the svn:ignoreproperty on the branch root.
*~
nbproject
*.project

我该如何让reposurgeon不在所有标签中为gitignore创建这样的提交?并让它创建简单的标签,这些标签不会出现在时间线上作为提交? reposurgeon手册中说:
用户生成的.gitignore 这个消息意味着reposurgeon在分析的Subversion仓库中找到了.gitignore文件。这可能是因为有人正在使用git-svn作为实时网关,并创建了一些忽略文件,这些文件可能与将被转换为Subversion忽略属性的生成的.gitignore文件中的文件相符,也可能不相符。您需要就使用哪个忽略集合做出决策,并可能删除生成的.gitignore文件或用户创建的文件。
但没有例子说明如何做出这个决定。我该如何管理这个问题?

你可能需要使用 git-filter-branch 进行一些额外的“手术”来使转换后的存储库看起来符合你的要求。可以做一些像完全从历史记录中删除文件、编辑历史记录中的文件、移动标签等操作,但很难对此提供通用答案。 - 6EQUJ5
主要问题似乎是,SVN已经与git一起使用了,这导致了.gitignore文件的创建。 - rubo77
4个回答

2
在阅读您的Subversion仓库后,只需添加以下内容:
expunge /gitignore/

这将删除reposurgeon自动添加的所有.gitignore文件。


expunge似乎删除了所有.gitignore文件,这太好了!但现在中间有成百上千个空提交:http://i.stack.imgur.com/ZdXEQ.png 我能把它们也清除掉吗? - rubo77
它们实际上是空提交,还是只是名为“emptycommit”的标签? - Tom Mayfield
我不知道。但是截图显示了它们:http://i.stack.imgur.com/ZdXEQ.png 我怎么能找到更多关于它们的详细信息?我通常使用smartGit/hg。 - rubo77
@rubo77:不,它会在没有另一个提交的情况下将它们删除。也就是说,它看起来好像这些文件从未存在过。但要注意,您可能会因此引入不一致性。 - 0xC0000022L
@rubo77:显然要用/^emptycommit-/n delete ;) (n是用来查找“名称”,比如标签 - 这些实际上默认是在expunge之后的标签) - 0xC0000022L
显示剩余4条评论

2
您需要就在转换中使用哪个忽略集做出策略决定,并可能删除生成的.gitignore文件或用户创建的文件之一。如果您在转换之前有一个.gitignore文件,请将其与转换后的文件进行比较。这似乎与您的“提交顺序”问题无关,对吧?基本上,策略问题只是“获得您喜欢的最终.gitignore”。要达到目标,请尽一切办法。在git中,.gitignore文件的管理方式与任何其他文件完全相同。因此,您可以说git log .gitignore,并查看哪些提交对其做出了贡献。假设整个.gitignore文件是10个提交块之前提交的,并且您希望将其分开。如果是这样,您可以执行git rebase --interactive HEAD~11编辑相关提交。对于每行您想要拆分的内容,执行git add --partial .gitignore; git commit。然后执行git rebase --continue以结束操作。如果您希望每个新列出的提交都成为它们对应的更大代码提交的一部分,则需要再次进行交互式变基以重新排列顺序并将它们与其合作伙伴提交压缩在一起。如果这听起来像是不必要的工作,那么这可能确实是这样。如果可以的话,我建议您关注存储库最终状态的完整性,而不是历史记录的完美表达。注意:我不理解您在此上下文中使用“标签”一词的含义,因为SVN和git都有“标签”,但您似乎没有涉及其中任何一个。也许“忽略行”或“条目”会更清晰。要在版本控制中清除历史记录很困难。在所有分支上更改历史记录实际上是创建一个新存储库,因为对于任何内容(每个人都必须进行变基),都不再存在向下游追随者的连续性。但是,如果您想要这样做,请针对每个分支查找文件系统中的所有.gitignore文件,并查看哪些提交触及了它们。
  git log `find . -name .gitignore`

你可以按照上面所述的步骤使用rebase --interactive来更改这些提交。如果提交只影响到.gitignore文件,那么你可以将其删除。但是,如果提交涉及到100个文件,包括.gitignore,则必须将好的和坏的分开。

另外,如果您知道所有.gitignore文件的路径(在每个分支上检出并运行上面的find命令),那么您可以使用filter-branch,就像github文档中所述

git filter-branch --force --index-filter      \
 'git rm --cached --ignore-unmatch .gitignore path/to/other/.gitignore'  \
 --prune-empty --tag-name-filter cat -- --all

他们还提到了一个BFG Java工具,但是filter-branch应该可以满足您的需求。

我不想要任何.gitignore文件。svn没有这些文件,它们只会在这里搞乱事情。当我完成转换时,我会创建一个(仅一个!)。 - rubo77
我所说的标签是版本标签。它们是一种标准。有分支和标签。标签通常不包含提交。但在我的转换之后,它们都包含了一个空提交和这个gitignore文件。 - rubo77
你能否提供一个示例,演示如何从整个历史记录中的所有分支和标签中删除所有.gitignore文件? - rubo77
已添加。最后一个示例可能是您想要的。 - Joe Atzberger
你可以使用 find 命令在代码库中查找所有 .gitignore 文件,并将其传递给以下命令:git filter-branch --force --index-filter "git rm --cached --ignore-unmatch $(find . -name .gitignore|xargs )" --prune-empty --tag-name-filter cat -- --all - rubo77
你应该将“Alternative”移动到你的答案顶部,因为这是一个可接受的工作量。你的其他提示很好,但使用百分之几的标签和分支会产生太多的工作量。 - rubo77

0

0

@robrich

我是reposurgeon的作者。不要使用git-svn进行转换!那是一个灾难区域。请参阅此公告:

http://esr.ibiblio.org/?p=6778


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