Chapters ▾ 2nd Edition

1.3 Ξεκινώντας με το Git - Τι είναι το Git;

Τι είναι το Git;

Τι είναι, λοιπόν, το Git με λίγα λόγια; Η συγκεκριμένη ενότητα είναι σημαντική επειδή αν καταλάβουμε τι είναι το Git και πώς δουλεύει, θα είναι πιο εύκολο να το χρησιμοποιήσουμε αποτελεσματικά. Καθώς μαθαίνουμε το Git, ας προσπαθήσουμε να αδειάσουμε το μυαλό μας από γνώσεις που μπορεί να έχουμε για άλλα συστήματα ελέγχου έκδοσεων, όπως το Subversion και το Perforce — με αυτό τον τρόπο θα αποφύγουμε την όποια σύγχυση όταν χρησιμοποιούμε το εργαλείο. Αν και η διεπαφή χρήστη του Git είναι παρόμοια με αυτές των άλλων VCS, το Git αποθηκεύει και αντιμετωπίζει τα δεδομένα με πολύ διαφορετικό τρόπο και η κατανόηση των διαφορών θα μας βοηθήσει να μην μπερδευόμαστε όταν το χρησιμοποιούμε.

Στιγμιότυπα, όχι διαφορές

Η σημαντικότερη διαφορά ανάμεσα στο Git και τα άλλα VCS συστήματα βρίσκεται στον τρόπο με τον οποίο το Git αντιλαμβάνεται τα δεδομένα. Εννοιολογικά, τα περισσότερα συστήματα αποθηκεύουν τις πληροφορίες ως μια λίστα από αλλαγές σε αρχεία. Αυτά τα συστήματα (CVS, Subversion, Perforce, και άλλα) αντιμετωπίζουν τις πληροφορίες που αποθηκεύουν ως ένα σύνολο αρχείων και αλλαγών που έχουν γίνει στα αρχεία με την πάροδο του χρόνου (αυτός ο τρόπος ονομάζεται συνήθως έλεγχος εκδόσεων βασισμένος στις διαφορές (delta-based)).

Αποθήκευση των δεδομένων ως διαφορών σε σχέση με μία βασική έκδοση κάθε αρχείου
Figure 4. Αποθήκευση των δεδομένων ως διαφορών σε σχέση με μία βασική έκδοση κάθε αρχείου

Το Git δεν αντιλαμβάνεται ούτε αποθηκεύει δεδομένα με αυτό τον τρόπο. Αντίθετα, το Git αντιλαμβάνεται τα δεδομένα ως μια σειρά στιγμιοτύπων ενός μικροσκοπικού συστήματος αρχείων (file system). Κάθε φορά που υποβάλουμε (commit) ή αποθηκεύουμε την κατάσταση του έργου μας, το Git παίρνει μια φωτογραφία της εικόνας των αρχείων μας εκείνη τη στιγμή και αποθηκεύει έναν δείκτη (reference) σε αυτό το στιγμιότυπο. Για να είναι πιο αποδοτικό, το Git δεν ξαναποθηκεύει ένα αρχείο, εφόσον αυτό δεν έχει τροποποιηθεί, απλώς αποθηκεύει έναν σύνδεσμο προς το προηγούμενο όμοιο αρχείο το οποίο έχει ήδη αποθηκευτεί. Το Git λοιπόν αντιλαμβάνεται τα δεδομένα περισσότερο σαν μία ροή από στιγμιότυπα.

Αποθήκευση δεδομένων ως στιγμιοτύπων του έργου με την πάροδο του χρόνου.
Figure 5. Αποθήκευση δεδομένων ως στιγμιοτύπων του έργου με την πάροδο του χρόνου.

