如何从暂存中删除而不实际删除

时间:2019-06-10 22:14:17

标签: git

我已经阅读了所有文章,但仍然感到困惑。

由于无法提交,我试图强迫Git释放文件。我认为原始问题是由进行提交然后在编写提交消息之前关闭我的文本编辑器引起的。为了解决这个问题,我cd到主目录并执行了force命令。

我的问题是我忘了cd回到我的副本,并且git add .添加了我所有的网站和副本。

现在git status执行时,我会看到所有文件

如果我执行git reset,则在执行git status时会看到文件,它们被标记为untracked files

如果我checkout commit较旧,git status仍会标记为未跟踪文件。

如何重置staging,以便在那里没有文件,但不会删除我的整个主目录。

我知道我会为此被打下烙印,但是我为删除所有这些文件而感到震惊。确认一下,尽管我浏览了存储库,但我认为.git文件在存储库中。所以我应该能够简单地删除或重命名该文件吗?

2 个答案:

答案 0 :(得分:4)

这整个过程有些棘手(这是我从不将Git用作主目录的原因之一,例如,我将点文件存储在Git中,但是通过符号链接或复制来执行此操作,因此不会使用存储库我的主目录中。

重要的是要记住,在处理Git时,文件有三个位置。三种存储之一是永久存储,这是一种数据库,其中文件一直保持冻结状态,您可以随时将其取回。 1 这些是 commits 永远不能更改任何现有提交的任何部分,其中包括在每个提交中存储为完整快照的文件。 (请参阅脚注1。)

但是Git还有另外两个地方存储文件,这很重要。当您意识到Git中的冻结文件采用特殊的,压缩的,仅Git格式时,这一点尤其重要。因此,这些文件对不是 Git的任何东西都完全没有用,而且,您甚至Git都无法更改。这意味着Git需要有一种方法来从提交中取出文件 ,并将其放回其正常的,每天可用的形式。

那样(那个地方)就是您的工作树。您的工作树包含文件的日常可用形式。 Git将根据需要复制 out 个提交文件,覆盖您工作树中的任何文件。如果合适的话,它还会从您的工作树中删除文件。

的意思是工作树中的文件不是 永久文件。但是它们 是有用的-与Git特殊的冻结副本不同-并且非常诱人的是使您的工作树不仅是您的“游戏”区域,而且是您日常实用的工作区域。这样做本质上没有错,但是您必须接受这样的想法,即Git能够在这个领域介入并大惊小怪,并了解Git何时,如何以及为什么这样做。

在提交数据库和您的工作树之间,Git存储每个文件的第三副本。第三份副本为冻结的格式,但未冻结。第三个副本是Git所称的 index staging area 。 Git通过其索引进行所有 new 提交。

与工作树一样,索引中的内容不是永久的。实际上,它们必须不是永久的:如果是,则不能更改它们!但是,无常,如果您删除它们,它们确实不存在了。对于文件的索引副本和工作树副本都是如此。 2

当您运行git commit时,Git会简单地打包紧随索引然后的所有文件,并对它们进行提交。 (提交还会添加您的姓名和电子邮件地址,日期和时间戳等,但是现在永久存储并冻结到提交中的文件是来自索引的文件。 )

您可以随时运行:

git rm --cached <file>

告诉Git:从索引中删除给定的,而不是将其从工作树中删除。此时,文件现在不是 在索引中。但这可能存在于某些现有的 commits 中。您现在可以进行 new 提交,并且新的提交将不包含该文件-因为该文件不在索引中。

如果您签出一些 old 提交,尽管……很好,git checkout的工作方式为: 3

  • 将提交复制到索引,然后
  • 将索引复制到工作树

,以使该提交中的所有文件都可用,无论是在索引中(基于旧提交,您可能会在一段时间内进行新提交),还是在工作树中(以便您可以看到并处理您的文件)。

假设在该提交中有一个名为F的文件,该文件不在git checkout之前的索引中,而是在工作树中。然后,您运行git checkout <that-commit>,现在F 在索引中,并且也在您的工作树中。现在,工作树副本(可能)与提交的副本匹配(有关“可能”的信息,请参见脚注3)。如果现在您确定已经完成了对旧提交的查看,并使用git checkout master返回现代,那么Git将从索引中删除文件F。 ,因此也可以从您的工作树中删除文件F

文件F(不在您的索引中)回到未跟踪,除了它从工作树中消失的巨大问题之外,因此它甚至不存在:其未跟踪状态无关紧要。在旧提交中有F 副本-毕竟是在您刚才进行的提交中-也许已经足够了:

git show <hash>:F

将允许您查看给定提交中的副本,您可以将其输出重定向到F,以在工作树中重新创建它。

没有一个完美的方法可以解决这个问题,除了一个例外:将Git存储库移到其他位置。使此工作区 not 成为Git工作树。 Git将不再以任何方式对其进行控制,因此不会删除或破坏其中的文件。真正的主要问题是历史提交中包含您不希望拥有的文件。您不能更改那些提交。您可以 将它们复制到没有文件的新改进的提交中。例如,请参见Remove sensitive files and their commits from Git history和标记中的所有内容。如果您确实使用了这些,请确保不要将新的存储库,新的和改进的提交以及错误的旧的和糟糕的存储库混在一起:Git旨在将所有的提交混在一起,并且“希望”留给您一个具有两者提交集的存储库。


1 从技术上讲,您可以摆脱提交。为此,您不能通过任何分支或标记名称或任何其他名称来查找提交。 Git会注意到无法达到提交(请参阅Think Like (a) Git,以更好地讨论 reachability ),并将最终将其从数据库中删除,然后再将其扔出数据库。文件的副本将消失。但是所有可到达的提交都将保留,并且它们还将保存文件的副本。

由于每个提交中的文件都被冻结,因此提交在未更改的情况下可以 share 。因此,如果您进行了100万次提交,所有这些提交都存储了4000行文件,但是在所有100万次提交中,4000行文件与 same 相同,即使文件存在一个副本,实际上也只有一个副本一百万次提交都拥有该副本。因此,每个提交都存储每个文件的事实并不能使提交数据库的大小爆炸式增长:它们通过共享存储。

2 通过外部 Git可以以某种方式将工作树文件取回。例如,MacOS提供其Time Machine。但是 Git 不知道如何工作,这与Git的工作有关。

3 这非常简化。有关大多数血腥细节,请参见Checkout another branch when there are uncommitted changes on the current branch。还有更多要知道是否定义了过滤器驱动程序

答案 1 :(得分:2)

您必须在import time time.sleep(5) 之前完成git init

要在造成任何实际伤害之前撤消此操作,只需删除git add .目录及其主目录中的所有内容。

如@torek所述,

  

工作树保持原状,现在只是一组普通的   目录/文件夹/任何您想打电话的东西-这些充满普通   文件。