Chapters ▾ 2nd Edition

A2.4 Appendix B: Ενσωμάτωση του Git στις εφαρμογές μας - go-git

go-git

Σε περίπτωση που θέλουμε να ενσωματώσουμε το Git σε μια υπηρεσία γραμμένη σε Golang, υπάρχει επίσης μια καθαρή υλοποίηση βιβλιοθήκης σε Go. Αυτή η υλοποίηση δεν έχει εγγενείς εξαρτήσεις και για αυτο δεν είναι επιρρεπής σε χειροκίνητη διαχείριση σφαλμάτων μνήμης. Είναι επίσης διαφανής για τα τυπικά εργαλεία ανάλυσης απόδοσης της Golang όπως CPU, προφίλ Μνήμης, ανιχνευτής αγώνα (race detector), κτλ.

Το go-git στοχεύει στην επεκτασιμότητα, συμβατότητα και υποστηρίζει τα περισσότερα APIs διοχέτευσης, που είναι την τεκμηρίωση https://github.com/go-git/go-git/blob/master/COMPATIBILITY.md.

Ένα σύνηθες παράδειγμα χρήσης των 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,
})

Μόλις έχουμε ένα στιγμιότυπο Repository, έχουμε πρόσβαση στις πληροφορίες και να κάνουμε μεταλλάξεις σε αυτό:

// 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)
}

Προηγμένη Λειτουργικότητα

Το go-git έχει μερικά αξιοσημείωτα προηγμένα χαρακτηριστικά, ένα από αυτά είναι το συνδεούμενο (pluggable) σύστημα αποθήκευσης, που είναι το ίδιο με την υλοποίηση του Libgit2. Η προεπιλεγμένη υλοποίηση είναι εντός-μνήμη αποθήκευση, που είναι πολύ γρήγορη.

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

Το συνδεούμενο (pluggable) σύστημα προσφέρει πολλές ενδιαφέρουσες επιλογές. Για παράδειγμα, https://github.com/go-git/go-git/tree/master/_examples/storage μας επιτρέπει να αποθηκεύουμε αναφορές, αντικείμενα, και διαμόρφωση (configuration) σε μια βάση Aerospike.

Ένα άλλο χαρακτηριστικό είναι η ευέλικτη αφαίρεση συστήματος αρχείων (flexible filesystem abstraction). Χρησιμοποιώντας https://pkg.go.dev/github.com/go-git/go-billy/v5?tab=doc#Filesystem είναι πολύ εύκολο να αποθηκεύσουμε όλα τα αρχεία με διαφορετικό τρόπο π.χ. πακετάρωντάς τα όλα σε ένα αρχείο στο δίσκο ή κρατώντας τα όλα εντός-μνήμης.

Μια άλλη προηγμένη περίπτωση-χρήσης περιλαμβάνει ένα βελτιστοποιημένο πελάτη HTTP, σαν αυτό που βρίσκεται https://github.com/go-git/go-git/blob/master/_examples/custom_http/main.go.

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})

Περαιτέρω ανάγνωση

Μια πλήρης διαχείριση των δυνατοτήτων του go-git είναι εκτός θέματος του βιβλίου. Αν θέλουμε περισσότερες πληροφορίες για το go-git, υπάρχει μια API τεκμηρίωση εδώ https://pkg.go.dev/github.com/go-git/go-git/v5, και ένα σύνολο παραδειγμάτων εδώ https://github.com/go-git/go-git/tree/master/_examples.