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

发布于 2024-08-16 10:41:23 字数 760 浏览 6 评论 0原文

我在使用 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 需要重新考虑作为一个有用的开发平台,因为这种行为是荒谬的。

I observed the following behavior while working with the perl code base (on branch 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

This is happening because the two files share an inode (they are the same file), but they are different in the git index. My question is: how did that happen? If git is tracking 2 links to the same file, should git be expected to flag it as an error when only one of them is modified? Is this a git bug or user error?

Update:

It appears that the issue is not with git, but is related to case sensitivity of the filesystem (hfs+).

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

I think perhaps that OS X needs to reconsidered as a useful platform for development, as this behavior is absurd.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

-黛色若梦 2024-08-23 10:41:23

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

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

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

Source control systems generally have problem tracking hardlinks. You should have made one of them a symlink and add the symlink to git and it would work fine. Git can handle symlinks fine.

Unless you would somehow point to a source control system that a file you add to repository is a hardlink, it has no way to know and it certainly won't go comparing inodes of all files on every add just to find out if that is the case.

Even systems that do allow hardlinks try to avoid creating them at all costs, since the number of problems created by hardlinks is quite high and all the resulting bugs and inconsistencies are very hard to track. After a while and few renames and moves of one of the links, two different teams could each own one piece of the hardlink in their part of source tree and a fight over the content of the version tree of the object ensues with nobody being too wise about why with no modifications done to your part of source tree a file content is changing. It's better to use symbolic links.

め七分饶幸 2024-08-23 10:41:23

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

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

Seems like a git bug to me. As I understand it you made a hardlink from Configure to configure and git is properly seeing them as separate entities but when one changes they should both change in the git index.

Am I correct in the assessment that these are hardlinked?

梦回旧景 2024-08-23 10:41:23

我不确定 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 status 的修改),我想知道这是否可能(如果不是错误)。你能举一个小例子来展示你观察到的行为吗?

I'm not sure git actually tracks inodes, it probably only concerns itself with file names. Take a look at this sample execution, for instance:

$ 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

Notice that if I record a commit with changes to only one of the files, git records a change to the file a and assumes b wasn't changed (as I would expect). As far as git is concerned, the other file wasn't modified. If you later do a git reset, the file inodes will no longer be the same as they differ.

I wasn't able to reproduce the behaviour you reported (git status reporting modifications right after a hard reset) and I wonder if this is even possible (if not for a bug). Can you come up with a small example that shows the behaviour you observed?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文