Git:如何取消跟踪文件而不暂存它们以进行删除

cclgggtu  于 2022-11-20  发布在  Git
关注(0)|答案(2)|浏览(237)

我想在本地修改一些配置文件,但又不想冒不小心提交这些更改的风险。它们也不能添加到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

git status看起来像这样:

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会将它们返回到暂存区,这是可以预见的。但是,如果某个文件在未被跟踪的同时仍处于暂存状态,即使该暂存是为了删除,这也是没有意义的。而且,我没有删除这些文件,但如果我现在提交,它们将被删除。
我意识到这可能是一个更好的模糊和清洁过滤器的用例,但是否有可能达到一个状态,以前跟踪的文件被取消跟踪,就像它从来没有被跟踪过?如果没有,有一个很好的理由,这是不可能的?
编辑澄清一下现在我对情况的了解稍微好一点了:我尝试创建的场景是这样的:当我工作时,文件在我的本地上不被跟踪,而不影响它们在远程上的跟踪状态。

mrwjdhj3

mrwjdhj31#

但如果我现在提交,它们将被删除。
不。* 文件 *(你在工作树中看到的东西)不会被删除。提交对工作树 * 没有影响 *。

  • commit* 会将它们记录为删除,因为它们在上一次提交时就已经存在,而现在你却说它们不应该在下一次提交时出现。这就是删除的含义:曾经存在的东西现在不再存在了。

Git的三个地方
听起来你可能会从了解Git“是什么”中受益。Git练习涉及三个方面:

*工作树。这是Git显示给你的。它是一个文件夹到磁盘上的渲染,这样你就可以编辑这些文件了。

  • 索引。也称为暂存区或缓存。这是一个不可见的文件引用集合,用于构造下一次提交所包含的内容。
  • 实际的repository。一个不可见的 commits 集合。commits本身都包含文件,在某种意义上,“包含”一词的细节在这里并不重要。

当你 checkout 一个分支时,你 checkout 的是一个提交。他们现在都很般配。
如果更改工作树中的一个文件(这是唯一一个你可以改变任何东西的地方),然后添加它并提交,那么只有一个文件改变了,真的,但所有其他文件仍然在工作树和索引中,所以这个提交包含了 * 所有的文件 * -不仅仅是你改变的文件(这是一个常见的误解)每次提交都是创建索引时索引的“整体”状态的快照,而索引的“整体”状态反过来又反映了工作树的“整体”状态,并以您选择添加到索引中的内容为中介。
所以索引是你用来控制你在工作树中所做的和下一次提交的关系的地方.当你说git add .时,你实际上是在说,“索引应该反映 * 我在工作树中所做的 * 一切”.但这是一个非常宽泛的命令;您可以对下一次提交之前索引的外观进行绝对的逐文件精细控制。
你做了什么
当您说git rm --cached config1.cfg时,您说的是“从 index 中删除对 config1.cfgreference”。它只会在 config1.cfg 不存在的情况下进行提交。
但是现在你考虑到了这个问题,你意识到这不是你想要说的,因为下一次提交将构成 config1.cfg 的 * 删除 *。你不喜欢这样。你 * 确实 * 希望下一次提交仍然包含 config1.cfg;您只是不希望它从上一次提交中被 * 更改 *。
我想这就是你说的
我想在本地更改一些配置文件,但不冒意外提交这些更改的风险

你应该做什么

您的目标不是提交一个不存在 config1.cfg 的文件。您的目标是提交一个 config1.cfg 与之前的状态相比 * 未更改 * 的文件,即使您实际上已经在工作树中编辑了它。
好吧,那么你应该做些什么来实现这一点呢?嗯,第一道防线是:不要说git add .或类似的笼统的globbing语句。相反,为了 * 不 * 将更改过的文件添加到索引中,* 不要添加它们 *。只需将您 * 希望 * 在下次提交时反映的更改过的文件添加到索引中。
但是,假设您鲁莽地突破了这一保护措施,并 * 确实 * 将处于更改状态的 config1.cfg 添加到了索引中。(您已经执行了。)然后输入git restore --staged config1.cfg。这将从上次提交中复制 config1.cfg(每次提交都包含所有文件,还记得吗?)。因此,现在索引中的 config1.cfg 看起来像上次提交,不像工作树版本。状态将是git知道你已经修改了工作树中的 config1.cfg(除非你已经将它添加到gitignores文件中),但是这个修改 * 不 * 会被包含在你的下一次提交中。
(在Git 2.25.0之前,你会使用git reset来实现这个目标,即git reset config1.cfg。但是git reset很可怕,所以如果你有一个足够新的Git,就使用restore

slwdgvem

slwdgvem2#

取消跟踪临时阶段的更改:

如果您碰巧使用git add [fileName]登台文件,并且希望从登台中取消跟踪这些文件,则可以使用以下命令:
git rm -r --cached [fileName]
如果要取消跟踪***登台***中的所有文件,可以使用以下命令:
git rm -r --cached .

相关问题