Git
Chapters ▾ 2nd Edition

2.2 Τα θεμελιώδη στοιχεία του Git - Καταχωρώντας αλλαγές στο αποθετήριο

Καταχωρώντας αλλαγές στο αποθετήριο

Έχετε λοιπόν ένα ολοκαίνουριο αποθετήριο Git και μια ενημερωμένη έκδοση των αρχείων του έργου. Η διαδικασία που θα ακολουθήσουμε είναι να κάνουμε μερικές αλλαγές στο έργο και να υποβάλλουμε ένα στιγμιότυπο από αυτές τις αλλαγές στο αποθετήριο κάθε φορά που θέλουμε να καταγράψουμε την εκάστοτε κατάσταση του έργου μας.

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

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

The lifecycle of the status of your files.
Figure 8. The lifecycle of the status of your files.

Ελέγχοντας την Κατάσταση των Αρχείων σας

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

$ git status
On branch master
nothing to commit, working directory clean

Το μήνυμα αυτό σημαίνει ότι έχετε ένα καθαρό κατάλογο εργασίας. Με άλλα λόγια, δεν υπάρχουν τροποποιημένα ή εντοπισμένα αρχεία. Επίσης δεν υπάρχουν ούτε μη εντοπισμένα αρχεία αλλιώς το Git θα τα είχε καταγράψει στο παραπάνω μήνυμα. Επίσης, η εντολή αυτή μας ενημερώνει σε ποιον κλάδο βρισκόμαστε καθώς και ότι δεν έχει αποκλίνει από τον αντίστοιχο κλάδο του διακομιστή. Προς το παρόν χρησιμοποιούμε τον κύριο κλάδο, “master”, ο οποίος είναι και ο προεπιλεγμένος. Θα αναφερθούμε πιο αναλυτικά στους κλάδους στο κεφάλαιο Διακλαδώσεις στο Git.

Έστω ότι έχουμε προσθέσει ένα νέο αρχείο στο έργο μας, ένα απλό αρχείο README. Αν το αρχείο αυτό δεν προυπήρχε και εκτελέσουμε την εντολή git status, θα δείτε το μη εντοπισμένο αρχείο σας ως εξής:

$ echo 'My Project' > README
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    README

nothing added to commit but untracked files present (use "git add" to track)

Βλέπουμε λοιπόν ότι το αρχείο README είναι μη εντοπισμένο καθώς βρίσκεται κάτω από την κατηγορία “Untracked files”. Ένα μη εντοπισμένο αρχείο ουσιαστικά σημαίνει ότι το Git βλέπει ένα αρχείο το οποίο δεν υπήρχε στο προηγούμενο στιγμιότυπο (την τελευταία φορά που υποβάλλατε αρχεία). Το Git δεν θα συμπεριλάβει το αρχείο αυτό στα επόμενα στιγμιότυπα που θα υποβάλλετε αν δεν το ζητήσετε ρητά. Αυτό γίνεται ώστε να μην συμπεριλάβετε κατά λάθος στο έργο σας αρχεία τα οποία δεν θέλατε, για παράδειγμα δυαδικά αρχεία. Στην περίπτωσή μας, θέλουμε να συμπεριλάβουμε το αρχείο README στο έργο μας οπότε πάμε να ενημερώσουμε το Git ώστε να το εντοπίσει.

Εντοπίζοντας Νέα Αρχεία

Για να εντοπίσει το Git ένα καινούριο αρχείο, χρησιμοποιούμε την εντολή git add. Ξεκινάμε τον εντοπισμό του αρχείου REAMDE με την εντολή:

$ git add README

Αν τώρα εκτελέσετε την εντολή για να δείτε την τρέχουσα κατάσταση του αποθετηρίου, θα δείτε ότι το αρχείο README είναι πλέον εντοπισμένο και καταχωρημένο ώστε να είναι έτοιμο να υποβληθεί:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README

Το αρχείο πλέον βρίσκεται κάτω από την κατηγορία “Changes to be committed” που σημαίνει ότι είναι καταχωρημένο. Αν σε αυτό το σημείο κάνετε υποβολή των αρχείων σας, η έκδοση του αρχείου README όταν εκτελέσατε την εντολή git add είναι αυτή που θα αποθηκευτεί στο στιγμιότυπο. Προηγουμένως κάναμε κάτι αντίστοιχο, εκτελέσαμε την εντολή git init ακολουθούμενη από git add (files). Με τον τρόπο αυτό ξεκινήσαμε τον εντοπισμό των αρχείων του καταλόγου. Η εντολή git add μπορεί να ακολουθείται είτε από ένα αρχείο είτε από έναν κατάλογο. Αν ακολουθείται από κατάλογο τότε η εντολή θα καταχωρήσει όλα τα αρχεία του συγκεκριμένου καταλόγου αναδρομικά.

