Un-stage файл с libgit2

С помощью target-git и libgit2 было довольно легко создать файл, готовый к фиксации:

GTIndex *repoIndex = [self.repository indexWithError:&error];

[repoIndex removeFile:path error:&error];

if (status != GTFileStatusIgnored && status != GTFileStatusWorkingDeleted) {
    // Now add the file to the index
    [repoIndex addFile:path error:&error];
}

[repoIndex write:&error];

Однако деинсталляция файла оказывается немного более сложной. Простое удаление его из индекса репозитория не работает, так как git думает, что файл был удален, что имеет смысл. Кажется, что мне нужно сделать, это изменить запись индекса в индексе на ту, которая была до того, как она была поставлена.

Я попытался сделать следующее, используя diff, чтобы получить старую дельту diff, построить из нее git_index_entry и вставить ее:

GTIndex *repoIndex = [self.repository indexWithError:&error];
GTBranch *localBranch = [self.repository currentBranchWithError:&error];
GTCommit *localCommit = [localBranch targetCommitAndReturnError:&error];

GTDiff *indexCommitDiff = [GTDiff diffIndexFromTree:localCommit.tree inRepository:self.repository options:nil error:&error];

// Enumerate through the diff deltas until we get to the file we want to unstage
[indexCommitDiff enumerateDeltasUsingBlock:^(GTDiffDelta *delta, BOOL *stop) {

    NSString *deltaPath = delta.newFile.path;

    // Check if it matches the path we want to usntage
    if ([deltaPath isEqualToString:path]) {
        GTDiffFile *oldFile = delta.oldFile;

        NSString *oldFileSHA = oldFile.OID.SHA;
        git_oid oldFileOID;
        int status = git_oid_fromstr(&oldFileOID, oldFileSHA.fileSystemRepresentation);

        git_index_entry entry;
        entry.mode = oldFile.mode;
        entry.oid = oldFileOID;
        entry.path = oldFile.path.fileSystemRepresentation;

        [repoIndex removeFile:path error:&error];

        status = git_index_add(repoIndex.git_index, &entry);

        [repoIndex write:&error];
    }
}];

Однако это оставляет индекс git в поврежденном состоянии, что приводит к тому, что любая команда git регистрирует фатальную ошибку:

fatal: Unknown index entry format bfff0000
fatal: Unknown index entry format bfff0000     

Как правильно удалить файл с помощью libgit2?


person Joshua    schedule 29.03.2014    source источник


Ответы (1)


Помните, что Git основан на моментальных снимках, поэтому все, что находится в индексе во время фиксации, будет зафиксировано.

Самого по себе несценического действия нет, так как оно зависит от контекста. Если файл новый, то его удаление — это то, что вы делаете, чтобы отключить его. В противном случае отмена подготовки и подготовка — это одна и та же операция с той разницей, что большой двоичный объект, который вы используете в записи, представляет собой старую версию файла.

Поскольку вы хотите переместить файлы обратно в их состояние в HEAD, не должно быть необходимости использовать diff, а возьмите дерево HEAD и найдите там нужные записи (хотя с первого взгляда я не вижу цель-git упаковка git_tree_entry_bypath())

Если мы запишем неверную версию индекса, это определенно ошибка в библиотеке, не могли бы вы открыть проблему, чтобы мы могли попытаться ее воспроизвести?

person Carlos Martín Nieto    schedule 30.03.2014
comment
Спасибо, Карлос, я сообщу о фатальной ошибке как о проблеме, но я не уверен, моя ли это вина, хотя запись кажется действительной. Если использовать git_tree_entry_bypath, можно ли использовать детали git_tree_entry для повторного построения исходной записи индекса? - person Joshua; 30.03.2014
comment
Запись недопустимого индексного файла является ошибкой независимо от того, что делает пользователь. Из записи дерева вы можете получить важную информацию, то есть режим файла и идентификатор. Все остальное в основном есть в индексе для кеширования. - person Carlos Martín Nieto; 30.03.2014