Git
Chapters ▾ 2nd Edition

A2.4 Appendix B: Git in Ihre Anwendungen einbetten - go-git

go-git

Für den Fall, dass Sie Git in einen in Golang geschriebenen Service integrieren wollen, gibt es auch eine direkte Umsetzung der Go-Bibliothek. Diese Implementierung hat keine eigenen Abhängigkeiten und ist daher nicht anfällig für manuelle Fehler in der Speicherverwaltung. Sie ist auch transparent für die standardmäßigen Golang-Tools zur Leistungsanalyse wie CPU, Memory-Profiler, Race-Detektor usw.

go-git konzentriert sich auf Erweiterbarkeit und Kompatibilität. Es unterstützt die meisten APIs für die Basisbefehle (engl. plumbing), die auf https://github.com/go-git/go-git/blob/master/COMPATIBILITY.md dokumentiert sind.

Hier ist ein einfaches Beispiel für die Verwendung der Go-APIs:

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

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

Sobald Sie eine Repository Instanz haben, können Sie auf Informationen zugreifen und Änderungen daran vornehmen:

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

// get the commit object, pointed by ref
commit, err := r.CommitObject(ref.Hash())

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

// iterates over the commits and print each
for _, c := range history {
    fmt.Println(c)
}

Erweiterte Funktionalität

go-git hat nur wenige nennenswerte fortgeschrittene Funktionen, von denen eine ein erweiterbares Speichersystem ist, das den Libgit2-Backends ähnlich ist. Die Standard-Implementierung ist der In-Memory Storage, welcher sehr effizient ist.

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

Die anpassbare Speicherlösung bietet viele interessante Optionen. So können Sie beispielsweise mit https://github.com/go-git/go-git/tree/master/_examples/storage Referenzen, Objekte und Konfiguration in einer Aerospike-Datenbank speichern.

Ein anderes Feature ist eine flexible Abstraktion des Dateisystems. Mit https://pkg.go.dev/github.com/go-git/go-billy/v5?tab=doc#Filesystem ist es einfach, alle Dateien auf unterschiedliche Weise zu speichern, d.h. alle Dateien in ein einziges Archiv auf der Festplatte zu komprimieren oder sie alle im Arbeitsspeicher zu halten.

Ein weiterer fortgeschrittener Verwendungszweck enthält einen fein anpassbaren HTTP-Client, wie er bei https://github.com/go-git/go-git/blob/master/_examples/custom_http/main.go zu finden ist.

customClient := &http.Client{
  Transport: &http.Transport{ // accept any certificate (might be useful for testing)
      TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
  },
  Timeout: 15 * time.Second,  // 15 second timeout
      CheckRedirect: func(req *http.Request, via []*http.Request) error {
      return http.ErrUseLastResponse // don't follow redirect
  },
}

// Override http(s) default protocol to use our custom client
client.InstallProtocol("https", githttp.NewClient(customClient))

// Clone repository using the new client if the protocol is https://
r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{URL: url})

Weiterführende Informationen

Eine vollständige Behandlung der Fähigkeiten von go-git liegt außerhalb des eigentlichen Ziels dieses Buches. Wenn Sie weitere Informationen über go-git wünschen, finden Sie die API-Dokumentation auf https://pkg.go.dev/github.com/go-git/go-git/v5 und eine Reihe von Anwendungsbeispielen unter https://github.com/go-git/go-git/tree/master/_examples.