Αυτή είναι μια πολύ σημαντική διαφορά μεταξύ του Git και σχεδόν όλων των υπόλοιπων συστημάτων ελέγχου εκδόσεων. Αναγκάζει το Git να αναθεωρήσει σχεδόν όλες τις πτυχές του ελέγχου εκδόσεων, που αντέγραψαν τα υπόλοιπα συστήματα από την προηγούμενη γενιά. Αυτό κάνει το Git να φαντάζει σαν ένα μίνι σύστημα αρχείων με πολλά εργαλεία φτιαγμένα πάνω σε αυτό παρά σαν ένα απλό VCS. Θα διερευνήσουμε κάποια από τα οφέλη που κερδίζουμε όταν χρησιμοποιούμε τα δεδομένα με αυτό τον τρόπο όταν καλύψουμε τις διακλαδώσεις (branches) του Git Διακλαδώσεις στο Git.

Σχεδόν όλες οι λειτουργίες εκτελούνται τοπικά

Οι περισσότερες λειτουργίες στο Git χρειάζονται μόνο τοπικά αρχεία και πόρους για να εκτελεστούν — γενικά, δεν χρειάζεται να μεταφερθεί καμία πληροφορία από κάποιον άλλο υπολογιστή του δικτύου μας. Αν είστε συνηθισμένοι σε ένα συγκεντρωτικό VCS, όπου οι περισσότερες λειτουργίες καθυστερούν εξαιτίας του χρόνου απόκρισης του δικτύου, τότε αυτή η πτυχή του Git θα μας κάνει να νομίζουμε ότι οι θεοί της ταχύτητας ευλόγησαν το Git με υπερκόσμιες δυνάμεις. Οι περισσότερες λειτουργίες στο Git φαίνονται σχεδόν στιγμιαίες, κυρίως λόγω του ότι το πλήρες ιστορικό του έργου βρίσκεται στον τοπικό μας δίσκο.

Για παράδειγμα, για να δούμε στο ιστορικό του έργου μας, το Git δεν χρειάζεται να λάβει το ιστορικό από τον διακομιστή και να το εμφανίσει στον χρήστη — χρειάζεται απλά να το διαβάσει από την τοπική μας βάση δεδομένων. Αυτό σημαίνει ότι μπορούμε να δούμε το ιστορικό του έργου μας σχεδόν στιγμιαία. Αν θέλουμε να δούμε τις αλλαγές που εισήχθησαν ανάμεσα στην τρέχουσα έκδοση ενός αρχείου και στην έκδοσή του πριν από ένα μήνα, το Git θα εντοπίσει το αρχείο όπως ήταν πριν από ένα μήνα και θα κάνει έναν τοπικό υπολογισμό των διαφορών, αντί να ζητήσει από τον διακομιστή να το κάνει ή να τραβήξει την παλιά έκδοση του αρχείου και να υπολογίσει τις διαφορές τοπικά.

Αυτό επιπλέον σημαίνει ότι είναι πολύ λίγες οι λειτουργίες που δεν μπορούμε να κάνουμε όταν είμαστε εκτός δικτύου ή δεν είμαστε συνδεδεμένοι στο VPN. Αν βρισκόμαστε σε ένα αεροπλάνο ή στο τρένο και θέλουμε να εργαστούμε, μπορούμε να υποβάλουμε τις αλλαγές μας χωρίς πρόβλημα (στο τοπικό μας αντίγραφο) και να τις μεταφορτώσουμε όταν ξανασυνδεθούμε στο δίκτυο. Αν βρισκόμαστε στο σπίτι μας και το VPN client μας δεν δουλεύει καλά και δεν μπορούμε να συνδεθούμε, μπορούμε ακόμα να εργαστούμε. Σε πολλά άλλα συστήματα, αυτό είναι είτε αδύνατο είτε επίπονο. Για παράδειγμα, στο Perforce δεν μπορούμε να κάνουμε πολλά πράγματα αν δεν είμαστε συνδεδεμένοι με τον διακομιστή· στο Subversion και το CVS μπορούμε να επεξεργαστούμε αρχεία, αλλά δεν είναι δυνατό υποβάλουμε τις αλλαγές στη βάση δεδομένων μας (διότι δεν είμαστε συνδεδεμένοι με αυτή). Τα παραπάνω μπορεί να μην φαίνονται πολύ σημαντικά, αλλά θα εκπλαγούμε με το πόσο μεγάλη διαφορά μπορεί να κάνουν.

