- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我对git add file
和git checkout -- file
有以下理解(但不确定是否正确)。
每当我们使用文本编辑器编辑文件时,我们都会在工作目录中进行操作。每次我们可以通过执行staging area
将文件移动到所谓的git add file_name
。如果我们再次编辑文件(在git add
之后),我们将在工作目录中更改文件,这样,在工作目录中,文件将处于"new"状态,而在staging area
中,文件将处于“旧”状态。
当再次使用git add
时,会将暂存区域中的文件置于"new"状态(工作目录中的状态)。
如果我们执行git checkout -- file_name
,我假设我们从登台区域中获取一个文件,并使用它来覆盖工作目录中的文件。这样,我们可以将工作目录中的文件置于“旧”状态。这是正确的吗?
对我来说还不清楚的是,我们是否从暂存区复制或移动文件。换句话说,git checkout -- file
是否会更改staging area
中文件的状态。我们是否可以说在git checkout -- file
之后,将暂存区中的文件的状态更改为暂存区中文件的先前状态?
最佳答案
几乎是对称的,但不是完全对称的。
的确,git add file
将文件复制到阶段(也称为“索引”)。但是,这样做的方式有点怪异。
在git仓库中,所有内容都存储为git“对象”。每个对象都有一个唯一的名称,即SHA-1(像753be37fca1ed9b0f9267273b82881f8765d6b23
这样的40个字符的字符串,该字符串来自我在这里使用的实际.gitignore
)。该名称是通过计算文件内容上的哈希值构造的(或多或少,例如,为了确保您不会从目录树中生成文件或提交该文件而引起哈希冲突,有些头)。 Git假定无论内容如何,SHA-1都是唯一的:没有两个不同的文件,树,提交或带注释的标签将永远不会哈希到相同的值。
文件(和符号链接(symbolic link))是“blob”类型的对象。因此,对git repo中的文件进行了哈希处理,并且git在某个地方有一个映射:“名为.gitignore
的文件”到“哈希值753be37fca1ed9b0f9267273b82881f8765d6b23
”)。
在存储库中,目录树存储为“树”类型的对象。树对象包含名称(如.gitignore
),模式,对象类型(另一棵树或blob)和SHA-1的列表:
$ git cat-file -p HEAD:
100644 blob 753be37fca1ed9b0f9267273b82881f8765d6b23 .gitignore
[snip]
提交对象为您(或git)提供了一个树对象,该对象最终为您提供了Blob ID。
.git/index
。该文件包含1名称(以有趣的略微压缩的形式压缩目录树), merge 冲突时的“阶段号”和SHA-1。实际的文件内容还是git repo中的blob。 (Git不在索引中存储目录:索引仅使用扁平化格式的实际文件。)
git add file_name
git做到了这一点(或多或少,我故意掩盖过滤器):
file_name
(git hash-object -t blob
)内容的哈希值。 -w
的hash-object
选项)。 .git/index
(或$GIT_INDEX_FILE
),使其具有在file_name
名称下的映射,以映射到从git hash-object
出来的名称。这始终是“stage 0”条目(这是正常的,没有 merge 冲突的版本)。 git checkout [<tree-ish>] -- file_name
这样做:
<tree-ish>
(提交名称,树对象ID等-基本上git可以解析为树),请通过将参数转换为树对象来从树中查找名称。使用这样定位的对象ID,在阶段0处更新索引中的哈希。(如果file_name
命名一个树对象,则git递归地处理树所代表的目录中的所有文件。)通过创建阶段0条目,所有 merge 冲突file_name
现在已解决。file_name
是目录,可能不确定git会读取工作目录,所以不知道会发生什么)。将file_name
转换为对象ID(此时将是blob)。如果没有阶段0条目,除非给出了-m
,--ours
和--theirs
选项,否则将出现“unmerged”消息错误。使用-m
将“取消 merge ”文件(删除阶段0条目并重新创建冲突的merge2),而--ours
和--theirs
将任何阶段0条目保留在原位置(解决的冲突得以解决)。file_name
命名为目录)提取到工作目录中。git checkout
有时会修改索引,有时仅使用它。但是,文件本身从不存储在索引中,而仅存储在存储库中。如果您对文件进行
git add
,对其进行更多更改,然后再次对其进行
git add
,则将git fsck视为“悬空 Blob ”:没有引用的对象。
--assume-unchanged
等。(这些与此处的add/checkout操作无关。)
merge.conflictstyle
所做的任何更改,因此,如果您决定喜欢
diff3
输出,并且在没有
diff3
样式的情况下已经存在冲突的 merge ,则可以更改git config并使用
git checkout -m
来获取具有新样式的新工作目录 merge 。
关于git - "git add file"和 "git checkout -- file"是对称的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20397024/
概述 CentOS Stream 成立于 2019 年,是“RHEL 下一步的滚动预览”。Red Hat 首席技术官 Chris Wright 和 CentOS 社区经理 Rich Bowen 各
我有一个使用 Mesosphere DC/OS 编排选项进行配置的 Azure 容器服务 (ACS) 集群。我可以在 Marathon UI 中创建一个应用程序。 但是,当我通过 Marathon U
我是一名优秀的程序员,十分优秀!