git 源码解析(四)commit-tree

commit-tree命令类似于以后的git commit命令,格式 commit-tree <sha1> [-p <sha1>] 

int main(int argc, char **argv)
{
    unsigned char tree_sha1[20];
    get_sha1_hex(argv[1], tree_sha1);
    for (i = 2; i < argc; i += 2)
        a = argv[i]; b = argv[i+1];
        if (!b || strcmp(a, "-p") || get_sha1_hex(b, parent_sha1[parents]))
            usage("commit-tree <sha1> [-p <sha1>]* < changelog");
        parents++;
    init_buffer(&buffer, &size);
    add_buffer(&buffer, &size, "tree %s\n", sha1_to_hex(tree_sha1));
    for (i = 0; i < parents; i++)
        add_buffer(&buffer, &size, "parent %s\n", sha1_to_hex(parent_sha1[i]));
    add_buffer(&buffer, &size, "author %s <%s> %s\n", gecos, email, date);
    add_buffer(&buffer, &size, "committer %s <%s> %s\n\n", realgecos, realemail, realdate);
    while (fgets(comment, sizeof(comment), stdin) != NULL)
        add_buffer(&buffer, &size, "%s", comment);
    finish_buffer("commit ", &buffer, &size); 
    // buffer: "commit %lu\0tree %s\nparent %s\n..parent %s\nauthor %s <%s> %s\ncommitter %s <%s> %s\n\n%s"
    // %lu: size of "tree %s\nparent %s\n..parent %s\nauthor %s <%s> %s\ncommitter %s <%s> %s\n\n%s"
    // size: size of buffer
    write_sha1_file(buffer, size);
        stream.next_in = buffer;
        stream.avail_in = size;
        stream.next_out = compressed;
        stream.avail_out = len;
        while (deflate(&stream, Z_FINISH) == Z_OK);
        size = stream.total_out;
        SHA1_Init(&c);
        SHA1_Update(&c, compressed, size);
        SHA1_Final(sha1, &c);
        write_sha1_buffer(sha1, compressed, size);
            char *filename = sha1_file_name(sha1);
            fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
            write(fd, compressed, size);
            close(fd);
}

 

1. buffer信息格式:commit %lu\0tree %s\nparent %s\nauthor %s <%s> %s\ncommitter %s <%s> %s\n\n%s

%lu # "tree %s\nparent %s\nauthor %s <%s> %s\ncommitter %s <%s> %s\n\n%s" 内容长度

 

2. write_sha1_file(buffer, size); # 将信息写入sha1文件

int write_sha1_file(char *buf, unsigned len)
{
	int size;
	char *compressed;
	z_stream stream;
	unsigned char sha1[20];
	SHA_CTX c;

	/* Set it up */
	memset(&stream, 0, sizeof(stream));
	deflateInit(&stream, Z_BEST_COMPRESSION);
	size = deflateBound(&stream, len);
	compressed = malloc(size);

	/* Compress it */
	stream.next_in = buf;
	stream.avail_in = len;
	stream.next_out = compressed;
	stream.avail_out = size;
	while (deflate(&stream, Z_FINISH) == Z_OK)
		/* nothing */;
	deflateEnd(&stream);
	size = stream.total_out;

	/* Sha1.. */
	SHA1_Init(&c);
	SHA1_Update(&c, compressed, size);
	SHA1_Final(sha1, &c);

	if (write_sha1_buffer(sha1, compressed, size) < 0)
		return -1;
	printf("%s\n", sha1_to_hex(sha1));
	return 0;
}

2.1 write_sha1_buffer(sha1, compressed, size); # 将组装的buffer信息压缩,然后对压缩值取hash,将压缩内容写入sha1文件

int write_sha1_buffer(unsigned char *sha1, void *buf, unsigned int size)
{
	char *filename = sha1_file_name(sha1);
	int i, fd;

	fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0666);
	if (fd < 0)
		return (errno == EEXIST) ? 0 : -1;
	write(fd, buf, size);
	close(fd);
	return 0;
}

2.1.1 char *filename = sha1_file_name(sha1); # 根据hash值生成.dircache/objects/xx/xx..xx(38位)文件名

2.1.2 新建并将压缩数据写入sha1文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值