Git
Chapters ▾ 2nd Edition

1.3 Ξεκινώντας με το Git - Τα βασικά του Git

Τα βασικά του Git

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

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

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

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

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

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

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

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

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

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

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

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

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

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

24b9da6552252987aa493b52f8696cd6d3b00373

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

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

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

Αυτό κάνει τη χρήση του Git πανεύκολη καθώς μπορούμε να πειραματιστούμε χωρίς τον κίνδυνο να τα θαλασσώσουμε. Μια πιο διεξοδική ματιά στο πώς αποθηκεύει τα δεδομένα του το Git και πώς μπορούμε να ανακτήσουμε δεδομένα που φαίνονται χαμένα, υπάρχουν στην ενότητα [_undoing].

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

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

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

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

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

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

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

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

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

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

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

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

  2. Καταχωρούμε τα αρχεία, προσθέτωντας στιγμιότυπά τους στο ενδιάμεσο στάδιο.

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

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