| 1 | #!/usr/bin/perl |
| 2 | # |
| 3 | # Build a v2 index file from entries listed on stdin. |
| 4 | # Each line: "octalmode hex-oid name" |
| 5 | # Output: binary index written to stdout. |
| 6 | # |
| 7 | # This bypasses all D/F safety checks in add_index_entry(), simulating |
| 8 | # what happens when code uses ADD_CACHE_JUST_APPEND to bulk-load entries. |
| 9 | use strict; |
| 10 | use warnings; |
| 11 | use Digest::SHA qw(sha1 sha256); |
| 12 | |
| 13 | my $hash_algo = $ENV{'GIT_DEFAULT_HASH'} || 'sha1'; |
| 14 | my $hash_func = $hash_algo eq 'sha256' ? \&sha256 : \&sha1; |
| 15 | |
| 16 | my @entries; |
| 17 | while (my $line = <STDIN>) { |
| 18 | chomp $line; |
| 19 | my ($mode, $oid_hex, $name) = split(/ /, $line, 3); |
| 20 | push @entries, [$mode, $oid_hex, $name]; |
| 21 | } |
| 22 | |
| 23 | my $body = "DIRC" . pack("NN", 2, scalar @entries); |
| 24 | |
| 25 | for my $ent (@entries) { |
| 26 | my ($mode, $oid_hex, $name) = @{$ent}; |
| 27 | # 10 x 32-bit stat fields (zeroed), with mode in position 7 |
| 28 | my $stat = pack("N10", 0, 0, 0, 0, 0, 0, oct($mode), 0, 0, 0); |
| 29 | my $oid = pack("H*", $oid_hex); |
| 30 | my $flags = pack("n", length($name) & 0xFFF); |
| 31 | my $entry = $stat . $oid . $flags . $name . "\0"; |
| 32 | # Pad to 8-byte boundary |
| 33 | while (length($entry) % 8) { $entry .= "\0"; } |
| 34 | $body .= $entry; |
| 35 | } |
| 36 | |
| 37 | binmode STDOUT; |
| 38 | print $body . $hash_func->($body); |