Re:Shit – An implementation of Git using POSIX shell
by TeMPOraL on Wednesday February 12, 2020 @01:13PM
(#22311146)
Is git even a Merkle tree? Git history forms a DAG, not a tree. But I'm not 100% sure about how the hashes are computed - whether they work on the DAG, or on some local subtree.
Re:Shit – An implementation of Git using POSIX shell
by ilammy on Wednesday February 12, 2020 @04:09PM
(#22312839)
No, it’s not. Commit hashes are exactly what it says on the tin: hash sums of commit objects, which are basically text files that include hash sums of tree objects (directory tree state), hash sums of parent commits, your commit message and other metadata. You can see it with "git cat-file":
$ git cat-file -p d8defd0bb0062ed541de173a2aec834b64d6adbe
tree cbdb56fe9bb1766d8fc2b2e53c9c934efbacbf1c
parent a8a1049c06d100a3f926a82414e6addb9b9af5e8
author ilammy <[email protected]> 1581533224 +0200
committer ilammy <[email protected]> 1581533224 +0200
fixup! Avoid unsigned overflow in length computations
And compute the commit hash manually to verify that: $ sha=d8defd0bb0062ed541de173a2aec834b64d6adbe
$ cat <(echo -ne "$(git cat-file -t $sha) $(git cat-file -s $sha)\0") \
<(git cat-file -p $sha) | sha1sum
d8defd0bb0062ed541de173a2aec834b64d6adbe -
Git prefixes object content with object type ("commit" in case of commits), its size in bytes (textual, decimal), terminated by a null byte. And hashes all of that get the commit hash.
Not really, not every block chain is a Merkle tree. Since Git history is not linear, you can’t order the commits in any canonical way. You definitely can order them in some way (like "git log" does) and then construct a tree for that list of hashes, but this is not really useful computation. Git repo integrity is verified simply by HEAD commit hash because you normally clone the entire repository anyway.