libgit2 не возвращает допустимый BLOB-объект - PullRequest
0 голосов
/ 10 апреля 2020

Я пытаюсь получить блоб репозитория с помощью libgit2:

#include <git2.h>
#include <stdio.h>

int main() {

    git_libgit2_init();

    git_repository *repo = NULL;
    int error = git_repository_open(&repo, "/home/martin/Dokumente/TestRepository");

    if (error < 0) {
  const git_error *e = git_error_last();
  printf("Error %d/%d: %s\n", error, e->klass, e->message);
  exit(error);
}

git_diff *diff = NULL;
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
opts.flags |= GIT_DIFF_IGNORE_WHITESPACE;
opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;

error = git_diff_index_to_workdir(&diff, repo, NULL, &opts);
if (error < 0) {
  const git_error *e = git_error_last();
  printf("Error %d/%d: %s\n", error, e->klass, e->message);
  exit(error);
}

git_patch* patch = nullptr;
git_patch_from_diff(&patch, diff, 0);

bool oldFile = false;
const git_diff_delta *dd = git_patch_get_delta(patch);
const git_oid &id = (!oldFile) ? dd->new_file.id : dd->old_file.id;

git_object *obj = nullptr;
git_object_lookup(&obj, repo, &id, GIT_OBJECT_ANY);
git_blob* blob = reinterpret_cast<git_blob *>(obj);

const char* pointer = (const char*)git_blob_rawcontent(blob);

// cleanup
git_object_free(obj);
git_patch_free(patch);
git_diff_free(diff);
git_repository_free(repo);

return 0;
}

Репозиторий

  • создать новый репозиторий

  • зафиксировать файл как:

    1 2 3 4

  • удалить 4 снова, но не фиксировать

  • разрешить запуск программы

Ожидается : Программа работает нормально.

Наблюдается : объект еще не завершен nullptr после выполнения git_object_lookup ()

При установке переменной oldFile в значение true программа работает нормально, а указатель «указатель» содержит необработанный BLOB-объект.

Кто-нибудь знает, почему я этого не делаю получить верный объект из git_object_lookup () обратно?

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

Проблема в том, что вы пытаетесь получить объект с идентификатором dd->new_file.id. Этот файл находится в рабочем каталоге, так как он еще не был добавлен или зафиксирован. Это означает, что это еще не в хранилище. Когда вы запускаете git_object_lookup(), он не может найти объект, так как он не был добавлен в дерево. OID не соответствует ни одному совпадению, поэтому он возвращает ноль.

Если вы хотите получить данные текущего рабочего каталога, вы должны сначала создать объект в дереве с помощью git_blob_create_from_workdir, а затем при попытке доступ к нему, он будет найден. Ваш новый код может выглядеть так:

bool oldFile = false;
const git_diff_delta *dd = git_patch_get_delta(patch);
git_oid id;

if (!oldFile) {
    error = git_blob_create_from_workdir(&id, repo, dd->new_file.path);
    if (error < 0) {
        const git_error *e = git_error_last();
        printf("Error %d/%d: %s\n", error, e->klass, e->message);
        exit(error);
    }
} else {
    id = dd->old_file.id;
}

git_object *obj = nullptr;
git_object_lookup(&obj, repo, &id, GIT_OBJECT_ANY);
git_blob* blob = reinterpret_cast<git_blob *>(obj);

const char* pointer = (const char*)git_blob_rawcontent(blob);
2 голосов
/ 10 апреля 2020

При разнице между индексом и рабочим каталогом сторона дельты new представляет файл в рабочем каталоге. Его id - это ха sh файла на диске. Если вы явно не вставите этот BLOB-объект в хранилище объектов репозитория каким-либо другим способом, у вас пока нет причин для этого.

...