【发布时间】:2020-03-29 11:23:10
【问题描述】:
我是 git 的新手。
我刚刚介绍了工作目录和暂存区的概念。
我对暂存区的使用不是很清楚。
如果暂存区不存在并且我们可以直接从工作目录提交到本地 repo,会出现什么问题?
抱歉,如果我的问题很愚蠢。
感谢您的问候, 京东
【问题讨论】:
-
@ilkerkaran:这不是重复的,这是关于 Eclipse 中的一个措辞故障。
标签: git
我是 git 的新手。
我刚刚介绍了工作目录和暂存区的概念。
我对暂存区的使用不是很清楚。
如果暂存区不存在并且我们可以直接从工作目录提交到本地 repo,会出现什么问题?
抱歉,如果我的问题很愚蠢。
感谢您的问候, 京东
【问题讨论】:
标签: git
除了Obsidian's answer,它还涉及到您可以做 使用索引/暂存区域(同一个底层 Git 事物的两个短语)。 是可以构建一个没有索引/暂存区的版本控制系统。
Mercurial 就是这样一个系统。在 Mercurial 中,工作树是建议的下一次提交。这确实需要一些额外的幕后技巧,但系统运行良好,而且 Mercurial 的新手使用它的麻烦远少于 Git 的新手使用 Git。从中可以清楚地看出,索引/暂存区是一个艰难的概念。这不是绝对必要的——尽管它确实启用了各种技巧——而且一个没有的系统更容易使用。
但 Git 确实有它,所以如果您使用 Git,请记住 Git 始终为每个文件保留 三个 个副本1:@ 中的冻结一个987654322@(当前提交),索引中暂存的提交,以及您可以在工作树中查看和编辑的提交。使用git add 将 工作树复制到 索引中。使用git reset 复制从 冻结的HEAD 复制到 索引。如果您有 Git 2.23 或更高版本,请使用 git restore 将 索引复制到 工作树。
(如果你的 Git 版本比那个旧,有一个 git checkout 模式可以从索引复制到工作树。你不能复制到 HEAD 副本,因为它被冻结了!所以唯一的选择是:@ 987654329@ -> 索引,HEAD -> 索引 -> 工作树,索引 -> 工作树和工作树 -> 索引。)
旁注:花哨的git add -p 和git reset -p 通过将索引副本提取到临时文件、比较临时副本和工作树副本并进行任何您喜欢的更改来完成他们的工作——然后为git add -p ,将更新后的临时副本放回索引中。
1从技术上讲,所有 Git 化(压缩、冻结格式)的副本在所有可能的范围内都共享。索引中的内容是 blob 对象的哈希 ID。当您从工作树副本更新索引时,Git 准备一个新的或重用的 blob 对象,准备好提交,并更新索引哈希 ID。除了没有使用额外的磁盘空间这一事实之外,这在使用 Git 进行普通工作时通常是不可见的。您可以将索引副本视为私有副本,只要您记住 git ls-files --stage 和 git update-index 在现实中使用 blob 哈希即可。
请注意,即使您从不提交某些 blob,只要 blob 仍在索引中,Git 就会一直保留它……除了添加工作树的一个相当讨厌的错误,从 Git 2.5 开始并在 Git 2.15 中修复.同时,使用git add -p 会创建大量未使用的 blob 对象,这些对象最终会被垃圾回收,但在此之前确实会占用一些额外的磁盘空间。
【讨论】:
git add 将内容添加到存储库 并更新索引条目。 Git 确实不保留三个副本。 Git 保留一份副本,以及一个指向它的索引条目。工作树是你的。
git update-index 替换索引副本很重要,因为现在您需要知道首先使用git hash-object -w。
你的问题一点也不傻。它是构成整个 Git 大厦的少数基本概念之一。
.git 子目录。这将形成您的 git 存储库,以及您最初克隆的远程存储库的本地副本。.git 子目录下包含大小固定的条目,简称为 @987654323 @。这意味着位于工作目录中但 Git 未明确遵循的所有文件将始终保持不变。您还需要知道 Git 是一个基于快照的 SCM 系统:每次修改文件时,都会重新完整记录一次。 Git 不会记录版本之间的差异(至少现阶段不会)。因此,每个提交都由一个树状文件列表构成,该文件列表引用每个提交的当前版本。
这就是索引开始变得聪明的地方:当您使用git add将文件添加到跟踪列表时,您不仅仅是将其名称和路径添加到索引中:Git 还将其当前内容保存在一个对象中,从而开始构建实际即将到来的提交的有效负载。然后当您执行git commit 时,git 只是将此索引的内容保存为新修订版。这就是使该索引事实上成为“暂存区”的原因。
这有几个后果:
git add 时一样,而不是 git commit ;我们可以通过以下方式总结最后一点:
git add(这仍然完全合法)或您使用@987654329 执行了基于补丁块的部分添加后,您再次修改了文件@ 仅选择文件中感兴趣的内容:“暂存更改”和“未暂存更改”都显示在 git status 中。最后,这提供了最后但并非最不重要的优势:由于修改检测是基于文件内容而不是其最后修改时间,因此您可以轻松取消您所做的事情。当文件“意外”恢复到最初的状态时,它会自动从git status的列表中消失。
【讨论】:
您可以使用它来选择要提交的内容——该文件中的这几行更改,该文件中的那个部分...如果没有暂存区域,这种事情将很难做到。
我喜欢使用git add -p 命令添加要提交的内容,该命令会遍历所有更改的文件并逐段显示差异,您可以在其中选择将每个文件与其他文件分开。然后你提交结果(可能再次运行git add -p 以创建另一个提交)。
【讨论】: