git commit 错误信息:无法打开(以前删除的源文件)

kkm*_*kkm 5 git

每次我在该 git 存储库中提交任何内容时,都会收到一条(显然是无害的)错误消息,其中提到了一些不再存在的文件:

$ git commit -a
error: Could not open cssrc/csgrpc/Main.cs
error: Could not open cssrc/csgrpc/Main.cs
Recorded preimage for 'cssrc/csgrpc/Main.cs'
... more 3-line groups like one above ...
[x017-upgrade a86861b] Point Audio to new location of....
 1 file changed, 1 insertion(+), 1 deletion(-)
Run Code Online (Sandbox Code Playgroud)

这些文件最初是子树的一部分,用 维护git subtree -P cssrc ...,我在git subtree pull冲突期间删除了它们,因为在这个项目中不再需要它们(但之前被修改并提交,因此发生冲突)。

这些文件确实既不在索引中也不在工作树中:

$ git ls-files -cs | grep Main.cs
$ find -name 'Main.cs'
$
Run Code Online (Sandbox Code Playgroud)

rerere.enabled选项设置为true。它是罪魁祸首吗?指向这些文件名的卡住指针存储在哪里?如何清洁?

qua*_*rpi 4

错误的来源是 gitrerere或 xe2x80x9creuse 记录的解析 xe2x80x9d 功能。由于您“在”期间删除了它们(您的文件)git subtree pull conflict,因此您无意中将 git 置于“未解决”状态。git rerere尽最大努力保留干净的冲突解决记录,以便以后重复使用。因为您在冲突解决过程中删除了文件,所以您在 中引用了这些文件rerere,导致 git 查找不再存在的文件。了解为了让 git 重用记录的解决方案,它必须记录所涉及的步骤。但是,这并不意味着 git 正在跟踪您使用的命令;而是意味着 git 正在跟踪您使用的命令。这解释了为什么它不知道为什么处于冲突状态的文件在其已解决状态中丢失。它希望您选择该文件的一个版本或另一个版本,而不是完全删除该文件。

\n\n

如果您有兴趣了解更多信息,git rerere我建议您阅读git 手册页

\n\n

如果您对此问题中描述的问题的工作示例以及该问题的解决方案(我确信还有更多)感兴趣,请按照下面列出的步骤操作。我知道它很长,但我不知道还能如何澄清这个问题。

\n\n

在适合测试代码的目录中...

