mirror of
https://github.com/gosticks/SwiftGit2.git
synced 2025-10-16 11:55:34 +00:00
76 lines
1.9 KiB
Swift
76 lines
1.9 KiB
Swift
//
|
|
// Created by Arnon Keereena on 4/28/17.
|
|
// Copyright (c) 2017 GitHub, Inc. All rights reserved.
|
|
//
|
|
|
|
import Result
|
|
import libgit2
|
|
|
|
public class CommitIterator: IteratorProtocol {
|
|
public typealias Element = Result<Commit, NSError>
|
|
let repo: Repository
|
|
private var revisionWalker: OpaquePointer? = nil
|
|
|
|
private enum Next {
|
|
case over
|
|
case ok
|
|
case error(NSError)
|
|
|
|
init(_ result: Int32, name: String) {
|
|
switch result {
|
|
case GIT_ITEROVER.rawValue:
|
|
self = .over
|
|
case GIT_OK.rawValue:
|
|
self = .ok
|
|
default:
|
|
self = .error(NSError(gitError: result, pointOfFailure: name))
|
|
}
|
|
}
|
|
}
|
|
|
|
init(repo: Repository, root: git_oid) {
|
|
self.repo = repo
|
|
setupRevisionWalker(root: root)
|
|
}
|
|
|
|
deinit {
|
|
git_revwalk_free(self.revisionWalker)
|
|
}
|
|
|
|
private func setupRevisionWalker(root: git_oid) {
|
|
var oid = root
|
|
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 next(withName name: String, from result: Int32) -> Next {
|
|
if result == GIT_OK.rawValue || result == GIT_ITEROVER.rawValue {
|
|
return Next(result, name: name)
|
|
} else {
|
|
return Next.error(NSError(gitError: result, pointOfFailure: name))
|
|
}
|
|
}
|
|
|
|
public func next() -> Element? {
|
|
var unsafeCommit: OpaquePointer? = nil
|
|
var oid = git_oid()
|
|
let revwalkGitResult = git_revwalk_next(&oid, revisionWalker)
|
|
let nextResult = next(withName: "git_revwalk_next", from: revwalkGitResult)
|
|
if case let .error(error) = nextResult {
|
|
return Result.failure(error)
|
|
} else if case .over = nextResult {
|
|
return nil
|
|
}
|
|
let lookupGitResult = git_commit_lookup(&unsafeCommit, repo.pointer, &oid)
|
|
guard lookupGitResult == GIT_OK.rawValue,
|
|
let unwrapCommit = unsafeCommit else {
|
|
return nil
|
|
}
|
|
let result: Element = Result.success(Commit(unwrapCommit))
|
|
git_commit_free(unsafeCommit)
|
|
return result
|
|
}
|
|
}
|