Το προφίλ μας στο Google Plus
1

Πρώτη γνωριμία κι εξάσκηση με το Git

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

Όπως μπορείτε να δείτε κι από τον επίσημο δικτυακό τόπο του Git, το δημοφιλές κατανεμημένο Version Control System διατίθεται, μεταξύ άλλων, για διανομές Linux, για το macOS αλλά και για τα Windows. Εναλλακτικά, ο χρήστης έχει τη δυνατότητα να το μεταγλωττίσει ξεκινώντας από τον πηγαίο κώδικα και κατόπιν να το εγκαταστήσει στο λειτουργικό της προτίμησής του. Αν και υπάρχουν γραφικά αλλά και web front-ends για το Git, έχει περισσότερο νόημα να το γνωρίσουμε πρώτα από το φυσικό του περιβάλλον. Αυτό δεν είναι άλλο από τη γραμμή εντολών. Αφού κατανοήσουμε τη λειτουργία του από εκεί, μετά δεν θα έχουμε κανένα πρόβλημα με οποιοδήποτε άλλο front-end. Στο παρόν άρθρο δουλεύουμε σε περιβάλλον openSUSE Leap. Περιττό να σημειώσουμε ότι παρόμοια θα εργαστεί κανείς από οποιαδήποτε άλλη διανομή Linux, από το macOS ή ακόμη κι από τα Windows. (Παραδεχόμαστε, ωστόσο, ότι σε περιβάλλον Windows δεν έχουμε χρησιμοποιήσει ποτέ το Git.) Για την εγκατάσταση δεν επιλέξαμε τη μεταγλώττιση από το source. Πολύ πιο απλά, στραφήκαμε στον package manager της διανομής μας:

<br />
cvar@ohsuse:~&gt; sudo zypper ref<br />
cvar@ohsuse:~&gt; sudo zypper in git-core<br />

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

Τώρα, κάθε φορά που κάνουμε ένα commit (βλ. παρακάτω) στο πρότζεκτ που δουλεύουμε, το συνοδεύουμε κι από ένα σύντομο μήνυμα. Επειδή πρέπει να φαίνεται εύκολα ποιοι έχουν κάνει commit στο πρότζεκτ, ορίζουμε εξ αρχής δύο σχετικές παραμέτρους — συγκεκριμένα για το όνομα και για το email μας:

<br />
cvar@ohsuse:~&gt; git config --global user.name &quot;cvar&quot;<br />
cvar@ohsuse:~&gt; git config --global user.email &quot;cvar@colder.xyz&quot;<br />

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

<br />
cvar@ohsuse:~&gt; cat .gitconfig<br />
[user]<br />
	name = cvar<br />
	email = cvar@colder.xyz<br />

Αντί να κοιτάζουμε τα περιεχόμενα του αρχείου .gitconfig, κάλλιστα μπορούμε να δίνουμε στο git την εντολή config μαζί με την παράμετρο –list:

<br />
cvar@ohsuse:~&gt; git config --list<br />
user.name=cvar<br />
user.email=cvar@colder.xyz<br />

Αναμενόμενα, υπάρχουν ένα σωρό άλλες παράμετροι που έχουμε την ευκαιρία να θέσουμε. Για παράδειγμα, μερικές φορές το Git θα σταματά ό,τι κάνει και θα περιμένει από εμάς να πληκτρολογήσουμε κάτι. Για editor, θα χρησιμοποιεί τον προκαθορισμένο του συστήματος. Στο δικό μας είναι ο vim:

<br />
cvar@ohsuse:~&gt; which $EDITOR<br />
/usr/bin/vim<br />

Αν προτιμάμε κάποιον άλλον ειδικά για το Git, γράφουμε:

<br />
cvar@ohsuse:~&gt; git config --global core.editor nano<br />
cvar@ohsuse:~&gt; git config --list<br />
user.name=cvar<br />
user.email=cvar@colder.xyz<br />
core.editor=nano<br />

Προς το παρόν δεν χρειάζεται ν’ ασχοληθούμε άλλο με τις παραμέτρους. Έχουμε το Git εγκατεστημένο και μια χαρά ρυθμισμένο και είναι ώρα ν’ αρχίσουμε να το μαθαίνουμε.

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

<br />
cvar@ohsuse:~&gt; mkdir theGitProject<br />
cvar@ohsuse:~&gt; cd theGitProject<br />
cvar@ohsuse:~/theGitProject&gt;<br />

Προς το παρόν το πρότζεκτ είναι κενό, δεν περιλαμβάνει ούτε ένα αρχείο. Αυτό αλλάζει εύκολα:

<br />
cvar@ohsuse:~/theGitProject&gt; touch somefile<br />

Ωραία, για αρχή το κενό μας αρχείο, ονόματι somefile, είναι αρκετό. Η επόμενη κίνηση είναι να αρχικοποιήσουμε ένα repository (αποθετήριο) για το φιλόδοξο πρότζεκτ μας. Μη γελάτε. Μπορεί να μη δημιουργήσουμε κάποια αξιοπρόσεκτη εφαρμογή ή δικτυακό τόπο, θα σημειώσουμε όμως σημαντική πρόοδο στο σχέδιό μας για την κατάκτηση του Git. Μη λέτε, λοιπόν, ότι δεν είμαστε φιλόδοξοι. Η αρχικοποίηση του repository επιτυγχάνεται έτσι:

<br />
cvar@ohsuse:~/theGitProject&gt; git init<br />
Initialized empty Git repository in /home/cvar/theGitProject/.git<br />

Μάλιστα. Όπως βλέπουμε από το μήνυμα, το νέο repository αρχικοποιήθηκε επιτυχώς και προς το παρόν είναι κενό.

Παρακολούθηση αρχείων
Η δημιουργία repository  εντός καταλόγου, δεν σημαίνει ότι το Git παρακολουθεί (tracks) τα αρχεία του ίδιου καταλόγου. Πράγματι:

<br />
cvar@ohsuse:~/theGitProject&gt; git status<br />
On branch master</p>
<p>Initial commit</p>
<p>Untracked files:<br />
  (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)</p>
<p>	somefile</p>
<p>nothing added to commit but untracked files present (use &quot;git add&quot; to track)<br />

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

<br />
cvar@ohsuse:~/theGitProject&gt; git add somefile<br />

Δεν πήραμε κάποιο μήνυμα στο τερματικό μας — κι αυτό είναι καλό. Αν δώσουμε ξανά git status, διαπιστώνουμε ότι το Git βλέπει, πλέον, το αρχείο somefile και μάλιστα θα το συμπεριλάβει στο επόμενο commit:

<br />
cvar@ohsuse:~/theGitProject&gt; git status<br />
On branch master</p>
<p>Initial commit</p>
<p>Changes to be committed:<br />
  (use &quot;git rm --cached &lt;file&gt;...&quot; to unstage)</p>
<p>	new file:   somefile<br />

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

<br />
git add *.c<br />

ξεκινάμε το tracking όλων των αρχείων με κατάληξη “.c”. Για το tracking όλων ανεξαιρέτως των αρχείων του καταλόγου του πρότζεκτ, θα γράφαμε:

<br />
git add .<br />

Το αρχείο somefile μέσα στον κατάλογο του πρότζεκτ μας δεν παρακολουθείται από το Git: είναι untracked (1). Αφού όμως το προσθέσουμε στα αρχεία που επιβλέπει το Git (2), τότε παρακολουθείται και μάλιστα θα συμπεριληφθεί στο επόμενο commit (3).

Το αρχείο somefile μέσα στον κατάλογο του πρότζεκτ μας δεν παρακολουθείται από το Git: είναι untracked (1). Αφού όμως το προσθέσουμε στα αρχεία που επιβλέπει το Git (2), τότε παρακολουθείται και μάλιστα θα συμπεριληφθεί στο επόμενο commit (3).

Το πρώτο commit
Κάθε φορά που προσθέτουμε αρχεία υπό παρακολούθηση ή τροποποιούμε υπάρχοντα αρχεία (πάντα υπό παρακολούθηση), καλό είναι να κάνουμε κι ένα commit. Ειδικά για τον κόσμο του Git –και σε αντίθεση με άλλα VCS–, το commit σημαίνει ότι καταγράφουμε στην τοπική βάση του αποθετηρίου μας τις όποιες αλλαγές έχουν γίνει στο τρέχον branch (βλ. παρακάτω). Αν μετά θέλουμε να στείλουμε τις αλλαγές σε ένα απομακρυσμένο αποθετήριο, τότε κάνουμε το λεγόμενο push. Κάθε push πρέπει να περιλαμβάνει τουλάχιστον ένα commit και κάθε commit πρέπει να αφορά σε τουλάχιστον ένα αρχείο και να συνοδεύεται από ένα μήνυμα. Δεν υπάρχει περιορισμός στο πλήθος των commits, ωστόσο μετά από κάθε “περιστατικό” προτείνεται να προχωράμε σε commit. Τι σημαίνει όμως περιστατικό; Να σας πούμε. Δεν πρόκειται για κάποιον επίσημο όρο. Απλά, όταν στο παρόν κείμενο μιλάμε για περιστατικό έχουμε κατά νου μια σημαντική αλλαγή, όπως, π.χ., η διόρθωση ενός bug, η προσθήκη μιας συνάρτησης σε ένα αρχείο κώδικα, η πληκτρολόγηση μιας εκτενούς παραγράφου ή ενότητας σε post που ετοιμάζουμε κ.ο.κ. Έχουμε αυτή τη στιγμή κάποιο περιστατικό; Βεβαίως κι έχουμε: Ξεκινήσαμε το πρότζεκτ μας με το tracking του αρχείου somefile! Θα συμφωνήσετε, φανταζόμαστε, ότι η ενέργεια αυτή αποτελεί ορόσημο στον αγώνα μας για την κατανόηση του Git, οπότε σίγουρα είναι ώρα για ένα ωραιότατο commit. Μέσα από τον κατάλογο του πρότζεκτ μας, λοιπόν, αρκεί να πληκτρολογήσουμε:

<br />
cvar@ohsuse:~/theGitProject&gt; git commit<br />

Ανοίγει τότε ο προκαθορισμένος text editor (θέσατε την παράμετρο core.editor;) και καλούμαστε να γράψουμε ένα σύντομο μήνυμα που θα συνοδεύει το commit. Εναλλακτικά, θα μπορούσαμε να είχαμε δώσει το μήνυμα ως παράμετρο, από τη γραμμή εντολών:

<br />
cvar@ohsuse:~/theGitProject&gt; git commit -m &quot;This is my first commit ever!&quot;<br />

Το commit που μόλις κάναμε αφορούσε σε όλα τα νέα ή/και στα τροποποιημένα –και πάντα υπό παρακολούθηση– αρχεία. Από τη στιγμή που μιλάμε για το πρώτο commit, αυτή η “γενικότητα” δεν πειράζει. Στο εξής όμως τα commits καλό είναι να αφορούν σε συγκεκριμένα αρχεία ή/και σε καταλόγους. Αν, π.χ., θέλουμε ένα commit για μερικές αλλαγές που κάναμε στο αρχείο somefile, τότε γράφουμε:

<br />
cvar@ohsuse:~/theGitProject&gt; git commit -m &quot;Corrected some typos&quot; somefile<br />

Προκειμένου να δούμε όλα τα έως τώρα commits (του τρέχοντος branch), αρκεί να γράψουμε:

<br />
cvar@ohsuse:~/theGitProject&gt; git log<br />

Πατώντας το πλήκτρο [Q] φεύγουμε από τη λίστα με τα commits κι επιστρέφουμε στη γραμμή εντολών.

Κάνουμε το πρώτο μας commit και καλούμαστε να πληκτρολογήσουμε ένα μήνυμα που θα το συνοδεύει. Από το προτεινόμενο μήνυμα του Git (είναι 'σχολιασμένο' με το χαρακτήρα #) πληροφορούμαστε ότι βρισκόμαστε στο branch ονόματι master (το προκαθορισμένο μετά από κάθε αρχικοποίηση αποθετηρίου), καθώς και ότι το commit αφορά στην προσθήκη του νέου αρχείου με όνομα somefile. Ως μήνυμα του commit μπορούμε να χρησιμοποιήσουμε αυτές τις πληροφορίες ή να γράψουμε ό,τι άλλο θέλουμε.

Κάνουμε το πρώτο μας commit και καλούμαστε να πληκτρολογήσουμε ένα μήνυμα που θα το συνοδεύει. Από το προτεινόμενο μήνυμα του Git (είναι “σχολιασμένο” με το χαρακτήρα #) πληροφορούμαστε ότι βρισκόμαστε στο branch ονόματι master (το προκαθορισμένο μετά από κάθε αρχικοποίηση αποθετηρίου), καθώς και ότι το commit αφορά στην προσθήκη του νέου αρχείου με όνομα somefile. Ως μήνυμα του commit μπορούμε να χρησιμοποιήσουμε αυτές τις πληροφορίες ή να γράψουμε ό,τι άλλο θέλουμε.

Η έξοδος στο τερματικό, μετά το πρώτο μας commit.

Η έξοδος στο τερματικό, μετά το πρώτο μας commit.

Το ένα και μοναδικό commit έως τώρα. Ανά πάσα στιγμή, τα commits του τρέχοντος branch τα βλέπουμε δίνοντας git log. Από τον pager βγαίνουμε πατώντας το πλήκτρο [Q].

Το ένα και μοναδικό commit έως τώρα. Ανά πάσα στιγμή, τα commits του τρέχοντος branch τα βλέπουμε δίνοντας git log. Από τον pager βγαίνουμε πατώντας το πλήκτρο [Q].

Το πρώτο push
Με το Git μπορούμε να εργαζόμαστε αποκλειστικά στον υπολογιστή μας, χωρίς ν’ ανεβάζουμε το πρότζεκτ σε απομακρυσμένο server. Ίσως, π.χ., αυτό που θέλουμε είναι μόνο version control στα αρχεία ενός πρότζεκτ μας, οπότε με το Git έχουμε ακριβώς αυτό που χρειαζόμαστε και είμαστε 100% ικανοποιημένοι. Αν όμως συνεργαζόμαστε με άλλους, τότε σίγουρα χρειάζεται ν’ ανεβάζουμε τα αρχεία του πρότζεκτ σε server στο τοπικό δίκτυο ή –το πιθανότερο– στο Internet. Στον ίδιο server θ’ ανεβάζουν τη δουλειά τους και οι συνεργάτες ή απλά θα μπορούν να παίρνουν τα αρχεία στους δικούς τους υπολογιστές για να κάνουν δοκιμές. Όπως αναφέραμε και νωρίτερα, το ανέβασμα αρχείων ή/και αλλαγών σε απομακρυσμένο Git server –για την ακρίβεια σε απομακρυσμένο repository– ονομάζεται push. (Σε άλλα VCS ονομάζεται commit ή checkin, αλλά δεν υπάρχει λόγος να μπερδευόμαστε τώρα.)

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

<br />
cvar@ohsuse:~/theGitProject&gt; git remote add test-rr \<br />
> git@github.com:colder-is-better/theProject.git<br />

Τον απομακρυσμένο server που μόλις προσθέσαμε επιλέξαμε να ονομάσουμε test-rr (από το “test remote repository”). Το username μας στο GitHub, εξάλλου, είναι colder-is-better, οπότε εσείς φροντίστε να βάλετε το δικό σας. Η προηγούμενη εντολή δεν επέστρεψε κάποιο αποτέλεσμα. Γράφοντας όμως git remote -v διαπιστώνουμε ότι η παρουσία του απομακρυσμένου server, ονόματι test-rr, έχει ληφθεί υπόψη.

<br />
cvar@ohsuse:~/theGitProject&gt; git remote -v<br />
test-rr	git@github.com:colder-is-better/theProject.git (fetch)<br />
test-rr	git@github.com:colder-is-better/theProject.git (push)<br />

Πλέον, το push στο αποθετήριο του GitHub με όνομα theProject γίνεται έτσι:

<br />
cvar@ohsuse:~/theGitProject&gt; git push test-rr master<br />
Counting objects: 3, done.<br />
Writing objects: 100% (3/3), 215 bytes | 0 bytes/s, done.<br />
Total 3 (delta 0), reused 0 (delta 0)<br />
To git@github.com:colder-is-better/theProject.git<br />
 * [new branch]      master -&gt; master<br />

Όλα καλά. Από τον web browser της προτίμησής σας επισκεφτείτε, αν θέλετε, και τη διεύθυνση του repository στο GitHub (π.χ., το σχετικό URL για εμάς είναι το https://github.com/colder-is-better/theProject). Εκεί θα δείτε τα περιεχόμενα του τοπικού repository, το οποίο στο πλαίσιο του παραδείγματός μας προς το παρόν έχει ένα μόνο (κενό) αρχείο: το somefile. Και πριν συνεχίσουμε, δύο μόνο παρατηρήσεις:

  • Εξ ορισμού, μετά την αρχικοποίηση ενός τοπικού αποθετηρίου έχουμε ένα μόνο branch: το master. Το περιεχόμενο αυτού στείλαμε στο απομακρυσμένο repository.
  • Προκειμένου να δουλέψει το push, στο λογαριασμό μας στο GitHub θα πρέπει να έχουμε στείλει το δημόσιο κλειδί από την τοπική εγκατάσταση του SSH. Περισσότερα για τα SSH passwordless logins και το key-based authentication μπορείτε να διαβάσετε στο σχετικό άρθρο.

Θέλουμε να πιστεύουμε ότι όλα όσα βλέπατε τόσον καιρό στο web ή διαβάζατε απ’ εδώ κι απ’ εκεί –πάντα περί Git και GitHub–, πλέον έχουν αρχίσει ν’ αποκτούν νόημα. Αν μάλιστα έχετε αρχίσει να πωρώνεστε, πραγματικά δεν ξέρουμε τι θα κάνετε στη συνέχεια.

Προσθήκη απομακρυσμένου αποθετηρίου ονόματι theProject από το GitHub (1) -- και έλεγχος (2). Μπορούμε πλέον ν' ανεβάσουμε το περιεχόμενο του τοπικού branch, ονόματι master, στο master του απομακρυσμένου repository (3). Ένας οποιοσδήποτε συνεργάτης μας θα είναι σε θέση να κλωνοποιήσει, στον τοπικό του υπολογιστή, το σχετικό αποθετήριο του GitHub (π.χ., git clone git@github.com:colder-is-better/theProject.git).

Προσθήκη απομακρυσμένου αποθετηρίου ονόματι theProject από το GitHub (1) — και έλεγχος (2). Μπορούμε πλέον ν’ ανεβάσουμε το περιεχόμενο του τοπικού branch, ονόματι master, στο master του απομακρυσμένου repository (3). Ένας οποιοσδήποτε συνεργάτης μας θα είναι σε θέση να κλωνοποιήσει, στον τοπικό του υπολογιστή, το σχετικό αποθετήριο του GitHub (π.χ., git clone git@github.com:colder-is-better/theProject.git).

Ιδού το απομακρυσμένο repository ονόματι theProject, στο GitHub. Στο πλαίσιο των δοκιμών μας περιλαμβάνει ένα και μόνο ένα αρχείο (somefile).

Ιδού το απομακρυσμένο repository ονόματι theProject, στο GitHub. Στο πλαίσιο των δοκιμών μας περιλαμβάνει ένα και μόνο ένα αρχείο (somefile).

Τα branches και οι φυσικοί νόμοι
Αν δεν ασχοληθούμε με τα branches, δεν πρόκειται να εκτιμήσουμε την αξία του Git. Πρακτικά, το branch είναι μια ξεχωριστή “οικογένεια” αλλαγών επί του περιεχομένου του πρότζεκτ μας. Κάθε αποθετήριο του Git ξεκινά με ένα branch ονόματι master κι επιτρέπεται να έχει περισσότερα του ενός. Σκεφτείτε κάθε branch ως ένα παράλληλο Σύμπαν, το οποίο κάποια δεδομένη χρονική στιγμή –και με τρόπο μυστηριώδη– υφίσταται, αρχίζοντας ακριβώς με ό,τι περιλαμβάνει το master (ή το branch από το οποίο ξεκίνησε, τέλος πάντων). Από εκεί και μετά, το νέο Σύμπαν εκτείνεται και μετασχηματίζεται κι εξελίσσεται με το δικό του τρόπο και ρυθμό, χωρίς φυσικά να επηρεάζει τα άλλα branches.

Σε πολύ λίγο θα φτιάξουμε ένα νέο branch για το δοκιμαστικό μας πρότζεκτ. Σ’ αυτό το νέο branch σκοπεύουμε να δουλεύουμε ή/και να δοκιμάζουμε τις ιδέες μας. Όταν θα είμαστε ικανοποιημένοι, θα συγχωνεύουμε (merge) τις προσθήκες ή/και τις αλλαγές που έλαβαν χώρα στο νέο branch, πίσω στο περιεχόμενο του master. Ναι: Στον κόσμο του Git οι φυσικοί νόμοι είναι πιο ελαστικοί σε σύγκριση με τον δικό μας κόσμο –ή τουλάχιστον έτσι υποθέτουμε– κι επιτρέπουν τη μεταφορά και την ενσωμάτωση ύλης μεταξύ παραλλήλων συμπάντων.

Ανά πάσα στιγμή, προκειμένου να δούμε τα branches ενός αποθετηρίου γράφουμε:

<br />
cvar@ohsuse:~/theGitProject&gt; git branch<br />
* master<br />

Όπως βλέπετε κι εσείς, προς το παρόν έχουμε ένα μόνο branch: το master. Αν στην εντολή git branch προσθέσουμε και την παράμετρο -a, βλέπουμε και τα branches στα απομακρυσμένα repositories:

<br />
cvar@ohsuse:~/theGitProject&gt; git branch -a<br />
* master<br />
  remotes/test-rr/master<br />

Και στα δύο παραδείγματα θα παρατηρήσατε φυσικά τον αστερίσκο, ο οποίος υποδεικνύει το branch στο οποίο βρισκόμαστε. Τώρα είμαστε στο master κι αυτό δεν μας προκαλεί καμία έκπληξη. Ας φτιάξουμε επιτέλους ένα νέο branch, ονόματι devel:

<br />
cvar@ohsuse:~/theGitProject&gt; git checkout -b devel<br />
Switched to a new branch 'devel'<br />
cvar@ohsuse:~/theGitProject&gt; git branch<br />
* devel<br />
  master<br />

Μάλιστα. Τι συνέβη μόλις; Να σας πούμε:

  • Στην ορολογία του Git, το checkout δεν σημαίνει ό,τι σε άλλα VCS (βλ. πρώτο μέρος της σειράς μας). Αντίθετα, σημαίνει “αλλαγή branch”.
  • Το checkout μαζί με την παράμετρο -b δημιουργεί ένα νέο branch και ταυτόχρονα μας μεταφέρει σ’ αυτό. Στο παράδειγμά μας, λοιπόν, με το git checkout -b devel φτιάχνουμε το νέο Σύμπαν με όνομα devel κι αμέσως τηλεμεταφερόμαστε σ’ αυτό.
  • Η θέση του αστερίσκου στην έξοδο του git branch έχει φύγει από τ’ αριστερά του master και τώρα βρίσκεται σ’ αριστερά του devel. Πράγματι, λοιπόν, είμαστε τώρα στο νέο branch, το devel.

Αν για οποιονδήποτε λόγο θέλουμε να πάμε στο master, δίνουμε:

<br />
cvar@ohsuse:~/theGitProject&gt; git checkout master<br />
Switched to branch 'master'<br />
cvar@ohsuse:~/theGitProject&gt; git branch<br />
  devel<br />
* master<br />

Μια χαρά, ας γυρίσουμε όμως και πάλι στο devel:

<br />
cvar@ohsuse:~/theGitProject&gt; git checkout devel<br />
Switched to branch 'devel'<br />
cvar@ohsuse:~/theGitProject&gt; git branch<br />
* devel<br />
  master<br />

Αλλαγές, προσθήκες και συγχώνευση περιεχομένου
Βρισκόμαστε λοιπόν στο branch με όνομα devel, κάτι που φαίνεται κι από την έξοδο της git status:

<br />
cvar@ohsuse:~/theGitProject&gt; git status<br />
On branch devel<br />
nothing to commit, working directory clean<br />

Πάμε αμέσως να προσθέσουμε περιεχόμενο στο –κενό, έως αυτή τη στιγμή– αρχείο, με όνομα somefile. Πληκτρολογούμε:

<br />
cvar@ohsuse:~/theGitProject&gt; echo &quot;this ain't Kansas no more&quot; &gt;&gt; somefile<br />
cvar@ohsuse:~/theGitProject&gt; cat somefile<br />
this ain't Kansas no more<br />

Ωραία. Προσέξτε τώρα:

<br />
cvar@ohsuse:~/theGitProject&gt; git status<br />
On branch devel<br />
Changes not staged for commit:<br />
  (use &quot;git add &lt;file&gt;...&quot; to update what will be committed)<br />
  (use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)</p>
<p>	modified:   somefile</p>
<p>no changes added to commit (use &quot;git add&quot; and/or &quot;git commit -a&quot;)<br />

Το Git κατάλαβε ότι το αρχείο somefile τροποποιήθηκε, μας πληροφορεί όμως ότι δεν είναι staged για το επόμενο commit. Θα γίνει staged αν αρχίσουμε να το παρακολουθούμε (track) και στο branch που τώρα βρισκόμαστε. Δίνουμε

<br />
cvar@ohsuse:~/theGitProject&gt; git add somefile<br />

και είμαστε έτοιμοι:

<br />
cvar@ohsuse:~/theGitProject&gt; git status<br />
On branch devel<br />
Changes to be committed:<br />
  (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</p>
<p>	modified:   somefile<br />

Ας κάνουμε και το commit:

<br />
cvar@ohsuse:~/theGitProject&gt; git commit -m &quot;added some content&quot; somefile<br />
[devel 1453d47] added some content<br />
 1 file changed, 1 insertion(+)<br />

Θυμηθείτε, είμαστε στο branch ονόματι devel.

<br />
cvar@ohsuse:~/theGitProject&gt; git log<br />
commit 1453d47027760fcff2a99004d4f65553c9e0ca4f<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 11:20:29 2016 +0300</p>
<p>    added some content</p>
<p>commit 668b62748042fd2b372cda18abd463d87fd92cf3<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 09:57:56 2016 +0300</p>
<p>    This is my first commit ever!<br />

Το νέο branch, το devel, έχει “κληρονομήσει” το ένα και μοναδικό commit που είχαμε κάνει στο branch με όνομα master. Λογικό κι αναμενόμενο, με βάση όλα όσα έχουμε πει για τα branches. Αλήθεια, πώς έχει η κατάσταση αυτή τη στιγμή στο master; Στοιχηματίζουμε ότι γνωρίζετε, ας πάμε όμως να δούμε.

<br />
cvar@ohsuse:~/theGitProject&gt; git checkout master<br />
Switched to branch 'master'<br />
cvar@ohsuse:~/theGitProject&gt; cat somefile<br />
cvar@ohsuse:~/theGitProject&gt; git log<br />
commit 668b62748042fd2b372cda18abd463d87fd92cf3<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 09:57:56 2016 +0300</p>
<p>    This is my first commit ever!<br />

Ό,τι περιμέναμε: Στο master δεν υπάρχει καμία αλλαγή στο αρχείο somefile, ενώ αντί για δύο έχουμε ένα μόνο commit. Πιστεύουμε ότι ήδη έχει αρχίσει να φαίνεται η τρομερή ευελιξία που προσφέρουν τα branches του Git. Πάμε πάλι στο devel:

<br />
cvar@ohsuse:~/theGitProject&gt; git checkout devel<br />
Switched to branch 'devel'<br />

Ας δημιουργήσουμε ένα νέο αρχείο, το newdirection:

<br />
cvar@ohsuse:~/theGitProject&gt; touch newdirection<br />
cvar@ohsuse:~/theGitProject&gt; git status<br />
On branch devel<br />
Untracked files:<br />
  (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)</p>
<p>	newdirection</p>
<p>nothing added to commit but untracked files present (use &quot;git add&quot; to track)<br />
cvar@ohsuse:~/theGitProject&gt; git add newdirection<br />
cvar@ohsuse:~/theGitProject&gt; git status<br />
On branch devel<br />
Changes to be committed:<br />
  (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)</p>
<p>	new file:   newdirection<br />

Αμέσως μετά τη δημιουργία του, το αρχείο newdirection δεν παρακολουθείται από το git (είναι untracked). Αυτό αλλάζει εύκολα με ένα git add newdirection. Με αφορμή την παρουσία του newdirection (δεν μπαίνουμε στον κόπο να του προσθέσουμε περιεχόμενο τώρα), κάνουμε κι άλλο ένα σχετικό commit:

<br />
cvar@ohsuse:~/theGitProject&gt; git commit -m &quot;added a new file, will need it later&quot; newdirection<br />
[devel ff0d768] added a new file, will need it later<br />
 1 file changed, 0 insertions(+), 0 deletions(-)<br />
 create mode 100644 newdirection<br />
cvar@ohsuse:~/theGitProject&gt; git log<br />
commit ff0d76845f4e8d03a5403bf0ec6d350d5b761f2f<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 11:54:45 2016 +0300</p>
<p>    added a new file, will need it later</p>
<p>commit 1453d47027760fcff2a99004d4f65553c9e0ca4f<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 11:20:29 2016 +0300</p>
<p>    added some content</p>
<p>commit 668b62748042fd2b372cda18abd463d87fd92cf3<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 09:57:56 2016 +0300</p>
<p>    This is my first commit ever!<br />

Μια χαρά, στο devel έχουμε τρία commits. Πάμε ξανά να δούμε πώς έχει η κατάσταση στο branch ονόματι master:

<br />
cvar@ohsuse:~/theGitProject&gt; git checkout master<br />
Switched to branch 'master'<br />
cvar@ohsuse:~/theGitProject&gt; ls -lh<br />
total 0<br />
-rw-r--r-- 1 cvar users 0 Jul  7 11:57 somefile<br />
cvar@ohsuse:~/theGitProject&gt; git log<br />
commit 668b62748042fd2b372cda18abd463d87fd92cf3<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 09:57:56 2016 +0300</p>
<p>    This is my first commit ever!<br />

Θεσπέσια όλα! Η θεωρία συμβαδίζει με την πράξη: Το αρχείο newdirection πολύ σωστά δεν υπάρχει στο master, ενώ επίσης πολύ σωστά έχουμε ένα μόνο commit. Έχει φτάσει η στιγμή να κάνουμε την πρώτη μας συγχώνευση (merge). Θα φέρουμε, μ’ άλλα λόγια, όλες τις αλλαγές και τις προσθήκες που έχουν ήδη γίνει στο devel, πίσω στο master. Κάτι που πρέπει να θυμόμαστε πριν το merge, είναι ότι πρέπει να βρισκόμαστε στο branch όπου πρόκειται να εισαχθούν οι αλλαγές. Στο πλαίσιο του παραδείγματός μας, είμαστε ήδη σ’ αυτό (είναι το master). Για το merge αρκεί να πληκτρολογήσουμε

<br />
cvar@ohsuse:~/theGitProject&gt; git merge devel<br />
Updating 668b627..ff0d768<br />
Fast-forward<br />
 newdirection | 0<br />
 somefile     | 1 +<br />
 2 files changed, 1 insertion(+)<br />
 create mode 100644 newdirection<br />

Όλα δείχνουν ότι το merge πραγματοποιήθηκε επιτυχώς, όμως ας κάνουμε και τους δικούς μας ελέγχους:

<br />
cvar@ohsuse:~/theGitProject&gt; ls -lh<br />
total 4.0K<br />
-rw-r--r-- 1 cvar users  0 Jul  7 12:14 newdirection<br />
-rw-r--r-- 1 cvar users 26 Jul  7 12:14 somefile<br />
cvar@ohsuse:~/theGitProject&gt; cat somefile<br />
this ain't Kansas no more<br />

Υπάρχει πλέον το αρχείο newdirection, ενώ και το somefile δεν είναι κενό. Επιτυχία! Α, και μην ξεχνάτε και τα commits που έγιναν στο devel:

<br />
cvar@ohsuse:~/theGitProject&gt; git log<br />
commit ff0d76845f4e8d03a5403bf0ec6d350d5b761f2f<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 11:54:45 2016 +0300</p>
<p>    added a new file, will need it later</p>
<p>commit 1453d47027760fcff2a99004d4f65553c9e0ca4f<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 11:20:29 2016 +0300</p>
<p>    added some content</p>
<p>commit 668b62748042fd2b372cda18abd463d87fd92cf3<br />
Author: cvar &lt;cvar@colder.xyz&gt;<br />
Date:   Thu Jul 7 09:57:56 2016 +0300</p>
<p>    This is my first commit ever!<br />

Θυμόσαστε εκείνο το απομακρυσμένο repository, στο GitHub; Κρίμα δεν είναι να μην περιλαμβάνει τις αλλαγές που έχουν συντελεστεί στο (τοπικό) master; Πράγματι είναι κρίμα, γι’ αυτό ας στείλουμε τις αλλαγές:

<br />
cvar@ohsuse:~/theGitProject&gt; git push test-rr master<br />
Counting objects: 5, done.<br />
Delta compression using up to 2 threads.<br />
Compressing objects: 100% (3/3), done.<br />
Writing objects: 100% (5/5), 510 bytes | 0 bytes/s, done.<br />
Total 5 (delta 0), reused 0 (delta 0)<br />
To git@github.com:colder-is-better/theProject.git<br />
   668b627..ff0d768  master -&gt; master<br />
Branch master set up to track remote branch master from test-rr.<br />

Από έναν web browser, πηγαίνετε αν θέλετε στο URL του απομακρυσμένου repository και βεβαιωθείτε ότι οι προσθήκες/αλλαγές έχουν ανέβει.

Μετά το push στο GitHub, τα περιεχόμενα του απομακρυσμένου αποθετηρίου έχουν αυξηθεί κατά 100% (μιλάμε, δηλαδή, για 2 αρχεία αντί για 1 :D) Παρατηρήστε και τα μηνύματα των commits, τα οποία κάναμε τοπικά.

Μετά το push στο GitHub, τα περιεχόμενα του απομακρυσμένου αποθετηρίου έχουν αυξηθεί κατά 100% (μιλάμε, δηλαδή, για 2 αρχεία αντί για 1 :D) Παρατηρήστε και τα μηνύματα των commits, τα οποία κάναμε τοπικά.

Η συνέχεια
Θέλουμε να πιστεύουμε ότι τα VCS γενικότερα –και βεβαίως το Git ειδικότερα– έχουν κερδίσει το ενδιαφέρον σας. Τα δύο άρθρα του μίνι αφιερώματός μας δεν είναι παρά μια εισαγωγή σ’ αυτόν τον συναρπαστικό κόσμο, με τα εξαιρετικά χρήσιμα εργαλεία που αλλάζουν και βελτιώνουν τον τρόπο εργασίας μας. Θα έχουμε την ευκαιρία να επανέλθουμε στο Git, ξεκινώντας με τη δημιουργία ενός static site που θα τελεί υπό την εποπτεία του δημοφιλούς αυτού κατανεμημένου VCS. Εσείς, βέβαια, δεν χρειάζεται να μας περιμένετε για να ξεκινήσετε με τους πειραματισμούς σας. Στοιχηματίζουμε μάλιστα ότι αρκετοί θα σπεύσετε να φέρετε το Git στο καθημερινό σας workflow, όπως λένε και στο Λευκαντί Ευβοίας.

Καλή σας συνέχεια — και καλή σας διασκέδαση.

Σας άρεσε το άρθρο; Αν ναι, τι θα λέγατε για ένα tip στο PayPal;

One Response to “Πρώτη γνωριμία κι εξάσκηση με το Git”

  1. ToPnt | 02/07/2017 at 22:10

    Θα ήταν ωραίο να μας έδειχνες πως μπορούμε να ρυθμίσουμε και το passwordless για το gitHub ( χωρίς δηλαδή να βάζουμε κωδικό κάθε φορά στο git ), πως το στέλνουμε στο gitHub και πως ίσος μπορούμε να το χρησιμοποιήσουμε και για διαφορετικούς λογαριασμούς.
    Αλλά τέλος πάντων..

Leave a Reply

You must be logged in to post a comment.

Σύνδεση

Αρχείο δημοσιεύσεων