当两个指向同一文件的链接不同时,git应该如何表现?

时间:2009-12-29 16:05:04

标签: git macos hfs+

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

bash-3.2$ git status | grep modified
#       modified:   configure
bash-3.2$ git reset --hard
HEAD is now at 9a4fb7e copy over bleads .gitignore
bash-3.2$ git status | grep modified
#       modified:   Configure
bash-3.2$ git reset --hard
HEAD is now at 9a4fb7e copy over bleads .gitignore
bash-3.2$ git status | grep modified
#       modified:   configure

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

更新

问题似乎不是git,而是与文件系统的区分大小写(hfs +)有关。

$ mkdir tmp
$ cd tmp
$ touch foo
$ ls -i foo Foo
10301082 Foo    10301082 foo

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

3 个答案:

答案 0 :(得分:1)

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

除非你以某种方式指向一个源控制系统,你添加到存储库的文件是一个硬链接,它无法知道,它肯定不会比较每个添加的所有文件的inode只是为了找出是否就是这样。

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

答案 1 :(得分:0)

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

我在评估中是否正确认为这些是硬链接的?

答案 2 :(得分: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重置,则文件inode将不再相同。

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