2

免责声明:我不是在寻求解决方案、变通方法或任何关于如何做事的建议,我只是对 Mercurial 的内部结构感到好奇。

我有一个 mercurial 存储库,其中包含一些子存储库(Git 和 Mercurial)。

  1. 我的存储库和所有子存储库都处于干净状态(即:hg st -S不返回任何内容)。
  2. 我在根目录进行了一些激进的权限更改:chown www-data:www-data -R *

现在,hg st -S返回 Git 子存储库的每个文件(Mercurial 仍然被认为是“干净的”)作为修改。的输出hg diff -S -g为空。我想知道为什么会这样?

到目前为止我发现了什么:

  1. 如果我git status在其中一个子存储库中执行操作,则该命令不会显示未完成的修改,并且此特定存储库不再被标记为已hg st修改
  2. 如果我将权限更改限制为子存储库,则只有此子存储库被标记为已修改(即“问题”未链接到.hg目录中文件的状态)
  3. 做一个干净的更新(hg up -C)“解决”问题
  4. 如果我仅在.git目录中更改权限,则 subrepo 仍然被认为是干净的
  5. hg --debug up -C标记为已修改的 Git 子存储库的输出不同:

“干净” git subrepo :

subrepo/git1: git config --bool core.bare 
subrepo/git1: git rev-parse HEAD
subrepo/git1: git diff-index --quiet HEAD

“修改” git subrepo :

subrepo/git2: git config --bool core.bare
subrepo/git2: git rev-parse HEAD
subrepo/git2: git diff-index --quiet HEAD
  subrepo subrepo/git2: other changed, get git://github.com/XXXX/YYYY.git:6f2442d36bb44724af116b97c85d2e344fc9a0a2:git
subrepo/git2: git cat-file -e 6f2442d36bb44724af116b97c85d2e344fc9a0a2
subrepo/git2: git config --bool core.bare
subrepo/git2: git rev-parse HEAD
subrepo/git2: git reset HEAD
subrepo/git2: git reset --hard HEAD

所以,据我所知,元数据中的权限更改不是这里的原因,那是什么?我可能只是错过了一些非常简单的东西。

仅供参考,我使用的是 1.9.3 版本,我不记得我是否在以前的版本上发表过相同的评论。

在有人提议我停止像这样进行权限更改之前,我已经这样做了,而且我不再面临这个问题,只是我想了解为什么会发生某些事情;)

更新

运行git diff-index HEAD给出以下输出:

[...]
:100644 100644 fef0f187a5eabc82dc1a90661bd86d317114e40e 0000000000000000000000000000000000000000 M      my/file/insubrepo.php
[...]

如果我运行git diff-index -p HEAD,差异是空的。我仍然不知道为什么 git 会考虑修改这些文件。

4

1 回答 1

2

可能的问题(有潜在的解决方案):

更改文件模式将更改相对于 Git 索引的文件统计信息(如此所述)。

要纠正问题,请尝试:

  1. 导航到您的 Git sburepo
  2. git update-index --refresh

那应该可以修复文件统计信息变脏。


Mercurial内部的背景信息:

为了确定 Git 子存储库是否脏(即有本地修改),Mercurial 运行git diff-index --quiet HEAD.

dirty方法subrepos.py::gitsubrepo

我希望在您更改权限后,git diff-index显示您手动执行git status没有的更改。

的输出git diff-index格式如下(详见手册页):

:<mode before> <mode after> <status> <file>

鉴于您上面列出的输出,这表示:“文件my/file/insubrepo.php已在工作副本中修改,但文件模式相同”。

于 2011-11-17T20:24:39.947 回答