如何使用Objective-Git(libgit2)“取消”文件?

时间:2016-01-27 22:00:08

标签: libgit2 objective-git

我正在编写一个允许使用Objective-Git执行基本git操作的应用程序,但我无法弄清楚如何“取消暂停”文件。更具体地说,我有一个先前已添加到当前GTIndex的更改文件,我现在想要丢弃这些更改(不会丢失文件在磁盘上的当前状态)。

以下是我的程序在切换文件的“暂存”状态时当前遵循的相关逻辑的大致轮廓:

- Fetch current GTIndex using GTRepository.indexWithError:
- Fetch GTIndexEntry for the file using GTIndex.entryWithPath:
- If the file has an index and GTIndexEntry.status == GTIndexEntryStatusUpdated:
    - Here's where I'm stuck

According to this old unanswered question我需要在当前的HEAD中查找文件的信息。在这种情况下,这是我到达的逻辑:

- Fetch head's GTReference using GTRepository.headReferenceWithError:
- If the reference resolves to a GTCommit object:
    - Fetch the GTTree using GTCommit.tree
    - Fetch the file's GTTreeEntry using GTTree.entryWithPath:error:
    - Stuck again! Do I convert GTTreeEntry to GTIndexEntry somehow?

任何指导表示赞赏!我不害怕直接进入libgit2,如果必须的话(这个项目已经需要一两次了),但是因为我在Swift工作,所以我想避免它,如果我可以“取消”一个文件看起来像是一个标准程序,我认为我不能理解Objective-Git类如何结合在一起。

2 个答案:

答案 0 :(得分:1)

让它静置一段时间后,我发现它实际上比我制作它容易得多;而不是将HEAD树与活动索引进行比较,您可以简单地使用GTRepository.statusForFile:success:error:来确定文件是否已暂存,未分阶段等,然后根据文件添加,删除或添加blob这一点。

原创方法

(在关闭的情况下,它包含了其他人的有用信息。)

这比最初看起来更简单,主要是因为GTTreeEntry和GTIndexEntry之间的转换是不必要的。相反,我只需要抓住GTTreeEntry的GTObject(这是文件的blob),然后将blob的数据传递给GTIndex。

我最终得到的代码流大致如下:

- Fetch head's GTReference using GTRepository.headReferenceWithError:
- If the reference resolves to a GTCommit =>
    - Fetch the GTIndexEntry using GTIndex.entryWithPath:
    - If we have an index entry =>
        - Fetch the GTTree using GTCommit.tree
        - Fetch the GTTreeEntry using GTTree.entryWithPath:error:
        - If GTTreeEntry.SHA == GTIndexEntry.OID.SHA =>
            - GTIndex.addFile:error:
            (using this approach, it's possible to end up with identical
             tree and index entries, which means the file is unstaged)
        - Else if GTTreeEntry.type == GTObjectTypeBlob =>
            - Fetch GTBlob using GTTreeEntry.GTObject:error:
            - Pass GTBlob.data to GTIndex.addData:withPath:error:
        - Else if no GTTreeEntry => GTIndex.removeFile:error:
    - Else add the file/directory to the GTIndex (since we have no index entry)
    - Write the changes to disk with GTIndex.write:

希望它们有助于未来几代人抨击Objective-Git在很大程度上没有记录的隐藏内容:

  • GTIndexEntry.status在这种情况下没用;它引用了一些used internally by libgit2 during the construction of the index的标志但是对于确定之后文件的状态没有帮助(我坦率地不确定为什么这些标志会被Objective-Git公开)
  • 如果你想取消/暂存工作目录中的所有文件,你可以让Objective-Git使用GTDiff +diffIndexFromTree:inRepository:options:error:
  • 做很多工作。

答案 1 :(得分:0)

从HEAD提交获得树条目后,您可以从中提取数据以填充新的索引条目。您无需填写所有字段,但至少需要设置pathmodeid。您可以直接从树条目中复制它们。然后使用与git_index_add等效的objective-git来使用新条目更新索引。

如果HEAD树中不存在该文件(因为之前没有跟踪过),那么您只需使用git_index_remove_bypath将其从索引中删除。