注意:fallgamer在 2011 年进行了一些测试(因此它们可能已经过时),以下是他的发现:
运营
- 文件在本地存储库和上游都被更改
git pull
:
无论如何,Git 都会保留本地更改。
因此,您不会意外丢失用任何标志标记的任何数据。
- 带有
assume-unchanged
标志的文件:Git 不会覆盖本地文件。相反,它会输出冲突和建议如何解决它们
- 带有
skip-worktree
标志的文件:Git 不会覆盖本地文件。相反,它会输出冲突和建议如何解决它们
- 文件在本地存储库和上游都发生了更改,无论如何都尝试拉取
使用会导致一些额外的手动工作,但至少如果您有任何本地更改,您不会丢失任何数据。
git stash
git pull
skip-worktree
- 带有
assume-unchanged
标志的文件:丢弃所有本地更改,无法恢复它们。效果就像'<code>git reset --hard'。'<code>git pull' 调用将成功
- 带有
skip-worktree
标志的文件:Stash 不适用于skip-worktree
文件。'<code>git pull' 将失败并出现与上述相同的错误。开发人员被迫手动重置skip-worktree
标志,以便能够存储并完成失败pull
。
- 没有本地更改,上游文件已更改
这两个标志都不会阻止您获取上游更改。Git 检测到你违背了承诺,并选择通过重置标志来反映现实。
git pull
assume-unchanged
- 带有
assume-unchanged
标志的文件:内容已更新,标志丢失。
'<code>git ls-files -v' 将显示该标志已修改为H
(from h
)。
- 带有
skip-worktree
标志的文件:更新内容,保留标志。
'<code>git ls-files -v' 将显示S
与pull
.
- 随着本地文件的更改
,Git 不会触及文件并反映文件的现实(承诺不变的文件实际上已更改)。
git reset --hard
skip-worktree
assume-unchanged
- 带有
assume-unchanged
标志的文件:文件内容被还原。标志重置为H
(从h
)。
- 带
skip-worktree
标志的文件:文件内容完好无损。标志保持不变。
他补充了以下分析:
看:
他总结道:
实际上,这两个标志都不够直观。
assume-unchanged
假定开发人员不应该更改文件。如果一个文件被改变了——那么这个改变并不重要。此标志旨在提高 SDK 等不更改文件夹的性能。
但是如果承诺被破坏并且文件实际上被更改,git 会恢复标志以反映现实。可能在通常不打算更改的文件夹中有一些不一致的标志是可以的。
另一方面skip-worktree
,当您指示 git 永远不要触摸特定文件时很有用。这对于已经跟踪的配置文件很有用。
上游主存储库托管一些生产就绪配置,但您希望更改配置中的一些设置以便能够进行一些本地测试。并且您不想意外检查此类文件中的更改以影响生产配置。在那种情况下skip-worktree
制作完美的场景。
使用 Git 2.25.1(2020 年 2 月),进一步澄清了上面提到的“实际上这两个标志都不够直观”:
请参阅提交 7a2dc95和提交 1b13e90(2020 年 1 月 22 日),作者是brian m。卡尔森 ( bk2204
) .
(由Junio C Hamano 合并gitster
——在提交 53a8329中,2020 年 1 月 30 日)
(Git 邮件列表)
doc
: 劝阻用户不要试图忽略跟踪的文件
签字人:Jeff King
签字人:brian m. 卡尔森
用户想要忽略 Git 跟踪的文件的更改是很常见的。
这种情况的常见场景是 IDE 设置和配置文件,它们通常不应该被跟踪,并且可能使用模板机制从跟踪的文件中生成。
但是,用户了解了假设不变和跳过工作树位并尝试使用它们来执行此操作。
git checkout
这是有问题的,因为当设置了这些位时,许多操作会按照用户的预期进行,但在需要替换文件时它们通常无济于事。
在这种情况下没有明智的行为,因为有时数据很宝贵,例如某些配置文件,有时用户会很乐意丢弃不相关的数据。
由于这不是受支持的配置,并且用户很容易将现有功能误用于非预期目的,从而导致普遍的悲伤和困惑,让我们在文档中记录现有行为和陷阱,git update-index
以便用户知道他们应该探索替代解决方案。
此外,让我们提供一个推荐的解决方案来处理配置文件的常见情况,因为在许多环境中成功使用了众所周知的方法。
git update-index
手册页现在包括:
用户经常尝试使用assume-unchanged
和skip-worktree
位来告诉 Git 忽略对被跟踪文件的更改。这不像预期的那样工作,因为 Git 在执行某些操作时可能仍会根据索引检查工作树文件。一般来说,Git 不提供忽略跟踪文件更改的方法,因此建议使用替代解决方案。
例如,如果您要更改的文件是某种配置文件,则存储库可以包含一个示例配置文件,然后可以将其复制到忽略的名称中并进行修改。存储库甚至可以包含一个脚本,将示例文件视为模板,自动修改和复制它。
最后一部分是我描述的基于 smudge/clean 脚本的典型内容过滤器驱动程序。