git

package module
v4.0.0-rc9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 1, 2017 License: MIT Imports: 29 Imported by: 0

README

go-git GoDoc Build Status codecov.io codebeat badge

A highly extensible git implementation in pure Go.

go-git aims to reach the completeness of libgit2 or jgit, nowadays covers the majority of the plumbing read operations and some of the main write operations, but lacks the main porcelain operations such as merges.

It is highly extensible, we have been following the open/close principle in its design to facilitate extensions, mainly focusing the efforts on the persistence of the objects.

... is this production ready?

The master branch represents the v4 of the library, it is currently under active development and is planned to be released in early 2017.

If you are looking for a production ready version, please take a look to the v3 which is being used in production at source{d} since August 2015 to analyze all GitHub public repositories (i.e. 16M repositories).

We recommend the use of v4 to develop new projects since it includes much new functionality and provides a more idiomatic git API

Installation

The recommended way to install go-git is:

go get -u srcd.works/go-git.v4/...

Examples

Please note that the functions CheckIfError and Info 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/src-d/go-git")

_, err := git.PlainClone("/tmp/foo", false, &git.CloneOptions{
    URL:      "https://github.com/src-d/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/src-d/go-siva")

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

CheckIfError(err)

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

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

// ... retrieves the commit object
commit, err := r.Commit(ref.Hash())
CheckIfError(err)

// ... retrieves the commit history
history, err := commit.History()
CheckIfError(err)

// ... just iterates over the commits, printing it
for _, c := range history {
    fmt.Println(c)
}

Outputs:

commit ded8054fd0c3994453e9c8aacaf48d118d42991e
Author: Santiago M. Mola <santi@mola.io>
Date:   Sat Nov 12 21:18:41 2016 +0100

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

commit df707095626f384ce2dc1a83b30f9a21d69b9dfc
Author: Santiago M. Mola <santi@mola.io>
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 other at the examples folder

Contribute

If you are interested on contributing to go-git, open an issue explaining which missing functionality you want to work in, and we will guide you through the implementation.

License

MIT, see LICENSE

Documentation

Overview

A highly extensible git implementation in pure Go.

go-git aims to reach the completeness of libgit2 or jgit, nowadays covers the majority of the plumbing read operations and some of the main write operations, but lacks the main porcelain operations such as merges.

It is highly extensible, we have been following the open/close principle in its design to facilitate extensions, mainly focusing the efforts on the persistence of the objects.

Index

Examples

Constants

View Source
const (
	// DefaultRemoteName name of the default Remote, just like git command
	DefaultRemoteName = "origin"
)

Variables

View Source
var (
	ErrObjectNotFound          = errors.New("object not found")
	ErrInvalidReference        = errors.New("invalid reference, should be a tag or a branch")
	ErrRepositoryNotExists     = errors.New("repository not exists")
	ErrRepositoryAlreadyExists = errors.New("repository already exists")
	ErrRemoteNotFound          = errors.New("remote not found")
	ErrRemoteExists            = errors.New("remote already exists")
	ErrWorktreeNotProvided     = errors.New("worktree should be provided")
	ErrIsBareRepository        = errors.New("worktree not available in a bare repository")
)
View Source
var (
	ErrMissingURL = errors.New("URL field is required")
)
View Source
var ErrWorktreeNotClean = errors.New("worktree is not clean")
View Source
var NoErrAlreadyUpToDate = errors.New("already up-to-date")

Functions

func References

func References(c *object.Commit, path string) ([]*object.Commit, error)

References returns a References for the file at "path", the commits are sorted in commit order. It stops searching a branch for a file upon reaching the commit were the file was created.

Caveats:

  • Moves and copies are not currently supported.
  • Cherry-picks are not detected unless there are no commits between them and therefore can appear repeated in the list. (see git path-id for hints on how to fix this).

Types

type BlameResult

type BlameResult struct {
	Path  string
	Rev   plumbing.Hash
	Lines []*Line
}

func Blame

func Blame(c *object.Commit, path string) (*BlameResult, error)

Blame returns the last commit that modified each line of a file in a repository.

The file to blame is identified by the input arguments: repo, commit and path. The output is a slice of commits, one for each line in the file.

Blaming a file is a two step process:

1. Create a linear history of the commits affecting a file. We use revlist.New for that.

2. Then build a graph with a node for every line in every file in the history of the file.

Each node (line) holds the commit where it was introduced or last modified. To achieve that we use the FORWARD algorithm described in Zimmermann, et al. "Mining Version Archives for Co-changed Lines", in proceedings of the Mining Software Repositories workshop, Shanghai, May 22-23, 2006.

Each node is assigned a commit: Start by the nodes in the first commit. Assign that commit as the creator of all its lines.

Then jump to the nodes in the next commit, and calculate the diff between the two files. Newly created lines get assigned the new commit as its origin. Modified lines also get this new commit. Untouched lines retain the old commit.

All this work is done in the assignOrigin function which holds all the internal relevant data in a "blame" struct, that is not exported.

type CloneOptions

type CloneOptions struct {
	// The (possibly remote) repository URL to clone from
	URL string
	// Auth credentials, if required, to use with the remote repository
	Auth transport.AuthMethod
	// Name of the remote to be added, by default `origin`
	RemoteName string
	// Remote branch to clone
	ReferenceName plumbing.ReferenceName
	// Fetch only ReferenceName if true
	SingleBranch bool
	// Limit fetching to the specified number of commits
	Depth int
	// Progress is where the human readable information sent by the server is
	// stored, if nil nothing is stored and the capability (if supported)
	// no-progress, is sent to the server to avoid send this information
	Progress sideband.Progress
}

CloneOptions describes how a clone should be performed

func (*CloneOptions) Validate

func (o *CloneOptions) Validate() error

Validate validates the fields and sets the default values

type FetchOptions

type FetchOptions struct {
	// Name of the remote to fetch from. Defaults to origin.
	RemoteName string
	RefSpecs   []config.RefSpec
	// Depth limit fetching to the specified number of commits from the tip of
	// each remote branch history.
	Depth int
	// Auth credentials, if required, to use with the remote repository
	Auth transport.AuthMethod
	// Progress is where the human readable information sent by the server is
	// stored, if nil nothing is stored and the capability (if supported)
	// no-progress, is sent to the server to avoid send this information
	Progress sideband.Progress
}

FetchOptions describes how a fetch should be performed

func (*FetchOptions) Validate

func (o *FetchOptions) Validate() error

Validate validates the fields and sets the default values

type FileStatus

type FileStatus struct {
	Staging  StatusCode
	Worktree StatusCode
	Extra    string
}

FileStatus status of a file in the Worktree

type Line

type Line struct {
	Author string // email address of the author of the line.
	Text   string // original text of the line.
}

Line values represent the contents and author of a line in BlamedResult values.

type PullOptions

type PullOptions struct {
	// Name of the remote to be pulled. If empty, uses the default.
	RemoteName string
	// Remote branch to clone.  If empty, uses HEAD.
	ReferenceName plumbing.ReferenceName
	// Fetch only ReferenceName if true.
	SingleBranch bool
	// Limit fetching to the specified number of commits.
	Depth int
	// Auth credentials, if required, to use with the remote repository
	Auth transport.AuthMethod
	// Progress is where the human readable information sent by the server is
	// stored, if nil nothing is stored and the capability (if supported)
	// no-progress, is sent to the server to avoid send this information
	Progress sideband.Progress
}

PullOptions describes how a pull should be performed

func (*PullOptions) Validate

func (o *PullOptions) Validate() error

Validate validates the fields and sets the default values.

type PushOptions

type PushOptions struct {
	// RemoteName is the name of the remote to be pushed to.
	RemoteName string
	// RefSpecs specify what destination ref to update with what source
	// object. A refspec with empty src can be used to delete a reference.
	RefSpecs []config.RefSpec
	// Auth credentials, if required, to use with the remote repository
	Auth transport.AuthMethod
}

PushOptions describes how a push should be performed

func (*PushOptions) Validate

func (o *PushOptions) Validate() error

Validate validates the fields and sets the default values

type Remote

type Remote struct {
	// contains filtered or unexported fields
}

Remote represents a connection to a remote repository

func (*Remote) Config

func (r *Remote) Config() *config.RemoteConfig

Config return the config

func (*Remote) Fetch

func (r *Remote) Fetch(o *FetchOptions) error

Fetch fetches references from the remote to the local repository. Returns nil if the operation is successful, NoErrAlreadyUpToDate if there are no changes to be fetched, or an error.

func (*Remote) Push

func (r *Remote) Push(o *PushOptions) (err error)

Push performs a push to the remote. Returns NoErrAlreadyUpToDate if the remote was already up-to-date.

func (*Remote) String

func (r *Remote) String() string

type Repository

type Repository struct {
	// contains filtered or unexported fields
}

Repository represents a git repository

func Clone

func Clone(s Storer, worktree billy.Filesystem, o *CloneOptions) (*Repository, error)

Clone a repository into the given Storer and worktree Filesystem with the given options, if worktree is nil a bare repository is created. If the given storer is not empty ErrRepositoryAlreadyExists is returned

Example
// Filesystem abstraction based on memory
fs := memfs.New()
// Git objects storer based on memory
storer := memory.NewStorage()

// Clones the repository into the worktree (fs) and storer all the .git
// content into the storer
_, _ = git.Clone(storer, fs, &git.CloneOptions{
	URL: "https://github.com/git-fixtures/basic.git",
})

// Prints the content of the CHANGELOG file from the cloned repository
changelog, _ := fs.Open("CHANGELOG")

io.Copy(os.Stdout, changelog)
Output:

Initial changelog

func Init

func Init(s Storer, worktree billy.Filesystem) (*Repository, error)

Init creates an empty git repository, based on the given Storer and worktree. The worktree Filesystem is optional, if nil a bare repository is created. If the given storer is not empty ErrRepositoryAlreadyExists is returned

func Open

func Open(s Storer, worktree billy.Filesystem) (*Repository, error)

Open opens a git repository using the given Storer and worktree filesystem, if the given storer is complete empty ErrRepositoryNotExists is returned. The worktree can be nil when the repository being opened is bare, if the repository is a normal one (not bare) and worktree is nil the err ErrWorktreeNotProvided is returned

func PlainClone

func PlainClone(path string, isBare bool, o *CloneOptions) (*Repository, error)

PlainClone a repository into the path with the given options, isBare defines if the new repository will be bare or normal. If the path is not empty ErrRepositoryAlreadyExists is returned

Example
// Tempdir to clone the repository
dir, err := ioutil.TempDir("", "clone-example")
if err != nil {
	log.Fatal(err)
}

defer os.RemoveAll(dir) // clean up

// Clones the repository into the given dir, just as a normal git clone does
_, err = git.PlainClone(dir, false, &git.CloneOptions{
	URL: "https://github.com/git-fixtures/basic.git",
})

if err != nil {
	log.Fatal(err)
}

// Prints the content of the CHANGELOG file from the cloned repository
changelog, err := os.Open(filepath.Join(dir, "CHANGELOG"))
if err != nil {
	log.Fatal(err)
}

io.Copy(os.Stdout, changelog)
Output:

Initial changelog

func PlainInit

func PlainInit(path string, isBare bool) (*Repository, error)

PlainInit create an empty git repository at the given path. isBare defines if the repository will have worktree (non-bare) or not (bare), if the path is not empty ErrRepositoryAlreadyExists is returned

func PlainOpen

func PlainOpen(path string) (*Repository, error)

PlainOpen opens a git repository from the given path. It detects if the repository is bare or a normal one. If the path doesn't contain a valid repository ErrRepositoryNotExists is returned

func (*Repository) Blob

func (r *Repository) Blob(h plumbing.Hash) (*object.Blob, error)

Blob returns a Blob with the given hash. If not found plumbing.ErrObjectNotFound is returne

func (*Repository) Blobs

func (r *Repository) Blobs() (*object.BlobIter, error)

Blobs returns an unsorted BlobIter with all the blobs in the repository

func (*Repository) Commit

func (r *Repository) Commit(h plumbing.Hash) (*object.Commit, error)

Commit return a Commit with the given hash. If not found plumbing.ErrObjectNotFound is returned

func (*Repository) Commits

func (r *Repository) Commits() (*object.CommitIter, error)

Commits returns an unsorted CommitIter with all the commits in the repository

func (*Repository) Config

func (r *Repository) Config() (*config.Config, error)

Config return the repository config

func (*Repository) CreateRemote

func (r *Repository) CreateRemote(c *config.RemoteConfig) (*Remote, error)

CreateRemote creates a new remote

Example
r, _ := git.Init(memory.NewStorage(), nil)

// Add a new remote, with the default fetch refspec
_, err := r.CreateRemote(&config.RemoteConfig{
	Name: "example",
	URL:  "https://github.com/git-fixtures/basic.git",
})

if err != nil {
	log.Fatal(err)
}

list, err := r.Remotes()
if err != nil {
	log.Fatal(err)
}

for _, r := range list {
	fmt.Println(r)
}

// Example Output:
// example https://github.com/git-fixtures/basic.git (fetch)
// example https://github.com/git-fixtures/basic.git (push)
Output:

func (*Repository) DeleteRemote

func (r *Repository) DeleteRemote(name string) error

DeleteRemote delete a remote from the repository and delete the config

func (*Repository) Fetch

func (r *Repository) Fetch(o *FetchOptions) error

Fetch fetches changes from a remote repository. Returns nil if the operation is successful, NoErrAlreadyUpToDate if there are no changes to be fetched, or an error.

func (*Repository) Head

func (r *Repository) Head() (*plumbing.Reference, error)

Head returns the reference where HEAD is pointing to.

func (*Repository) Object

Object returns an Object with the given hash. If not found plumbing.ErrObjectNotFound is returned

func (*Repository) Objects

func (r *Repository) Objects() (*object.ObjectIter, error)

Objects returns an unsorted BlobIter with all the objects in the repository

func (*Repository) Pull

func (r *Repository) Pull(o *PullOptions) error

Pull incorporates changes from a remote repository into the current branch. Returns nil if the operation is successful, NoErrAlreadyUpToDate if there are no changes to be fetched, or an error.

func (*Repository) Push

func (r *Repository) Push(o *PushOptions) error

Push pushes changes to a remote.

func (*Repository) Reference

func (r *Repository) Reference(name plumbing.ReferenceName, resolved bool) (
	*plumbing.Reference, error)

Reference returns the reference for a given reference name. If resolved is true, any symbolic reference will be resolved.

func (*Repository) References

func (r *Repository) References() (storer.ReferenceIter, error)

References returns an unsorted ReferenceIter for all references.

Example
r, _ := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
	URL: "https://github.com/git-fixtures/basic.git",
})