Καταχωρώντας Τροποποιημένα Αρχεία

Πάμε λοιπόν να τροποποιήσουμε ένα αρχείο το οποίο είναι ήδη εντοπισμένο. Έστω ότι τροποποιήτε ένα ήδη εντοπισμένο αρχείο, το “CONTRIBUTING.md” και εκτελείτε την εντολή git status ξανά:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Το αρχείο “CONTRIBUTING.md” βρίσκεται κάτω από την κατηγορία “Changed but not staged for commit”, που σημαίνει ότι ένα ήδη εντοπισμένο αρχείο έχει τροποποιηθεί στο κατάλογο εργασίας αλλά δεν έχει καταχωρηθεί ακόμα. Για να το καταχωρήσουμε θα πρέπει να εκτελέσουμε την εντολή git add. Η εντολή git add έχει πολλές λειτουργίες: την χρησιμοποιείτε για να ξεκινήσετε τον εντοπισμό καινούριων αρχείων, για να καταχωρήσετε αρχεία αλλά και για άλλες λειτουργίες όπως το να σημειώσετε αρχεία που προέρχονται από συγκρούσεις συγχώνευσης (merge conflicts) ως επιλυμένα. Μπορείτε να σκεφτείτε την εντολή ως “πρόσθεσε αυτό το περιεχόμενο σε ό,τι υποβάλλεις την επόμενη φορά” αντί για “πρόσθεσε αυτό το αρχείο στο έργο”. Πάμε λοιπόν να εκτελέσουμε την εντολή git add για να καταχωρήσουμε το αρχείο`‘CONTRIBUTING.md’' και έπειτα να δούμε την τρέχουσα κατάσταση του αποθετηρίου:

$ git add CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Και τα δύο αρχεία πλέον είναι καταχωρημένα και θα συμπεριληφθούν στην επόμενη υποβολή στιγμιοτύπου. Στο σημείο αυτό, ας υποθέσουμε ότι θυμάστε μια μικρή αλλαγή που θέλετε να κάνετε στο αρχείο CONTRIBUTING.md πριν το υποβάλλετε. Αφού κάνετε την αλλαγή που θέλετε, είσαστε έτοιμοι για την υποβολή. Παρ' όλα αυτά ας εκτελέσουμε git status άλλη μια φορά:

$ vim CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Περίεργο ε; Το αρχείο CONTRIBUTING.md αναφέρεται πλέον ως καταχωρημένο αλλά και ως μη καταχωρημένο. Πως είναι αυτό δυνατόν? Αυτό που συμβαίνει είναι ότι το Git καταχωρεί ένα αρχείο ακριβώς όπως είναι την στιγμή που εκτελείτε την εντολή git add. Αν υποβάλλετε το στιγμιότυπο τώρα, η έκδοση του αρχείου CONTRIBUTING.md που υπήρχε όταν εκτελέσατε την εντολή git add είναι αυτή που θα συμπεριληφθεί στην υποβολή (και όχι η τωρινή έκδοση του αρχείου). Γενικά, αν τροποποιήσετε ένα αρχείο αφότου έχει εκτελέσει την εντολή git add, θα πρέπει να την εκτελέσετε ξανά ώστε να καταχωρήσετε την τελευταία έκσοτη του αρχείου:

$ git add CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README
    modified:   CONTRIBUTING.md

Σύντομη κατάσταση

Ενώ η εντολή git status μας δίνει αρκετά περιεκτική πληροφορία, είναι επίσης και πολύ μακροσκελής. Στο Git μπορείτε να δείτε και μια πιο σύντομη περιγραφή της κατάστασης του αποθετηρίου. Αν εκτελέσετε git status -s ή git status --short θα έχετε ένα πιο απλοποιημένο αποτέλεσμα.

$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt

Τα καινούργια αρχεία που δεν έχουν εντοπιστεί ακόμα συμβολίζονται με ??, τα καινούρια αρχεία που έχουν καταχωρηθεί με A, τα τροποποιημένα αρχεία με M κ.ο.κ. Το αποτέλεσμα της εντολής περιλαμβάνει δύο σύμβολα για το κάθε αρχείο. Το αριστερό σύμβολο υποδηλώνει ότι το αρχείο έχει καταχωρηθεί και το δεξί ότι έχει τροποποιηθεί. Για παράδειγμα, το αρχείο README είναι τροποιποιημένο στο κατάλογο εργασίας αλλά δεν έχει καταχωρηθεί ακόμα. Το αρχείο lib/simplegit.rb είναι τροποποιημένο και καταχωρημένο. Το αρχείο Rakefile από την άλλη έχει τροποποιηθεί, καταχωρηθεί, και τροποποιηθεί ξανά που σημαίνει ότι υπάρχουν κάποιες αλλαγές που έχουν καταχωρηθεί και κάποιες που δεν έχουν.

Αγνοώντας αρχεία

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

$ cat .gitignore
*.[oa]
*~

Η πρώτη γραμμή ενημερώνει το Git ώστε να αγνοεί όλα τα αρχεία που τελειώνουν σε “.o” ή “.a”. Η δεύτερη γραμμή ενημερώνει το Git ώστε να αγνοεί όλα τα αρχεία που τελειώνουν με τον χαρακτήρα της ισπανικής περισπωμένης (~), το οποίο χρησιμοποιείται από πολλούς επεξεργαστές κειμένου, όπως ο Emacs, για να δηλώσει τα προσωρινά αρχεία. Μπορείτε επίσεις να συμπεριλάβεται καταλόγους που περιλαμβάνουν αρχεία καταγραφής, προσωρινούς καταλόγους κ.ό.κ. Γενικά είναι καλή ιδέα να ρυθμίσετε το αρχείο .gitignore νωρίς ώστε να μην υποβάλλετε κατά λάθος αρχεία που δεν θέλετε να βρίσκονται στο αποθετήριο.

Οι κανόνες για τα μοτίβα που μπορείτε να δηλώσετε στο αρχείο .gitignore είναι οι εξής:

  • Οι κενές γραμμές ή οι γραμμές που ξεκινούν με # θα αγνοηθούν.

  • Μπορείτε να χρησιμοποιήσετε τα κλασικά μοτίβα για ονόματα αρχείων (glob patterns).

  • Μπορείτε να ξεκινήσετε τα μοτίβα σας με μια κάθετο (/) ώστε να αποφύγετε την αναδρομικότητα

  • Μπορείτε να τελειώσετε τα μοτίβα σας με μια κάθετο (/) ώστε να ορίσετε έναν κατάλογο.

  • Μπορείτε να αντιστρέψετε ένα μοτίβο χρησιμοποιώντας ένα θαυμαστικό (!) στην αρχή του.

Τα μοτίβα αυτά είναι σαν απλοποιημένες κανονικές εκφράσεις (regular expressions) που χρησιμοποιούν τα λειτουργικά συστήματα. Ένας αστερίσκος (*) αντιστοιχεί σε 0 ή περισσότερους χαρακτήρες. Το [abc] αντιστοιχεί σε οποιονδήποτε χαρακτήρα βρίσκεται μέσα στις αγκύλες. Το σύμβολο του αγγλικού ερωτηματικού (?) αντιστοιχεί σε έναν και μόνο χαρακτήρα. Αν οι αγκύλες περιέχουν 2 χαρακτήρες που μεταξύ τους χωρίζονται με παύλα ([0-9]) τότε αυτή η έκφραση αντιστοιχεί σε όλους τους χαρακτήρες που υπάρχουν μεταξύ των 2 χαρακτήρων (στην περίπτωσή μας, όλοι οι αριθμοί από το 0 μέχρι το 9). Μπορείτε επίσης να χρησιμοποιήσετε 2 αστερίσκους για να αντιστοιχίσετε εμφωλευμένους καταλόγους: η έκφραση a/**/z αντιστοιχεί στους καταλόγους a/z, a/b/z, a/b/c/z κ.ό.κ.

Ας δούμε άλλο ένα παράδειγμα ενός αρχείου .gitignore:

# no .a files
*.a

# but do track lib.a, even though you're ignoring .a files above
!lib.a

# only ignore the TODO file in the current directory, not subdir/TODO
/TODO

# ignore all files in the build/ directory
build/

# ignore doc/notes.txt, but not doc/server/arch.txt
doc/*.txt

# ignore all .pdf files in the doc/ directory
doc/**/*.pdf
Tip

Αν θέλετε κάποια παραδείγματα για να ξεκινήσετε, το GitHub συντηρεί μια λίστα με παραδείγματαα αρχείων .gitignore για πολλές γλώσσες προγραμματισμού στην διεύθυνση https://github.com/github/gitignore.

Βλέποντας τις καταχωρημένες και μη αλλαγές

Αν η εντολή git status είναι πολύ αόριστη για εσάς και θέλετε να δείτε ακριβώς τι έχετε αλλάξει (και όχι μόνο ποια αρχεία έχουν αλλάξει), μπορείτε να χρησιμοποιήσετε την εντολή git diff. Θα καλύψουμε την εντολή αυτή πιο αναλυτικά αργότερα, αλλά θα την χρησιμοποιείτε συχνά για να απαντήσετε σε 2 ερωτήσεις: Τι έχετε αλλάξει και δεν έχετε καταχωρήσει ακόμα; Και επίσης, τι έχετε καταχωρήσει που είναι έτοιμο για να υποβληθεί; Ενώ η εντολή git status απαντά σε αυτές τις ερωτήσεις πολύ γενικά, απαριθμώντας τα ονόματα των αρχείων, η εντολή git diff θα σας δείξει ακριβώς ποιες γραμμές προστέθηκαν ή αφαιρέθηκαν.

Έστω λοιπόν ότι επεξεργάζεστε και καταχωρείτε το αρχείο README και μετά επεξεργάζεστε το αρχείο CONTRIBUTING.md χωρίς να το καταχωρήσετε. Αν τώρα εκτελέσετε την εντολή git status, θα δείτε κάτι τέτοιο:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Για να δείτε τι έχετε αλλάξει αλλά δεν έχετε καταχωρήσει ακόμα, πληκτρολογήστε git diff:

$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that it's

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

Αν θέλετε να δείτε τι έχετε καταχωρήσει μέχρι τώρα, που θα είναι και μέρος της επόμενης υποβολής, μπορείτε να χρησιμοποιήσετε την εντολή git diff --staged. Η εντολή αυτή συγκρίνει τις καταχωρημένες αλλαγές με την τελευταία υποβολή:

$ git diff --staged
diff --git a/README b/README
new file mode 100644
index 0000000..03902a1
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+My Project

Είναι σημαντικό να σημειώσουμε ότι η εντολή git diff από μόνη της δεν μας εμφανίζει τις αλλαγές που έγιναν από την τελευταία υποβολή, παρά μόνο τις αλλαγές που δεν έχουν ακόμα καταχωρηθεί. Το γεγονός αυτό μπορεί να προκαλεί σύγχυση καθώς για παράδειγμα αν έχετε καταχωρήσει όλες σας τις αλλαγές, η εντολή git diff δεν θα σας επιστρέψει κάποιο αποτέλεσμα.

Για να καταλάβουμε καλύτερα την χρήση της εντολής αυτής, ας δούμε άλλο ένα παράδειγμα. Έστω ότι έχουμε ένα αρχείο CONTRIBUTING.md που έχουμε ήδη καταχωρήσει, και έπειτα το έχουμε τροποποιήσει. Μπορούμε να χρησιμοποιήσουμε την εντολή git diff για να δούμε ποιες ακριβώς αλλαγές του αρχείου έχουν καταχωρηθεί και ποιες όχι. Αν λοιπόν το περιβάλλον εργασίας μας είναι κάπως έτσι:

$ git add CONTRIBUTING.md
$ echo '# test line' >> CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   CONTRIBUTING.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Μπορούμε να χρησιμοποιήσουμε την εντολή git diff για να δούμε τι δεν έχει καταχωρηθεί ακόμα

$ git diff
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 643e24f..87f08c8 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -119,3 +119,4 @@ at the
 ## Starter Projects

 See our [projects list](https://github.com/libgit2/libgit2/blob/development/PROJECTS.md).
+# test line

καθώς και την εντολή git diff --cached για να δούμε τι έχει καταχωρηθεί μέχρι τώρα (τα --staged και --cached είναι συνώνυμα):

$ git diff --cached
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 8ebb991..643e24f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -65,7 +65,8 @@ branch directly, things can get messy.
 Please include a nice description of your changes when you submit your PR;
 if we have to read the whole diff to figure out why you're contributing
 in the first place, you're less likely to get feedback and have your change
-merged in.
+merged in. Also, split your changes into comprehensive chunks if your patch is
+longer than a dozen lines.

 If you are starting to work on a particular area, feel free to submit a PR
 that highlights your work in progress (and note in the PR title that it's
Note
Χρησιμοποιώντας την εντολή Git Diff μέσω άλλου προγράμματος

Θα συνεχίσουμε να χρησιμοποιούμε την εντολή git diff με διάφορους τρόπους στο βιβλίο. Αν όμως προτιμάτε να βλέπετε τις διαφορές μεταξύ των αρχείων με κάποιο γραφικό εργαλείο (και όχι μέσα από την γραμμή εντολών), υπάρχει και άλλος τρόπος. Αν εκτελέσετε την εντολή git difftool αντί για git diff μπορείτε να δείτε τις διαφορές των αρχείων με προγράμματα όπως τα Araxis, emerge, vimdiff και άλλα. Δοκιμάστε να εκτελέσετε την εντολή git difftool --tool-help για να δείτε τι προγράμματα είναι διαθέσιμα για το σύστημά σας.

Υποβάλλοντας τις αλλαγές σας

Τώρα που η περιοχή καταχώρησης περιέχει τις αλλαγές που θέλετε, είσαστε έτοιμοι να τις υποβάλλετε. Θυμηθείτε ότι όλα τα μη καταχωρημένα αρχεία, δηλαδή όσα αρχεία έχετε δημιουργήσει ή τροποποιήσει και για τα οποία δεν εκτελέσατε την εντολή git add, δεν θα συμπεριληφθούν σε αυτή την υποβολή. Αντί γι αυτό, θα παραμείνουν ως τροποποιημένα αρχεία στον δίσκο σας. Στην περίπτωσή μας, έστω ότι έχουμε εκτελέσει την εντολή git status και βλέπουμε ότι όλες οι αλλαγές που θέλουμε είναι καταχωρημένες. Είμαστε έτοιμοι πλέον να υποβάλλουμε τις αλλαγές μας. Ο πιο απλός τρόπος για να υποβάλλετε αλλαγές είναι να πληκτρολογήσετε git commit:

$ git commit

Με την εντολή αυτή θα εκκινήσετε τον προεπιλεγμένο επεξεργαστή κειμένου. Αυτός είναι καθορισμένος από την μεταβλητή περιβάλλοντος (environment variable) $EDITOR της γραμμής εντολών, συνήθως είναι το vim ή το emacs. Παρ' όλα αυτά μπορείτε να χρησιμοποιήσετε την εντολή git config --global core.editor ώστε να χρησιμοποιήσετε τον επεξεργαστή κειμένου της αρεσκείας σας, όπως είδαμε στο κεφάλαιο Ξεκινώντας.

Ο επεξεργαστής κειμένου θα σας εμφανίσει το παρακάτω κείμενο (στο παράδειγμά μας χρησιμοποιούμε το Vim):

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#	new file:   README
#	modified:   CONTRIBUTING.md
#
~
~
~
".git/COMMIT_EDITMSG" 9L, 283C

Βλέπετε ότι το προεπιλεγμένο μήνυμα υποβολής περιέχει το τελευταίο αποτέλεσμα της ενοτλής git status μέσα σε σχόλια (οι γραμμές που ξεκινούν με την δίεση, #, αποτελούν σχόλια) και μια κενή γραμμή στην αρχή. Μπορείτε να αφαιρέσετε τα σχόλια αυτά και να γράψετε το δικό σας μήνυμα υποβολής ή να τα αφήσετε ως έχουν ώστε να σας βοηθήσουν αργότερα να θυμηθείτε ποι αρχεία υποβάλλετε. (Για να έχετε μια ακόμα πιο ρητή υπενθύμιση των αλλαγών που έχετε κάνει, μπορείτε να χρησιμοποιήσετε την επιλογή -v στην εντολή git commit. Με τον τρόπο αυτό, θα εισάγετε τις αλλαγές σας στον επεξεργαστή κειμένου ώστε να δείτε ακριβώς ποιες αλλαγές θα υποβάλλετε.) Αφού κλείσετε τον επεξεργαστή κειμένου, το Git θα δημιουργήσει την υποβολή σας με το παραπάνω μήνυμα (τα σχόλια θα αφαιρεθούν).

Εναλλακτικά, μπορείτε να γράψετε το μήνυμα υποβολής σας μαζί με την εντολή commit, χρησιμοποιώντας την επιλογή -m ως εξής:

$ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
 2 files changed, 2 insertions(+)
 create mode 100644 README

Μόλις κάνατε την πρώτη σας υποβολή! Βλέπετε ότι η υποβολή αυτή σας έχει δώσει κάποιες πληροφορίες: τον κλάδο στον οποίο υποβάλλατε τις αλλαγές σας (master στην περίπτωσή μας), το SHA-1 άθροισμα ελέγχου (SHA-1 checksum) της υποβολής (463dc4f), πόσα αρχεία αλλάξατε, καθώς και στατιστικά για το πόσες γραμμές προσθέσατε και αφαιρέσατε στην υποβολή αυτή.

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

Παραλείποντας την περιοχή καταχώρησης

Παρ' όλο που η περιοχή καταχώρησης είναι πολύ χρήσιμη για να διαμορφώνετε τις υποβολές σας ακριβώς όπως θέλετε, κάποιες φορές είναι πιο περίπλοκη από όσο χρειάζεστε για την εργασία σας. Αν θέλετε να παραλείψετε την περιοχή καταχώρησης, το Git παρέχει μια απλή συντόμευση. Προσθέτοντας την επιλογή -a στην εντολή git commit κάνει το Git να καταχωρεί αυτόματα κάθε αρχείο το οποίο είναι ήδη εντοπισμένο πριν κάνετε την υποβολή. Με αυτόν τον τρόπο μπορείτε να παραλείψετε την εντολή git add:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

no changes added to commit (use "git add" and/or "git commit -a")
$ git commit -a -m 'added new benchmarks'
[master 83e38c7] added new benchmarks
 1 file changed, 5 insertions(+), 0 deletions(-)

Παρατηρήστε πως στην περίπτωση αυτή, δεν έχετε να εκτελέσετε την εντολή git add στο αρχείο “CONTRIBUTING.md” πριν κάνετε την υποβολή σας.

Αφαιρώντας αρχεία

Για να αφαιρέσετε ένα αρχείο από το Git, θα πρέπει να το αφαιρέσετε από τη λίστα με τα εντοπισμένα αρχεία (ή πιο σωστά, να το αφαιρέσετε από την περιοχή καταχώρησης) και έπειτα να το υποβάλλετε. Αυτό πραγματοποιείτε με την εντολή git rm, η οποία επίσης θα αφαιρέσει το αρχείο από τον κατάλογο εργασίας σας έτσι ώστε να μην το έχετε ως μη εντοπισμένο αρχείο.

Αν απλά αφαιρέσετε το αρχείο από τον κατάλογο εργασίας σας, θα εμφανίζεται κάτω από την κατηγορία “Changed but not updated” (που ουσιαστικά σημαίνει μη καταχωρημένο) του αποτελέσματος της εντολής git status:

$ rm PROJECTS.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    PROJECTS.md

no changes added to commit (use "git add" and/or "git commit -a")

Έπειτα η εντολή git rm θα καταχωρήσει την αφαίρεση του αρχείου:

$ git rm PROJECTS.md
rm 'PROJECTS.md'
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    PROJECTS.md

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

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

$ git rm --cached README

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

$ git rm log/\*.log

Προσέξτε την ανάποδη κάθετο (\) μπροστά από τον αστερίσκο, *. Αυτή είναι απαραίτητη επειδή το Git χρησιμοποιεί τον δικό του τρόπο ώστε να επεκτείνει το όνομα των αρχείων, επιπροσθέτως του τρόπου που χρησιμοποιεί η γραμμή εντολών σας. Η παραπάνω εντολή αφαιρεί όλα τα αρχεία που έχουν την κατάληξη .log στον κατάλογο log/. Επίσης, θα μπορούσατε να κάνετε κάτι τέτοιο:

$ git rm \*~

Η εντολή αυτή αφαιρεί όλα τα αρχεία που τελειώνουν με τον χαρακτήρα ~.

Μετακινώντας αρχεία

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

Έτσι, είναι λίγο περίπλοκο το γεγονός ότι το Git έχει την εντολή mv. Αν θέλετε να μετονομάσετε ένα αρχείο στο Git, μπορείτε να το κάνετε κάπως έτσι

$ git mv file_from file_to

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

$ git mv README.md README
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Η εντολή αυτή όμως, είναι ισοδύναμη με το να εκτελέσετε κάτι τέτοιο:

$ mv README.md README
$ git rm README.md
$ git add README

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