\n\n
    \n
  1. $ mkdir test_rerere
  2. \n
  3. $ cd test_rerere
  4. \n
  5. $ git init
  6. \n
  7. $ cd .git
  8. \n
  9. $ mkdir rr-cache
  10. \n
  11. $ cd ..
  12. \n
  13. 使用以下代码创建一个名为 hello.rb 的文件

    \n\n
    #! /usr/bin/env ruby\n\ndef hello\n  puts \'hello world\'\nend\n
    Run Code Online (Sandbox Code Playgroud)
  14. \n
  15. $ git commit -a -m"added hello.rb"
  16. \n
  17. 使用以下代码创建名为 goodbye.rb 的文件

    \n\n
    #! /usr/bin/env ruby\n\ndef bye\n  puts "goodbye world"\nend\n
    Run Code Online (Sandbox Code Playgroud)
  18. \n
  19. $ git commit -m"added goodbye.rb"
  20. \n
  21. $ git branch i18-world
  22. \n
  23. 将 hello.rb 中的 hello 更改为 Hola
  24. \n
  25. $ git commit -a -m"changed hello to hola in hello.rb"
  26. \n
  27. $ git checkout i18-world
  28. \n
  29. 将 hello.rb 中的 world 更改为 mundo
  30. \n
  31. $ git commit -a -m"changed world to mundo in hello.rb"
  32. \n
  33. 将goodbye.rb中的goodbye更改为ados
  34. \n
  35. $ git commit -a -m"changed goodbye to adios in goodbye.rb"
  36. \n
  37. $ git checkout master
  38. \n
  39. 在goodbye.rb中将世界改变为世界
  40. \n
  41. $ git commit -a -m"changed world to mundo in goodbye.rb"\n现在我们有两个分支,有两个相似但不相同的文件。花一点时间查看两个分支中存在的每个文件。
  42. \n
  43. $ git status应该说

    \n\n
    On branch master\nnothing to commit, working tree clean\n
    Run Code Online (Sandbox Code Playgroud)
  44. \n
  45. $ git merge i18-world
  46. \n
  47. 你应该得到看起来像这样的东西......

    \n\n
    Auto-merging hello.rb\nCONFLICT (content): Merge conflict in hello.rb\nAuto-merging goodbye.rb\nCONFLICT (content): Merge conflict in goodbye.rb\nRecorded preimage for \'goodbye.rb\'\nRecorded preimage for \'hello.rb\'\nAutomatic merge failed; fix conflicts and then commit the result.\n
    Run Code Online (Sandbox Code Playgroud)
  48. \n
  49. 您没有处于冲突状态,并且 rerere 正在执行其工作...请注意上面记录的原像日志。
  50. \n
  51. $ git rerere status返回 goodbye.rb 和 hello.rb,因为正在记录此冲突的两个文件。现在不是尝试的好时机,git rerere diff现在git ls-files -u让我们创建一个错误状态。
  52. \n
  53. 首先,让我们将 hello.rb 解析为 print hola mundo,并且在不提交的情况下,让$ git rm goodbye.rb. 这会导致你的错误。看一下$ git status,goodbye.rb 确实已被删除(尽管 git 抱怨)并且 hello.rb 已被修改并准备合并。
  54. \n
  55. $ git commit -a -m"HUH?"
  56. \n
  57. 请注意,此时您得到的错误与问题中描述的错误完全相同,并且我们也有一个巨大的线索来了解记录的原像位出现时发生的情况。现在让我们确定它是否真的损坏了。
  58. \n
  59. $ git log --oneline --decorate --graph --all查看我们提交历史的漂亮图片。
  60. \n
  61. 将 hello.rb 从“hola mundo”更改为“hola chica bonita!”
  62. \n
  63. $ git commit -a -m"changed \'hola mundo\' to \'hola chica bonita!\' in hello.rb"
  64. \n
  65. 请注意,错误仍然出现,并且我们仍然得到Recorded preimage
  66. \n
  67. $ git rerere status仍然应该返回goodbye.rb,因为它仍然记录在原像中。
  68. \n
  69. $ git rerere diff返回致命错误,因为 goodbye.rb 不存在。
  70. \n
  71. 为了获得清晰的图片,$ git log --oneline --decorate --graph --all
  72. \n
  73. 再次注意,在这种未解决的状态下,git statusgit rerere status不会返回相同的结果。请确保您的工作目录中不存在 goodbye.rb,以确保您的理智。
  74. \n
  75. 现在,让我们通过检查我们在合并之前所做的提交来修复这个讨厌的错误消息。如果您一直遵循提交消息,那么它就是“在 goodbye.rb 中将再见更改为 adios”的消息。我们将使用文件特定的签出(因为我们不想搞乱 hello.rb 中的工作)$ git checkout **yoursha1** goodbye.rb
  76. \n
  77. 验证 hello.rb 未被更改。应该说“hola chica bonita!”。
  78. \n
  79. 大修复! git rerere……哒哒!请注意,git 说“Recorded resolution for \'goodbye.rb\”。
  80. \n
  81. 好吧,如果你不困惑的话,太棒了!一开始这让我很困惑,但后来我想起来了…… rerere 只是渴望重用我已经应用的解决方案。它唯一的抱怨是我从它下面删除了一个文件,并且没有给它机会追上。现在goodbye.rb再次存在,它非常高兴地删除了它一直携带的引用,并生活在一个goodbye.rb不存在的世界中。神奇的是,不再有错误。
  82. \n
  83. 好吧,既然你仍然持怀疑态度,我会向你证明这一点。
  84. \n
  85. $ git checkout i18-world
  86. \n
  87. $ git rebase master
  88. \n
  89. $ git status回报nothing to commit, working tree clean
  90. \n
  91. $ ls返回“hello.rb”,所以我们知道我们已经摆脱了那个讨厌的 goodbye.rb 文件。
  92. \n
  93. $ git log --oneline --decorate --graph --all向我们展示了我们所有的辛勤工作。
  94. \n
  95. $ git rerere status不返回任何内容,因为没有任何内容被跟踪(没有原像)。
  96. \n
  97. $ cat hello.rb向我们展示

    \n\n
    #! /usr/bin/env ruby\n\ndef hello\n  puts \'hola chica bonita!\'\nend\n
    Run Code Online (Sandbox Code Playgroud)
  98. \n
  99. 将 hello.rb 从“hola chica bonita!”更改为“hola chica bonita!” 我爱你”。
  100. \n
  101. $ git commit -a -m"updated hello in hello.rb to say \'hola chica bonita! te amo"
  102. \n
  103. git log --oneline --decorate --graph --all看到i18-world领先于master。
  104. \n
  105. $ git checkout master
  106. \n
  107. $ git merge i18-world
  108. \n
  109. $ git branch应该返回i18-world *master
  110. \n
  111. $ git branch -d i18-world
  112. \n
\n\n

您现在可以确信您的工作目录是干净且没有错误的。另外,如果您需要回到存在“goodbye.rb”的状态,您可以!

\n\n

我对这个答案的长度表示歉意,但希望现在您了解问题出在哪里,以及修复它们是多么容易(至少在这个小示例中)。

\n