本文共 7939 字,大约阅读时间需要 26 分钟。
本文翻译自:
I have local changes to a file that I don't want to commit to my repository. 我对一个我不想提交到我的存储库的文件进行了本地更改。 It is a configuration file for building the application on a server, but I want to build locally with different settings. 它是用于在服务器上构建应用程序的配置文件,但我想在本地使用不同的设置进行构建。 Naturally, the file always shows up when i do 'git status' as something to be staged. 当然,当我将'git status'作为要上演的东西时,该文件总是显示出来。 I would like to hide this particular change and not commit it. 我想隐藏这个特定的更改而不是提交它。 I won't make any other changes to the file. 我不会对文件进行任何其他更改。
After some digging around, I see 2 options: 'assume-unchanged' and 'skip-worktree'. 经过一番挖掘后,我看到了两个选项:'假设未改变'和'跳过工作树'。 A previous question talks about them but doesn't really explain their differences. 的前一个问题谈到了它们,但并没有真正解释它们之间的区别。 My question is this: how are the two commands different? 我的问题是:这两个命令有何不同? Why would someone use one or the other? 为什么有人会使用其中一个?
参考:
You want skip-worktree
. 你想要skip-worktree
。
assume-unchanged
is designed for cases where it is expensive to check whether a group of files have been modified; assume-unchanged
是针对检查一组文件是否已被修改的情况而设计的; when you set the bit, git
(of course) assumes the files corresponding to that portion of the index have not been modified in the working copy. 当您设置该位时, git
(当然)假定在工作副本中尚未修改与该索引部分对应的文件。 So it avoids a mess of stat
calls. 所以它避免了一堆乱的stat
调用。 This bit is lost whenever the file's entry in the index changes (so, when the file is changed upstream). 只要索引中的文件条目发生更改(因此,当文件在上游更改时),此位就会丢失。
skip-worktree
is more than that: even where git
knows that the file has been modified (or needs to be modified by a reset --hard
or the like), it will pretend it has not been, using the version from the index instead. skip-worktree
:即使git
知道文件已被修改(或需要通过reset --hard
等修改),它也会假装它没有使用,而是使用索引中的版本。 This persists until the index is discarded. 这将持续到索引被丢弃。
There is a good summary of the ramifications of this difference and the typical use cases here: . 这里有一个很好的总结分歧和典型用例: : 。
From that article: 从那篇文章:
--assume-unchanged
assumes that a developer shouldn't change a file. --assume-unchanged
假定开发人员不应更改文件。 This flag is meant for improving performance for not-changing folders like SDKs. 此标志用于提高 SDK等不可更改文件夹的性能 。 --skip-worktree
is useful when you instruct git not to touch a specific file ever because developers should change it. --skip-worktree
当你指示git不要触摸特定文件时, --skip-worktree
非常有用,因为开发人员应该更改它。 For example, if the main repository upstream hosts some production-ready configuration files and you don't want to accidentally commit changes to those files, --skip-worktree
is exactly what you want. 例如,如果主存储库上游托管了一些生产就绪配置文件,并且您不想意外地提交对这些文件的更改,那么--skip-worktree
正是您想要的。 Note: did some tests in 2011 (so they may be outdated), and here are his : 注意: 在2011年进行了一些测试(因此它们可能已经过时),以下是他的 :
Operations 操作
git pull
: git pull
: Git preserves local changes anyway. 无论如何,Git都会保留本地更改。 Thus you wouldn't accidentally lose any data that you marked with any of the flags. 因此,您不会意外丢失任何标记有任何标志的数据。 assume-unchanged
flag: Git wouldn't overwrite local file. 带有assume-unchanged
标志的文件:Git不会覆盖本地文件。 Instead it would output conflicts and advices how to resolve them 相反,它会输出冲突并建议如何解决它们 skip-worktree
flag: Git wouldn't overwrite local file. 带有skip-worktree
标志的文件:Git不会覆盖本地文件。 Instead it would output conflicts and advices how to resolve them 相反,它会输出冲突并建议如何解决它们 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. 使用skip-worktree
导致一些额外的手动工作,但如果您有任何本地更改,至少不会丢失任何数据。 assume-unchanged
flag: Discards all local changes without any possibility to restore them. 带有assume-unchanged
标志的文件:放弃所有本地更改,而无法恢复它们。 The effect is like ' git reset --hard
'. 效果就像' git reset --hard
'。 ' git pull
' call will succeed ' git pull
'电话会成功 skip-worktree
flag: Stash wouldn't work on skip-worktree
files. 带有skip-worktree
标志的文件:Stash不适用于skip-worktree
文件。 ' git pull
' will fail with the same error as above. ' git pull
'将失败并出现与上述相同的错误。 Developer is forced to manually reset skip-worktree
flag to be able to stash and complete the failing pull
. 开发人员被迫手动重置skip-worktree
标志,以便能够存储并完成失败的pull
。 git pull
Both flags wouldn't prevent you from getting upstream changes. 这两个标志都不会阻止您获得上游更改。 Git detects that you broke assume-unchanged
promise and choses to reflect the reality by resetting the flag. Git检测到你打破了assume-unchanged
承诺,并选择通过重置标志来反映现实。 assume-unchanged
flag: Content is updated, flag is lost. 带有assume-unchanged
标志的文件:内容已更新,标志丢失。 ' git ls-files -v
' would show that flag is modified to H
(from h
). ' git ls-files -v
'会显示该标志被修改为H
(来自h
)。 skip-worktree
flag: Content is updated, flag is preserved. 带有skip-worktree
标志的文件:内容已更新,标志已保留。 ' git ls-files -v
' would show the same S
flag as before the pull
. ' git ls-files -v
'将显示与pull
之前相同的S
标志。 git reset --hard
Git doesn't touch skip-worktree
file and reflects reality (the file promised to be unchanged actually was changed) for assume-unchanged
file. Git没有触及skip-worktree
文件并且反映了assume-unchanged
文件的实际情况(承诺实际上未更改的文件已更改)。 assume-unchanged
flag: File content is reverted. 带有assume-unchanged
标志的文件:还原文件内容。 Flag is reset to H
(from h
). 标志重置为H
(从h
)。 skip-worktree
flag: File content is intact. 带有skip-worktree
标志的文件:文件内容完好无损。 Flag remains the same. 国旗保持不变。 He adds the following analysis: 他补充以下分析:
It looks like skip-worktree
is trying very hard to preserve your local data . 看起来像skip-worktree
正在努力保存您的本地数据 。 But it doesn't prevent you to get upstream changes if it is safe. 但是,如果它是安全的,它不会阻止您获得上游更改。 Plus git doesn't reset the flag on pull
. 加上Git并不重置旗pull
。
reset --hard
' command could become a nasty surprise for a developer. 但忽略' reset --hard
'命令可能会成为开发人员的一个令人讨厌的惊喜 。 Assume-unchanged
flag could be lost on the pull
operation and the local changes inside such files doesn't seem to be important to git. 在pull
操作中可能会丢失Assume-unchanged
标志,并且这些文件中的本地更改似乎对git不重要。
See: 看到:
, ,
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)." 特别是,Junio指出assume-unchanged
文件assume-unchanged
可能会被意外提交:“如果Git可以确定标记为assume-unchanged
的路径已更改而不会产生额外的lstat(2)成本,则它保留报告该权限的权利路径已被修改(因此, git commit -a
可以自由提交该更改)。“
. 。
He concludes: 他的结论是:
Actually neither of the flags is intuitive enough . 实际上这两个标志都不够直观 。
assume-unchanged
assumes that a developer shouldn't change a file. assume-unchanged
假定开发人员不应更改文件。 If a file was changed – then that change is not important. 如果文件已更改 - 那么该更改并不重要。 This flag is meant for improving performance for not-changing folders like SDKs. 此标志用于提高SDK等不可更改文件夹的性能。
On the other hand skip-worktree
is useful when you instruct git not to touch a specific file ever. 另一方面,当您指示git不要触摸特定文件时, skip-worktree
非常有用。 That is useful for an already tracked config file. 这对已经跟踪的配置文件很有用。
skip-worktree
makes perfect scene. 在这种情况下, skip-worktree
可以完美呈现场景。 转载地址:http://izjnb.baihongyu.com/