0

我正在编写一个允许使用 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

根据这个未回答的老问题,我需要在当前 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 类是如何联系在一起的。

4

2 回答 2

2

稍等片刻后,我发现它实际上比我做的要容易得多;无需将 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 在这种情况下是没有用的;它引用了一些标志,这些标志在构建索引期间由 libgit2 内部使用,但对之后确定文件的状态没有帮助(坦率地说,我不确定为什么这些标志会被 Objective-Git 公开)
  • 如果你想取消/暂存工作目录中的所有文件,你可以让 Objective-Git 使用 GTDiff 做很多工作+diffIndexFromTree:inRepository:options:error:
于 2016-01-29T20:07:58.050 回答
0

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

如果文件在 HEAD 树中不存在(因为它之前没有被跟踪),那么您可以简单地将其从索引中删除git_index_remove_bypath

于 2016-01-27T22:55:50.507 回答