使用libgit2取消阶段文件

时间:2014-03-29 13:15:12

标签: objective-c git libgit2 objective-git

使用objective-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 delta并从中构建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 个答案:

答案 0 :(得分:0)

请记住,Git是基于快照的,因此在提交时索引中的任何内容都将是提交的内容。

由于它依赖于上下文,因此本身没有非阶段行为。如果文件是新的,那么删除它就是你取消它的做法。否则,unstaging和staging是相同的操作,区别在于您在条目中使用的blob是文件的旧版本。

由于你想在HEAD中将文件移回状态,所以不应该使用diff,而是采用HEAD树并查找你想要的条目(尽管从中快速浏览,我没有看到objective-git wrap git_tree_entry_bypath()

如果我们写出索引的错误版本,那肯定是库中的一个错误,你是否可以打开一个问题,以便我们可以尝试重现它?