bey*_*ran 3 git internals digital-signature
在git status查看本地文件夹中是否有任何更改时会发生什么?
据我所知,每个文件都通过哈希码(准确地说:sha1)进行"注册",并且git status"简单地"尝试匹配到目前为止已注册的哈希值,并且如果有不同的东西则被认为是状态改变.说实话,我不太确定,如果我错了,我想纠正.无论如何,出现了一些问题:
git add,git commit -am,git gc要理解这一点,首先需要了解对象git存储,所有这些都由SHA1哈希标识.他们是承诺,树木和斑点.
Commit包含提交消息,提交者,日期,父提交的SHA1和树的SHA1(以及一些附加信息).
树代表一个目录.它包含它包含的文件和目录的名称(和其他元数据).对于每个文件,它还包含相应blob的SHA1,并且对于每个子目录,它包含另一个树的SHA1.
Blob表示文件的内容,没有名称或任何其他元数据.
现在,git status比较三棵树:
HEAD通常是当前分支上的最新提交).git add它们的地方,用于在实际提交之前准备提交.这就是为什么,如果你编辑一个文件(比如a.txt),git add然后编辑它,然后再使用git status,你得到一个这样的输出:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: a.txt
#
Run Code Online (Sandbox Code Playgroud)
现在问你的实际问题:
在哪里可以找到哈希?repo特定的东西有很多哈希,但我在哪里找到每个文件的注册哈希?
它们存储在树对象中.例如,要查看当前commit(HEAD)的树对象,请使用git ls-tree HEAD:
$ git ls-tree HEAD
100644 blob 9c59e24b8393179a5d712de4f990178df5734d99 a.txt
Run Code Online (Sandbox Code Playgroud)
您可以看到repo的根目录包含一个blob名为a.txt的文件(),其SHA1为9c59e24b8393179a5d712de4f990178df5734d99.
您可以使用相同的命令查看子目录中的子目录和文件的SHA1,有关详细信息,请参阅命令文档.
要计算磁盘上某些文件的SHA1,您可以使用git hash-object.
如果运行以下命令之一,这些哈希会发生什么
您应该记住SHA1基于对象的内容.并且每个对象都是完全不可变的,因此某个对象的SHA1永远不会改变.但是许多操作可以创建新对象,例如它们也可以更改为某个分支点的对象.
git add 获取暂存区域中的树,通过根据命令的参数添加或更改某些文件来修改它,并将修改后的树保存回暂存区域.git commit获取暂存区域中的树并创建指向该树的提交.新提交也具有当前日期,您作为提交者,当前提交作为其父项.然后,该命令将当前分支更改为指向新提交.git commit -a只是git add后面的捷径git commit.git gc查看它存储的所有对象并删除那些无法访问的对象.可访问对象是所有分支,标记或当前提交的提示,也是它们以递归方式引用的所有对象.最近使用的提交(以及它们引用的对象)也不会被删除,因为它们可以通过reflog访问.