mirror of
https://github.com/NixOS/nix.git
synced 2025-11-08 19:46:02 +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:
parent
7f4acb9f10
commit
d21e3f88ec
20 changed files with 350 additions and 181 deletions
|
|
@ -74,5 +74,10 @@ rec {
|
|||
nar-not-recursive = f2 "foo" ./fixed.builder2.sh "nar" "md5" "3670af73070fa14077ad74e0f5ea4e42";
|
||||
|
||||
# Experimental feature
|
||||
git = f2 "foo" ./fixed.builder2.sh "git" "sha1" "cd44baf36915d5dec8374232ea7e2057f3b4494e";
|
||||
|
||||
git-sha1 = f2 "foo" ./fixed.builder2.sh "git" "sha1" "cd44baf36915d5dec8374232ea7e2057f3b4494e";
|
||||
|
||||
git-sha256 =
|
||||
f2 "foo" ./fixed.builder2.sh "git" "sha256"
|
||||
"3c957653f90c34c0a8badf343b61393936cddf4a2ca93f64b21f02303ddedcc2";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
# shellcheck shell=bash
|
||||
|
||||
source ../common.sh
|
||||
|
||||
TODO_NixOS # Need to enable git hashing feature and make sure test is ok for store we don't clear
|
||||
|
|
|
|||
|
|
@ -5,4 +5,8 @@ source common.sh
|
|||
# Store layer needs bugfix
|
||||
requireDaemonNewerThan "2.27pre20250122"
|
||||
|
||||
nix-build ../fixed.nix -A git --no-out-link
|
||||
nix-build ../fixed.nix -A git-sha1 --no-out-link
|
||||
|
||||
if isDaemonNewer "2.31pre20250724"; then
|
||||
nix-build ../fixed.nix -A git-sha256 --no-out-link
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ suites += {
|
|||
'name': 'git-hashing',
|
||||
'deps': [],
|
||||
'tests': [
|
||||
'simple.sh',
|
||||
'simple-sha1.sh',
|
||||
'simple-sha256.sh',
|
||||
'fixed.sh',
|
||||
],
|
||||
'workdir': meson.current_source_dir(),
|
||||
|
|
|
|||
96
tests/functional/git-hashing/simple-common.sh
Normal file
96
tests/functional/git-hashing/simple-common.sh
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# shellcheck shell=bash
|
||||
|
||||
source common.sh
|
||||
|
||||
# Assert is set
|
||||
[[ ${hashAlgo+x} ]]
|
||||
|
||||
repo="$TEST_ROOT/scratch"
|
||||
|
||||
initRepo () {
|
||||
git init "$repo" --object-format="$hashAlgo"
|
||||
|
||||
git -C "$repo" config user.email "you@example.com"
|
||||
git -C "$repo" config user.name "Your Name"
|
||||
}
|
||||
|
||||
# Compare Nix's and git's implementation of git hashing
|
||||
try () {
|
||||
local expected="$1"
|
||||
|
||||
local hash
|
||||
hash=$(nix hash path --mode git --format base16 --algo "$hashAlgo" "$TEST_ROOT/hash-path")
|
||||
[[ "$hash" == "$expected" ]]
|
||||
|
||||
git -C "$repo" rm -rf hash-path || true
|
||||
cp -r "$TEST_ROOT/hash-path" "$repo/hash-path"
|
||||
git -C "$repo" add hash-path
|
||||
git -C "$repo" commit -m "x"
|
||||
git -C "$repo" status
|
||||
local hash2
|
||||
hash2=$(git -C "$repo" rev-parse HEAD:hash-path)
|
||||
[[ "$hash2" = "$expected" ]]
|
||||
}
|
||||
|
||||
# Check Nix added object has matching git hash
|
||||
try2 () {
|
||||
local hashPath="$1"
|
||||
local expected="$2"
|
||||
|
||||
local path
|
||||
path=$(nix store add --mode git --hash-algo "$hashAlgo" "$repo/$hashPath")
|
||||
|
||||
git -C "$repo" add "$hashPath"
|
||||
git -C "$repo" commit -m "x"
|
||||
git -C "$repo" status
|
||||
local hashFromGit
|
||||
hashFromGit=$(git -C "$repo" rev-parse "HEAD:$hashPath")
|
||||
[[ "$hashFromGit" == "$expected" ]]
|
||||
|
||||
local caFromNix
|
||||
caFromNix=$(nix path-info --json "$path" | jq -r ".[] | .ca")
|
||||
[[ "fixed:git:$hashAlgo:$(nix hash convert --to nix32 "$hashAlgo:$hashFromGit")" = "$caFromNix" ]]
|
||||
}
|
||||
|
||||
test0 () {
|
||||
rm -rf "$TEST_ROOT/hash-path"
|
||||
echo "Hello World" > "$TEST_ROOT/hash-path"
|
||||
}
|
||||
|
||||
test1 () {
|
||||
rm -rf "$TEST_ROOT/hash-path"
|
||||
mkdir "$TEST_ROOT/hash-path"
|
||||
echo "Hello World" > "$TEST_ROOT/hash-path/hello"
|
||||
echo "Run Hello World" > "$TEST_ROOT/hash-path/executable"
|
||||
chmod +x "$TEST_ROOT/hash-path/executable"
|
||||
}
|
||||
|
||||
test2 () {
|
||||
rm -rf "$repo/dummy1"
|
||||
echo Hello World! > "$repo/dummy1"
|
||||
}
|
||||
|
||||
test3 () {
|
||||
rm -rf "$repo/dummy2"
|
||||
mkdir -p "$repo/dummy2"
|
||||
echo Hello World! > "$repo/dummy2/hello"
|
||||
}
|
||||
|
||||
test4 () {
|
||||
rm -rf "$repo/dummy3"
|
||||
mkdir -p "$repo/dummy3"
|
||||
mkdir -p "$repo/dummy3/dir"
|
||||
touch "$repo/dummy3/dir/file"
|
||||
echo Hello World! > "$repo/dummy3/dir/file"
|
||||
touch "$repo/dummy3/dir/executable"
|
||||
chmod +x "$repo/dummy3/dir/executable"
|
||||
echo Run Hello World! > "$repo/dummy3/dir/executable"
|
||||
}
|
||||
|
||||
test5 () {
|
||||
rm -rf "$repo/dummy4"
|
||||
mkdir -p "$repo/dummy4"
|
||||
mkdir -p "$repo/dummy4/dir"
|
||||
touch "$repo/dummy4/dir/file"
|
||||
ln -s './hello/world.txt' "$repo/dummy4/dir/symlink"
|
||||
}
|
||||
27
tests/functional/git-hashing/simple-sha1.sh
Executable file
27
tests/functional/git-hashing/simple-sha1.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
hashAlgo=sha1
|
||||
|
||||
source simple-common.sh
|
||||
|
||||
initRepo
|
||||
|
||||
# blob
|
||||
test0
|
||||
try "557db03de997c86a4a028e1ebd3a1ceb225be238"
|
||||
|
||||
# tree with children
|
||||
test1
|
||||
try "e5c0a11a556801a5c9dcf330ca9d7e2c572697f4"
|
||||
|
||||
test2
|
||||
try2 dummy1 "980a0d5f19a64b4b30a87d4206aade58726b60e3"
|
||||
|
||||
test3
|
||||
try2 dummy2 "8b8e43b937854f4083ea56777821abda2799e850"
|
||||
|
||||
test4
|
||||
try2 dummy3 "f227adfaf60d2778aabbf93df6dd061272d2dc85"
|
||||
|
||||
test5
|
||||
try2 dummy4 "06f3e789820fc488d602358f03e3a1cbf993bf33"
|
||||
29
tests/functional/git-hashing/simple-sha256.sh
Executable file
29
tests/functional/git-hashing/simple-sha256.sh
Executable file
|
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
hashAlgo=sha256
|
||||
|
||||
source simple-common.sh
|
||||
|
||||
requireDaemonNewerThan 2.31pre20250724
|
||||
|
||||
initRepo
|
||||
|
||||
# blob
|
||||
test0
|
||||
try "7c5c8610459154bdde4984be72c48fb5d9c1c4ac793a6b5976fe38fd1b0b1284"
|
||||
|
||||
# tree with children
|
||||
test1
|
||||
try "cd79952f42462467d0ea574b0283bb6eb77e15b2b86891e29f2b981650365474"
|
||||
|
||||
test2
|
||||
try2 dummy1 "f5b5cec05fb6f9302b507a48c1573e6f36075e954d97caa8667f784e9cdb0d13"
|
||||
|
||||
test3
|
||||
try2 dummy2 "399d851c74ceac2c2b61b53b13dcf5e88df3b6135c7df1f248a323c3c2f9aa78"
|
||||
|
||||
test4
|
||||
try2 dummy3 "d3ae8fc87e76b9b871bd06a58c925c5fb5f83b5393f9f58e4f6dba3f59470289"
|
||||
|
||||
test5
|
||||
try2 dummy4 "8c090dd057e8e01ffe1fec24a3133dfe52ba4eda822e67ee7fefc2af7c6a2906"
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source common.sh
|
||||
|
||||
repo="$TEST_ROOT/scratch"
|
||||
git init "$repo"
|
||||
|
||||
git -C "$repo" config user.email "you@example.com"
|
||||
git -C "$repo" config user.name "Your Name"
|
||||
|
||||
# Compare Nix's and git's implementation of git hashing
|
||||
try () {
|
||||
local hash=$(nix hash path --mode git --format base16 --algo sha1 $TEST_ROOT/hash-path)
|
||||
[[ "$hash" == "$1" ]]
|
||||
|
||||
git -C "$repo" rm -rf hash-path || true
|
||||
cp -r "$TEST_ROOT/hash-path" "$TEST_ROOT/scratch/hash-path"
|
||||
git -C "$repo" add hash-path
|
||||
git -C "$repo" commit -m "x"
|
||||
git -C "$repo" status
|
||||
local hash2=$(git -C "$TEST_ROOT/scratch" rev-parse HEAD:hash-path)
|
||||
[[ "$hash2" = "$1" ]]
|
||||
}
|
||||
|
||||
# blob
|
||||
rm -rf $TEST_ROOT/hash-path
|
||||
echo "Hello World" > $TEST_ROOT/hash-path
|
||||
try "557db03de997c86a4a028e1ebd3a1ceb225be238"
|
||||
|
||||
# tree with children
|
||||
rm -rf $TEST_ROOT/hash-path
|
||||
mkdir $TEST_ROOT/hash-path
|
||||
echo "Hello World" > $TEST_ROOT/hash-path/hello
|
||||
echo "Run Hello World" > $TEST_ROOT/hash-path/executable
|
||||
chmod +x $TEST_ROOT/hash-path/executable
|
||||
try "e5c0a11a556801a5c9dcf330ca9d7e2c572697f4"
|
||||
|
||||
# Check Nix added object has matching git hash
|
||||
try2 () {
|
||||
local hashPath="$1"
|
||||
local expected="$2"
|
||||
|
||||
local path=$(nix store add --mode git --hash-algo sha1 "$repo/$hashPath")
|
||||
|
||||
git -C "$repo" add "$hashPath"
|
||||
git -C "$repo" commit -m "x"
|
||||
git -C "$repo" status
|
||||
local hashFromGit=$(git -C "$repo" rev-parse "HEAD:$hashPath")
|
||||
[[ "$hashFromGit" == "$2" ]]
|
||||
|
||||
local caFromNix=$(nix path-info --json "$path" | jq -r ".[] | .ca")
|
||||
[[ "fixed:git:sha1:$(nix hash convert --to nix32 "sha1:$hashFromGit")" = "$caFromNix" ]]
|
||||
}
|
||||
|
||||
rm -rf "$repo/dummy1"
|
||||
echo Hello World! > "$repo/dummy1"
|
||||
try2 dummy1 "980a0d5f19a64b4b30a87d4206aade58726b60e3"
|
||||
|
||||
rm -rf "$repo/dummy2"
|
||||
mkdir -p "$repo/dummy2"
|
||||
echo Hello World! > "$repo/dummy2/hello"
|
||||
try2 dummy2 "8b8e43b937854f4083ea56777821abda2799e850"
|
||||
|
||||
rm -rf "$repo/dummy3"
|
||||
mkdir -p "$repo/dummy3"
|
||||
mkdir -p "$repo/dummy3/dir"
|
||||
touch "$repo/dummy3/dir/file"
|
||||
echo Hello World! > "$repo/dummy3/dir/file"
|
||||
touch "$repo/dummy3/dir/executable"
|
||||
chmod +x "$repo/dummy3/dir/executable"
|
||||
echo Run Hello World! > "$repo/dummy3/dir/executable"
|
||||
try2 dummy3 "f227adfaf60d2778aabbf93df6dd061272d2dc85"
|
||||
|
||||
rm -rf "$repo/dummy4"
|
||||
mkdir -p "$repo/dummy4"
|
||||
mkdir -p "$repo/dummy4/dir"
|
||||
touch "$repo/dummy4/dir/file"
|
||||
ln -s './hello/world.txt' "$repo/dummy4/dir/symlink"
|
||||
try2 dummy4 "06f3e789820fc488d602358f03e3a1cbf993bf33"
|
||||
Loading…
Add table
Add a link
Reference in a new issue