我正在做一些 Java 类来从 Git 对象读取信息。每个类都以相同的方式工作:使用存储库路径和哈希来检索文件,然后打开、膨胀并每次读取一行。这对于 blob 和提交非常有效,但不知何故,膨胀不适用于树对象。
我用来读取文件的代码在任何地方都是相同的:
FileInputStream fis = new FileInputStream(path);
InflaterInputStream inStream = new InflaterInputStream(fis);
BufferedReader bf = new BufferedReader(new InputStreamReader(inStream));
对于树木之外的每个物体,它都可以正常工作。当我尝试以这种方式读取一棵树时,我得到:
tree 167100644 README.mdDRwJiU��#�%?^>n��40000 dir1*�j4ކ��K-�������100644 file1�⛲��CK�)�wZ���S�100644 file2�⛲��CK�)�wZ���S�100644 file4�⛲��CK�)�wZ���S�
似乎文件名和八进制模式是以正确的方式解码的,而哈希值则不然(并且我用上面的代码解码其他哈希值没有任何问题)。树对象和其他 git 对象中的哈希编码之间有什么区别吗?
最佳答案
问题的核心是 git 树文件中有两种编码(文档中并不清楚)。文件的大部分内容都是用 ASCII 编码的,这意味着可以用您喜欢的任何内容来读取它但哈希值没有编码,它们只是原始字节。
由于有两种不同的编码,最好的解决方案是逐字节读取文件,记住文件在哪里。
我的解决方案(我只对内容的名称和哈希值感兴趣,所以其余的都被丢弃):
FileInputStream fis = new FileInputStream(this.filepath);
InflaterInputStream inStream = new InflaterInputStream(fis);
int i = -1;
while((i = inStream.read()) != 0){
//First line
}
//Content data
while((i = inStream.read()) != -1){
while((i = inStream.read()) != 0x20){ //0x20 is the space char
//Permission bytes
}
//Filename: 0-terminated
String filename = "";
while((i = inStream.read()) != 0){
filename += (char) i;
}
//Hash: 20 byte long, can contain any value, the only way
// to be sure is to count the bytes
String hash = "";
for(int count = 0; count < 20 ; count++){
i = inStream.read();
hash += Integer.toHexString(i);
}
}
关于java - 如何膨胀 git 树对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42009133/