To Git έχει ακεραιότητα

Οτιδήποτε υπάρχει στο Git περνά από έλεγχο αθροίσματος (checksum) πριν αποθηκευτεί και έπειτα μπορούμε να αναφερόμαστε σε αυτό το άθροισμα ελέγχου. Αυτό σημαίνει ότι είναι αδύνατο κάποιος να αλλάξει το περιεχόμενο ενός αρχείου ή ενός καταλόγου χωρίς το Git να το γνωρίζει. Η λειτουργικότητα αυτή είναι ενσωματωμένη στο Git στα χαμηλότερα επίπεδα και είναι αναπόσπαστη από τη φιλοσοφία του. Είναι αδύνατο να χαθεί πληροφορία κατά τη μεταφορά της ή να παραφθαρεί κάποιο αρχείο χωρίς το Git να το ανιχνεύσει.

Ο μηχανισμός που χρησιμοποιεί το Git για τον αθροιστικό έλεγχο ονομάζεται κατακερματισμός SHA-1. Το SHA-1 είναι μια συμβολοσειρά 40 δεκαεξαδικών ψηφίων (0-9 και a-f) και υπολογίζεται με βάση τα περιεχόμενα μιας δομής αρχείου ή φακέλου στο Git. Μια συμβολοσειρά με κατακερματισμό SHA-1 έχει αυτή τη μορφή:

24b9da6552252987aa493b52f8696cd6d3b00373

Θα βλέπουμε αυτές τις κατακερματισμένες τιμές παντού στο Git γιατί τις χρησιμοποιεί πολύ. Μάλιστα, το Git αποθηκεύει τα πάντα στη βάση δεδομένων του με βάση την κατακερματισμένη τιμή των περιεχομένων ενός αρχείου και όχι με βάση το όνομα του αρχείου.

Το Git γενικά μόνο προσθέτει δεδομένα

Όταν κάνουμε κάτι στο Git, σχεδόν πάντα προσθέτονται δεδομενα στη βάση δεδομένων του Git. Είναι σχεδόν αδύνατο να αναγκάσουμε το σύστημα να κάνει κάτι που δεν αναιρείται ή να διαγράψει δεδομένα. Όπως σε κάθε σύστημα διαχείρισης ελέγχου εκδόσεων (VCS) είναι δυνατό να χάσουμε ή να μπουρδουκλώσουμε αλλαγές που δεν έχουν υποβληθεί ακόμα, αλλά από τη στιγμή που υποβάλουμε ένα στιγμιότυπο στο Git είναι πολύ δύσκολο να χαθεί, ειδικά αν ωθήσουμε (push) την τοπική μας βάση δεδομένων τακτικά σε κάποιο άλλο αποθετήριο.

Αυτό καθιστά τη χρήση του Git ευχάριστη διότι γνωρίζουμε ότι μπορούμε να πειραματιστούμε χωρίς να φοβόμαστε ότι θα τα κάνουμε μαντάρα. Μια πιο διεξοδική ματιά στο πώς αποθηκεύει τα δεδομένα του το Git και πώς μπορούμε να ανακτήσουμε δεδομένα που φαίνονται χαμένα, υπάρχει στην ενότητα Αναιρέσεις (undoing).

Οι τρεις καταστάσεις

