我有一些配置文件,我想在本地进行更改,但不要冒意外提交这些更改的风险。它们也不能添加到gitignore中,因为需要对整个项目进行跟踪。当我修改这些文件以满足我的环境需要时,我的git status
看起来像这样:
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: config1.cfg
modified: config2.cfg
Untracked files:
(use "git add <file>..." to include in what will be committed)
whatever.html
somethingElse.js
然后我运行:
git rm --cached config1.cfg config2.cfg
CCD_ 2看起来像这样:
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
deleted: config1.cfg
deleted: config2.cfg
Untracked files:
(use "git add <file>..." to include in what will be committed)
config1.cfg
config2.cfg
whatever.html
somethingElse.js
运行git reset --HEAD config1.cfg config2.cfg
可以预见地将它们返回到暂存区。但是,即使某些内容是为了删除,也可以取消跟踪并同时暂存,这是没有意义的。但是——我没有删除这些文件,但如果我现在提交,它们就会被删除。
我意识到这可能是污迹和干净过滤器的更好用例,但有可能达到以前跟踪的文件未被跟踪的状态吗?如果没有,是否有充分的理由不可能?
编辑澄清一下,现在我对情况有了更好的理解:我试图创建的场景是,当我工作时,在不影响远程跟踪状态的情况下,在我的本地上取消对文件的跟踪。
但如果我现在提交,它们将被删除。
否。文件(您在工作树中看到的内容)不会被删除。提交对工作树没有任何影响。
提交将把它们记录为已删除,这是必须的,因为它们在上一次提交中存在,而现在你说它们不应该出现在下一次提交。这就是删除:曾经存在的东西现在已经不存在了。
Git的三个地方
听起来你可能会从了解Git";是";。Git在三个地方发挥影响力:
-
工作树。这就是Git向您展示的内容。它是将一个装满文件的文件夹渲染到磁盘上,以便您可以编辑这些文件。
-
索引。也称为暂存区或缓存。这是一个不可见的引用集合到构建下一次提交内容的文件。
-
实际的存储库。一个不可见的提交集合。提交本身每个都包含文件,在某种意义上是"提交"一词;包含";其细节在这里并不重要。
当您签出分支时,您就是在签出提交。提交用于填充工作树和索引;他们在那一刻都很相配。
如果您更改了工作树中的一个文件(这是可以更改任何内容的唯一地方)并添加它并提交,那么只有一个文件更改了,为true,但所有其他文件仍在工作树和索引中,因此此提交包含所有文件,而不仅仅是您更改的文件(这通常是一种误解)。每次提交都是创建索引时整个状态的快照,这反过来又反映了工作树的整体的状态,由您选择添加到索引的内容来调节。
因此,索引是您可以操作工作树中所做内容与下一次提交内容之间关系的地方。当你说git add .
时,你实际上是在说";索引应该反映我在工作树中所做的一切";。但这是一个非常宽泛的命令;在下一次提交之前,您可以对索引的外观进行绝对的逐文件精细控制。
你做了什么
当你说git rm --cached config1.cfg
时,你说;从索引中删除对config1.cfg的引用"当您提交时,这不会对工作树产生任何影响;它只会在config1.cfg不存在的情况下进行提交。
但现在你正在考虑这个问题,你意识到这不是你想说的,因为下一次提交将构成config1.cfg的删除。你不喜欢这样。您确实希望下一次提交仍然包含config1.cfg;您只是不希望它从上一次提交更改。
我认为,这就是你说的的意思
我有一些配置文件,我想在本地更改,但不要冒意外提交这些更改的风险
你应该做什么
您的目标不是进行不存在config1.cfg的提交。您的目标是进行一个提交,其中config1.cfg与以前的状态保持不变,即使您实际上已经在工作树中编辑了它。
好吧,那么为了实现这一点,你应该做些什么呢?好吧,第一道防线是:不要说git add .
或类似的笼统的胡言乱语。相反,为了不将更改的文件添加到索引中,不要添加它们。只需将所做的希望在下一次提交中反映的更改文件添加到索引中即可。
但假设您鲁莽地突破了该保护,并且确实将config1.cfg的更改状态添加到了索引中。(你做到了。)然后说git restore --staged config1.cfg
。这将config1.cfg从上次提交(每次提交都包含所有文件,还记得吗?)复制到索引中。因此,现在索引中的config1.cfg看起来像以前的提交,而不是工作树版本。此时的状态是git知道您已经修改了工作树中的config1.cfg(除非您已将其添加到gitigners文件中),但该更改不是,而将包含在您进行的下一次提交中。
(在Git 2.25.0版本之前,你会使用git reset
的形式来实现这个目标,即git reset config1.cfg
。但git reset
很可怕,所以如果你有一个足够新的Git,请使用restore
。)
从暂存阶段取消跟踪更改:
如果您碰巧使用git add [fileName]
暂存文件,并且希望从暂存中取消对它们的跟踪,则可以使用以下命令:
git rm -r --cached [fileName]
如果您想取消跟踪阶段中的所有文件,可以使用以下命令:
git rm -r --cached .