SPM-native · iOS & macOS · libgit2

Async-first Git
for Swift

A modern, type-safe libgit2 wrapper. Branches, commits, diffs, merge, rebase, stash — all with a clean Swift API.

Package.swift
dependencies: [
    .package(url: "https://github.com/RonenMars/Gitty", from: "0.1.0"),
]

Everything Git, in Swift

Async-first

Clone, fetch, and push with native Swift concurrency. Synchronous operations stay fast and simple.

Zero dependencies

Bundles libgit2 as a pure SPM package. No Homebrew, no CMake, no system setup required.

Type-safe errors

All libgit2 error codes surface as GittyError. No silent failures, no raw integer codes.

Full branch & remote support

Create, delete, rename, checkout. Manage multiple remotes, fetch, and push with credentials.

Merge, Rebase & Cherry-pick

Typed merge results — up-to-date, fast-forward, merged, or conflict. Full rebase and cherry-pick support.

Diff & Blame

Typed hunks and lines from any diff. Blame any file to trace changes back to their original commit.

Tags & Stash

Lightweight and annotated tags. Full stash push, pop, apply, drop, and list.

Worktrees

Add, remove, lock, and unlock linked working trees for parallel branch workflows.

Flexible credentials

Token, username/password, SSH agent, or system credential helper — all supported out of the box.

A taste of the API

import Gitty

// Clone a private repo
let repo = try await Repository.clone(
    from: URL(string: "https://github.com/user/repo")!,
    to: localURL,
    credentials: .token("ghp_yourtoken")
)

// Stage all changes and commit
let author = Signature(name: "Alice", email: "alice@example.com")
try repo.stageAll()
let commit = try repo.commit(message: "feat: add login", author: author)

// Merge a branch and handle the result
switch try repo.merge(branch: branch) {
case .fastForward(let c): print("Fast-forwarded to", c.oid.shortString)
case .merged(let c):      print("Merged:", c.oid.shortString)
case .conflict(let files): print("Conflicts:", files.map(.path))
default: break
}

Start building with Gitty

Add it to your Swift project in seconds. No system setup required.