Rom*_*man 5 git git-add git-checkout
我的下列理解git add file和git checkout -- file(但我不知道这是否是正确的).
每当我们使用文本编辑器编辑文件时,我们都会在工作目录中进行编辑.每次我们都可以staging area通过执行将文件移动到所谓的git add file_name.如果我们再次编辑文件(之后git add),我们更改工作目录中的文件,这样,在工作目录中,我们使文件处于"新"状态,而staging area文件处于"旧"状态.
当我们git add再次使用时,我们将暂存区域中的文件带到"新"状态(工作目录中的状态).
如果我们这样做git checkout -- file_name,我假设我们从暂存区域获取一个文件并使用它来覆盖工作目录中的文件.通过这种方式,我们可以将工作目录中的文件置于"旧"状态.这是对的吗?
我还不清楚的是,如果我们从暂存区域复制或移动文件.换句话说,确实git checkout -- file改变了文件的状态staging area.我们可以说,在git checkout -- file暂存区域中的文件将文件状态更改为暂存区域中的先前状态后?
这几乎是,但并不完全是对称的.
git add file将文件复制到舞台(也就是"索引")是真的.然而,它这样做的方式有点奇怪.
在git repo中,一切都存储为git"对象".每个对象都有一个唯一的名称,它的SHA-1(那些40个字符的字符串,就像我在这里753be37fca1ed9b0f9267273b82881f8765d6b23的实际情况一样.gitignore).该名称是通过计算文件内容的散列来构造的(或多或少 - 有一些噱头,以确保您不会从目录树或提交中创建文件,并导致例如哈希冲突).Git假设无论内容如何,SHA-1都是唯一的:没有两个不同的文件,树,提交或带注释的标签将会散列到相同的值.
文件(和符号链接)是"blob"类型的对象.因此,git repo中的文件被散列,并且在某处,git具有映射:"文件命名.gitignore"为"散列值753be37fca1ed9b0f9267273b82881f8765d6b23").
在repo中,目录树存储为"树"类型的对象.树对象包含名称(如.gitignore),模式,对象类型(另一个树或blob)和SHA-1的列表:
$ git cat-file -p HEAD:
100644 blob 753be37fca1ed9b0f9267273b82881f8765d6b23 .gitignore
[snip]
Run Code Online (Sandbox Code Playgroud)
提交对象会获取(或git)树对象,最终会获取blob ID.
另一方面,暂存区域("索引")只是一个文件.git/index.此文件包含1个名称(以有趣的略微压缩形式展平目录树),合并冲突情况下的"阶段编号"和SHA-1.实际的文件内容再次是git repo中的blob.(Git不在索引中存储目录:索引只有实际文件,使用该展平格式.)
所以,当你这样做时:
git add file_name
Run Code Online (Sandbox Code Playgroud)
git这样做(或多或少,我故意掩盖过滤器):
file_name(git hash-object -t blob)内容的哈希值.-w选项to hash-object)..git/index(或$GIT_INDEX_FILE)以便它具有名称下的映射file_name到出来的名称git hash-object.这始终是"阶段0"条目(这是正常的,不合并冲突的版本).因此,文件不是真正"在"临时区域,它真的"在"回购本身!暂存区域中的内容是SHA-1映射的名称.
相比之下,git checkout [<tree-ish>] -- file_name这样做:
如果给定a <tree-ish>(提交名称,树对象ID等 - 基本上任何git都可以解析为树),则通过将参数转换为树对象从树中查找名称.使用这样定位的对象ID,更新索引中的哈希,作为阶段0.(如果file_name命名树对象,git递归地处理树表示的目录中的所有文件.)通过创建阶段0条目,任何合并冲突file_name都是现在已经解决
否则,在索引中进行名称查找(不确定如果file_name是目录会发生什么,可能git会读取工作目录).转换file_name为对象ID(此时将是一个blob).如果没有0级项,错误出与"未合并"的消息,除非给出-m,--ours,--theirs选项.使用-m将"取消合并"的文件(删除0期进入,并重新创建冲突合并2),而--ours并--theirs留在原地的任何阶段0条目(解决冲突撑解决).
在任何情况下,如果还没有出错,请使用这样定位的blob SHA-1将repo副本(或副本,如果file_name命名目录)提取到工作目录中.
因此,短版本是"是和否":git checkout有时修改索引,有时只使用它.但是,文件本身永远不会存储在索引中,只存储在repo中.如果你git add是一个文件,再改变它,git add它再次,这留下了git fsck会发现的"悬空blob":一个没有引用的对象.
1我故意省略索引中的许多其他东西,以使git表现良好,并允许--assume-unchanged等等(这些与此处的添加/结帐操作无关.)
2这种重新创建尊重任何更改merge.conflictstyle,因此如果您决定使用diff3输出并且已经存在没有diff3样式的冲突合并,则可以更改git配置并使用git checkout -m以获得与新样式合并的新工作目录.
| 归档时间: |
|
| 查看次数: |
1555 次 |
| 最近记录: |