mirror of
https://github.com/gosticks/SwiftGit2.git
synced 2025-10-16 11:55:34 +00:00
Refactor allCommits to return CommitIterator instead,
as loading all commits in one go is not good for repository with a lot of commits
This commit is contained in:
parent
3b04a2b94a
commit
e69e5ca153
@ -540,4 +540,64 @@ final public class Repository {
|
||||
}
|
||||
return Result.success(commits)
|
||||
}
|
||||
|
||||
public class CommitIterator: IteratorProtocol {
|
||||
public typealias Element = Result<Commit, NSError>
|
||||
var repo: Repository
|
||||
var branch: Branch
|
||||
var revisionWalker: OpaquePointer? = nil
|
||||
var oid: git_oid
|
||||
|
||||
public init(repo: Repository, branch: Branch) {
|
||||
self.repo = repo
|
||||
self.branch = branch
|
||||
self.oid = branch.oid.oid
|
||||
setupRevisionWalker()
|
||||
}
|
||||
|
||||
deinit {
|
||||
git_revwalk_free(self.revisionWalker)
|
||||
}
|
||||
|
||||
private func setupRevisionWalker() {
|
||||
git_revwalk_new(&revisionWalker, repo.pointer)
|
||||
git_revwalk_sorting(revisionWalker, GIT_SORT_TOPOLOGICAL.rawValue)
|
||||
git_revwalk_sorting(revisionWalker, GIT_SORT_TIME.rawValue)
|
||||
git_revwalk_push(revisionWalker, &oid)
|
||||
}
|
||||
|
||||
private func error(from gitCommands: [(key: String, value: () -> Int32)]) -> NSError? {
|
||||
// TODO: Make a flatMap command that stops on first nil
|
||||
let errors: [NSError] = gitCommands.flatMap {
|
||||
let result = $0.value()
|
||||
return result == GIT_OK.rawValue ? nil : NSError(gitError: result, pointOfFailure: $0.key)
|
||||
}
|
||||
if errors.count > 0 {
|
||||
return errors.first!
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
public func next() -> Element? {
|
||||
var unsafeCommit: OpaquePointer? = nil
|
||||
let gitCommands = [
|
||||
(key: "git_revwalk_next", value: { return git_revwalk_next(&self.oid, self.revisionWalker) }),
|
||||
(key: "git_commit_lookup", value: { return git_commit_lookup(&unsafeCommit, self.repo.pointer, &self.oid) })
|
||||
]
|
||||
if let error = error(from: gitCommands) {
|
||||
return Result.failure(error)
|
||||
} else {
|
||||
guard let commit = unsafeCommit else {
|
||||
return nil
|
||||
}
|
||||
git_commit_free(unsafeCommit)
|
||||
return Result.success(Commit(commit))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func commits(in branch: Branch) -> CommitIterator {
|
||||
return CommitIterator(repo: self, branch: branch)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user