Kapitel ▾ 2. Auflage

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

go-git

Wenn Sie Git in einen in Golang geschriebenen Dienst integrieren möchten, gibt es auch eine reine Go-Bibliotheksimplementierung. Diese Implementierung hat keine nativen Abhängigkeiten und ist somit nicht anfällig für Fehler bei der manuellen Speicherverwaltung. Sie ist auch transparent für die Standard-Golang-Performance-Analysewerkzeuge wie CPU-, Speicherprofiler, Race-Detektor usw.

go-git konzentriert sich auf Erweiterbarkeit und Kompatibilität und unterstützt die meisten Plumbing-APIs, wie auf https://github.com/go-git/go-git/blob/master/COMPATIBILITY.md dokumentiert.

Hier ist ein einfaches Beispiel für die Verwendung von 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 darauf zugreifen und Änderungen 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 einige bemerkenswerte erweiterte Funktionen, von denen eine ein erweiterbares Speichersystem ist, das Libgit2-Backends ähnelt. Die Standardimplementierung ist der In-Memory-Speicher, der sehr schnell ist.

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

Der erweiterbare Speicher bietet viele interessante Optionen. Zum Beispiel ermöglicht Ihnen https://github.com/go-git/go-git/tree/master/_examples/storage das Speichern von Referenzen, Objekten und Konfigurationen in einer Aerospike-Datenbank.

Eine weitere Funktion ist eine flexible Dateisystemabstraktion. 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, z. B. indem Sie sie alle in einem einzigen Archiv auf der Festplatte packen oder sie alle im Speicher behalten.

Ein weiterer fortgeschrittener Anwendungsfall umfasst einen feinabstimmbaren HTTP-Client, wie er unter 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 Literatur

Eine vollständige Behandlung der Fähigkeiten von go-git liegt außerhalb des Rahmens dieses Buches. Wenn Sie weitere Informationen zu go-git wünschen, finden Sie die API-Dokumentation unter 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.