git svn - <file>在提交<hash>中未找到

25

在使用git-svn从一个相当大的svn仓库中拉取代码时,我遇到了以下错误消息(由于涉及实际信息,将出现一般性的信息):

Found possible branch point: svn://server/project/trunk/dir => svn://server/project/branches/branchname, <revision>
Initializing parent: refs/remotes/branchname@<revision>
project/trunk/dir/file was not found in commit <hash> (r<revision>)

我在其他帖子中读到,通过一些调整可以“取消获取”此信息。但是,我宁愿不丢失历史记录并尽可能轻松地继续前进。

如何使git-svn fetch继续?


这个答案对我有用:https://dev59.com/XUvSa4cB1Zd3GeqPeXTq - 执行 git svn reset -r <previous> 然后执行 git svn fetch - the_mandrill
7个回答

34
这很可能意味着你正在接收一个新的svn修订版,该修订版修改了一个在你的git提交等价物中不存在的文件(由于某种原因)。造成这种情况的一种非常简单的方法是在--ignore-paths方面不一致(最初没有办法配置它们,必须在可能获取的每个git-svn命令行上输入)。另一种方式是,svn服务器端的某个人以这样的方式更改存储库权限,以致于(从您的角度)整个子树的文件突然出现在您的git存储库中,但您的git存储库对此没有历史记录。

解决这个问题并继续执行git-svn fetch的最简单方法是使用--ignore-paths(或更好的svn-remote.svn.ignore-paths配置条目)来忽略树的问题部分。你可以通过命令行参数传递单个版本,并且在svn端有人修改它之前你不会再次遇到这个问题。

如果你想恢复而不使用--ignore-paths,那么你需要修复父修订版,使其包括被修改的文件。我专门编写了git-svn reset,以便以较少的改动来执行你所提到的“未获取”操作。它可以将你的svn远程重置回文件实际创建的位置,以便你可以将其集成到你的历史记录中。这不会清除你的工作副本,但你需要将任何工作分支重新父配到这个新的历史记录上。


2
当我运行 git svn dcommit 时,正好有其他人提交到 SVN,这种情况发生在我身上。当进行变基操作时,git 变得非常困惑,并创建了一个提交对象,其中树仅包含本地提交修改的文件,因此看起来整个工作目录的内容都消失了。我能够使用 git svn reset 来重新获取错误的版本。 - dOxxx
我遇到了这个问题,因为我有一个带有umlaut的文件。幸运的是只有一个文件,所以我像你建议的那样使用svn-remote.svn.ignore-paths配置项来忽略这个单独的文件,它起作用了。 - CodeStage
@CodeStage:另一种解决umlaut问题的替代方法,而不是简单地忽略树的这一部分,可以参考这个答案 - zb226
@BenJackson 假设我无法重写git历史记录,有没有办法解决这个问题?最近一个新文件夹被公开使用,但是它的历史记录追溯到几千个修订版本之前/创建git-svn镜像之前。我尝试手动提交最接近公开版本的文件,然后运行git svn fetch继续同步,但是我得到了相同的错误。 - HeroCC
我能够找到一个解决方法,它不需要重写历史记录或忽略这个问题。可能有更好的方法,但在未知之前,我在下面发布了我的解决方案。 - HeroCC
显示剩余4条评论

2
一个快速的解决方案是重置到一个相对早于问题版本的修订版本。
git svn reset <a past revision>

例如,当错误消息提到r1000时,运行git svn reset r990等命令。
然后运行git svn rebasegit svn fetch命令。

2

好的,我曾经为此苦苦挣扎,但找到了一个解决方法。您将失去当前git仓库版本之前文件的历史记录,但历史记录将保持完整,而且您不必使用--ignore-paths。如果重写历史是一种选择,您应该遵循Ben Jackson的git svn resetanswer

假设您在r123上,并且没有访问scripts/文件夹,该文件夹是在r100中创建的。在某个时候,您被授予访问权限。这实际上不会生成修订版本,在SVN中是可以接受的,但在git中,它有效地重写了历史记录。git-svn仓库继续正常更新,直到修改了scripts/中的某些内容(我们称之为r126)。现在git svn fetch失败了,因为它不知道该怎么办——它有一个文件的差异,但该文件不存在!

我解决问题的方法如下:

