go-git is a free, open source version control & collaboration project written in Go and released under Apache-2.0. It has 7,723 GitHub stars, 1,035 forks and 248 open issues, and was last pushed 5 hours ago. On this registry it ranks #16 of 30 tracked projects in Version Control & Collaboration, with 5 head-to-head comparisons available. It gained 5 stars over the last 3 tracked days.

What is go-git?

go-git is a pure Go implementation of Git, published as the library github.com/go-git/go-git/v6, for Go developers who need to read, write and manipulate Git repositories from inside their own programs instead of shelling out to the git binary.

What it is

go-git is a highly extensible Git implementation library written in pure Go, licensed under Apache-2.0 and actively developed since 2015. It exposes the Git object model and operations through an idiomatic Go API at two levels: low level (plumbing) and high level (porcelain). Storage is pluggable through the Storer interface in the plumbing/storer package, which allows repositories to live in memory, on a custom filesystem, or in a backing store the developer supplies. The library carries a broad set of topics, including git, git-client, git-library, git-server, go-git and golang, and its documentation lives at https://pkg.go.dev/github.com/go-git/go-git/v6.

The concrete problem it solves is that embedding Git functionality in a Go program would otherwise require the git binary to be present, invoked as an external process, with its output parsed back. go-git replaces that dependency with a Go package: clone, log, ref lookup and commit traversal happen in process, over an API the compiler checks. That matters most where the working tree does not exist at all, as with the in-memory example that clones https://github.com/go-git/go-billy into memory.NewStorage() and then walks HEAD history with r.Log(&git.LogOptions{From: ref.Hash()}) and cIter.ForEach over *object.Commit. It also matters for tooling that must serve many repositories at once or keep repository data in application-controlled storage.

Key capabilities

  • Clone a remote repository to a local directory with git.PlainClone and git.CloneOptions{URL: ..., Progress: os.Stdout}, mirroring the behaviour of git clone.
  • Clone into memory with git.Clone(memory.NewStorage(), nil, ...), so the working tree never touches disk.
  • Work at the plumbing level directly, including refs and commit objects, or at the porcelain level for the higher-level operations.
  • Back repositories with custom storage by implementing the Storer interface from plumbing/storer.
  • Traverse commit history through an iterator, using r.Head() to resolve the HEAD ref and r.Log with git.LogOptions{From: ref.Hash()}, then cIter.ForEach.
  • Track compatibility against upstream git, with porcelain operations written to behave as git does; the outstanding differences are catalogued in COMPATIBILITY.md.
  • Serve the client, library and server sides of Git, as indicated by the project topics git-client, git-library and git-server.

Who uses it and how

  • Gitea uses go-git inside a self-hosted Git hosting service, where the library handles repository operations in process rather than through the git command line.
  • Keybase uses it for encrypted Git, embedding repository access in an end-to-end encrypted client.
  • Pulumi uses go-git across its codebase, as shown by source searches within the Pulumi organisation.
  • Kubernetes Prow and Flux, both CNCF projects, depend on it for their Git-driven automation.
  • GitSight treats go-git as a critical component used at scale, which is the clearest indication of the library running against many repositories rather than a single working copy.

Getting started

Install the module by importing it in Go source with import "github.com/go-git/go-git/v6"; the README recommends this as the installation path. From there, git.PlainClone, git.Clone with memory.NewStorage(), and the history-walking example are the documented entry points.

How it compares

The project is measured directly against git itself, aiming for full compatibility, with all porcelain operations implemented to work exactly as git does. The README is candid that git is a humongous project built by thousands of contributors over many years, making complete feature parity a challenge, and it points readers to COMPATIBILITY.md for the current comparison. Within this registry, go-git's distinguishing trait is that it is a Go library bound to the Storer interface rather than a wrapper around an external binary.

When to use it — and when not to

