Libgit2 git_blob 对比内存

Libgit2 git_blob vs memory

我不清楚 blob 的内容实际上是在什么时候加载到内存中的。

我的代码中的逻辑如下:

git_blob_lookup(&blob_, repo_, oid)

if (git_blob_rawsize(blob_) < LIMIT)
  git_blob_rawcontent(blob_)

这是为了防止自己读取大文件DOSing。但是根据 API 的描述,我不太确定这是否真的阻止了 blob 被加载到内存中。

如果没有,是否有一个 API 调用可以给我一个 blob 的大小,而不将其加载到内存中?

这会将 blob 的全部内容读入内存。

如果您想在阅读之前了解有关 blob 的更多信息,则需要直接与对象数据库对话。

特别是,调用 git_odb_read_header 将只读取对象的元数据,即对象的类型 (blob/tree/commit) 和对象的大小。 (这是 git_blob_rawsize 将返回的大小。)

git_blob_rawcontent来自libgit2的“src/blob.c”的来源如下:

const void *git_blob_rawcontent(const git_blob *blob)
{
        assert(blob);
        if (blob->raw)
                return blob->data.raw.data;
        else
                return git_odb_object_data(blob->data.odb);
}

来自“src/odb.c”的git_odb_object_data的来源如下:

const void *git_odb_object_data(git_odb_object *object)
{
        return object->buffer;
}

所以 git_block_rawcontent 没有从 repo 加载任何数据,它只是 return 指向已经加载的数据的指针,并且被 blob->data.raw.datablob->data.odb->buffer。加载(可能来自已加载对象的缓存)由 git_blob_lookup 调用完成。


我能找到的无需加载整个 blob(或其他对象类型)即可读取大小的唯一方法是调用 git_odb_read_header,但请注意 git_odb_read_header 的文档中说:

Note that most backends do not support reading only the header of an object, so the whole object will be read and then the header will be returned.

不过,如果你想试试,原型如下:

int get_odb_read_header(size_t *len_out, git_object_t *type_out, git_odb *db, const git_oid *id);

如果在 ODB 中找到 OID(return 如果找到则值为 0,如果未找到 GIT_ENOTFOUND),对象的长度和类型将通过 returned len_outtype_out。 blob 的类型值为 GIT_OBJECT_BLOB.

要调用 get_odb_read_header,您需要存储库的 ODB 指针。这可以通过调用 git_repository_odb 获得,其原型如下:

int git_repository_odb(git_odb **out, git_repository *repo);

git_repository_odb returns 成功时为 0,失败时为错误代码。如果它 returned 成功,当 ODB 不再需要时应该通过调用 git_odb_free 来释放 ODB,其原型如下:

void git_odb_free(git_odb *db);