注:fallengamer在2011年做了一些测试(所以它们可能已经过时了),以下是他的发现:
操作
文件在本地存储库和上游都被更改
git拉:
Git无论如何都会保留本地更改。
因此,您不会意外地丢失使用任何标志标记的任何数据。
带有assume-unchanged标志的文件:Git不会覆盖本地文件。相反,它将输出冲突和如何解决冲突的建议
带有skip-worktree标志的文件:Git不会覆盖本地文件。相反,它将输出冲突和如何解决冲突的建议
File is changed both in local repository and upstream, trying to pull anyway
git stash
git pull
Using skip-worktree results in some extra manual work but at least you wouldn’t lose any data if you had any local changes.
File with assume-unchanged flag: Discards all local changes without any possibility to restore them. The effect is like ‘git reset --hard’. ‘git pull’ call will succeed
File with skip-worktree flag: Stash wouldn’t work on skip-worktree files. ‘git pull’ will fail with the same error as above. Developer is forced to manually reset skip-worktree flag to be able to stash and complete the failing pull.
没有本地更改,上游文件已更改
git拉
这两个标志都不会阻止您获得上游更改。Git检测到您违反了假设不变的承诺,并选择通过重置标志来反映现实。
带有assume-unchanged标志的文件:内容被更新,标志丢失。
' git ls-files -v '将显示该标志被修改为H(从H)。
带有skip-worktree标志的文件:更新内容,保留标志。
' git ls-files -v'将显示与pull之前相同的S标志。
修改了本地文件
Git重置——很难
Git不涉及跳跃式工作树文件,并反映了假设不变文件的现实(承诺不变的文件实际上已被更改)。
带有assume-unchanged标志的文件:恢复文件内容。标志被重置为H(从H)。
带skip-worktree标志的文件:文件内容完整。旗帜保持不变。
他补充了以下分析:
看起来skip-worktree正在非常努力地保存本地数据。但如果安全的话,它不会阻止您进行上游更改。而且少不更事者不会在拉扯时重置标志。
但忽略“reset—hard”命令可能会让开发人员大吃一惊。
假设-unchanged标志可能会在pull操作中丢失,而这些文件中的本地更改对git来说似乎并不重要。
See:
Junio's (current git maintainer) comment regarding intent of assume-unchanged,
In particular, Junio points out that changes to assume-unchanged files could accidentally be committed: "if Git can determine a path
that is marked as assume-unchanged has changed without incurring
extra lstat(2) cost, it reserves the right to report that the path
has been modified (as a result, git commit -a is free to commit
that change)."
difference between assume-unchanged and skip-worktree as discussed in git mailing list upon addition of skip-worktree patch.
他的结论是:
实际上,这两个标志都不够直观。
assume-unchanged assumes that a developer shouldn’t change a file. If a file was changed – then that change is not important. This flag is meant for improving performance for not-changing folders like SDKs.
But if the promise is broken and a file is actually changed, git reverts the flag to reflect the reality. Probably it’s ok to have some inconsistent flags in generally not-meant-to-be-changed folders.
On the other hand skip-worktree is useful when you instruct git not to touch a specific file ever. That is useful for an already tracked config file.
Upstream main repository hosts some production-ready config but you would like to change some settings in the config to be able to do some local testing. And you don’t want to accidentally check the changes in such file to affect the production config. In that case skip-worktree makes perfect scene.
在Git 2.25.1(2020年2月)中,上面提到的“实际上两个标志都不够直观”得到了进一步的澄清:
参见brian m. carlson (bk2204)的commit 7a2dc95, commit 1b13e90(2020年1月22日)。
(由Junio C Hamano—gitster—在commit 53a8329,2020年1月30日合并)
(Git邮件列表)
doc: dissuade users from trying to ignore tracked files
Signed-off-by: Jeff King
Signed-off-by: brian m. carlson
It is quite common for users to want to ignore the changes to a file that Git tracks.
Common scenarios for this case are IDE settings and configuration files, which should generally not be tracked and possibly generated from tracked files using a templating mechanism.
However, users learn about the assume-unchanged and skip-worktree bits and try to use them to do this anyway.
This is problematic, because when these bits are set, many operations behave as the user expects, but they usually do not help when git checkout needs to replace a file.
There is no sensible behavior in this case, because sometimes the data is precious, such as certain configuration files, and sometimes it is irrelevant data that the user would be happy to discard.
Since this is not a supported configuration and users are prone to misuse the existing features for unintended purposes, causing general sadness and confusion, let's document the existing behavior and the pitfalls in the documentation for git update-index so that users know they should explore alternate solutions.
In addition, let's provide a recommended solution to dealing with the common case of configuration files, since there are well-known approaches used successfully in many environments.
git更新索引手册页现在包括:
Users often try to use the assume-unchanged and skip-worktree bits to tell Git to ignore changes to files that are tracked.
This does not work as expected, since Git may still check working tree files against the index when performing certain operations.
In general, Git does not provide a way to ignore changes to tracked files, so alternate solutions are recommended.
For example, if the file you want to change is some sort of config file, the repository can include a sample config file that can then be copied into the ignored name and modified.
The repository can even include a script to treat the sample file as a template, modifying and copying it automatically.
最后一部分是我描述的基于smudge/clean脚本的典型内容过滤器驱动程序。