Και τώρα προσοχή — το παρακάτω είναι το βασικό πράγμα που πρέπει να θυμόμαστε για το Git, αν θέλουμε η υπόλοιπη διαδικασία μάθησής του να κυλήσει ομαλά. Τα αρχεία στο Git μπορούν να βρίσκονται σε τρεις κύριες καταστάσεις: τροποποιημένο (modified), επισημασμένο (staged) και υποβεβλημένο (committed).

  • Τροποποιημένο (modified) σημαίνει ότι το αρχείο έχει αλλάξει, αλλά δεν έχει ακόμα δεσμευτεί στη βάση δεδομένων.

  • Επισημασμένο (staged) σημαίνει ότι ένα τροποποιημένο αρχείο της τρέχουσας έκδοσης όταν έχει επισημανθεί για βρίσκεται στο επόμενο υποβεβλημένο στιγμιότυπο.

  • Υποβεβλημένο (commited) είναι ένα αρχείο όταν τα δεδομένα του είναι αποθηκευμένα με ασφάλεια στην τοπική βάση δεδομένων.

Αυτό μας φέρνει στις τρεις βασικές περιοχές ενός έργου στο Git: το δέντρο εργασίας, τον προθάλαμο και τον κατάλογο του Git.

Δέντρο εργασίας, προθάλαμος και κατάλογος του Git
Figure 6. Κατάλογος εργασίας, προθάλαμος και κατάλογος του Git

Το δέντρο εργασίας είναι το στιγμιότυπο μίας έκδοσης του έργου. Τα αρχεία ανασύρονται (pulled) από τη συμπιεσμένη βάση δεδομένων του καταλόγου του Git και τοποθετούνται στον τοπικό δίσκο ώστε να τα χρησιμοποιήσουμε ή να τα τροποποιήσoυμε.

Ο προθάλαμος είναι ένα αρχείο το οποίο γενικά περιλαμβάνεται στον κατάλογο μας του Git, στο οποίο είναι αποθηκευμένες πληροφορίες σχετικά με το τι θα υποβληθεί στην επόμενη υποβολή (commit). Το τεχνικό όνομα του προθαλάμου στην ορολογία του Git είναι “index” (ευρετήριο), αλλά το όνομα “staging area” (προθάλαμος) είναι επίσης σύνηθες.

Ο κατάλογος του Git είναι το μέρος όπου το Git αποθηκεύει τα μεταδεδομένα (metadata) και τη βάση δεδομένων των αντικειμένων του έργου. Αυτό είναι το πιο σημαντικό τμήμα του Git και είναι αυτό που αντιγράφεται όταν δημιουργούμε έναν κλώνο ενός αποθετηρίου από έναν άλλο υπολογιστή.

Η βασική ροή εργασίας του Git είναι κάτι σαν το εξής:

  1. Τροποποιούμε κάποια αρχεία στον δεντρο εργασίας μας.

  2. Επιλέγουμε ποιες αλλαγές θέλουμε να υποβληθούν στην επόμενη υποβολή, τοποθετώντας μόνο αυτές τις αλλαγές στον προθάλαμο.

  3. Πραγματοποιούμε μια υποβολή, η οποία παίρνει τα αρχεία όπως είναι στον προθάλαμο και αποθηκεύει αυτό το στιγμιότυπο μόνιμα στον κατάλογο του Git.

Αν μια συγκεκριμένη έκδοση ενός αρχείου βρίσκεται στον κατάλογο του Git, θεωρείται υποβεβλημένο (committed). Αν έχει τροποποιηθεί και έχει προστεθεί στον προθάλαμο, ονομάζεται επισημασμένο (staged). Τέλος, αν έχει τροποποιηθεί από τότε που ανακλήθηκε αλλά δεν έχει επισημανθεί, τότε λέμε ότι είναι τροποποιημένο. Στο κεφάλαιο Τα θεμελιώδη στοιχεία του Git, θα μάθουμε περισσότερα για αυτές τις καταστάσεις και για το πώς μπορούμε να τις εκμεταλευτούμε ή να παρακάμψουμε εντελώς τον προθάλαμο.