diff --git a/SwiftGit2.xcodeproj/project.pbxproj b/SwiftGit2.xcodeproj/project.pbxproj index 7546a65..f30824d 100644 --- a/SwiftGit2.xcodeproj/project.pbxproj +++ b/SwiftGit2.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ BE244A4E1A11707D00F8BE42 /* git2.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB31F9B1A0E581400F525B9 /* git2.h */; settings = {ATTRIBUTES = (Public, ); }; }; BE244A501A11709600F8BE42 /* git2 in Resources */ = {isa = PBXBuildFile; fileRef = BE244A4F1A11709600F8BE42 /* git2 */; }; BE244A511A11709E00F8BE42 /* git2 in Copy libgit2 Headers */ = {isa = PBXBuildFile; fileRef = BE244A4F1A11709600F8BE42 /* git2 */; }; + BE2E3BE61A31261300C67092 /* Objects.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE2E3BE51A31261300C67092 /* Objects.swift */; }; + BE2E3BE81A31262800C67092 /* ObjectsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE2E3BE71A31262800C67092 /* ObjectsSpec.swift */; }; BE70B3E51A1ACB1A002C3F4E /* OID.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE70B3E41A1ACB1A002C3F4E /* OID.swift */; }; BE70B3E71A1ACB37002C3F4E /* OIDSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE70B3E61A1ACB37002C3F4E /* OIDSpec.swift */; }; BEB31F291A0D6F7A00F525B9 /* SwiftGit2.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB31F281A0D6F7A00F525B9 /* SwiftGit2.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -66,6 +68,8 @@ BE14AA581A1996B70015B439 /* FixturesSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FixturesSpec.swift; sourceTree = ""; }; BE244A4F1A11709600F8BE42 /* git2 */ = {isa = PBXFileReference; lastKnownFileType = folder; name = git2; path = External/libgit2/include/git2; sourceTree = ""; }; BE244A521A117DA100F8BE42 /* SwiftGit2.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = SwiftGit2.modulemap; sourceTree = ""; }; + BE2E3BE51A31261300C67092 /* Objects.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Objects.swift; sourceTree = ""; }; + BE2E3BE71A31262800C67092 /* ObjectsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectsSpec.swift; sourceTree = ""; }; BE70B3E41A1ACB1A002C3F4E /* OID.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OID.swift; sourceTree = ""; }; BE70B3E61A1ACB37002C3F4E /* OIDSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OIDSpec.swift; sourceTree = ""; }; BEB31F231A0D6F7A00F525B9 /* SwiftGit2.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SwiftGit2.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -161,6 +165,7 @@ children = ( BEB31F281A0D6F7A00F525B9 /* SwiftGit2.h */, BE14AA4F1A1974010015B439 /* SwiftGit2.m */, + BE2E3BE51A31261300C67092 /* Objects.swift */, BE70B3E41A1ACB1A002C3F4E /* OID.swift */, BEB31F6C1A0D78F300F525B9 /* Repository.swift */, BEB31F261A0D6F7A00F525B9 /* Supporting Files */, @@ -182,6 +187,7 @@ children = ( BE14AA531A1983520015B439 /* Fixtures */, BE70B3E61A1ACB37002C3F4E /* OIDSpec.swift */, + BE2E3BE71A31262800C67092 /* ObjectsSpec.swift */, BEB31F351A0D6F7A00F525B9 /* RepositorySpec.swift */, BE14AA581A1996B70015B439 /* FixturesSpec.swift */, BEB31F331A0D6F7A00F525B9 /* Supporting Files */, @@ -433,6 +439,7 @@ files = ( BE70B3E51A1ACB1A002C3F4E /* OID.swift in Sources */, BEB31F6D1A0D78F300F525B9 /* Repository.swift in Sources */, + BE2E3BE61A31261300C67092 /* Objects.swift in Sources */, BE14AA501A1974010015B439 /* SwiftGit2.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -442,6 +449,7 @@ buildActionMask = 2147483647; files = ( BEB31F361A0D6F7A00F525B9 /* RepositorySpec.swift in Sources */, + BE2E3BE81A31262800C67092 /* ObjectsSpec.swift in Sources */, BE14AA591A1996B70015B439 /* FixturesSpec.swift in Sources */, BE14AA551A1984550015B439 /* Fixtures.swift in Sources */, BE70B3E71A1ACB37002C3F4E /* OIDSpec.swift in Sources */, diff --git a/SwiftGit2/Objects.swift b/SwiftGit2/Objects.swift new file mode 100644 index 0000000..36aff38 --- /dev/null +++ b/SwiftGit2/Objects.swift @@ -0,0 +1,25 @@ +// +// Objects.swift +// SwiftGit2 +// +// Created by Matt Diephouse on 12/4/14. +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// + +/// A git object. +public protocol Object { + /// The OID of the object. + var oid: OID { get } +} + +/// A git commit. +public struct Commit: Object { + public let oid: OID + public let message: String + + /// Create an instance with a libgit2 `git_commit` object. + public init(pointer: COpaquePointer) { + oid = OID(oid: git_object_id(pointer).memory) + message = String.fromCString(git_commit_message(pointer))! + } +} diff --git a/SwiftGit2/Repository.swift b/SwiftGit2/Repository.swift index 42e28e9..a5655dd 100644 --- a/SwiftGit2/Repository.swift +++ b/SwiftGit2/Repository.swift @@ -55,4 +55,28 @@ final public class Repository { /// The URL of the repository's working directory, or `nil` if the /// repository is bare. public let directoryURL: NSURL? + + // MARK: - Object Lookups + + /// Loads the commit with the given OID. + /// + /// oid - The OID of the commit to lookup. + /// + /// Returns the commit if it exists, or an error. + public func commitWithOID(oid: OID) -> Result { + let pointer = UnsafeMutablePointer.alloc(1) + let repository = self.pointer + var oid = oid.oid + let result = git_object_lookup(pointer, repository, &oid, GIT_OBJ_COMMIT) + + if result < GIT_OK.value { + pointer.dealloc(1) + return failure() + } + + let commit = Commit(pointer: pointer.memory) + git_object_free(pointer.memory) + pointer.dealloc(1) + return success(commit) + } } diff --git a/SwiftGit2Tests/ObjectsSpec.swift b/SwiftGit2Tests/ObjectsSpec.swift new file mode 100644 index 0000000..283e0a8 --- /dev/null +++ b/SwiftGit2Tests/ObjectsSpec.swift @@ -0,0 +1,18 @@ +// +// ObjectSpec.swift +// SwiftGit2 +// +// Created by Matt Diephouse on 12/4/14. +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// + +import LlamaKit +import SwiftGit2 +import Nimble +import Quick + +class CommitSpec: QuickSpec { + override func spec() { + + } +} diff --git a/SwiftGit2Tests/RepositorySpec.swift b/SwiftGit2Tests/RepositorySpec.swift index 5a54a08..98603f0 100644 --- a/SwiftGit2Tests/RepositorySpec.swift +++ b/SwiftGit2Tests/RepositorySpec.swift @@ -25,5 +25,34 @@ class RepositorySpec: QuickSpec { expect(result.error()).notTo(beNil()) } } + + describe("-commitWithOID") { + it("should return the commit if it exists") { + let repo = Fixtures.simpleRepository + let oid = OID(string: "dc220a3f0c22920dab86d4a8d3a3cb7e69d6205a")! + + let result = repo.commitWithOID(oid) + let commit = result.value() + expect(commit).notTo(beNil()) + expect(commit?.oid).to(equal(oid)) + } + + it("should error if the commit doesn't exist") { + let repo = Fixtures.simpleRepository + let oid = OID(string: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")! + + let result = repo.commitWithOID(oid) + expect(result.error()).notTo(beNil()) + } + + it("should error if the oid doesn't point to a commit") { + let repo = Fixtures.simpleRepository + // This is a tree in the repository + let oid = OID(string: "f93e3a1a1525fb5b91020da86e44810c87a2d7bc")! + + let result = repo.commitWithOID(oid) + expect(result.error()).notTo(beNil()) + } + } } }