libgit2
libgit2 copied to clipboard
Tree lookup fails with "fake" repositories since 1.6.1
Reproduction steps
The following C code passes with libgit2 <=1.5.2 and fails with >= 1.6.1
#include <git2.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[]) {
char template[] = "/tmp/tmpdir.XXXXXX";
char *tmpdir = mkdtemp(template);
git_libgit2_init();
git_oid blob_id;
git_oid tree_id;
git_odb *odb = NULL;
{ // create test repo and obtain odb
git_repository *repo = NULL;
if (git_repository_init(&repo, tmpdir, /*bare does not matter*/0) != 0) {
fprintf(stderr, "Could not initialize repository: %s\n",
git_error_last()->message);
return 1;
}
if (git_repository_odb(&odb, repo) != 0) {
fprintf(stderr, "Could not open ODB: %s\n", git_error_last()->message);
return 1;
}
if (git_odb_write(&blob_id, odb, "foo", 3, GIT_OBJECT_BLOB) != 0) {
fprintf(stderr, "Could not write blob: %s\n",
git_error_last()->message);
return 1;
}
git_treebuilder *tb = NULL;
if (git_treebuilder_new(&tb, repo, NULL) != 0) {
fprintf(stderr, "Could not create tree builder: %s\n",
git_error_last()->message);
return 1;
}
if (git_treebuilder_insert(NULL, tb, "foo", &blob_id, GIT_FILEMODE_BLOB) !=
0) {
fprintf(stderr, "Could not insert blob foo: %s\n",
git_error_last()->message);
return 1;
}
if (git_treebuilder_write(&tree_id, tb) != 0) {
fprintf(stderr, "Could not write tree: %s\n", git_error_last()->message);
return 1;
}
git_treebuilder_free(tb);
git_repository_free(repo);
}
git_repository *repo = NULL;
//if (git_repository_open(&repo, tmpdir) != 0) { // "real" repo works
if (git_repository_wrap_odb(&repo, odb) != 0) { // "fake" repo fails
fprintf(stderr, "Could not create \"fake\" repository: %s\n",
git_error_last()->message);
return 1;
}
git_blob *blob = NULL;
int retb = git_blob_lookup(&blob, repo, &blob_id);
printf("Blob lookup: %s\n", retb == 0 ? "success" : "failed");
if (retb != 0) {
fprintf(stderr, "Could not lookup blob: %s\n", git_error_last()->message);
}
git_tree *tree = NULL;
int rett = git_tree_lookup(&tree, repo, &tree_id);
printf("Tree lookup: %s\n", rett == 0 ? "success" : "failed");
if (rett != 0) {
fprintf(stderr, "Could not lookup tree: %s\n", git_error_last()->message);
}
git_tree_free(tree);
git_blob_free(blob);
git_odb_free(odb);
git_repository_free(repo);
git_libgit2_shutdown();
return 0;
}
Could not lookup tree: failed to parse tree: can't parse filemode
When using git_repository_open() instead of git_repository_wrap_odb() everything works as expected. Only trees are affected, blob lookup works fine in both cases. Possibly related to https://github.com/libgit2/libgit2/issues/6543.
Expected behavior
The tree lookup should succeed.
Actual behavior
The tree is not found, although present.
Version of libgit2 (release number or SHA1)
1.6.1 - 1.6.4
Operating system(s) tested
Ubuntu 22.04, Debian 11, ArchLinux
Created pull request https://github.com/libgit2/libgit2/pull/6554 to fix the issue.
Fixed via #6554