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?
1 ответ
Помните, что Git основан на снимках, поэтому все, что находится в индексе во время принятия, будет тем, что зафиксировано.
Там нет никакого нестандартного действия само по себе, поскольку оно зависит от контекста. Если файл новый, то удалите его, чтобы удалить его. В противном случае, unstaging и staging - это одна и та же операция, с той разницей, что большой двоичный объект, который вы используете в записи, является старой версией файла.
Поскольку вы хотите перевести файлы обратно в их состояние в HEAD, не должно быть необходимости использовать diff, но возьмите дерево HEAD и найдите нужные записи (хотя с первого взгляда я не вижу объективная упаковка git_tree_entry_bypath()
)
Если мы напишем неверную версию индекса, это определенно ошибка в библиотеке, не могли бы вы открыть проблему, чтобы мы могли попытаться воспроизвести ее?