// simulating a git show-ref
refs, _ := r.References()
refs.ForEach(func(ref *plumbing.Reference) error {
	if ref.Type() == plumbing.HashReference {
		fmt.Println(ref)
	}

	return nil
})

// Example Output:
// 6ecf0ef2c2dffb796033e5a02219af86ec6584e5 refs/remotes/origin/master
// e8d3ffab552895c19b9fcf7aa264d277cde33881 refs/remotes/origin/branch
// 6ecf0ef2c2dffb796033e5a02219af86ec6584e5 refs/heads/master
Output:

func (*Repository) Remote

func (r *Repository) Remote(name string) (*Remote, error)

Remote return a remote if exists

func (*Repository) Remotes

func (r *Repository) Remotes() ([]*Remote, error)

Remotes returns a list with all the remotes

func (*Repository) Tag

func (r *Repository) Tag(h plumbing.Hash) (*object.Tag, error)

Tag returns a Tag with the given hash. If not found plumbing.ErrObjectNotFound is returned

func (*Repository) Tags

func (r *Repository) Tags() (*object.TagIter, error)

Tags returns a unsorted TagIter that can step through all of the annotated tags in the repository.

func (*Repository) Tree

func (r *Repository) Tree(h plumbing.Hash) (*object.Tree, error)

