Merge develop to master

This commit is contained in:
Arnon Keereena 2017-04-28 22:20:01 +02:00
commit 96e9cf61a7
4 changed files with 91 additions and 26 deletions

View File

@ -21,6 +21,8 @@
/* End PBXAggregateTarget section */ /* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
2549921B34FFC36AF8C9CD6D /* CommitIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25499A996CA7BD416620A397 /* CommitIterator.swift */; };
25499D325997CAB9BEFFCA4D /* CommitIterator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25499A996CA7BD416620A397 /* CommitIterator.swift */; };
621E66A01C72958800A0F352 /* OID.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE70B3E41A1ACB1A002C3F4E /* OID.swift */; }; 621E66A01C72958800A0F352 /* OID.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE70B3E41A1ACB1A002C3F4E /* OID.swift */; };
621E66A11C72958800A0F352 /* Remotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECB5F6D1A57284700999413 /* Remotes.swift */; }; 621E66A11C72958800A0F352 /* Remotes.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECB5F6D1A57284700999413 /* Remotes.swift */; };
621E66A21C72958800A0F352 /* CheckoutStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE276B281ACCD3CF00D6DAD7 /* CheckoutStrategy.swift */; }; 621E66A21C72958800A0F352 /* CheckoutStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE276B281ACCD3CF00D6DAD7 /* CheckoutStrategy.swift */; };
@ -129,6 +131,7 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
25499A996CA7BD416620A397 /* CommitIterator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommitIterator.swift; sourceTree = "<group>"; };
621E66B41C72958800A0F352 /* SwiftGit2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftGit2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 621E66B41C72958800A0F352 /* SwiftGit2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftGit2.framework; sourceTree = BUILT_PRODUCTS_DIR; };
621E66CE1C72958D00A0F352 /* SwiftGit2-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwiftGit2-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 621E66CE1C72958D00A0F352 /* SwiftGit2-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwiftGit2-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
621E66D81C72989900A0F352 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Result.framework; path = "Carthage/Checkouts/Result/build/Debug-iphoneos/Result.framework"; sourceTree = "<group>"; }; 621E66D81C72989900A0F352 /* Result.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Result.framework; path = "Carthage/Checkouts/Result/build/Debug-iphoneos/Result.framework"; sourceTree = "<group>"; };
@ -313,6 +316,7 @@
BECB5F691A56F19900999413 /* References.swift */, BECB5F691A56F19900999413 /* References.swift */,
BECB5F6D1A57284700999413 /* Remotes.swift */, BECB5F6D1A57284700999413 /* Remotes.swift */,
BEB31F261A0D6F7A00F525B9 /* Supporting Files */, BEB31F261A0D6F7A00F525B9 /* Supporting Files */,
25499A996CA7BD416620A397 /* CommitIterator.swift */,
); );
path = SwiftGit2; path = SwiftGit2;
sourceTree = "<group>"; sourceTree = "<group>";
@ -749,6 +753,7 @@
621E66A71C72958800A0F352 /* Pointers.swift in Sources */, 621E66A71C72958800A0F352 /* Pointers.swift in Sources */,
621E66A81C72958800A0F352 /* Errors.swift in Sources */, 621E66A81C72958800A0F352 /* Errors.swift in Sources */,
621E66A91C72958800A0F352 /* SwiftGit2.m in Sources */, 621E66A91C72958800A0F352 /* SwiftGit2.m in Sources */,
2549921B34FFC36AF8C9CD6D /* CommitIterator.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -781,6 +786,7 @@
BE7A753F1A4A2BCC002DA7E3 /* Pointers.swift in Sources */, BE7A753F1A4A2BCC002DA7E3 /* Pointers.swift in Sources */,
DA5914761A94579000AED74C /* Errors.swift in Sources */, DA5914761A94579000AED74C /* Errors.swift in Sources */,
BE14AA501A1974010015B439 /* SwiftGit2.m in Sources */, BE14AA501A1974010015B439 /* SwiftGit2.m in Sources */,
25499D325997CAB9BEFFCA4D /* CommitIterator.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -0,0 +1,67 @@
//
// 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>
var repo: Repository
var branch: Branch
var revisionWalker: OpaquePointer? = nil
var oid: git_oid
private var unsafeCommit: OpaquePointer? = nil
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 result(withName name: String, from result: Int32) -> (stop: Bool, error: NSError?) {
guard result == GIT_OK.rawValue else {
if result == GIT_ITEROVER.rawValue {
return (stop: true, error: nil)
} else {
return (stop: false, error: NSError(gitError: result, pointOfFailure: name))
}
}
return (stop: false, error: nil)
}
public func next() -> Element? {
let revwalkGitResult = git_revwalk_next(&self.oid, self.revisionWalker)
let revwalkResult = result(withName: "git_revwalk_next", from: revwalkGitResult)
if revwalkResult.stop {
return nil
} else if let error = revwalkResult.error {
return Result.failure(error)
}
let lookupGitResult = git_commit_lookup(&self.unsafeCommit, self.repo.pointer, &self.oid)
let lookupResult = result(withName: "git_commit_lookup", from: lookupGitResult)
if lookupResult.stop {
return nil
} else if let error = lookupResult.error {
return Result.failure(error)
}
guard let commit = unsafeCommit else {
return nil
}
git_commit_free(unsafeCommit)
return Result.success(Commit(commit))
}
}

View File

@ -510,34 +510,22 @@ final public class Repository {
return setHEAD(reference).flatMap { self.checkout(strategy: strategy, progress: progress) } return setHEAD(reference).flatMap { self.checkout(strategy: strategy, progress: progress) }
} }
/// Cache for commits(in: branch)
///
/// Specifically for allowing syntax "while let commit = repo.commits(in: branch).next() {}"
public var branchCommitIteratorMap: [Branch: CommitIterator] = [:]
/// Load all commits in the specified branch in topological & time order descending /// Load all commits in the specified branch in topological & time order descending
/// ///
/// :param: branch The branch to get all commits from /// :param: branch The branch to get all commits from
/// :returns: Returns a result with array of branches or the error that occurred /// :returns: Returns a result with array of branches or the error that occurred
public func allCommits(in branch: Branch) -> Result<[Commit], NSError> { public func commits(in branch: Branch) -> CommitIterator {
var commits: [Commit] = [] if let iterator = branchCommitIteratorMap[branch] {
var walker: OpaquePointer? = nil return iterator
var unsafeCommit: OpaquePointer? = nil } else {
var oid = branch.oid.oid let iterator = CommitIterator(repo: self, branch: branch)
git_revwalk_new(&walker, self.pointer) branchCommitIteratorMap[branch] = iterator
defer { return iterator
git_revwalk_free(walker)
} }
git_revwalk_sorting(walker, GIT_SORT_TOPOLOGICAL.rawValue)
git_revwalk_sorting(walker, GIT_SORT_TIME.rawValue)
git_revwalk_push(walker, &oid)
while git_revwalk_next(&oid, walker) == GIT_OK.rawValue {
let result = git_commit_lookup(&unsafeCommit, self.pointer, &oid)
guard result == GIT_OK.rawValue else {
return Result.failure(NSError(gitError: result, pointOfFailure: "git_commit_lookup"))
}
guard let commit = unsafeCommit else {
continue
}
commits += [Commit(commit)]
git_commit_free(unsafeCommit)
}
return Result.success(commits)
} }
} }

View File

@ -605,9 +605,13 @@ class RepositorySpec: QuickSpec {
it("should return all (9) commits") { it("should return all (9) commits") {
let repo = Fixtures.simpleRepository let repo = Fixtures.simpleRepository
let branches = repo.localBranches().value! let branches = repo.localBranches().value!
let commits = branches.map { repo.allCommits(in: $0).value!.map { $0 } } var count = 0
let count = commits.reduce(0) { $0 + $1.count } let expected = 9
let expected = 9 for branch in branches {
while let commit = repo.commits(in: branch).next() {
count += 1
}
}
expect(count).to(equal(expected)) expect(count).to(equal(expected))
} }
} }