Git
Chapters ▾ 2nd Edition

A2.4 Appendix B: Встраивание Git в ваши приложения - go-git

go-git

Для интеграции Git в сервисы, написанные на языке Golang, существует библиотека на чистом Go. Она не имеет собственных зависимостей, поэтому не подвержена ошибкам ручного управления памятью. Так же эта библиотека прозрачна для стандартных Golang утилит анализа производительности, таких как профайлеры потребления ЦПУ и памяти, детектор гонки и других.

go-git ориентирован на расширяемость, совместимость и поддерживает большинство подключаемых API, которые описаны здесь https://github.com/src-d/go-git/blob/master/COMPATIBILITY.md.

Вот простой пример использования Go API:

import 	"gopkg.in/src-d/go-git.v4"

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

Как только у вас есть экземпляр Repository, вы можете получить доступ к информации и изменять её:

// получаем ветку по указателю HEAD
ref, err := r.Head()

// получаем объект коммита по указателю ref
commit, err := r.CommitObject(ref.Hash())

// получаем историю коммита
history, err := commit.History()

// проходим по коммитам и выводим каждый из них
for _, c := range history {
    fmt.Println(c)
}

Расширенная функциональность

go-git обладает некоторыми дополнительными функциями, одна из которых - это подключаемое хранилище, что близко по смыслу с бэкендами Libgit2. Реализация по умолчанию - хранилище в памяти, которое очень быстро работает.

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

Подключаемое хранилище предоставляет много интересных возможностей. Например, https://github.com/src-d/go-git/tree/master/_examples/storage позволяет вам сохранять ссылки, объекты и конфигурацию в базе данных Aerospike.

Другая особенность - гибкая абстракция файловой системы. Используя https://godoc.org/github.com/src-d/go-billy#Filesystem легко сохранять все файлы по-разному, т.е. упаковав их все в один архив хранить на диске или держать в памяти.

Ещё одна продвинутая возможность - это тонко настраиваемый HTTP клиент, как например вот этот https://github.com/src-d/go-git/blob/master/_examples/custom_http/main.go.

customClient := &http.Client{
	Transport: &http.Transport{ // принимать любой сертификат (полезно при тестировании)
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	},
	Timeout: 15 * time.Second,  // таймаут в 15 секунд
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
		return http.ErrUseLastResponse // не следовать перенаправлениям
	},
}

// Перегружаем http(s) протокол по умолчанию для использования собственного клиента
client.InstallProtocol("https", githttp.NewClient(customClient))

// Клонируем репозиторий используя новый клиент, если протокол https://
r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{URL: url})

Дополнительные материалы

Полный разбор возможностей go-git выходит за рамки этой книги. Если вы хотите получить больше информации о go-git, воспользуйтесь документацией к API https://godoc.org/gopkg.in/src-d/go-git.v4 и примерами использования https://github.com/src-d/go-git/tree/master/_examples.