Choose go-git when a Go program must manipulate repositories in process, especially when the storage should be in memory or a custom backend rather than a normal working directory. Because it is a library rather than a service, there is no database, object store or SMTP server to operate, but there is also nothing to deploy without writing Go code against the API. Do not pick it if full parity with git is a hard requirement — the compatibility gaps are real and documented — or if the surrounding stack is not Go; the 248 open issues also indicate a broad surface of ongoing work rather than a frozen, finished one.

project readme (upstream, from github) — read inline

go-git logo GoDoc Build Status Go Report Card OpenSSF Scorecard

go-git is a highly extensible git implementation library written in pure Go.

It can be used to manipulate git repositories at low level (plumbing) or high level (porcelain), through an idiomatic Go API. It also supports several types of storage, such as in-memory filesystems, or custom implementations, thanks to the Storer interface.

It has been actively developed since 2015 and is used extensively by Keybase, Gitea, and Pulumi, among many other libraries and tools. It is also a dependency in major CNCF projects such as Kubernetes Prow and Flux.

Project Status

For the full backstory see HISTORY.md.

The project is actively maintained by individual contributors, including several of the original authors. It is backed by GitSight, where go-git is a critical component used at scale, and by Entire, which supports ongoing maintenance and development of new features.

Comparison with git

go-git aims to be fully compatible with git, all the porcelain operations are implemented to work exactly as git does.

git is a humongous project with years of development by thousands of contributors, making it challenging for go-git to implement all the features. You can find a comparison of go-git vs git in the compatibility documentation.

Installation

The recommended way to install go-git is:

import "github.com/go-git/go-git/v6"

Examples

Please note that the CheckIfError and Info functions used in the examples are from the examples package just to be used in the examples.

Basic example

A basic example that mimics the standard git clone command

// Clone the given repository to the given directory
Info("git clone https://github.com/go-git/go-git")

_, err := git.PlainClone("/tmp/foo", &git.CloneOptions{
    URL:      "https://github.com/go-git/go-git",
    Progress: os.Stdout,
})

CheckIfError(err)

Outputs:

Counting objects: 4924, done.
Compressing objects: 100% (1333/1333), done.
Total 4924 (delta 530), reused 6 (delta 6), pack-reused 3533

In-memory example

Cloning a repository into memory and printing the history of HEAD, just like git log does

// Clones the given repository in memory, creating the remote, the local
// branches and fetching the objects, exactly as:
Info("git clone https://github.com/go-git/go-billy")

r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
    URL: "https://github.com/go-git/go-billy",
})

CheckIfError(err)

// Gets the HEAD history from HEAD, just like this command:
Info("git log")

// ... retrieves the branch pointed by HEAD
ref, err := r.Head()
CheckIfError(err)


// ... retrieves the commit history
cIter, err := r.Log(&git.LogOptions{From: ref.Hash()})
CheckIfError(err)

// ... just iterates over the commits, printing it
err = cIter.ForEach(func(c *object.Commit) error {
	fmt.Println(c)
	return nil
})
CheckIfError(err)

Outputs:

commit ded8054fd0c3994453e9c8aacaf48d118d42991e
Author: Santiago M. Mola <[email protected]>
Date:   Sat Nov 12 21:18:41 2016 +0100

    index: ReadFrom/WriteTo returns IndexReadError/IndexWriteError. (#9)

commit df707095626f384ce2dc1a83b30f9a21d69b9dfc
Author: Santiago M. Mola <[email protected]>
Date:   Fri Nov 11 13:23:22 2016 +0100

    readwriter: fix bug when writing index. (#10)

    When using ReadWriter on an existing siva file, absolute offset for
    index entries was not being calculated correctly.
...

You can find this example and many others in the examples folder.

Contribute

Contributions are more than welcome, if you are interested please take a look to our Contributing Guidelines.

License

Apache License Version 2.0, see LICENSE

Frequently asked questions

Is go-git free to use?

go-git is open source under the Apache-2.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does go-git do?

A highly extensible Git implementation in pure Go.

What is go-git written in?

go-git is primarily written in Go. Its source is publicly available at https://github.com/go-git/go-git, and it has 7,723 GitHub stars.