From 12e0765577d2e0d4c26267f3b8fd781aed84d365 Mon Sep 17 00:00:00 2001 From: Meghan Denny Date: Fri, 13 Mar 2026 14:03:11 -0700 Subject: [PATCH] fix a commit from the linux kernel --- git.zig | 68 +++--- test.zig | 8 +- ...f-a0482e3446cea426bf16571e0000423ed5b25af0 | 208 ++++++++++++++++++ 3 files changed, 254 insertions(+), 30 deletions(-) create mode 100644 testdata/diff-a0482e3446cea426bf16571e0000423ed5b25af0 diff --git a/git.zig b/git.zig index 31ff0f72f674bb32595363a5ab542a4e0f92ebf4..90a18ecf6a78044663e411f7b85d1701aec31f82 100644 --- a/git.zig +++ b/git.zig @@ -6,8 +6,7 @@ const extras = @import("extras"); const tracer = @import("tracer"); const nfs = @import("nfs"); -// 40 is length of sha1 hash -pub const Id = *const [40]u8; +pub const Id = []const u8; pub const TreeId = struct { id: Id, @@ -96,9 +95,10 @@ pub fn getHEAD(alloc: std.mem.Allocator, dir: nfs.Dir) !?CommitId { return ensureObjId(CommitId, h); } +// 40 is length of sha1 hash pub fn ensureObjId(comptime T: type, input: string) T { extras.assertLog(input.len == 40, "ensureObjId: {s}", .{input}); - return .{ .id = input[0..40] }; + return .{ .id = input }; } // TODO make this inspect .git/objects @@ -450,7 +450,7 @@ pub fn getTreeDiff(alloc: std.mem.Allocator, dir: nfs.Dir, commitid: CommitId, p .cwd_dir = dir.to_std(), // 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is a hardcode for the empty tree in git sha1 // result of `printf | git hash-object -t tree --stdin` - .argv = &.{ "git", "diff-tree", "-p", "--raw", "4b825dc642cb6eb9a060e54bf8d69288fbee4904", commitid.id }, + .argv = &.{ "git", "diff-tree", "-p", "--raw", "--full-index", "4b825dc642cb6eb9a060e54bf8d69288fbee4904", commitid.id }, .max_output_bytes = 1024 * 1024 * 1024, }); std.debug.assert(result.term == .Exited and result.term.Exited == 0); @@ -459,7 +459,7 @@ pub fn getTreeDiff(alloc: std.mem.Allocator, dir: nfs.Dir, commitid: CommitId, p const result = try std.process.Child.run(.{ .allocator = alloc, .cwd_dir = dir.to_std(), - .argv = &.{ "git", "diff-tree", "-p", "--raw", parentid.?.id, commitid.id }, + .argv = &.{ "git", "diff-tree", "-p", "--raw", "--full-index", parentid.?.id, commitid.id }, .max_output_bytes = 1024 * 1024 * 1024, }); std.debug.assert(result.term == .Exited and result.term.Exited == 0); @@ -478,7 +478,7 @@ pub fn getTreeDiffPath(alloc: std.mem.Allocator, dir: nfs.Dir, commitid: CommitI .cwd_dir = dir.to_std(), // 4b825dc642cb6eb9a060e54bf8d69288fbee4904 is a hardcode for the empty tree in git sha1 // result of `printf | git hash-object -t tree --stdin` - .argv = &.{ "git", "diff-tree", "-p", "--raw", "4b825dc642cb6eb9a060e54bf8d69288fbee4904", commitid.id, "--", path }, + .argv = &.{ "git", "diff-tree", "-p", "--raw", "--full-index", "4b825dc642cb6eb9a060e54bf8d69288fbee4904", commitid.id, "--", path }, .max_output_bytes = 1024 * 1024 * 1024, }); std.debug.assert(result.term == .Exited and result.term.Exited == 0); @@ -487,7 +487,7 @@ pub fn getTreeDiffPath(alloc: std.mem.Allocator, dir: nfs.Dir, commitid: CommitI const result = try std.process.Child.run(.{ .allocator = alloc, .cwd_dir = dir.to_std(), - .argv = &.{ "git", "diff-tree", "-p", "--raw", parentid.?.id, commitid.id, "--", path }, + .argv = &.{ "git", "diff-tree", "-p", "--raw", "--full-index", parentid.?.id, commitid.id, "--", path }, .max_output_bytes = 1024 * 1024 * 1024, }); std.debug.assert(result.term == .Exited and result.term.Exited == 0); @@ -602,22 +602,9 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff { }, .action = std.meta.stringToEnum(TreeDiff.Action, action_s).?, .sub_path = kter.rest(), - .adds = 0, - .subs = 0, }); } - const S = struct { - fn eql(comptime a: u8) fn (u8) bool { - const SS = struct { - fn actual(b: u8) bool { - return a == b; - } - }; - return SS.actual; - } - }; - // diff --git a/notes/all_packages.txt b/notes/all_packages.txt // index c06b41d..e8f91cf 100644 // --- a/notes/all_packages.txt @@ -630,10 +617,17 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff { blk: while (true) { const first_line = lineiter.next().?; std.debug.assert(std.mem.startsWith(u8, first_line, "diff --git")); - const i = diffs.items.len; - try diffs.append(.{ .before_path = overview.items[i].sub_path, .after_path = overview.items[i].sub_path, .content = "" }); - if (extras.matchesAll(u8, overview.items[i].before.blob.id, S.eql('0'))) diffs.items[i].before_path = "/dev/null"; - if (extras.matchesAll(u8, overview.items[i].after.blob.id, S.eql('0'))) diffs.items[i].after_path = "/dev/null"; + var i = diffs.items.len; + for (overview.items[0..i]) |o| i -= @intFromBool(o.action == .T); + try diffs.append(.{ + .index = .{ "", "" }, + .before_path = overview.items[i].sub_path, + .after_path = overview.items[i].sub_path, + .subs = 0, + .adds = 0, + .content = "", + }); + const diff = &diffs.items[diffs.items.len - 1]; while (true) { if (lineiter.index.? >= input.len) { @@ -641,6 +635,13 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff { } if (lineiter.peek()) |lin| { if (std.mem.startsWith(u8, lin, "index")) { + const index = lin[6..]; + var iiter = std.mem.splitSequence(u8, index, ".."); + diff.index[0] = iiter.next().?; + diff.index[1] = iiter.next().?; + std.debug.assert(iiter.next() == null); + if (std.mem.indexOfScalar(u8, diff.index[1], ' ')) |j| diff.index[1] = diff.index[1][0..j]; + lineiter.index.? += lin.len + 1; break; } @@ -676,10 +677,12 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff { } if (lineiter.peek()) |lin| { if (std.mem.startsWith(u8, lin, "--- ")) { + diff.before_path = extras.trimPrefix(lin[4..], "a/"); lineiter.index.? += lin.len + 1; continue; } if (std.mem.startsWith(u8, lin, "+++ ")) { + diff.after_path = extras.trimPrefix(lin[4..], "b/"); lineiter.index.? += lin.len + 1; continue; } @@ -701,7 +704,7 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff { } } if (lineiter.index.? >= input.len) { - diffs.items[diffs.items.len - 1].content = input[content_start..]; + diff.content = input[content_start..]; break :blk; } @@ -709,13 +712,19 @@ pub fn parseTreeDiff(alloc: std.mem.Allocator, input: string) !TreeDiff { if (lineiter.peek()) |lin| { if (std.mem.startsWith(u8, lin, "diff --git")) { const content_end = lineiter.index.? - 1; - diffs.items[diffs.items.len - 1].content = input[content_start..content_end]; + diff.content = input[content_start..content_end]; continue :blk; } + if (lin[0] == '-') { + diff.subs += 1; + } + if (lin[0] == '+') { + diff.adds += 1; + } lineiter.index.? += lin.len + 1; if (lineiter.index.? >= input.len) { - diffs.items[diffs.items.len - 1].content = input[content_start..]; + diff.content = input[content_start..]; break :blk; } } @@ -737,8 +746,6 @@ pub const TreeDiff = struct { after: State, action: Action, sub_path: string, - adds: u32, - subs: u32, }; pub const State = struct { @@ -764,8 +771,11 @@ pub const TreeDiff = struct { }; pub const Diff = struct { + index: [2][]const u8, before_path: string, after_path: string, + adds: u32, + subs: u32, content: string, }; }; diff --git a/test.zig b/test.zig index db7ea5d3a7e8fd485beb6cab326b06ff404df142..27924b878b0c6b55aa92e165605396f2d7a189c4 100644 --- a/test.zig +++ b/test.zig @@ -145,7 +145,7 @@ test { ":100644 100644 73c7032166db0eb23c4be11a4ff8ff26ec47c582 b229eadbd5d6655c2dfbaca5a5f68f2f8f3c5454 M\tgit.zig\n" ++ "\n" ++ "diff --git a/git.zig b/git.zig\n" ++ - "index 73c7032..b229ead 100644\n" ++ + "index 73c7032166db0eb23c4be11a4ff8ff26ec47c582..b229eadbd5d6655c2dfbaca5a5f68f2f8f3c5454 100644\n" ++ "--- a/git.zig\n" ++ "+++ b/git.zig\n" ++ "@@ -251,10 +251,10 @@ pub fn parseTree(alloc: std.mem.Allocator, treefile: string) !Tree {\n" ++ @@ -250,3 +250,9 @@ test { const alloc = arena.allocator(); _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-1f7390f3999e80f775dbc0e62f1dcb071c3bed77")); // zig } +test { + var arena = std.heap.ArenaAllocator.init(std.testing.allocator); + defer arena.deinit(); + const alloc = arena.allocator(); + _ = try git.parseTreeDiff(alloc, @embedFile("./testdata/diff-a0482e3446cea426bf16571e0000423ed5b25af0")); // linux +} diff --git a/testdata/diff-a0482e3446cea426bf16571e0000423ed5b25af0 b/testdata/diff-a0482e3446cea426bf16571e0000423ed5b25af0 new file mode 100644 index 0000000000000000000000000000000000000000..b5c66737f55661eb5e44f0a27a98660d9e9819d0 --- /dev/null +++ b/testdata/diff-a0482e3446cea426bf16571e0000423ed5b25af0 @@ -0,0 +1,208 @@ +:100644 100644 12a0614b9fd4983deffe5d6a7cfa06ba8d92a516 918a2caa070ebc681a9525f0518afffcf10f5ae3 M tools/testing/selftests/vDSO/Makefile +:100644 100644 722260f9756198956f0dfccced907284b6851e76 5fdd0f36233742bc47ae79f23d2cfae5a0f56dee M tools/testing/selftests/vDSO/vdso_config.h +:100644 120000 9ce795b806f0992b83cef78c7e16fac0e54750da 4d3d96f1e440c965474681a6f35375a60b3921be T tools/testing/selftests/vDSO/vdso_standalone_test_x86.c +:100644 100644 8757f738b0b1a76a48c83c5e5df79925a30c1bc7 0aad682b12c8836efabb49a65a47cf87466891a3 M tools/testing/selftests/vDSO/vdso_test_chacha.c +:100644 100644 38d46a8bf7cba7a9b4a9b13b5eb17aa207972bd0 b5d5f59f725a703c357dfca91bfe170aaaeb42fa M tools/testing/selftests/vDSO/vdso_test_clock_getres.c +:100644 100644 5fb97ad67eeaf17b6cfa4f82783c57894f03e5c5 da651cf53c6ca4242085de109c7fc57bd807297c M tools/testing/selftests/vDSO/vdso_test_correctness.c +:100644 100644 95057f7567db22226d9cb09a667a56e387a33a46 dd1132508a0db29a32ec977b30f64b20aa43e03d M tools/testing/selftests/vDSO/vdso_test_getrandom.c + +diff --git a/tools/testing/selftests/vDSO/Makefile b/tools/testing/selftests/vDSO/Makefile +index 12a0614b9fd4..918a2caa070e 100644 +--- a/tools/testing/selftests/vDSO/Makefile ++++ b/tools/testing/selftests/vDSO/Makefile +@@ -12,7 +12,7 @@ TEST_GEN_PROGS += vdso_test_correctness + TEST_GEN_PROGS += vdso_test_getrandom + TEST_GEN_PROGS += vdso_test_chacha + +-CFLAGS := -std=gnu99 -O2 ++CFLAGS := -std=gnu99 -O2 -Wall -Wstrict-prototypes + + ifeq ($(CONFIG_X86_32),y) + LDLIBS += -lgcc_s +diff --git a/tools/testing/selftests/vDSO/vdso_config.h b/tools/testing/selftests/vDSO/vdso_config.h +index 722260f97561..5fdd0f362337 100644 +--- a/tools/testing/selftests/vDSO/vdso_config.h ++++ b/tools/testing/selftests/vDSO/vdso_config.h +@@ -58,6 +58,7 @@ + #define VDSO_NAMES 1 + #endif + ++__attribute__((unused)) + static const char *versions[7] = { + "LINUX_2.6", + "LINUX_2.6.15", +@@ -68,6 +69,7 @@ static const char *versions[7] = { + "LINUX_5.10" + }; + ++__attribute__((unused)) + static const char *names[2][7] = { + { + "__kernel_gettimeofday", +diff --git a/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c +deleted file mode 100644 +index 9ce795b806f0..000000000000 +--- a/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c ++++ /dev/null +@@ -1,58 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0-only +-/* +- * vdso_test_gettimeofday.c: Sample code to test parse_vdso.c and +- * vDSO gettimeofday() +- * Copyright (c) 2014 Andy Lutomirski +- * +- * Compile with: +- * gcc -std=gnu99 vdso_test_gettimeofday.c parse_vdso_gettimeofday.c +- * +- * Tested on x86, 32-bit and 64-bit. It may work on other architectures, too. +- */ +- +-#include +-#ifndef NOLIBC +-#include +-#include +-#endif +- +-#include "../kselftest.h" +-#include "parse_vdso.h" +-#include "vdso_config.h" +-#include "vdso_call.h" +- +-int main(int argc, char **argv) +-{ +- const char *version = versions[VDSO_VERSION]; +- const char **name = (const char **)&names[VDSO_NAMES]; +- +- unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR); +- if (!sysinfo_ehdr) { +- printf("AT_SYSINFO_EHDR is not present!\n"); +- return KSFT_SKIP; +- } +- +- vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR)); +- +- /* Find gettimeofday. */ +- typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz); +- gtod_t gtod = (gtod_t)vdso_sym(version, name[0]); +- +- if (!gtod) { +- printf("Could not find %s\n", name[0]); +- return KSFT_SKIP; +- } +- +- struct timeval tv; +- long ret = VDSO_CALL(gtod, 2, &tv, 0); +- +- if (ret == 0) { +- printf("The time is %lld.%06lld\n", +- (long long)tv.tv_sec, (long long)tv.tv_usec); +- } else { +- printf("%s failed\n", name[0]); +- return KSFT_FAIL; +- } +- +- return 0; +-} +diff --git a/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c +new file mode 120000 +index 000000000000..4d3d96f1e440 +--- /dev/null ++++ b/tools/testing/selftests/vDSO/vdso_standalone_test_x86.c +@@ -0,0 +1 @@ ++vdso_test_gettimeofday.c +\ No newline at end of file +diff --git a/tools/testing/selftests/vDSO/vdso_test_chacha.c b/tools/testing/selftests/vDSO/vdso_test_chacha.c +index 8757f738b0b1..0aad682b12c8 100644 +--- a/tools/testing/selftests/vDSO/vdso_test_chacha.c ++++ b/tools/testing/selftests/vDSO/vdso_test_chacha.c +@@ -76,7 +76,8 @@ static void reference_chacha20_blocks(uint8_t *dst_bytes, const uint32_t *key, u + + void __weak __arch_chacha20_blocks_nostack(uint8_t *dst_bytes, const uint32_t *key, uint32_t *counter, size_t nblocks) + { +- ksft_exit_skip("Not implemented on architecture\n"); ++ ksft_test_result_skip("Not implemented on architecture\n"); ++ ksft_finished(); + } + + int main(int argc, char *argv[]) +diff --git a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c +index 38d46a8bf7cb..b5d5f59f725a 100644 +--- a/tools/testing/selftests/vDSO/vdso_test_clock_getres.c ++++ b/tools/testing/selftests/vDSO/vdso_test_clock_getres.c +@@ -13,7 +13,6 @@ + + #define _GNU_SOURCE + #include +-#include + #include + #include + #include +diff --git a/tools/testing/selftests/vDSO/vdso_test_correctness.c b/tools/testing/selftests/vDSO/vdso_test_correctness.c +index 5fb97ad67eea..da651cf53c6c 100644 +--- a/tools/testing/selftests/vDSO/vdso_test_correctness.c ++++ b/tools/testing/selftests/vDSO/vdso_test_correctness.c +@@ -108,7 +108,7 @@ static void *vsyscall_getcpu(void) + } + + +-static void fill_function_pointers() ++static void fill_function_pointers(void) + { + void *vdso = dlopen("linux-vdso.so.1", + RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); +diff --git a/tools/testing/selftests/vDSO/vdso_test_getrandom.c b/tools/testing/selftests/vDSO/vdso_test_getrandom.c +index 95057f7567db..dd1132508a0d 100644 +--- a/tools/testing/selftests/vDSO/vdso_test_getrandom.c ++++ b/tools/testing/selftests/vDSO/vdso_test_getrandom.c +@@ -21,7 +21,6 @@ + #include + #include + #include +-#include + #include + + #include "../kselftest.h" +@@ -101,6 +100,7 @@ static void *vgetrandom_get_state(void) + return state; + } + ++__attribute__((unused)) /* Example for libc implementors */ + static void vgetrandom_put_state(void *state) + { + if (!state) +@@ -242,6 +242,7 @@ static void kselftest(void) + pid_t child; + + ksft_print_header(); ++ vgetrandom_init(); + ksft_set_plan(2); + + for (size_t i = 0; i < 1000; ++i) { +@@ -265,7 +266,7 @@ static void kselftest(void) + } + for (;;) { + struct ptrace_syscall_info info = { 0 }; +- int status, ret; ++ int status; + ksft_assert(waitpid(child, &status, 0) >= 0); + if (WIFEXITED(status)) { + ksft_assert(WEXITSTATUS(status) == 0); +@@ -295,8 +296,6 @@ static void usage(const char *argv0) + + int main(int argc, char *argv[]) + { +- vgetrandom_init(); +- + if (argc == 1) { + kselftest(); + return 0; +@@ -306,6 +305,9 @@ int main(int argc, char *argv[]) + usage(argv[0]); + return 1; + } ++ ++ vgetrandom_init(); ++ + if (!strcmp(argv[1], "bench-single")) + bench_single(); + else if (!strcmp(argv[1], "bench-multi")) -- 2.54.0