1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-22 02:09:36 +01:00

Implement support for Git hashing with SHA-256

SHA-256 is Git's next hash algorithm. The world is still basically stuck
on SHA-1 with git, but shouldn't be. We can at least do our part to get
ready.

On the C++ implementation side, only a little bit of generalization was
needed, and that was fairly straight-forward. The tests (unit and
system) were actually bigger, and care was taken to make sure they were
all cover both algorithms equally.
This commit is contained in:
John Ericson 2025-07-24 14:44:05 -04:00
parent 7f4acb9f10
commit d21e3f88ec
20 changed files with 350 additions and 181 deletions

44
src/libutil-tests/data/git/check-data.sh Normal file → Executable file
View file

@ -2,30 +2,34 @@
set -eu -o pipefail
export TEST_ROOT=$(realpath ${TMPDIR:-/tmp}/nix-test)/git-hashing/check-data
mkdir -p $TEST_ROOT
TEST_ROOT=$(realpath "${TMPDIR:-/tmp}/nix-test")/git-hashing/check-data
export TEST_ROOT
mkdir -p "$TEST_ROOT"
repo="$TEST_ROOT/scratch"
git init "$repo"
for hash in sha1 sha256; do
repo="$TEST_ROOT/scratch-$hash"
git init "$repo" --object-format="$hash"
git -C "$repo" config user.email "you@example.com"
git -C "$repo" config user.name "Your Name"
git -C "$repo" config user.email "you@example.com"
git -C "$repo" config user.name "Your Name"
# `-w` to write for tree test
freshlyAddedHash=$(git -C "$repo" hash-object -w -t blob --stdin < "./hello-world.bin")
encodingHash=$(sha1sum -b < "./hello-world-blob.bin" | head -c 40)
# `-w` to write for tree test
freshlyAddedHash=$(git -C "$repo" hash-object -w -t blob --stdin < "./hello-world.bin")
encodingHash=$("${hash}sum" -b < "./hello-world-blob.bin" | sed 's/ .*//')
# If the hashes match, then `hello-world-blob.bin` must be the encoding
# of `hello-world.bin`.
[[ "$encodingHash" == "$freshlyAddedHash" ]]
# If the hashes match, then `hello-world-blob.bin` must be the encoding
# of `hello-world.bin`.
[[ "$encodingHash" == "$freshlyAddedHash" ]]
# Create empty directory object for tree test
echo -n | git -C "$repo" hash-object -w -t tree --stdin
# Create empty directory object for tree test
echo -n | git -C "$repo" hash-object -w -t tree --stdin
# Relies on both child hashes already existing in the git store
freshlyAddedHash=$(git -C "$repo" mktree < "./tree.txt")
encodingHash=$(sha1sum -b < "./tree.bin" | head -c 40)
# Relies on both child hashes already existing in the git store
tree=tree-${hash}
freshlyAddedHash=$(git -C "$repo" mktree < "${tree}.txt")
encodingHash=$("${hash}sum" -b < "${tree}.bin" | sed 's/ .*//')
# If the hashes match, then `tree.bin` must be the encoding of the
# directory denoted by `tree.txt` interpreted as git directory listing.
[[ "$encodingHash" == "$freshlyAddedHash" ]]
# If the hashes match, then `tree.bin` must be the encoding of the
# directory denoted by `tree.txt` interpreted as git directory listing.
[[ "$encodingHash" == "$freshlyAddedHash" ]]
done