Un-stage file with libgit2

最后都变了- 提交于 2019-12-11 21:25:37

问题


Using objective-git and libgit2 it has been fairly easy to stage a file ready for commit:

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];

However un-staging a file is proving to be a tad more tricky. Simply removing it from the repository's index doesn't work as git then thinks the file has been deleted which makes sense. It seems what I need to do is change the index entry in the index to the one it was before it was staged.

I have tried doing the following, using diff to get the old diff delta and constructing a git_index_entry from that and inserting it:

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];
    }
}];

However this leaves the git index in a corrupt state resulting in any git command logging a fatal error:

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

What is the correct way to un-stage a file using libgit2?


回答1:


Remember that Git is snapshot-based, so whatever is in the index at commit time will be what's committed.

There is no unstage action by itself, as it's context-dependent. If the file is new, then removing it is what you do to unstage it. Otherwise, unstaging and staging are the same operation, with the difference that the blob you use in the entry is the old version of the file.

Since you want to move files back to their state in HEAD, there shouldn't be a need to use diff, but take the tree of HEAD and look up the entries you want there (though from a quick glance, I don't see objective-git wrapping git_tree_entry_bypath())

If we write out a bad version of the index, that's definitely a bug in the library, could you open an issue so we can try to reproduce it?



来源:https://stackoverflow.com/questions/22731553/un-stage-file-with-libgit2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!