Tree return a Tree with the given hash. If not found plumbing.ErrObjectNotFound is returned

func (*Repository) Trees

func (r *Repository) Trees() (*object.TreeIter, error)

Trees returns an unsorted TreeIter with all the trees in the repository

func (*Repository) Worktree

func (r *Repository) Worktree() (*Worktree, error)

Worktree returns a worktree based on the given fs, if nil the default worktree will be used.

type Status

type Status map[string]*FileStatus

Status current status of a Worktree

func (Status) File

func (s Status) File(filename string) *FileStatus

func (Status) IsClean

func (s Status) IsClean() bool

func (Status) String

func (s Status) String() string

type StatusCode

type StatusCode int8

StatusCode status code of a file in the Worktree

const (
	Unmodified StatusCode = iota
	Untracked
	Modified
	Added
	Deleted
	Renamed
	Copied
	UpdatedButUnmerged
)

func (StatusCode) String

func (c StatusCode) String() string

type Storer

Storer is a generic storage of objects, references and any information related to a particular repository. The package srcd.works/go-git.v4/storage contains two implementation a filesystem base implementation (such as `.git`) and a memory implementations being ephemeral

type Worktree

type Worktree struct {
	// contains filtered or unexported fields
}

func (*Worktree) Checkout

func (w *Worktree) Checkout(commit plumbing.Hash) error

