-
1. Ξεκινώντας με το Git
-
2. Τα θεμελιώδη στοιχεία του Git
-
3. Διακλαδώσεις στο Git
-
4. Το Git στον διακομιστή
- 4.1 Τα πρωτόκολλα
- 4.2 Εγκατάσταση του Git σε διακομιστή
- 4.3 Δημιουργία δημόσιου κλειδιού SSH
- 4.4 Στήσιμο του διακομιστή
- 4.5 Δαίμονες του Git
- 4.6 Έξυπνο HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Επιλογές φιλοξενίας από τρίτους
- 4.10 Ανακεφαλαίωση
-
5. Κατανεμημένο Git
-
6. GitHub
-
7. Εργαλεία του Git
- 7.1 Επιλογή αναθεώρησης
- 7.2 Διαδραστική εργασία με το στάδιο καταχώρισης
- 7.3 Αποθέματα και Καθαρισμός
- 7.4 Υπογραφή της δουλειάς μας
- 7.5 Αναζήτηση
- 7.6 Η ιστορία ξαναγράφεται
- 7.7 Απομυθοποίηση της reset
- 7.8 Προχωρημένη Συγχώνευση
- 7.9 Rerere
- 7.10 Αποσφαλμάτωση με το Git
- 7.11 Υπομονάδες
- 7.12 Δεμάτιασμα δεδομένων
- 7.13 Replace
- 7.14 Αποθήκευση διαπιστευτηρίων
- 7.15 Ανακεφαλαίωση
-
8. Εξατομίκευση του Git
-
9. Το Git και άλλα συστήματα
- 9.1 Το Git ως πελάτης
- 9.2 Μετανάστευση στο Git
- 9.3 Ανακεφαλαίωση
-
10. Εσωτερική λειτουργία του Git
- 10.1 Διοχετεύσεις και πορσελάνες
- 10.2 Αντικείμενα του Git
- 10.3 Αναφορές του Git
- 10.4 Πακετάρισμα αρχείων
- 10.5 Τα refspec
- 10.6 Πρωτόκολλα μεταφοράς
- 10.7 Διατήρηση και ανάκτηση δεδομένων
- 10.8 Μεταβλητές περιβάλλοντος
- 10.9 Ανακεφαλαίωση
-
A1. Appendix A: Το Git σε άλλα περιβάλλοντα
- A1.1 Γραφικές διεπαφές
- A1.2 Το Git στο Visual Studio
- A1.3 Git στο Visual Studio Code
- A1.4 Git στο IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git στο Sublime Text
- A1.6 Το Git στο Bash
- A1.7 Το Git στο Zsh
- A1.8 Το Git στο Powershell
- A1.9 Ανακεφαλαίωση
-
A2. Appendix B: Ενσωμάτωση του Git στις εφαρμογές μας
- A2.1 Γραμμή εντολών Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Appendix C: Εντολές Git
- A3.1 Ρύθμιση και διαμόρφωση
- A3.2 Λήψη και δημιουργία έργων
- A3.3 Βασική λήψη στιγμιοτύπων
- A3.4 Διακλάδωση και συγχώνευση
- A3.5 Κοινή χρήση και ενημέρωση έργων
- A3.6 Επιθεώρηση και σύγκριση
- A3.7 Αποσφαλμάτωση
- A3.8 Επιθέματα
- A3.9 Ηλεκτρονικό ταχυδρομείο
- A3.10 Εξωτερικά Συστήματα
- A3.11 Διοίκηση
- A3.12 Εντολές διοχέτευσης
A2.2 Appendix B: Ενσωμάτωση του Git στις εφαρμογές μας - Libgit2
Libgit2
© Μια άλλη επιλογή στη διάθεσή μας είναι να χρησιμοποιήσουμε το Libgit2. Το Libgit2 είναι μια υλοποίηση του Git χωρίς εξαρτήσεις (dependencies), με έμφαση σε ένα ωραίου API για χρήση σε άλλα προγράμματα. Μπορούμε να το βρούμε στην https://libgit2.org.
Αρχικά, ας ρίξουμε μια ματιά πως μοιάζει το API για C. Ακολουθεί ένα παράδειγμα τυφώνας!
// Open a repository
git_repository *repo;
int error = git_repository_open(&repo, "/path/to/repository");
// Dereference HEAD to a commit
git_object *head_commit;
error = git_revparse_single(&head_commit, repo, "HEAD^{commit}");
git_commit *commit = (git_commit*)head_commit;
// Print some of the commit's properties
printf("%s", git_commit_message(commit));
const git_signature *author = git_commit_author(commit);
printf("%s <%s>\n", author->name, author->email);
const git_oid *tree_id = git_commit_tree_id(commit);
// Cleanup
git_commit_free(commit);
git_repository_free(repo);
Οι πρώτες δύο γραμμές ανοίγουν ένα αποθετήριο Git.
Ο τύπος git_repository αντιπροσωπεύει έναν χειριστή ελέγχου (handle) σε ένα αποθετήριο με κρυφή μνήμη (cache) στη μνήμη.
Αυτή είναι η απλούστερη μέθοδος εφόσον γνωρίζουμε την ακριβή διαδρομή στον κατάλογο εργασίας του αποθετηρίου ή στον φάκελο .git.
Υπάρχούν επίσης η git_repository_open_ext που περιλαμβάνει επιλογές αναζήτησης, η git_clone και οι σχετικές εντολές για τη δημιουργία τοπικού κλώνου ενός απομακρυσμένου αποθετηρίου και η git_repository_init για τη δημιουργία ενός εντελώς νέου αποθετηρίου.
Το δεύτερο κομμάτι του κώδικα χρησιμοποιεί σύνταξη rev-parse (βλ. ενότητα Αναφορές κλάδων σχετικά) για να πάρει την υποβολή στην οποία δείχνει τελικά ο HEAD.
Ο τύπος που επιστρέφεται είναι ένας δείκτης git_object, που αντιπροσωπεύει κάτι που υπάρχει στη βάση δεδομένων αντικειμένων Git για ένα αποθετήριο.
Το git_object είναι στην πραγματικότητα ένας τύπος “parent” για πολλά διαφορετικά είδη αντικειμένων· η διάταξη μνήμης για καθέναν από τους τύπους “child” είναι ίδια με εκείνη του git_object, ώστε να μπορούμε να κάνουμε μετατροπή στο σωστό με ασφάλεια.
Σε αυτήν την περίπτωση, η git_object_type(commit) θα επέστρεφε GIT_OBJ_COMMIT, επομένως είναι ασφαλές να κάνουμε μετατροπή σε έναν δείκτη git_commit.
Το επόμενο κομμάτι δείχνει τον τρόπο πρόσβασης στις ιδιότητες της υποβολής.
Η τελευταία γραμμή εδώ χρησιμοποιεί έναν τύπο git_oid· αυτή είναι η αναπαράσταση του Libgit2 για έναν αριθμό SHA-1.
Από αυτό το παράδειγμα, έχουν αρχίσει να αναδύονται δύο μοντέλα:
-
Αν δηλώσουμε έναν δείκτη και περάσουμε μια αναφορά σε αυτό σε μια κλήση Libgit2, αυτή η κλήση θα επιστρέψει πιθανώς έναν ακέραιο κωδικό σφάλματος. Η τιμή
0υποδηλώνει επιτυχία· ο,τιδήποτε άλλο υποδηλώνει σφάλμα. -
Αν το Libgit2 συγκεντρώσει έναν δείκτη για εμάς, είμαστε υπεύθυνοι για την απελευθέρωσή του.
-
Αν το Libgit2 επιστρέψει έναν δείκτη
constαπό μια κλήση, δεν χρειάζεται να τον απελευθερώσουμε, αλλά θα ακυρωθεί όταν το αντικείμενο στο οποίο ανήκει ελευθερωθεί. -
Ο προγραμματισμός σε C είναι λίγο οδυνηρός.
Αυτό το τελευταίο σημαίνει ότι δεν είναι πολύ πιθανό ότι θα γράφουμε C όταν χρησιμοποιούμε το Libgit2. Ευτυχώς, υπάρχει ένας αριθμός γλωσσών script που είναι διαθέσιμες και καθιστούν αρκετά εύκολο να δουλέψουμε με αποθετήρια Git από τη συγκεκριμένη γλώσσα και το περιβάλλον μας. Ας ρίξουμε μια ματιά στο παραπάνω παράδειγμα που γράφτηκε χρησιμοποιώντας τις συνδέσεις (bindings) Ruby για το Libgit2, οι οποίες ονομάζονται Rugged και μπορούν να βρεθούν στην https://github.com/libgit2/rugged.
repo = Rugged::Repository.new('path/to/repository')
commit = repo.head.target
puts commit.message
puts "#{commit.author[:name]} <#{commit.author[:email]}>"
tree = commit.tree
Όπως βλέπουμε ο κώδικας είναι πιο συμμαζεμένος.
Καταρχάς, η Rugged χρησιμοποιεί εξαιρέσεις (exceptions)· μπορεί να επικαλεστεί σφάλματα όπως ConfigError ή ObjectError για να σηματοδοτήσει συνθήκες σφαλμάτων.
Κατά δεύτερο λόγο, δεν υπάρχει ρητή απελευθέρωση πόρων, διότι η Ruby έχει αυτόματο συλλέκτη σκουπιδιών.
Ας δούμε ένα λίγο πιο σύνθετο παράδειγμα: υλοποίηση μίας υποβολής εκ του μηδενός.