每次我在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(-)
这些文件最初是子树的一部分,由git subtree -P cssrc ...
维护,我在git subtree pull
冲突期间删除了它们,因为这个项目不再需要它们(但之前已经修改过并且已经提交了)因此是一场冲突。)
文件确实既没有在索引中也没在工作树中找到:
$ git ls-files -cs | grep Main.cs
$ find -name 'Main.cs'
$
rerere.enabled
选项设置为true
。这是罪魁祸首吗?指向这些文件名的卡住指针存储在哪里?如何清洁?
答案 0 :(得分:3)
错误来源是git' s rerere
或“重复记录的分辨率”功能。由于您在git subtree pull conflict
"期间删除了它们(您的文件),因此您无意中将git置于"未解决的"州。 git rerere
尽力保持清晰的冲突解决记录,以便以后再使用。因为您在冲突解决过程中删除了文件,所以您在rerere
中引用了这些文件,导致git查找不再存在的文件。了解为了让git重用已记录的分辨率,它必须记录所涉及的步骤。但是,这并不意味着git正在跟踪您使用的命令;这解释了为什么它不知道为什么处于冲突状态的文件在其解析状态中缺失。它希望您选择该文件的一个版本或另一个版本,而不是完全删除文件。
如果您有兴趣详细了解git rerere
,建议您阅读git manual pages。
如果您对此问题中描述的问题的工作示例感兴趣,并且对此问题有解决方案(我确定还有更多问题),请按照下面列出的步骤操作。我知道这很长,但我不知道如何澄清这个问题。
在适合测试代码的目录中......
$ mkdir test_rerere
$ cd test_rerere
$ git init
$ cd .git
$ mkdir rr-cache
$ cd ..
使用以下代码
创建名为hello.rb的文件#! /usr/bin/env ruby
def hello
puts 'hello world'
end
$ git commit -a -m"added hello.rb"
使用以下代码
创建名为goodbye.rb的文件#! /usr/bin/env ruby
def bye
puts "goodbye world"
end
$ git commit -m"added goodbye.rb"
$ git branch i18-world
$ git commit -a -m"changed hello to hola in hello.rb"
$ git checkout i18-world
$ git commit -a -m"changed world to mundo in hello.rb"
$ git commit -a -m"changed goodbye to adios in goodbye.rb"
$ git checkout master
$ git commit -a -m"changed world to mundo in goodbye.rb"
现在我们有两个分支,两个文件相似,但不完全相同。花一点时间查看两个分支中存在的每个文件。 $ git status
应该说
On branch master
nothing to commit, working tree clean
$ git merge i18-world
你应该得到这样的东西......
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Auto-merging goodbye.rb
CONFLICT (content): Merge conflict in goodbye.rb
Recorded preimage for 'goodbye.rb'
Recorded preimage for 'hello.rb'
Automatic merge failed; fix conflicts and then commit the result.
$ git rerere status
返回goodbye.rb和hello.rb,因为这两个文件都是为此冲突而记录的。不是试用git rerere diff
和git ls-files -u
的好时机。现在,让我们创建一个错误状态。hola mundo
,并且不提交,允许$ git rm goodbye.rb
。 这会导致您的错误。看看$ git status
,看看确实已经删除了goodbye.rb(虽然git抱怨)和hello.rb已被修改并准备合并。$ git commit -a -m"HUH?"
$ git log --oneline --decorate --graph --all
可以看到我们提交历史的精彩图片。$ git commit -a -m"changed 'hola mundo' to 'hola chica bonita!' in hello.rb"
$ git rerere status
仍然应该返回goodbye.rb,因为它仍然记录在原像中。$ git rerere diff
返回致命错误,因为goodbye.rb不存在。$ git log --oneline --decorate --graph --all
git status
和git rerere status
在此未解决状态下不会返回相同的内容。验证您的工作目录中不存在goodbye.rb的完整性。$ git checkout **yoursha1** goodbye.rb
使用特定于文件的结帐(因为我们不想在hello.rb中搞乱我们的工作)。git rerere
... Ta Da! 注意 git说记录了' goodbye.rb' $ git checkout i18-world
$ git rebase master
$ git status
返回nothing to commit, working tree clean
$ ls
返回" hello.rb"所以我们知道我们摆脱了那个讨厌的goodbye.rb文件。$ git log --oneline --decorate --graph --all
向我们展示了我们所有的辛勤工作。$ git rerere status
不返回任何内容,因为没有任何内容被跟踪(没有预先映像)。 $ cat hello.rb
告诉我们
#! /usr/bin/env ruby
def hello
puts 'hola chica bonita!'
end
$ git commit -a -m"updated hello in hello.rb to say 'hola chica bonita! te amo"
git log --oneline --decorate --graph --all
看到i18世界领先于大师。$ git checkout master
$ git merge i18-world
$ git branch
应该返回i18-world *master
$ git branch -d i18-world
您现在可以确信您的工作目录是干净且无错误的。此外,如果你需要回到“再见”的状态,那就是'存在,你可以!
我为这个答案的长度道歉,但希望现在你能够理解出错的地方,以及解决问题的方法(至少在这个小例子中)是多么容易。