0

我有一些我想在本地更改的配置文件,但不会冒意外提交这些更改的风险。它们也不能添加到 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会将他们送回集结区。但是,即使该分期是为了删除,某些东西可能未被跟踪但仍然在同一时间上演,这有点没有意义。而且 - 我没有删除文件,但如果我现在提交,那么它们将被删除。

我意识到这可能是涂抹和清洁过滤器的更好用例,但是是否有可能达到以前跟踪的文件未被跟踪并且就好像从未被跟踪过的状态?如果没有,是否有充分的理由不可能?

编辑以澄清现在我对情况的了解更好一点:我正在尝试创建的场景是在我工作时在我的本地未跟踪文件的场景,而不会影响它们在远程的跟踪状态。

4

1 回答 1

2

但如果我现在提交,那么它们将被删除。

不会。文件(您在工作树中看到的内容)不会被删除。提交对工作树没有影响。

提交会将它们记录为已删除,因为它必须这样做,因为它们存在于上一次提交中,现在您说它们不应该出现在下一次提交中。这就是删除:曾经存在的东西现在不再存在。

Git的三个地方

听起来您可能会受益于对 Git “是”的了解。Git 练习在三个地方摇摆不定:

  • 工作树。这就是 Git 向您展示的内容。它是将一个充满文件的文件夹渲染到磁盘上,以便您可以编辑这些文件。

  • 索引。_ 也称为暂存区或缓存。这是对构建下一次提交内容的文件的不可见引用集合。

  • 实际的存储库一个不可见的提交集合。提交本身每个都包含文件,在某种意义上的“包含”一词,其细节在这里并不重要。

当您签出一个分支时,您正在签出一个提交。提交用于填充工作树和索引;他们在那一刻都匹配。

如果您更改工作树中的一个文件(这是您唯一可以更改任何内容的地方)并添加并提交,那么只有一个文件更改了,真的,但所有其他文件仍然存在于工作树中,并且索引,所以这个提交包含所有文件——不仅仅是你更改的文件(这是一个常见的误解)。每个提交都是索引在创建时的整个状态的快照,这反过来又反映了工作树的整个状态,由您选择添加到索引中的内容进行调解。

因此,索引是您可以操纵您在工作树中所做的事情与将进入下一次提交的内容之间的关系的地方。当您说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(除非您已将其添加到 gitignores 文件中),但该更改不会包含在您进行的下一次提交中。

(在 Git 版本 2.25.0 之前,您会使用一种形式git reset来实现此目标,即git reset config1.cfg. 但是git reset很可怕,所以如果您有足够新的 Git,请restore改用。)

于 2020-11-05T19:30:14.590 回答