Git add 和 git commit 混淆

Liv*_*ana 11 git

我基本上知道 a 之间的区别git add,意思是“我想将此文件添加到我的下一个快照”和git commit“拍摄快照”。

但是,当我运行git add file1然后file1从我的工作目录中删除然后运行时,git commit它仍然可以工作。不知何故,快照是在添加时而不是在提交时拍摄的。我对吗?

Von*_*onC 8

git commit 获取快照

  • 查看索引(您添加文件的位置),
  • 不是通过查看工作树(您继续修改内容,包括添加或删除文件)

请参阅“ Git 中 HEAD、工作树和索引之间的区别是什么?

在您的情况下,删除文件后(但将其添加到索引后),agit status会给您:

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   go.mod

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        deleted:    go.mod
Run Code Online (Sandbox Code Playgroud)

该文件是:

  • 准备好成为下一次提交的一部分
  • 本地删除

Agit restore -- <myFile>足以在本地恢复它。


工作树(或工作目录)是实际检出文件的树。
工作树通常包含 HEAD 提交树的内容,以及您所做但尚未提交的任何本地更改。


这个想法是准备你的下一次提交,而不是盲目地你当前的所有修改变成一个巨大的提交。
最好进行小的连贯提交而不是巨大的提交,以获得逻辑历史,并使未来git bisect更容易。

您甚至可以暂存(添加到索引)文件的一部分交互式暂存

OP补充说:

想象一下,提交完成了实际提交和添加的工作。
我们称之为假想提交。
您仍然可以使用虚构的提交一点一点地完成这项工作

首先:该命令(添加所有并提交)确实存在:

git commit -am "Let's add everything"
Run Code Online (Sandbox Code Playgroud)

其次,要做“一点一点”,你必须使用git add,然后commit。
提交会获取索引中的所有内容


ang*_*son 5

事实上,你所知道的东西中缺少一些东西。

添加该文件后,您实际上拥有该文件的两个副本。您有工作树副本,这是您使用普通文本编辑器等查看和编辑的普通文件系统副本。

但是,另外你在索引中有一个副本。git add将文件及其内容从工作树复制到索引中。这是制作该特定文件的实际快照的地方。

当您随后发出 a 时git commit,索引将存储到提交中。在这一点上,工作树(又名磁盘上)中有或没有什么是无关紧要的。指数才是最重要的。

这就是为什么您会看到仍在添加文件的原因。它被复制到索引中git add,即使您随后从磁盘中删除了它,也git commit使用该索引作为提交的源。

拥有一个单独的索引来组成下一次提交的结果是,您可以决定下一次提交将包含什么,而不是“目前我磁盘上的所有内容”。好的 git 工具甚至可以让你将文件的一部分更改复制到索引中,这样如果你对一个文件进行了 2 次或多次更改,你就可以决定对该单个文件的所有更改是进入下一次提交还是只进行一次提交或其中几个。