首先,我将与Git一起工作多年,但我的知识仅限于非常基本的工作流程。意识到这一点,我在“高级” Git功能方面已经变得更好了,但这是我无法弄清楚的一个问题:
究竟是git checkout [file]
做什么的?
我的理解是,它将检索该特定文件的最新修订/提交,并丢弃所有未暂存的工作副本。
因此,我想知道这是否与有所不同git restore [file]
,以及何时可以使用两者之一。
可悲的是,我在其他地方找不到超级清晰的答案。
在axiac和Jay的答案之间,您有一个相当完整的图片,但是我想对整个内容有所不同。这里有两种git checkout
感兴趣的形式:
git checkout -- path
:path
参数被视为文件或目录(如果是目录,则表示递归该目录中的所有文件),Git将索引中找到的文件的当前副本复制到您的工作树中。
稍后我们将详细介绍该索引。
git checkout HEAD -- path
:该path
参数的处理方式相同,但Git的副本作为找到该文件的当前副本HEAD
提交给两个索引和工作树。
您可以使用HEAD
此处以外的名称:任何提交说明符都可以工作,并且Git复制会将文件的副本提交到索引和工作树。
对于git restore
,您具有更大的灵活性。您可以告诉Git复制文件:
--source
选项来显式选择源,或让命令自己找出一个源)--staged
复制到索引的--worktree
选项和/或复制到工作树的选项)。请注意,如果使用git checkout
并选择提交,则文件将同时到达两个位置:索引和工作树。复制“从索引到索引”实际上并没有任何作用(并且可能会使您感到抱怨,因为这似乎是很奇怪的问题)。
您的工作树非常简单明了。Git将每个提交存储为完整快照:您已提交的每个文件的完整副本。但是,存储在Git提交中的文件以特殊的,只读的,压缩的,去重复的,仅Git的格式存储。这可以防止.git
目录(适当的存储库)过大或过快。大多数提交实际上只是重用了大多数以前的文件,这意味着重复数据删除的效果非常好。对于无法正常运行的那些时期,压缩通常会处理其余的工作。1另一方面,由于此处的文件是只读文件,而不是普通文件,因此您实际上无法使用他们来完成您的工作。Git必须将这些文件复制出来,然后再转回您和您的计算机可以使用的普通文件。
文件的有用的日常工作副本出现在Git所谓的工作树或工作树中。您可以使用这些文件执行任何操作。Git实际上并没有使用它们!它创建它们,已经提取压缩的Git,只存储文件从提交,但它没有提交从他们。
Git的索引(Git也称其为暂存区)或有时(有时是近来的时候)缓存,保存了来自当前提交的每个文件的副本2,现在可以进入下一个提交了。3运行时,Git会打包当时索引中的所有内容。这就是为什么您必须保留文件的原因。如果更改文件,则没有更改Git的文件副本:您仅更改了工作树副本。您经常告诉Git:将更新后的工作树文件复制回索引中,替换那里的旧副本。git commit
git add
git add
因此,索引始终保留您建议的下一次提交。您可以使用git add
或(如果需要删除文件)git rm
使用更新或删除这些文件的索引副本。它们从您检出的提交中的副本开始:当前或HEAD
提交。因此,如果您尚未使用git add
,则索引和HEAD
提交副本通常会匹配。4当它们确实匹配时,索引副本的存在往往是不可见的:例如git status
,没有提及索引副本。
但是,如果您感到好奇,请尝试运行git ls-files --stage
(为在大型存储库中进行大量输出做好准备!-此命令不会通过寻呼机运行其输出)。这将显示索引中的每个文件。
1压缩,去重复的格式不适用于某些非常大的二进制文件格式。在这种情况下,Git会变得肿。这就是Git-LFS之类的东西出现的地方。
2从技术上讲,索引不是保存文件的实际副本,而是保存引用。仅当您开始使用低级命令git update-index
或时git ls-files --stage
,才会显示差异,它们可以直接检查索引内容。但是,对于日常使用而言,您可以将索引视为保存文件的副本。索引副本采用冻结和重复数据删除的格式(即可以进行预冻结和重复数据删除,尽管可以覆盖),从而使提交工作变得更快。
3当您必须处理合并冲突时,索引还将扮演扩展角色。这个答案不包括这种情况。
4这里的单词通常是要照顾很多极端情况,包括像这样的东西git reset --soft
和git commit
不需要特殊参数的特殊品种。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句