我是靠谱客的博主 美好铃铛,这篇文章主要介绍GIT 源码阅读之 cat-file,现在分享给大家,希望可以做个参考。

说明

本文所有代码基于 GIT COMMIT e83c5163316f89bfbde7d9ab23ca2e25604af290 版本的源码,在 Ubuntu 16.04 上编译运行,部分代码有所改动。

cat-file

cat-file 是 GIT 最初版本中用于获取 SHA1 对象的内容的命令,其使用方法为 cat-file <sha1> ,该程序将获取 SHA1 对象的类型同时创建了临时文件读取原始类型(blob 类型)或对象的基本信息。其源码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "cache.h" int main(int argc, char **argv) { unsigned char sha1[20]; char type[20]; void *buf; unsigned long size; char template[] = "temp_git_file_XXXXXX"; int fd; if (argc != 2 || get_sha1_hex(argv[1], sha1)) usage("cat-file: cat-file <sha1>"); buf = read_sha1_file(sha1, type, &size); if (!buf) exit(1); fd = mkstemp(template); if (fd < 0) usage("unable to create tempfile"); if (write(fd, buf, size) != size) strcpy(type, "bad"); printf("%s: %sn", template, type); return 0; }

该命令接收一个标识 SHA1 对象的 sha1 值。该命令通过 sha1 标识符获取到缓存目录中对象,并通过 read_sha1_file() 函数获取文件的类型及内容,接着创建临时文件将文件内容保存至临时文件中。read_sha1_file() 函数定义如下。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
void *read_sha1_file(unsigned char *sha1, char *type, unsigned long *size) { z_stream stream; char buffer[8192]; struct stat st; int i, fd, ret, bytes; void *map, *buf; char *filename = sha1_file_name(sha1); fd = open(filename, O_RDONLY); if (fd < 0) { perror(filename); return NULL; } if (fstat(fd, &st) < 0) { close(fd); return NULL; } map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); if (-1 == (int)(long)map) return NULL; /* Get the data stream */ memset(&stream, 0, sizeof(stream)); stream.next_in = map; stream.avail_in = st.st_size; stream.next_out = buffer; stream.avail_out = sizeof(buffer); inflateInit(&stream); ret = inflate(&stream, 0); if (sscanf(buffer, "%10s %lu", type, size) != 2) return NULL; bytes = strlen(buffer) + 1; buf = malloc(*size); if (!buf) return NULL; memcpy(buf, buffer + bytes, stream.total_out - bytes); bytes = stream.total_out - bytes; if (bytes < *size && ret == Z_OK) { stream.next_out = buf + bytes; stream.avail_out = *size - bytes; while (inflate(&stream, Z_FINISH) == Z_OK) /* nothing */; } inflateEnd(&stream); return buf; }

该函数通过 sha1 值获取到缓存目录中的 SHA1 对象名称,接着打开文件并映射到内存中,然后对其解压并存储在动态分配的内存空间中。

最后

以上就是美好铃铛最近收集整理的关于GIT 源码阅读之 cat-file的全部内容,更多相关GIT内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部