3

在使用 perl 代码库(在分支 maint-5.004 上)时,我观察到以下行为:

bash-3.2$ git 状态 | grep 修改
#修改:配置
bash-3.2$ git reset --hard
HEAD 现在是 9a4fb7e 副本超过 bleads .gitignore
bash-3.2$ git 状态 | grep 修改
#修改:配置
bash-3.2$ git reset --hard
HEAD 现在是 9a4fb7e 副本超过 bleads .gitignore
bash-3.2$ git 状态 | grep 修改
#修改:配置

发生这种情况是因为这两个文件共享一个 inode(它们是同一个文件),但它们在 git 索引中是不同的。我的问题是:这是怎么发生的?如果 git 跟踪到同一个文件的 2 个链接,当只有其中一个被修改时,是否应该期望 git 将其标记为错误?这是 git 错误还是用户错误?

更新:

看来问题不在于 git,而与文件系统(hfs+)的区分大小写有关。

$ mkdir tmp
$ cd 时间
$ touch foo
$ ls -i foo Foo
10301082 富 10301082 富

我认为也许 OS X 需要重新考虑作为一个有用的开发平台,因为这种行为是荒谬的。

4

3 回答 3

1

源代码控制系统通常存在跟踪硬链接的问题。您应该将其中一个设为符号链接并将符号链接添加到 git,它会正常工作。Git 可以很好地处理符号链接。

除非您以某种方式指向源代码控制系统,即您添加到存储库的文件是硬链接,否则它无法知道并且它肯定不会在每次添加时比较所有文件的 inode 来确定是否是案子。

即使允许硬链接的系统也会不惜一切代价避免创建它们,因为硬链接造成的问题数量非常多,并且所有由此产生的错误和不一致都很难跟踪。一段时间后,对其中一个链接进行少量重命名和移动,两个不同的团队可以各自拥有其源树部分中的一个硬链接,然后就对象的版本树的内容发生争执,没有人太聪明关于为什么没有对您的源树部分进行修改,文件内容正在发生变化。最好使用符号链接。

于 2009-12-29T20:31:08.080 回答
0

我不确定 git 是否真的跟踪 inode,它可能只关心文件名。看一下这个示例执行,例如:

$ mkdir so.question
$ cd so.question/
$ git init
Initialized empty Git repository in /tmp/so.question/.git/
$ echo "test" > a
$ ln a b
$ ls -i
539367 a  539367 b
$ git add a b
$ git commit -m"One"
[master (root-commit) 897cdea] One
 2 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 a
 create mode 100644 b
$ echo "test" >> a
$ git add a
$ git commit -m"Two"
[master bbcba39] Two
 1 files changed, 1 insertions(+), 0 deletions(-)
$ ls -i
539367 a  539367 b
$ git reset --hard
HEAD is now at bbcba39 Two
$ ls -i
539367 a  539389 b

请注意,如果我记录了仅对其中一个文件进行更改的提交,git 会记录对文件的更改a并假设b没有更改(如我所料)。就 git 而言,另一个文件没有被修改。如果您稍后执行 git reset,文件 inode 将不再相同,因为它们不同。

我无法重现您报告的行为(硬重置后立即报告 git 状态报告修改),我想知道这是否可能(如果不是因为错误)。你能想出一个小例子来展示你观察到的行为吗?

于 2009-12-29T18:16:09.150 回答
0

对我来说似乎是一个 git bug。据我了解,您从配置到配置进行了硬链接,git 正确地将它们视为单独的实体,但是当一个更改时,它们都应该在 git 索引中更改。

我对这些是硬链接的评估是否正确?

于 2009-12-29T16:15:04.947 回答