如何在 Node.js 中做正确的 Git 兼容的十六进制 sha packing/compression

How to do proper Git compatible hex sha packing/compression in Node.js

我目前正在尝试将 ruby 代码移植到 javascript。 我有这个

ENTRY_FORMAT = "A7Z*H40"
mode = "100644"
fileName = "tree.js"
sha= "baae99010b237a699ff0aba02fd5310c18903b1b"
[mode, filename, sha].pack(ENTRY_FORMAT)

其中MODE、entry.name和entry.oid为字符串

• A7 : 这会将第一个字符串 MODE 编码为在右侧用空格填充的七字节字符串

• Z* :这将第二个字符串 entry.name 编码为任意长度的空填充字符串,即 也就是说,它按原样表示字符串,并在末尾附加一个空字节

•H40 :这编码了一个由四十个十六进制数字组成的字符串 entry.oid ,通过打包每对 正如我们在第 2.3.3 节“磁盘上的树”中看到的那样,将数字转换为单个字节

我可以在 javaScript 中执行此操作吗?

我假设你的意思是 mode 也是一个字符串。

let fileName = "file.js";
let sha = "baae99010b237a699ff0aba02fd5310c18903b1b";
let mode = '100664';

// encode all into bytes
let enc = new TextEncoder();
let modeArray = enc.encode(mode.padEnd(7));
let fileNameArray = enc.encode(fileName + '[=10=]');
let shaArray = Uint8Array.from(sha.match(/../g), x => parseInt(x, 16));

// concatenate together
let array = new Uint8Array([...modeArray, ...fileNameArray, ...shaArray]);

console.log(array);

Node.js有Bufferclass,这简化了其中一些操作:

let modeBuffer = Buffer.from(mode.padEnd(7));
let fileNameBuffer = Buffer.from(fileName + '[=11=]');
let shaBuffer = Buffer.from(sha, 'hex');
let buffer = Buffer.concat([modeBuffer, fileNameBuffer, shaBuffer]);
// can fs.writeFile(file, buffer, ...)