# Clone the directory that is missing one revision before it is next changed
$ svn co -r 125 https://your-server/svn/bla/scripts

# copy the contents and (-p)reserve their attributes
$ cp -pr scripts/* ~/your-git-svn-mirror-on-r125ish/scripts

# Get the git-svn-id of the the most recent commit
$ cd ~/your-git-svn-mirror-on-r125ish
$ git log -1 | grep git-svn-id
git-svn-id: https://your-server/svn/bla/trunk@125 7b6d...daf

那个git-svn-id是问题的关键。它告诉git-svn每个修订版本映射到哪个提交。我们要欺骗它,让它认为我们手动提交的实际上是一个SVN提交。
# Add the missing new directory
$ git add scripts/

# An editor will open up, type a message warning this commit isn't a real svn revision
# The last line of your message should be the 'git-svn-id' from earlier.
$ git commit
<your message of warning>
git-svn-id: https://your-server/svn/bla/trunk@125 7b6d...daf

现在应该有另一个提交,将文件恢复到更新前的一个提交。最后,我们需要让git-svn重新构建历史记录,并注意我们的新提交。
# Backup the svn state in case something goes wrong
$ mv .git/svn .git/svn-BACKUP

# Cross your fingers, and fetch the changes from svn
# If your repo is large, it may take a long time to rebuild the mappings
$ git svn fetch

如果一切按计划进行,您应该拥有一个包含新文件的repo,而无需重写历史记录。您可以安全地使用git svn rebasegit push。虽然可能不是最优美的解决方案,但在git version 2.17.1中有效。

提醒一下,虽然我已经好几年没用过 git-svn 了,但是我记得那个 git-svn-id 的注释只有在 .git/svn 目录的索引丢失时才会被使用。因此,如果你需要加快这个工作流程的速度,你可以尝试更新索引而不是强制从头开始重建它。 - Ben Jackson

2
当仓库设置了svn:externals urls,而我的--ignore-paths正则表达式将其过滤掉时,从git svn fetch中出现了这个错误。

1
我遇到了一个问题,涉及到包含Unicode字符的目录名称,尽管错误抱怨特定文件在目录中。我尝试了以下命令:git svn fetch --ignore-paths path/up/to/filename,其中包括文件的完整路径,但没有起作用。尝试使用包含Unicode字符的目录的完整路径也不行。最终有效的命令是使用包含Unicode字符的目录的父目录,如下所示:
git svn fetch --ignore-paths path/up/to/but-not-including-unicode-chars

1

在Windows系统中,文件名中包含特殊字符(如umlauts)时出现了相同的错误:

(...)
r36770 = 24d589b34b952dd13ee8d231e7ce4d675ec1a82c (refs/remotes/origin/xxx)
    M   doc/specification/xxx/2013 03 07 Workflows.xls
xxx/branches/xxx/doc/specification/xxx/2013 03 07 München.xls 
    was not found in commit 24d589b34b952dd13ee8d231e7ce4d675ec1a82c (r36770)

这个文件确实在引用的版本中,但是git svn无法看到它。

我通过设置语言和区域环境变量来解决了这个问题,像这样:

SET LANG=C
SET LC_ALL=C

在运行git svn之前,您可以简单地执行这些命令,但它们只会在当前shell存在的时间内持续存在。如果您想永久设置它们,请前往控制面板>系统>高级系统设置>环境变量。


1

对于较新的MacOSX系统进行配置

git config --global core.precomposeunicode false

"

, 对于旧版 true。 在这里解释:

"

https://michael-kuehnel.de/git/2014/11/21/git-mac-osx-and-german-umlaute.html

正确设置配置选项后,我能够使用svn2git(它在底层使用git svn)导入SVN存储库。

我还遇到了

$ locale
LANG="de_DE.UTF-8"
LC_COLLATE="de_DE.UTF-8"
LC_CTYPE="de_DE.UTF-8"
LC_MESSAGES="de_DE.UTF-8"
LC_MONETARY="de_DE.UTF-8"
LC_NUMERIC="de_DE.UTF-8"
LC_TIME="de_DE.UTF-8"
LC_ALL="de_DE.UTF-8"

但我怀疑这并没有什么区别。


非常感谢,这很有帮助。如果您不想开始忽略多个问题路径,那么这非常有用! - Jean-Philippe Pellet

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