我对一个我不想提交到我的存储库的文件进行了本地更改。它是用于在服务器上构建应用程序的配置文件,但我想在本地使用不同的设置进行构建。当然,当我将'git status'作为要上演的东西时,该文件总是显示出来。我想隐藏这个特定的更改而不是提交它。我不会对文件进行任何其他更改。
经过一番挖掘后,我看到了两个选项:'假设未改变'和'跳过工作树'。上一个问题here谈到了它们,但并没有真正解释它们之间的区别。我的问题是:这两个命令有何不同?为什么有人会使用其中一个?
答案 0 :(得分:517)
您想要skip-worktree
。
assume-unchanged
适用于检查一组文件是否已被修改的情况;设置该位时,git
(当然)假定在工作副本中未修改与该索引部分对应的文件。所以它避免了一堆stat
次电话。只要索引中的文件条目发生变化(因此,当文件在上游更改时),该位就会丢失。
skip-worktree
不止于此:即使git
知道文件已被修改(或需要由reset --hard
等修改),它会假装它没有,使用索引的版本代替。这种情况一直持续到索引被丢弃为止。
此差异的后果和典型用例有一个很好的总结:http://fallengamer.livejournal.com/93321.html。
从那篇文章:
--assume-unchanged
假设开发者不应更改文件。此标记用于提高性能,用于不更改SDK等文件夹。 --skip-worktree
在您指示git不会触及特定文件时非常有用,因为开发人员应更改它。例如,如果主存储库上游托管了一些生产就绪的配置文件,并且您不希望意外地提交对这些文件的更改,那么--skip-worktree
正是您想要的。答案 1 :(得分:84)
注意:fallengamer在2011年进行了一些测试(因此可能已过时),这是他的findings:
<强>运营强>
git pull
强>:assume-unchanged
标记的文件:Git不会覆盖本地文件。相反,它会输出冲突并建议如何解决它们skip-worktree
标记的文件:Git不会覆盖本地文件。相反,它会输出冲突并建议如何解决它们
git stash
强> git pull
强> skip-worktree
会产生一些额外的手动工作,但如果您有任何本地更改,至少不会丢失任何数据。
assume-unchanged
标记的文件:放弃所有本地更改,而无法恢复它们。效果就像'git reset --hard
'。 “git pull
”通话将成功skip-worktree
标记的文件:Stash不适用于skip-worktree
个文件。 “git pull
”将失败并出现与上述相同的错误。开发人员被迫手动重置skip-worktree
标志,以便能够存储并完成失败的pull
。。
git pull
强> assume-unchanged
承诺并选择通过重置标志来反映现实。
assume-unchanged
标记的文件:内容已更新,标记已丢失
“git ls-files -v
”会将该标记修改为H
(来自h
)。skip-worktree
标记的文件:内容已更新,标记已保留
“git ls-files -v
”会显示与S
之前相同的pull
标记。
git reset --hard
强> skip-worktree
文件,反映了assume-unchanged
文件的实际情况(承诺实际上未更改的文件已更改)。
assume-unchanged
标记的文件:文件内容已恢复。标记重置为H
(来自h
)。skip-worktree
标记的文件:文件内容完好无损。国旗保持不变。 他补充了以下分析:
skip-worktree
似乎非常努力地保留您的本地数据。但是,如果它是安全的,它不会阻止您获得上游更改。加上git不会重置pull
上的标志
但忽略“reset --hard
”命令可能会成为开发人员的一个令人讨厌的意外
Assume-unchanged
标志可能会在pull
操作中丢失,而这些文件中的本地更改似乎对git不重要。
请参阅:
Junio's (current git maintainer) comment regarding intent of assume-unchanged
,
特别是,Junio指出可能会意外地提交对assume-unchanged
文件的更改:“如果Git可以确定路径
标记为assume-unchanged
的内容已发生变化,但未发生任何变化
额外的lstat(2)成本,它保留报告该路径的权利
已被修改(因此,git commit -a
可以自由提交
那个改变)。“
他总结道:
实际上两个标志都不够直观。
assume-unchanged
假定开发人员不应更改文件。如果文件被更改 - 那个更改并不重要。此标志用于提高SDK等不更改文件夹的性能
但是如果承诺被破坏并且文件实际被更改,git会恢复标志以反映现实。可能在一般意思不是要更改的文件夹中有一些不一致的标志是可以的。
另一方面,当您指示git不要触摸特定文件时, skip-worktree
非常有用。这对已经跟踪的配置文件很有用
上游主存储库托管一些生产就绪的配置,但您希望更改配置中的某些设置以便能够进行一些本地测试。并且您不希望意外检查此类文件中的更改以影响生产配置。在这种情况下,skip-worktree
可以完美呈现。