0

使用 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从中构造 a 并插入它:

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 取消暂存文件的正确方法是什么?

4

1 回答 1

0

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

本身没有 unstage 动作,因为它依赖于上下文。如果文件是新文件,则删除它就是您要取消暂存它的方法。否则,unstaging 和 staging 是相同的操作,不同之处在于您在条目中使用的 blob 是文件的旧版本。

由于您想将文件移回 HEAD 中的状态,因此不需要使用 diff,而是使用 HEAD 的树并在那里查找您想要的条目(尽管快速浏览,我没有看到目标 git 包装git_tree_entry_bypath()

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

于 2014-03-30T08:53:26.113 回答