func (*Worktree) Status

func (w *Worktree) Status() (Status, error)

Directories

Path Synopsis
log
cli
Package config contains the abstraction of multiple config files
Package config contains the abstraction of multiple config files
+build ignore +build ignore +build ignore +build ignore +build ignore +build ignore +build ignore +build ignore +build ignore
+build ignore +build ignore +build ignore +build ignore +build ignore +build ignore +build ignore +build ignore +build ignore
package plumbing implement the core interfaces and structs used by go-git
package plumbing implement the core interfaces and structs used by go-git
format/config
Package config implements decoding/encoding of git config files.
Package config implements decoding/encoding of git config files.
format/idxfile
Package idxfile implements an encoder and a decoder of idx files
Package idxfile implements an encoder and a decoder of idx files
format/index
Package index implements an encoder and a decoder of index format files
Package index implements an encoder and a decoder of index format files
format/packfile
Package packfile implements a encoder/decoder of packfile format
Package packfile implements a encoder/decoder of packfile format
format/pktline
Package pktline implements reading payloads form pkt-lines and encoding pkt-lines from payloads.
Package pktline implements reading payloads form pkt-lines and encoding pkt-lines from payloads.
protocol/packp/sideband
Package sideband implements a sideband mutiplex/demultiplexer
Package sideband implements a sideband mutiplex/demultiplexer
revlist
Package revlist implements functions to walk the objects referenced by a commit history.
Package revlist implements functions to walk the objects referenced by a commit history.
transport
Package transport includes the implementation for different transport protocols.
Package transport includes the implementation for different transport protocols.
transport/http
Package http implements a HTTP client for go-git.
Package http implements a HTTP client for go-git.
transport/internal/common
Package common implements the git pack protocol with a pluggable transport.
Package common implements the git pack protocol with a pluggable transport.
transport/server
Package server implements the git server protocol.
Package server implements the git server protocol.
transport/test
Package test implements common test suite for different transport implementations.
Package test implements common test suite for different transport implementations.
storage
filesystem
Package filesystem is a storage backend base on filesystems
Package filesystem is a storage backend base on filesystems
filesystem/internal/dotgit
https://github.com/git/git/blob/master/Documentation/gitrepository-layout.txt
https://github.com/git/git/blob/master/Documentation/gitrepository-layout.txt
memory
Package memory is a storage backend base on memory
Package memory is a storage backend base on memory
utils
binary
Package binary implements sintax-sugar functions on top of the standard library binary package
Package binary implements sintax-sugar functions on top of the standard library binary package
diff
Package diff implements line oriented diffs, similar to the ancient Unix diff command.
Package diff implements line oriented diffs, similar to the ancient Unix diff command.
merkletrie
Package merkletrie provides support for n-ary trees that are at the same time Merkle trees and Radix trees (tries), and provides an efficient tree comparison algorithm for them.
Package merkletrie provides support for n-ary trees that are at the same time Merkle trees and Radix trees (tries), and provides an efficient tree comparison algorithm for them.
merkletrie/internal/fsnoder
Package fsnoder allows to create merkletrie noders that resemble file systems, from human readable string descriptions.
Package fsnoder allows to create merkletrie noders that resemble file systems, from human readable string descriptions.
merkletrie/noder
Package noder provide an interface for defining nodes in a merkletrie, their hashes and their paths (a noders and its ancestors).
Package noder provide an interface for defining nodes in a merkletrie, their hashes and their paths (a noders and its ancestors).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL