Εισαγωγή
Τι είναι το Version Control System;
Ένα σύστημα ελέγχου εκδόσεων (Version Control System ή VCS) είναι ένα εργαλείο διαχείρισης και παρακολούθησης αλλαγών στον κώδικά μας. Καθώς αναπτύσσουμε μία εφαρμογή, προσθέτουμε λειτουργίες και διορθώνουμε σφάλματα, τροποποιώντας τον κώδικά μας συνεχώς. Το VCS μας επιτρέπει να αποθηκεύουμε «στιγμιότυπα» (snapshots) σε διάφορα στάδια υλοποίησης, ώστε ανά πάσα στιγμή να βλέπουμε τι άλλαξε, πότε και από ποιον.

Τα πιο γνωστά συστήματα ελέγχου εκδόσεων πηγαίου κώδικα είναι τα εξής:
- Git
- Apache Subversion (SVN)
- Mercurial
- Bazaar
Δημοφιλία VCS
Έχοντας περιγράψει τι είναι το VCS, αξίζει να εξετάσουμε ποιο από αυτά έχει κυριαρχήσει διαχρονικά. Για να απαντήσουμε, ανατρέχουμε στα ιστορικά δεδομένα αναζητήσεων μέσω της πλατφόρμας Google Trends, που καταγράφει τις τάσεις ενδιαφέροντος για δημοφιλείς όρους.
Το διάγραμμα Σχήμα 1 ξεκαθαρίζει το Git ως κυρίαρχο εργαλείο διαχείρισης εκδόσεων. Το Subversion (SVN) ήταν δημοφιλέστερο μέχρι και το 2010, ακολουθώντας έκτοτε σταθερά πτωτική πορεία από την οποία δεν ανέκαμψε ποτέ. Σήμερα, το Git αποτελεί το de facto πρότυπο για τη διαχείριση πηγαίου κώδικα, και γύρω του έχει αναπτυχθεί ένα ευρύ οικοσύστημα πλατφορμών φιλοξενίας, όπως το GitHub και το GitLab.
Πλεονεκτήματα
Γιατί να χρησιμοποιήσω ένα τέτοιο εργαλείο;
- Εύκολη επαναφορά: Αν μια αλλαγή δημιουργήσει πρόβλημα, μπορούμε να επιστρέψουμε σε προηγούμενη, λειτουργική έκδοση του κώδικα με μία μόνο εντολή.
- Εξοικονόμηση χρόνου: Αντί να ψάχνουμε χειροκίνητα τι σταμάτησε να λειτουργεί, το Git μας υποδεικνύει ακριβώς τι άλλαξε και πότε.
- Συνεργασία: Διευκολύνει σημαντικά την κοινή εργασία με άλλους προγραμματιστές, ιδίως μέσω πλατφορμών όπως το GitHub.
Αδυναμίες
Εντάξει, τα πλεονεκτήματα είναι σαφή — υπάρχει όμως και η άλλη πλευρά;
- Ένα επιπλέον εργαλείο: Το Git προσθέτει ένα βήμα στη ροή εργασίας μας, κάνοντάς τη ελαφρώς πιο σύνθετη στην αρχή.
- Καμπύλη εκμάθησης: Χρειάζεται χρόνος για να εξοικειωθούμε με προχωρημένες λειτουργίες (branching, merging, rebasing). Τα βασικά, ωστόσο, μαθαίνονται γρήγορα.
Φιλοξενία κώδικα
Τα εργαλεία που περιγράψαμε διαχειρίζονται τον κώδικα τοπικά, στη δική μας συσκευή. Αν θέλουμε να μοιραστούμε την εργασία μας ή να συνεργαστούμε με άλλους, χρειαζόμαστε μία υπηρεσία απομακρυσμένης φιλοξενίας. Οι πιο διαδεδομένες επιλογές είναι το GitHub, το GitLab και το Bitbucket.
Αν καμία από αυτές δεν μας ικανοποιεί, μπορούμε να φιλοξενήσουμε τον κώδικά μας οι ίδιοι. Εργαλεία όπως το Gitea ή το ενεργό του fork, Forgejo, μας επιτρέπουν να στήσουμε τη δική μας πλατφόρμα σε έναν ιδιωτικό server, ουσιαστικά το δικό μας GitHub, χωρίς εξάρτηση από τρίτες υπηρεσίες. Αν και ακούγεται ελκυστικό, η αυτο-φιλοξενία συνεπάγεται σημαντική λειτουργική πολυπλοκότητα και μας απομακρύνει από την ευρύτερη κοινότητα των προγραμματιστών.
Ρυθμίσεις του Git
Αποφασίσαμε να δοκιμάσουμε το Git σε ένα μικρό project, ή απλά θέλουμε να κρατάμε αρχείο εκδόσεων για την εργασία μας. Ας δούμε πώς να το ρυθμίσουμε σωστά από την αρχή.
Ορισμός ονόματος και email
Την πρώτη φορά που θα χρησιμοποιήσουμε το Git, θα μας ζητήσει να δηλώσουμε ένα όνομα και μια διεύθυνση email. Χωρίς αυτά, δεν μας επιτρέπει να καταγράψουμε καμία αλλαγή. Αυτό συμβαίνει διότι κάθε στιγμιότυπο που δημιουργούμε συνοδεύεται από τα στοιχεία του δημιουργού του.

Πηγή: Από τον LFAsia μέσω Wikimedia Commons, 2018 — Άδεια: CC BY 3.0. Δείτε την πρωτότυπη φωτογραφία.
Terminal
git config --global user.name "YourName"
git config --global user.email your_emailΑν σχεδιάζουμε να φιλοξενήσουμε τον κώδικά μας στο GitHub, ίσως αξίζει να αποκρύψουμε την προσωπική μας διεύθυνση email. Το GitHub προσφέρει για τον σκοπό αυτό μία noreply διεύθυνση, ώστε η πραγματική μας να μην εκτίθεται δημόσια. Μπορείτε να διαβάσετε περισσότερα στην τεκμηρίωση του GitHub.
Πρόγραμμα επεξεργασίας κειμένου
Πριν μιλήσουμε για τον editor, αξίζει να εξηγήσουμε τι είναι ένα commit. Κάθε φορά που θέλουμε να «αποθηκεύσουμε» την τρέχουσα κατάσταση του κώδικά μας, δημιουργούμε ένα commit. Στην ουσία δημιουργούμε ένα στιγμιότυπο που καταγράφει ακριβώς ποια αρχεία άλλαξαν και με ποιον τρόπο. Κάθε commit συνοδεύεται υποχρεωτικά από ένα σύντομο μήνυμα που περιγράφει τι αλλάξαμε και γιατί, ώστε να μπορούμε αργότερα να καταλαβαίνουμε την ιστορία του project μας με μια ματιά.
Για να γράψουμε αυτό το μήνυμα, το Git ανοίγει αυτόματα έναν text editor. Σε πολλά συστήματα (π.χ. Ubuntu) ο προεπιλεγμένος είναι το Vim. Ο Vim είναι ένας ισχυρός editor, αλλά με απότομη καμπύλη εκμάθησης για κάποιον που τον συναντά για πρώτη φορά. Αν δεν είμαστε εξοικειωμένοι μαζί του, μπορούμε να τον αλλάξουμε σε κάτι πιο οικείο.
Terminal
git config --global core.editor "editor_name"| Editor | Εντολή |
|---|---|
| Visual Studio Code | git config --global core.editor "code --wait" |
| Atom | git config --global core.editor "atom --wait" |
| Nano | git config --global core.editor "nano" |
Το Visual Studio Code είναι σήμερα ο πιο δημοφιλής editor σύμφωνα με την έρευνα του Stack Overflow για προγραμματιστές, οπότε αποτελεί ασφαλή επιλογή αν δεν έχουμε κάποια συγκεκριμένη προτίμηση.
Προεπιλεγμένο όνομα κλάδου (branch)
Ένα branch (κλάδος) είναι μια ανεξάρτητη «γραμμή ανάπτυξης» του κώδικά μας. Φανταστείτε το σαν ένα παράλληλο αντίγραφο του project μας, στο οποίο μπορούμε να πειραματιστούμε ή να αναπτύξουμε μια νέα λειτουργία, χωρίς να επηρεάζουμε τον κύριο κώδικα. Όταν είμαστε ικανοποιημένοι με τις αλλαγές μας, μπορούμε να τις συγχωνεύσουμε (merge) πίσω στον κύριο κλάδο. Κάθε Git repository ξεκινά πάντα με έναν αρχικό κλάδο, ο οποίος παραδοσιακά ονομαζόταν master.
Τον Οκτώβριο του 2020, το GitHub ανακοίνωσε ότι αλλάζει το προεπιλεγμένο όνομα αυτού του κλάδου από master σε main. Η αλλαγή αυτή έγινε στο πλαίσιο μιας ευρύτερης συζήτησης στον χώρο της τεχνολογίας για την αποφυγή ορολογίας με αρνητικές ιστορικές συνδηλώσεις (master/slave), και υιοθετήθηκε σταδιακά από την πλειοψηφία των εργαλείων και πλατφορμών.
The default branch name for new repositories is now main.
GitHub.blog — 1 Οκτωβρίου 2020
Καλό είναι να κάνουμε την ίδια αλλαγή και τοπικά, ώστε τα αποθετήριά μας να παραμένουν συνεπή με αυτά που ανεβάζουμε στο GitHub και να αποφύγουμε προβλήματα σύνδεσης μεταξύ τοπικού και απομακρυσμένου αποθετηρίου.
Terminal
git config --global init.defaultBranch mainΜέθοδος συγχώνευσης (merge strategy)
Μία ρύθμιση που δεν είναι απολύτως απαραίτητη, αλλά αξίζει να εξετάσουμε, αφορά τον τρόπο με τον οποίο το Git χειρίζεται τις συγχωνεύσεις. Ας υποθέσουμε ότι δημιουργούμε ένα feature branch για να αναπτύξουμε μια νέα λειτουργία. Όταν τελειώσουμε και θέλουμε να φέρουμε τις αλλαγές μας πίσω στο main, η συμπεριφορά του Git εξαρτάται από το αν ο κλάδος main έχει δεχθεί νέα commits εν τω μεταξύ.
Η πρώτη περίπτωση είναι το Fast-forward merge. Αν κανείς δεν έχει κάνει νέα commits στο main από τότε που φτιάξαμε το feature branch, το ιστορικό μοιάζει ως εξής:
Σε αυτήν την περίπτωση, το Git εκτελεί από προεπιλογή fast-forward merge: αντί να δημιουργήσει ένα νέο merge commit, μετακινεί απλώς τον δείκτη του main μέχρι την κορυφή του feature branch.
Το αποτέλεσμα είναι ένα «καθαρό», γραμμικό ιστορικό σαν να μην υπήρξε ποτέ ξεχωριστός κλάδος. Αυτό μπορεί να φαίνεται τακτοποιημένο, αλλά χάνουμε την πληροφορία ότι οι αλλαγές αναπτύχθηκαν σε ξεχωριστό branch.
Ενώ, η δεύτερη περίτπωση είναι Merge commit (χωρίς fast-forward), Αν έχουν γίνει νέα commits στο main εν τω μεταξύ, το fast-forward δεν είναι δυνατό και το Git δημιουργεί αυτόματα ένα νέο merge commit που ενώνει τους δύο κλάδους:
Εδώ το M είναι το merge commit. Το ιστορικό δείχνει ξεκάθαρα ότι υπήρξε ένας ξεχωριστός κλάδος ανάπτυξης, πότε δημιουργήθηκε και πότε συγχωνεύθηκε — κάτι πολύ χρήσιμο όταν δουλεύουμε σε ομάδα ή θέλουμε να παρακολουθούμε την εξέλιξη του project μας.
Η ρύθμιση merge.ff false
Ορίζοντας αυτήν την επιλογή, λέμε στο Git να δημιουργεί πάντα ένα merge commit, ακόμα και όταν το fast-forward θα ήταν εφικτό (Περίπτωση 1). Έτσι εξασφαλίζουμε ότι το ιστορικό των κλάδων μας παραμένει πάντα ορατό και συνεπές, ανεξάρτητα από το πότε αποφασίσαμε να κάνουμε merge.
Terminal
git config --global merge.ff falseΤο αν προτιμάμε fast-forward ή merge commits εξαρτάται από τη φιλοσοφία του project. Σε μεγάλες ομάδες, τα merge commits θεωρούνται καλή πρακτική γιατί διατηρούν ένα πλήρες ιστορικό αποφάσεων. Σε μικρά προσωπικά project, το γραμμικό ιστορικό του fast-forward μπορεί να είναι πιο ευανάγνωστο.
Στρατηγική λήψης αλλαγών (pull strategy)
Όταν δουλεύουμε με ένα απομακρυσμένο αποθετήριο (π.χ. στο GitHub), συχνά θέλουμε να «κατεβάσουμε» τις αλλαγές που έχουν κάνει άλλοι στο project. Αυτό γίνεται με την εντολή git pull. Αυτό που ίσως αγνοούμε είναι ότι το git pull δεν κατεβάζει απλώς τις αλλαγές, αλλά ταυτόχρονα αποφασίζει και πώς θα τις ενσωματώσει στο τοπικό μας αντίγραφο.
Από το Git 2.27 και μετά, αν δεν έχουμε ορίσει ρητά αυτή τη συμπεριφορά, το Git εμφανίζει μια προειδοποίηση κάθε φορά που τρέχουμε git pull. Για να την αποφύγουμε αρκεί να ορίσουμε τη στρατηγική που προτιμάμε.
Οι δύο κύριες επιλογές είναι:
| Στρατηγική | Εντολή | Πότε να τη χρησιμοποιούμε |
|---|---|---|
| Merge | pull.rebase false |
Ασφαλής επιλογή για αρχάριους — δημιουργεί merge commit |
| Rebase | pull.rebase true |
Κρατά το ιστορικό γραμμικό, αλλά απαιτεί εξοικείωση |
Για αρχή, η στρατηγική merge είναι η πιο ασφαλής επιλογή:
Terminal
git config --global pull.rebase falseΗ διαφορά μεταξύ merge και rebase είναι ένα θέμα που αξίζει ξεχωριστή ανάλυση. Για τώρα, αρκεί να γνωρίζουμε ότι και οι δύο επιτυγχάνουν τον ίδιο τελικό στόχο — να έχουμε τις αλλαγές των άλλων στον υπολογιστή μας — αλλά με διαφορετικό τρόπο. Αν ξεκινάμε με Git, η επιλογή false (merge) είναι αυτή που θα συναντάμε πιο συχνά σε οδηγούς και tutorials.
Αυτόματη υπογραφή commits
Όταν ανεβάζουμε commits στο GitHub, η πλατφόρμα δεν έχει τρόπο να επαληθεύσει ότι ο αποστολέας είναι πράγματι αυτός που ισχυρίζεται ότι είναι. Ο καθένας μπορεί να γράψει οποιοδήποτε όνομα και email στη ρύθμιση user.name/user.email. Η υπογραφή commits με ένα κρυπτογραφικό κλειδί λύνει αυτό το πρόβλημα. Το GitHub επαληθεύει την ταυτότητά μας και εμφανίζει μια πράσινη ένδειξη Verified δίπλα σε κάθε υπογεγραμμένο commit.
Υπάρχουν δύο τρόποι υπογραφής:
- GPG κλειδί — η παραδοσιακή προσέγγιση, πιο ισχυρή αλλά και πιο σύνθετη στη ρύθμιση.
- SSH κλειδί — απλούστερη εναλλακτική που υποστηρίζεται από το GitHub από το 2022. Αν χρησιμοποιούμε ήδη SSH για authentication, το ίδιο κλειδί μπορεί να χρησιμεύσει και για υπογραφή.
Αν δεν διαθέτουμε ακόμα GPG κλειδί, μπορούμε να ακολουθήσουμε τον οδηγό του GitHub για να δημιουργήσουμε ένα. Στη συνέχεια, μπορούμε να το συνδέσουμε με την πλατφόρμα φιλοξενίας μας:
Χωρίς επιπλέον ρύθμιση, η υπογραφή ενός commit απαιτεί το flag -S:
Terminal
git commit -S -m "μήνυμα"Αυτό είναι εύκολο να το ξεχάσουμε. Για αυτό το λόγο μπορούμε να ρυθμίσουμε το Git ώστε να υπογράφει αυτόματα κάθε commit:
Terminal
git config user.signingkey key_id
git config commit.gpgsign trueΈλεγχος των ρυθμίσεων
Αφού ολοκληρώσουμε τις παραπάνω ρυθμίσεις, μπορούμε να τις ανασκοπήσουμε όλες μαζί με την εξής εντολή:
Terminal
git config --list
Η παραπάνω εικόνα μας δίνει μια πλήρη εικόνα των ρυθμίσεων του Git. Κάθε χρήστης έχει διαφορετικές ανάγκες, οπότε αν θέλουμε να εξερευνήσουμε περαιτέρω επιλογές, η επίσημη τεκμηρίωση του git-config είναι το καλύτερο σημείο εκκίνησης.
Σύνοψη
Μια γρήγορη αναφορά όλων των εντολών που χρησιμοποιήσαμε για τη ρύθμιση του Git:
Terminal
git config --global user.name "YourName"
git config --global user.email your_email
git config --global core.editor "editor_name"
git config --global init.defaultBranch main
git config --global merge.ff false
git config --global pull.rebase false
# Υπογραφή commits με GPG κλειδί
gpg --list-secret-keys --keyid-format LONG
git config user.signingkey key_id
git config commit.gpgsign true
# Έλεγχος όλων των ρυθμίσεων και της προέλευσής τους
git config --list --show-originΌλες αυτές οι ρυθμίσεις αποθηκεύονται στο αρχείο .gitconfig, που βρίσκεται στον αρχικό κατάλογο (home directory) του συστήματός μας.
Το αρχείο .gitconfig μπορεί να μην είναι ορατό με την πρώτη ματιά, καθώς τα αρχεία που ξεκινούν με τελεία είναι κρυφά εξ ορισμού στα Unix-based συστήματα. Αν δεν το βλέπουμε, αρκεί να ενεργοποιήσουμε την εμφάνιση κρυφών αρχείων στον file manager μας (στο Ubuntu: Ctrl + H στο Nautilus).
Ευχαριστίες
Φωτογραφία από Daniel Skovran από το Pixabay
Αναφορές
Αναφορά
@online{2022,
author = {, stesiam},
title = {Παραμετροποίηση του Git},
date = {2022-11-04},
url = {https://stesiam.com/el/posts/git-commands/},
langid = {el}
}