当git status
查看本地文件夹中是否有任何更改时,究竟会发生什么?
据我所知,每个文件都是通过哈希码(确切地说:sha1)“注册”而git status
“只是”尝试匹配到目前为止已注册的哈希值,并且在运行中计算,如果有不同之处,则认为状态发生了变化。说实话,我不太确定,如果我错了,我想纠正。无论如何,出现了一些问题:
git add
,git commit -am
,git gc
答案 0 :(得分:5)
要理解这一点,首先需要了解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
#
现在问你的实际问题:
哪里可以找到哈希? repo特定的东西有很多哈希,但我在哪里找到每个文件的注册哈希值?
它们存储在树对象中。例如,要查看当前提交的树对象(HEAD
),请使用git ls-tree HEAD
:
$ git ls-tree HEAD
100644 blob 9c59e24b8393179a5d712de4f990178df5734d99 a.txt
您可以看到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访问。答案 1 :(得分:2)
查看chapter 9.2电子书的progit。
整本电子书值得一读。