Skip to content

Commit

Permalink
Merge pull request SwiftGit2#102 from jakeva/develop
Browse files Browse the repository at this point in the history
Implement git status and diffs
  • Loading branch information
jakeva authored Feb 9, 2018
2 parents 11ac476 + 97ee009 commit d35dac6
Show file tree
Hide file tree
Showing 6 changed files with 596 additions and 15 deletions.
15 changes: 14 additions & 1 deletion SwiftGit2.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
/* End PBXAggregateTarget section */

/* Begin PBXBuildFile section */
232861431F4A3A2E00276D65 /* Diffs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232861421F4A3A2E00276D65 /* Diffs.swift */; };
232861451F4A3A2E00276D65 /* Diffs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 232861421F4A3A2E00276D65 /* Diffs.swift */; };
237731C71F46542B0020A3FE /* repository-with-status.zip in Resources */ = {isa = PBXBuildFile; fileRef = 237731C61F46542B0020A3FE /* repository-with-status.zip */; };
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 */; };
Expand Down Expand Up @@ -129,6 +132,8 @@
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
232861421F4A3A2E00276D65 /* Diffs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Diffs.swift; sourceTree = "<group>"; };
237731C61F46542B0020A3FE /* repository-with-status.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = "repository-with-status.zip"; sourceTree = "<group>"; };
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; };
621E66CE1C72958D00A0F352 /* SwiftGit2-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "SwiftGit2-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -260,6 +265,7 @@
BE14AA531A1983520015B439 /* Fixtures */ = {
isa = PBXGroup;
children = (
237731C61F46542B0020A3FE /* repository-with-status.zip */,
BE0B1C5C1A9978890004726D /* detached-head.zip */,
BE14AA541A1984550015B439 /* Fixtures.swift */,
BE0991F61A578FB1007D4E6A /* Mantle.zip */,
Expand All @@ -272,6 +278,7 @@
isa = PBXGroup;
children = (
BEB31F251A0D6F7A00F525B9 /* SwiftGit2 */,
BEB31F261A0D6F7A00F525B9 /* Supporting Files */,
BEB31F321A0D6F7A00F525B9 /* SwiftGit2Tests */,
BEB31FA11A0E63C100F525B9 /* Libraries */,
BEB31F411A0D75EE00F525B9 /* Configuration */,
Expand Down Expand Up @@ -305,12 +312,12 @@
DA5914751A94579000AED74C /* Errors.swift */,
BE36354B1A632C9700D37EC8 /* Libgit2.swift */,
BE2E3BE51A31261300C67092 /* Objects.swift */,
232861421F4A3A2E00276D65 /* Diffs.swift */,
BE70B3E41A1ACB1A002C3F4E /* OID.swift */,
BE7A753E1A4A2BCC002DA7E3 /* Pointers.swift */,
BEB31F6C1A0D78F300F525B9 /* Repository.swift */,
BECB5F691A56F19900999413 /* References.swift */,
BECB5F6D1A57284700999413 /* Remotes.swift */,
BEB31F261A0D6F7A00F525B9 /* Supporting Files */,
25499A996CA7BD416620A397 /* CommitIterator.swift */,
);
path = SwiftGit2;
Expand All @@ -322,6 +329,7 @@
BEB31F271A0D6F7A00F525B9 /* Info.plist */,
);
name = "Supporting Files";
path = SwiftGit2;
sourceTree = "<group>";
};
BEB31F321A0D6F7A00F525B9 /* SwiftGit2Tests */ = {
Expand Down Expand Up @@ -655,6 +663,7 @@
buildActionMask = 2147483647;
files = (
BE0B1C5D1A9978890004726D /* detached-head.zip in Resources */,
237731C71F46542B0020A3FE /* repository-with-status.zip in Resources */,
BE0991F71A578FB1007D4E6A /* Mantle.zip in Resources */,
BE14AA571A198C6E0015B439 /* simple-repository.zip in Resources */,
);
Expand Down Expand Up @@ -742,6 +751,7 @@
622726351C84E52500C53D17 /* Credentials.swift in Sources */,
621E66A31C72958800A0F352 /* Repository.swift in Sources */,
621E66A41C72958800A0F352 /* Objects.swift in Sources */,
232861451F4A3A2E00276D65 /* Diffs.swift in Sources */,
621E66A51C72958800A0F352 /* References.swift in Sources */,
621E66A61C72958800A0F352 /* Libgit2.swift in Sources */,
621E66A71C72958800A0F352 /* Pointers.swift in Sources */,
Expand Down Expand Up @@ -775,6 +785,7 @@
622726341C84E52500C53D17 /* Credentials.swift in Sources */,
BEB31F6D1A0D78F300F525B9 /* Repository.swift in Sources */,
BE2E3BE61A31261300C67092 /* Objects.swift in Sources */,
232861431F4A3A2E00276D65 /* Diffs.swift in Sources */,
BECB5F6A1A56F19900999413 /* References.swift in Sources */,
BE36354C1A632C9700D37EC8 /* Libgit2.swift in Sources */,
BE7A753F1A4A2BCC002DA7E3 /* Pointers.swift in Sources */,
Expand Down Expand Up @@ -1014,6 +1025,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "org.libgit2.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = SwiftGit2;
SWIFT_INCLUDE_PATHS = "$(SRCROOT)/libgit2";
SWIFT_VERSION = 4.0;
};
name = Debug;
};
Expand Down Expand Up @@ -1042,6 +1054,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "org.libgit2.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = SwiftGit2;
SWIFT_INCLUDE_PATHS = "$(SRCROOT)/libgit2";
SWIFT_VERSION = 4.0;
};
name = Release;
};
Expand Down
16 changes: 8 additions & 8 deletions SwiftGit2/CommitIterator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ public class CommitIterator: IteratorProtocol, Sequence {
public typealias Iterator = CommitIterator
public typealias Element = Result<Commit, NSError>
let repo: Repository
private var revisionWalker: OpaquePointer? = nil
private var revisionWalker: OpaquePointer?

private enum Next {
case over
case ok
case okay
case error(NSError)

init(_ result: Int32, name: String) {
switch result {
case GIT_ITEROVER.rawValue:
self = .over
case GIT_OK.rawValue:
self = .ok
self = .okay
default:
self = .error(NSError(gitError: result, pointOfFailure: name))
}
Expand Down Expand Up @@ -55,7 +55,7 @@ public class CommitIterator: IteratorProtocol, Sequence {
return Result.failure(error)
case .over:
return nil
case .ok:
case .okay:
var unsafeCommit: OpaquePointer? = nil
let lookupGitResult = git_commit_lookup(&unsafeCommit, repo.pointer, &oid)
guard lookupGitResult == GIT_OK.rawValue,
Expand All @@ -76,7 +76,7 @@ public class CommitIterator: IteratorProtocol, Sequence {
public func map<T>(_ transform: (Result<Commit, NSError>) throws -> T) rethrows -> [T] {
var new: [T] = []
for item in self {
new = new + [try transform(item)]
new += [try transform(item)]
}
return new
}
Expand All @@ -85,7 +85,7 @@ public class CommitIterator: IteratorProtocol, Sequence {
var new: [Result<Commit, NSError>] = []
for item in self {
if try isIncluded(item) {
new = new + [item]
new += [item]
}
}
return new
Expand All @@ -104,12 +104,12 @@ public class CommitIterator: IteratorProtocol, Sequence {
self.repo = repo
}

public func dropFirst(_ n: Int) -> AnySequence<Iterator.Element> {
public func dropFirst(_ num: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.dropFirst)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}

public func dropLast(_ n: Int) -> AnySequence<Iterator.Element> {
public func dropLast(_ num: Int) -> AnySequence<Iterator.Element> {
notImplemented(functionName: self.dropLast)
return AnySequence<Iterator.Element> { return CommitIterator(repo: self.repo) }
}
Expand Down
111 changes: 111 additions & 0 deletions SwiftGit2/Diffs.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//
// Diffs.swift
// SwiftGit2
//
// Created by Jake Van Alstyne on 8/20/17.
// Copyright © 2017 GitHub, Inc. All rights reserved.
//
import Foundation
import libgit2

public struct StatusEntry {
public var status: Diff.Status
public var headToIndex: Diff.Delta?
public var indexToWorkDir: Diff.Delta?

public init(from statusEntry: git_status_entry) {
self.status = Diff.Status(rawValue: statusEntry.status.rawValue)

if let htoi = statusEntry.head_to_index {
self.headToIndex = Diff.Delta(htoi.pointee)
}

if let itow = statusEntry.index_to_workdir {
self.indexToWorkDir = Diff.Delta(itow.pointee)
}
}
}

public struct Diff {

/// The set of deltas.
public var deltas = [Delta]()

public struct Delta {
public static let type = GIT_OBJ_REF_DELTA

public var status: Status
public var flags: Flags
public var oldFile: File?
public var newFile: File?

public init(_ delta: git_diff_delta) {
self.status = Status(rawValue: UInt32(git_diff_status_char(delta.status)))
self.flags = Flags(rawValue: delta.flags)
self.oldFile = File(delta.old_file)
self.newFile = File(delta.new_file)
}
}

public struct File {
public var oid: OID
public var path: String
public var size: Int64
public var flags: Flags

public init(_ diffFile: git_diff_file) {
self.oid = OID(diffFile.id)
let path = diffFile.path
self.path = path.map(String.init(cString:))!
self.size = diffFile.size
self.flags = Flags(rawValue: diffFile.flags)
}
}

public struct Status: OptionSet {
// This appears to be necessary due to bug in Swift
// https://bugs.swift.org/browse/SR-3003
public init(rawValue: UInt32) {
self.rawValue = rawValue
}
public let rawValue: UInt32

public static let current = Status(rawValue: 0)
public static let indexNew = Status(rawValue: 1 << 0)
public static let indexModified = Status(rawValue: 1 << 1)
public static let indexDeleted = Status(rawValue: 1 << 2)
public static let indexRenamed = Status(rawValue: 1 << 3)
public static let indexTypeChange = Status(rawValue: 1 << 4)
public static let workTreeNew = Status(rawValue: 1 << 5)
public static let workTreeModified = Status(rawValue: 1 << 6)
public static let workTreeDeleted = Status(rawValue: 1 << 7)
public static let workTreeTypeChange = Status(rawValue: 1 << 8)
public static let workTreeRenamed = Status(rawValue: 1 << 9)
public static let workTreeUnreadable = Status(rawValue: 1 << 10)
public static let ignored = Status(rawValue: 1 << 11)
public static let conflicted = Status(rawValue: 1 << 12)
}

public struct Flags: OptionSet {
// This appears to be necessary due to bug in Swift
// https://bugs.swift.org/browse/SR-3003
public init(rawValue: UInt32) {
self.rawValue = rawValue
}
public let rawValue: UInt32

public static let binary = Flags(rawValue: 0)
public static let notBinary = Flags(rawValue: 1 << 0)
public static let validId = Flags(rawValue: 1 << 1)
public static let exists = Flags(rawValue: 1 << 2)
}

/// Create an instance with a libgit2 `git_diff`.
public init(_ pointer: OpaquePointer) {
for i in 0..<git_diff_num_deltas(pointer) {
if let delta = git_diff_get_delta(pointer, i) {
deltas.append(Diff.Delta(delta.pointee))
}
}
}
}
Loading

0 comments on commit d35dac6

Please sign in to comment.