【问题标题】:Git treats files as unchanged after doing git-add (they disappear from git-status entirely)Git 在执行 git-add 后将文件视为未更改(它们完全从 git-status 中消失)
【发布时间】:2017-04-24 18:59:22
【问题描述】:

我有一个文件看起来与我想要更改的文件相同,但我相信它们的 EOF 是不同的。

我试图通过将以下内容添加到我的.gitattributes 来修复 git 的混乱:

* -text -merge -whitespace

当我用新文件替换文件时,调用git status 时它显示为未暂存的更改。

但是,当我随后执行 git add . -f 时,它们会完全从 git-status 中消失。并且尝试做git commit -a 没有效果。就好像在登台时,git 决定文件根本没有改变。 (我想这很有用,但我怎么能告诉 git 不要忽略 EOF/EOL 等?)

【问题讨论】:

    标签: git eof eol


    【解决方案1】:

    这是正常的(尽管令人沮丧的终端问题令人沮丧)。

    git status 所做的是运行 两个 git diffs。

    第一个差异很简单。它只是将HEAD 提交与索引进行比较。此处显示的任何差异都是“为提交暂存的更改”:索引中的文件与当前提交中的文件不同,因此有一些新的和不同的东西可以提交。

    第二个差异比较棘手,因为 Git 进行了优化。

    原则上,第二个差异很简单:它将索引与工作树进行比较。此处显示的任何差异都是“未为提交暂存的更改”,即您可以git add 将文件复制工作树,索引,替换索引中的任何先前版本。

    但是,这里出现了“优化”以及它与 EOL 转换交互的方式(以及清洁过滤器,如果您使用这些过滤器)。繁荣,现在一切都变得复杂了。 :-)

    当您设置任一一个干净的过滤器 EOL转换(或两者)时,Git 会进行此清理(或转换,这基本上只是一个预编程的表单清理)在您运行 git add 以将文件从工作树复制到索引中时。这有两个棘手的含义:

    1. 索引中的文件确实,字面上,匹配工作树中的文件,然而,此时 Git 应该声称它确实 .
    2. Git 不知道,或者在这一点上甚至关心,清理对文件做了什么。对 Git 来说重要的是索引版本“已知是干净的并且与工作树版本匹配”,因为,好吧,您刚刚添加了它,它必须是干净的并且匹配工作-树版本。

    (我应该在这里提到另一个推论,即:当 Git 从索引工作树中提取文件时,它会应用任何“脏”涂抹过滤器或 EOL 转换。这意味着工作树文件与索引版本不同,然而,因为 Git 刚刚提取它,它应该被视为“干净”——或者至少,索引 = 工作树——就像你git add它,它在进来的时候被清理了。)

    Git 对 index-and-work-tree 的主要优化是保存 stat data,尤其是 mtime(修改时间)时间戳,以便它可以判断您是否已触及工作树版本自上次git add 以来的文件。如果保存的时间戳和其他统计数据都匹配,Git 可以假设工作树版本是“干净的”。

    (文件系统stat操作很慢,所以还有一个优化:Git将目录的stat数据保存在索引中,可以跳过stat-ing 内的文件如果目录 mtime 本身匹配,则目录。幸运的是,这并没有在这里咬你。它对于未跟踪的文件特别有用,使用相对较新的“未跟踪缓存”。不是很相关,只是一个有趣的旁注。)

    除此之外,使用 mtime 还有一个问题。详情请见https://www.kernel.org/pub/software/scm/git/docs/technical/racy-git.txt

    所有这一切的简短版本是,有时git status 故意撒谎。但是,一旦您 git added 文件,如果它没有显示为“暂存提交”,则文件的“清理”版本相同的作为HEAD(当前)提交中的那个。

    您可能想在此处尝试git update-index --refresh。或者,当然,您可以git add 看似修改过的文件,这可以解决问题,但很烦人。

    【讨论】:

    • 感谢您的澄清!这确实提供了丰富的信息。但是,我的意图是将文件更改为新文件,但 git 正在对其进行规范化,我不希望这样做,因为我必须使用从文件中读取的脚本无法正常工作.我试图将文件更改为新文件,但 git 将其视为未更改。所以当我在另一台计算机上克隆时,我得到了旧版本的文件。
    • 鉴于一旦你git add 文件,它没有改变,我怀疑你有问题倒退:它正在被改变在出路,即从 Git 提取到工作树中时。如果您提交 .gitattributes 更新,则 next 克隆会将其视为非文本文件,并且不会在退出时对其进行修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-13
    • 2014-11-25
    • 1970-01-01
    • 2013-07-17
    • 2014-09-16
    • 2011-01-02
    相关资源
    最近更新 更多