-- SPDX-FileCopyrightText: © 2022—2026 Vladimir Zorin -- SPDX-License-Identifier: LicenseRef-OWL-1.0-or-later -- Licensed under OWL v1.0+. See LICENSE. local testimony = require("testimony") local std = require("std") local git_pack = require("git.pack") local crypto = require("crypto") local testify = testimony.new("== git.pack ==") -- os.execute returns a boolean with LUA52COMPAT, a number otherwise local sh = function(cmd) local r = os.execute(cmd .. " >/dev/null 2>&1") return r == true or r == 0 end local has_git = sh("git --version") local sh_out = function(cmd) local f = io.popen(cmd) if not f then return nil end local out = f:read("*a") f:close() return out and out:match("^%s*(.-)%s*$") end local make_fixture = function() local dir = "/tmp/" .. std.nanoid() local g = "git -C " .. dir .. " -c user.name=test -c user.email=test@test" if not sh("git init -q " .. dir) then return nil end std.fs.write_file(dir .. "/readme.txt", "hello lilush pack writer\n") std.fs.mkdir(dir .. "/sub") std.fs.write_file(dir .. "/sub/data.bin", string.rep("\0\1\2\3", 1024)) sh(g .. " add -A") sh(g .. " commit -q -m first") std.fs.write_file(dir .. "/readme.txt", "hello again\n") sh(g .. " add -A") sh(g .. " commit -q -m second") local head = sh_out("git -C " .. dir .. " rev-parse HEAD") if not head or #head ~= 40 then return nil end return { dir = dir, git_dir = dir .. "/.git", head = head } end local fixture = has_git and make_fixture() or nil if fixture then testify:that("collect_objects: walks the full graph from HEAD", function() local objects = git_pack.collect_objects(fixture.git_dir, { fixture.head }) testimony.assert_not_nil(objects) -- 2 commits, 3 trees (root x2 + sub), 3 blobs (readme x2 + data.bin) testimony.assert_equal(8, #objects) end) testify:that("collect_objects: unknown want yields an error", function() local objects, err = git_pack.collect_objects(fixture.git_dir, { string.rep("f", 40) }) testimony.assert_nil(objects) testimony.assert_match("object not found", err) end) testify:that("build_pack: valid pack v2 structure and trailer", function() local objects = git_pack.collect_objects(fixture.git_dir, { fixture.head }) local pack = git_pack.build_pack(fixture.git_dir, objects) testimony.assert_equal("PACK", pack:sub(1, 4)) testimony.assert_equal("\0\0\0\2", pack:sub(5, 8)) testimony.assert_equal(#objects, string.byte(pack, 12)) testimony.assert_equal(crypto.sha1(pack:sub(1, -21)), pack:sub(-20)) end) testify:that("build_pack: output passes git index-pack --strict", function() local objects = git_pack.collect_objects(fixture.git_dir, { fixture.head }) local pack = git_pack.build_pack(fixture.git_dir, objects) local pack_path = fixture.dir .. "/generated.pack" std.fs.write_file(pack_path, pack) testimony.assert_true(sh("git index-pack --strict " .. pack_path)) end) else print("-- git binary not found (or fixture failed), skipping git.pack tests --") end if fixture then os.execute("rm -rf " .. fixture.dir) end testify:conclude()