-
1. Ξεκινώντας με το Git
-
2. Τα θεμελιώδη στοιχεία του Git
-
3. Διακλαδώσεις στο Git
-
4. Το Git στον διακομιστή
- 4.1 Τα πρωτόκολλα
- 4.2 Εγκατάσταση του Git σε διακομιστή
- 4.3 Δημιουργία δημόσιου κλειδιού SSH
- 4.4 Στήσιμο του διακομιστή
- 4.5 Δαίμονες του Git
- 4.6 Έξυπνο HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Επιλογές φιλοξενίας από τρίτους
- 4.10 Ανακεφαλαίωση
-
5. Κατανεμημένο Git
-
6. GitHub
-
7. Εργαλεία του Git
- 7.1 Επιλογή αναθεώρησης
- 7.2 Διαδραστική εργασία με το στάδιο καταχώρισης
- 7.3 stash και clean
- 7.4 Υπογραφή της δουλειάς μας
- 7.5 Αναζήτηση
- 7.6 Η ιστορία ξαναγράφεται
- 7.7 Απομυθοποίηση της reset
- 7.8 Συγχωνεύσεις για προχωρημένους
- 7.9 Rerere
- 7.10 Αποσφαλμάτωση με το Git
- 7.11 Λειτουργικές υπομονάδες
- 7.12 Δεμάτιασμα δεδομένων
- 7.13 Replace
- 7.14 Αποθήκευση διαπιστευτηρίων
- 7.15 Ανακεφαλαίωση
-
8. Εξατομίκευση του Git
-
9. Το Git και άλλα συστήματα
- 9.1 Το Git ως πελάτης
- 9.2 Μετανάστευση στο Git
- 9.3 Ανακεφαλαίωση
-
10. Εσωτερική λειτουργία του Git
- 10.1 Διοχετεύσεις και πορσελάνες
- 10.2 Αντικείμενα του Git
- 10.3 Αναφορές του Git
- 10.4 Πακετάρισμα αρχείων
- 10.5 Τα refspec
- 10.6 Πρωτόκολλα μεταφοράς
- 10.7 Διατήρηση και ανάκτηση δεδομένων
- 10.8 Μεταβλητές περιβάλλοντος
- 10.9 Ανακεφαλαίωση
-
A1. Appendix A: Το Git σε άλλα περιβάλλοντα
- A1.1 Γραφικές διεπαφές
- A1.2 Το Git στο Visual Studio
- A1.3 Git στο Eclipse
- A1.4 Το Git στο Bash
- A1.5 Το Git στο Zsh
- A1.6 Το Git στο Powershell
- A1.7 Ανακεφαλαίωση
-
A2. Appendix B: Ενσωμάτωση του Git στις εφαρμογές μας
- A2.1 Γραμμή εντολών Git
- A2.2 Libgit2
- A2.3 JGit
-
A3. Appendix C: Εντολές Git
- A3.1 Ρύθμιση και διαμόρφωση
- A3.2 Λήψη και δημιουργία έργων
- A3.3 Βασική λήψη στιγμιοτύπων
- A3.4 Διακλάδωση και συγχώνευση
- A3.5 Κοινή χρήση και ενημέρωση έργων
- A3.6 Επιθεώρηση και σύγκριση
- A3.7 Αποσφαλμάτωση
- A3.8 Επιθέματα
- A3.9 Ηλεκτρονικό ταχυδρομείο
- A3.10 Εξωτερικά Συστήματα
- A3.11 Διοίκηση
- A3.12 Εντολές διοχέτευσης
8.2 Εξατομίκευση του Git - Γνωρίσματα του Git
Γνωρίσματα του Git
Κάποιες από αυτές τις ρυθμίσεις μπορούν επίσης να οριστούν για μια διαδρομή, οπότε το Git εφαρμόζει αυτές τις ρυθμίσεις μόνο για έναν υποκατάλογο ή ένα υποσύνολο αρχείων.
Αυτές οι ρυθμίσεις για συγκεκριμένες διαδρομές ονομάζονται ιδιότητες του Git και ορίζονται ούμε σε ένα αρχείο .gitattributes
σε έναν από τους καταλόγους μας (συνήθως τον ριζικό κατάλογο του έργου μας) ούμε στο αρχείο .git/info/attributes
, εάν δεν θέλουμε το αρχείο γνωρίσματων να υποβάλλεται με το έργο μας.
Με τα γνωρίσματα, μπορούμε να κάνουμε πράγματα όπως να ορίσουμε ξεχωριστές στρατηγικές συγχώνευσης για μεμονωμένα αρχεία ή καταλόγους στο έργο μας, να πούμε στο Git πώς να κάνουμε diff σε δυαδικά αρχεία ή να φιλτράρουμε περιεχόμενο φίλτρου Git πριν το εισάγουμε σε ή εξάγουμε από το Git. Σε αυτήν την ενότητα, θα μάθουμε μερικά από τα γνωρίσματα που μπορούμε να ορίσουμε στις διαδρομές μας στο Git και θα δούμε μερικά παραδείγματα για τον τρόπο χρήσης αυτού του χαρακτηριστικού στην πράξη.
Δυαδικά αρχεία
Ένα όμορφο τέχνασμα για το οποίο μπορούμε να χρησιμοποιήσουμε τα γνωρίσματα του Git είναι να λέμε στο Git ποια αρχεία είναι δυαδικά (σε περπτώσεις στις οποίες δεν μπορεί να το καταλάβει) και να του δώσουμε συγκεκριμένες οδηγίες για το πώς να χειριστεί αυτά τα αρχεία. Για παράδειγμα, ορισμένα αρχεία κειμένου ενδέχεται να δημιουργούνται από τον υπολογιστή και να μην μπορούμε να τα περάσουμε από το diff ενώ αντίθετα ορισμένα δυαδικά αρχεία ενδέχεται να μπορούν να περάσουν από το diff. Θα δούμε πώς μπορούμε να πούμε στο Git ποια είναι ποια.
Αναγνώριση δυαδικών αρχείων
Ορισμένα αρχεία μοιάζουν με αρχεία κειμένου, αλλά ουσιαστικά πρέπει να αντιμετωπίζονται ως δυαδικά δεδομένα.
Για παράδειγμα, τα έργα Xcode σε Mac περιέχουν ένα αρχείο που με κατάληξη .pbxproj
, το οποίο είναι βασικά ένα σύνολο δεδομένων JSON (μορφοποίηση κειμένου Javascript) γραμμένη στον δίσκο από το IDE, το οποίο καταγράφει τις ρυθμίσεις δημιουργίας κ.λπ.
Αν και είναι τεχνικά ένα αρχείο κειμένου (αποτελείται αποκλειστικά από χαρακτήρες κωδικοποιημένους με UTF-8), δεν θέλουμε να το αντιμετωπίζουμε ως τέτοιο, επειδή στην πραγματικότητα είναι πραγματικά μια μικρή βάση δεδομένων —δεν μπορούμε να συγχωνεύσουμε το περιεχόμενο εάν δύο άτομα το τροποποιήσουν και τα diff γενικά δεν είναι χρήσιμα.
Το αρχείο προορίζεται να χρησιμοποιηθεί από ένα μηχάνημα.
Στην ουσία, θέλουμε να αντιμετωπίζεται ως δυαδικό αρχείο.
Για να πούμε στο Git να μεταχειρίζεται όλα τα αρχεία pbxproj
ως δυαδικά δεδομένα, προσθέτουμε την ακόλουθη γραμμή στο αρχείο .gitattributes
:
*.pbxproj binary
Τώρα, το Git δεν θα προσπαθήσει να μετατρέψει ή να διορθώσει προβλήματα CRLF· ούτε θα προσπαθήσει να υπολογίσει ή να εκτυπώσει μία διαφορά diff για αλλαγές σε αυτό το αρχείο όταν εκτελούμε τις git show
ή git diff
στο έργο μας.
Diff σε δυαδικά αρχεία
Μπορούμε επίσης να χρησιμοποιήσουμε τη λειτουργικότητα των γνωρισμάτων του Git για να κάνουμε αποτελεσματικά diff δυαδικά αρχεία. Αυτό μπορούμε να το κάνουμε αυτό λέγοντας στο Git πώς να μετατρέψει τα δυαδικά μας δεδομένα σε κείμενο που μπορεί να συγκριθεί με το κανονικό diff.
Πρώτα, θα χρησιμοποιήσουμε αυτήν την τεχνική για να λύσουμε ένα από τα πιο ενοχλητικά προβλήματα που είναι γνωστά στην ανθρωπότητα: τον έλεγχο εκδόσεων σε αρχεία του Microsoft Word.
Όλοι γνωρίζουμε ότι το Word είναι ο πιο αποκρουστικός επεξεργαστής κειμένου που υπάρχει, αλλά παραδόξως, όλοι το χρησιμοποιούμε ακόμα.
Εάν θέλουμε να έχουμε έγγραφα του Word που υπόκεινται σε έλεγχο εκδόσεων, μπορούμε να τα ρίξουμε σε ένα αποθετήριο Git και να τα υποβάλλουμε κάθε τόσο· αλλά τι προσφέρει κάτι τέτοιο;
Εάν τρέξουμε την git diff
όπως συνήθως, βλέπουμε κάτι τέτοιο:
$ git diff
diff --git a/chapter1.docx b/chapter1.docx
index 88839c4..4afcb7c 100644
Binary files a/chapter1.docx and b/chapter1.docx differ
Δεν μπορούμε να συγκρίνουμε απευθείας δύο εκδόσεις αρχείων Word, εκτός κι αν μεταβούμε (checkout) σε αυτές και τα διαβάσουμε οι ίδιοι, σωστά;
Αποδεικνύεται ότι μπορούμε να το κάνουμε αρκετά καλά χρησιμοποιώντας τα γνωρίσματα του Git.
Τοποθετούμε την ακόλουθη γραμμή στο αρχείο .gitattributes
:
*.docx diff=word
Αυτό λέει στο Git ότι κάθε αρχείο που ταιριάζει με αυτό το μοτίβο (.docx
) πρέπει να χρησιμοποιεί το φίλτρο word
όταν προσπαθούμε να δούμε το diff του.
Τι είναι φίλτρο word
;
Πρέπει να το ρυθμίσουμε.
Εδώ θα ρυθίσουμε το Git να χρησιμοποιήσει το πρόγραμμα docx2txt
για να μετατρέπει τα έγγραφα του Word σε αναγνώσιμα αρχεία, τα οποία στη συνέχεια μπορούμε να τα κάνουμε diff.
Καταρχήν, θα χρειαστεί να εγκαταστήσουμε το docx2txt
· μπορούμε να το κατεβάσουμε από http://docx2txt.sourceforge.net.
Ακολουθούμε τις οδηγίες στο αρχείο INSTALL
για να το βάλουμε κάπου, όπου το κέλυφός μας μπορεί να το βρει.
Στη συνέχεια, θα γράψουμε ένα script wrapper για να μετατρέψουμε την έξοδο στη μορφή που αναμένει το Git.
Δημιουργούμε ένα αρχείο, κάπου στη διαδρομή μας, που ονομάζεται docx2txt
και προσθέτουμε αυτά τα περιεχόμενα:
#!/bin/bash
docx2txt.pl $1 -
Δεν ξεχνάμε να chmod a+x
αυτό το αρχείο.
Τέλος, μπορούμε να διαμορφώσουμε το Git για να χρησιμοποιήσουμε αυτό το script:
$ git config diff.word.textconv docx2txt
Τώρα το Git ξέρει ότι αν επιχειρήσει να κάνει μια διαφορά μεταξύ δύο στιγμιότυπων και οποιοδήποτε από τα αρχεία τελειώνει στο .docx
, θα πρέπει να τρέξει αυτά τα αρχεία μέσω του φίλτρου` word '', το οποίο ορίζεται ως το πρόγραμμα `docx2txt
.
Αυτό ουσιαστικά δημιουργεί ωραίες εκδόσεις κειμένου των αρχείων του Word πριν προσπαθήσει να τα κάνει diff.
Ακολουθεί ένα παράδειγμα: Το κεφάλαιο 1 αυτού του βιβλίου μετατράπηκε σε μορφή Word και υποβλήθηκε σε ένα αποθετήριο Git.
Στη συνέχεια προστέθηκε μια νέα παράγραφος.
Ας δούμε τι δείχνει η git diff
:
$ git diff
diff --git a/chapter1.docx b/chapter1.docx
index 0b013ca..ba25db5 100644
--- a/chapter1.docx
+++ b/chapter1.docx
@@ -2,6 +2,7 @@
Το κεφάλαιο αυτό ασχολείται με το πώς να ξεκινήσουμε με το Git.
Θα ξεκινήσουμε αναφέροντας μερικά πράγματα για την ιστορία των εργαλείων ελέγχου εκδόσεων, έπειτα θα προχωρήσουμε στο πώς μπορεί κάποιος να εγκαταστήσει το Git στον υπολογιστή του και τελικά πώς να το ρυθμίσει, ώστε να μπορεί να ξεκινήσει να το δουλεύει.
1.1. Σχετικά με τον έλεγχο εκδόσεων
Τι είναι ο έλεγχος εκδόσεων και γιατί πρέπει να μας απασχολεί; Ο έλεγχος εκδόσεων είναι ένα σύστημα το οποίο καταγράφει αλλαγές σε ένα αρχείο ή σε ένα σύνολο αρχείων έτσι ώστε να μπορούμε να ανακαλέσουμε συγκεκριμένες εκδόσεις. Στα παραδείγματα του βιβλίου, τα αρχεία που θα χρησιμοποιήσουμε για έλεγχο εκδόσεων θα είναι αρχεία πηγαίου κώδικα λογισμικού αν και στην πραγματικότητα, θα μπορούσαμε να χρησιμοποιήσουμε αρχεία οποιουδήποτε τύπου.
+Δοκιμή: 1, 2, 3.
Αν είμαστε γραφίστες ή σχεδιαστές ιστοσελίδων και θέλουμε να κρατήσουμε κάθε έκδοση μιας εικόνας ή μιας διάταξης (κάτι το οποίο είναι πολύ πιθανό) τότε ένα Σύστημα Ελέγχου Εκδόσεων (Version Control System - VCS) είναι μια πολύ σοφή επιλογή. Ένα τέτοιο σύστημα μάς επιτρέπει να επαναφέρουμε συγκεκριμένα αρχεία σε κάποια προγενέστερη κατάσταση, να επαναφέρουμε ακόμα και ολόκληρο έργο (project) σε προγενέστερη κατάσταση, να συγκρίνουμε αλλαγές με την πάροδο του χρόνου, να δούμε ποιος τροποποίησε τελευταίος κάτι που ενδεχομένως δημιουργεί κάποιο πρόβλημα, ποιος έθεσε ένα ζήτημα και άλλα πολλά. Η χρήση ενός συστήματος ελέγχου εκδόσεων σημαίνει επίσης ότι αν τα κάνουμε θάλασσα ή χάσουμε αρχεία, είναι εύκολο να τα ανακτήσουμε. Επιπλέον, όλες αυτές οι δυνατότητες προσφέρονται με πολύ μικρή επιβάρυνση.
1.1.1. Τοπικά συστήματα ελέγχου εκδόσεων
Η μέθοδος που επιλέγουν πολλοί για έλεγχο εκδόσεων αρχείων είναι να αντιγράφουν τα αρχεία σε ένα άλλο κατάλογο (πιθανότατα ένα χρονολογημένο κατάλογο αν είναι έξυπνοι).
Αυτή η προσέγγιση είναι πολύ κοινή επειδή είναι τόσο απλή, συγχρόνως όμως είναι και πολύ επιρρεπής σε λάθη. Είναι εύκολο να ξεχάσει κανείς σε ποιον κατάλογο βρίσκεται και να γράψει στο λάθος αρχείο ή να αντιγράψει σε αρχεία που δεν ήθελε.
Το Git με επιτυχία και συνοπτικά μας λέει ότι προσθέσαμε τη συμβολοσειρά Δοκιμή: 1, 2, 3.
, κάτι που είναι σωστό.
Δεν είναι τέλειο —οι αλλαγές μορφοποίησης δεν θα εμφανιστούν εδώ— αλλά πάντως λειτουργεί.
Ένα άλλο ενδιαφέρον πρόβλημα που μπορούμε να επιλύσουμε με αυτόν τον τρόπο περιλαμβάνει το diff αρχείων εικόνας.
Ένας τρόπος για να γίνει αυτό είναι να περάσουμε αρχεία εικόνας μέσα από ένα φίλτρο που εξάγει τις πληροφορίες EXIF —μεταδεδομένα που καταγράφονται με τις περισσότερες μορφές εικόνας.
Εάν κατεβάσουμε και εγκαταστήσουμε το πρόγραμμα exiftool
, μπορούμε να το χρησιμοποιήσουμε για να μετατρέψουμε τις εικόνες μας σε κείμενο σχετικά με τα μεταδεδομένα, οπότε τουλάχιστον το diff θα μας δείξει μια αναπαράσταση κειμένου οποιωνδήποτε αλλαγών συνέβησαν:
$ echo '*.png diff=exif' >> .gitattributes
$ git config diff.exif.textconv exiftool
Εάν αντικαταστήσουμε μια εικόνα στο έργο μας και εκτελέσουμε το git diff
, θα δούμε κάτι σαν αυτό:
diff --git a/image.png b/image.png
index 88839c4..4afcb7c 100644
--- a/image.png
+++ b/image.png
@@ -1,12 +1,12 @@
ExifTool Version Number : 7.74
-File Size : 70 kB
-File Modification Date/Time : 2009:04:21 07:02:45-07:00
+File Size : 94 kB
+File Modification Date/Time : 2009:04:21 07:02:43-07:00
File Type : PNG
MIME Type : image/png
-Image Width : 1058
-Image Height : 889
+Image Width : 1056
+Image Height : 827
Bit Depth : 8
Color Type : RGB with Alpha
Μπορούμε εύκολα να δούμε ότι το μέγεθος του αρχείου και οι διαστάσεις εικόνας έχουν αλλάξει.
Επέκταση λέξεων-κλειδιών
Η επέκταση λέξεων-κλειδιών τύπου SVN ή CVS είναι κάτι που το ζητούν συχνά προγραμματιστές που έχουν χρησιμοποιήσει αυτά τα συστήματα. Το κύριο πρόβλημα με αυτό στο Git είναι ότι δεν μπορούμε να τροποποιήσουμε ένα αρχείο με πληροφορίες σχετικά με την υποβολή, αφού έχουμε υποβάλει, επειδή το Git πρώτα ελέγχει αριθμητικά το αρχείο. Ωστόσο, μπορούμε να προσθέσουμε κείμενο σε ένα αρχείο όταν αυτό έχει ενημερωθεί και να το αφαιρέσουμε ξανά πριν προστεθεί σε μια υποβολή. Τα γνωρίσματα του Git μάς προσφέρουν δύο τρόπους για να το κάνουμε αυτό.
Καταρχάς, μπορούμε να εισάγουμε το άθροισμα ελέγχου SHA-1 ενός blob σε ένα πεδίο $Id$
στο αρχείο.
Αν ορίσουμε αυτό το γνώρισμα σε ένα αρχείο ή ένα σύνολο αρχείων, τότε την επόμενη φορά που θα μεταβούμε σε αυτόν τον κλάδο, το Git θα αντικαταστήσει αυτό το πεδίο με το SHA-1 του blob.
Είναι σημαντικό να τονίσουμε ότι δεν είναι το SHA-1 της υποβολής αλλά το ίδιο το blob:
$ echo '*.txt ident' >> .gitattributes
$ echo '$Id$' > test.txt
Την επόμενη φορά που θα ενημερώσουμε (checkout) αυτό το αρχείο, το Git χώσει το SHA-1 του blob:
$ rm test.txt
$ git checkout -- test.txt
$ cat test.txt
$Id: 42812b7653c7b88933f8a9d6cad0ca16714b9bb3 $
Ωστόσο, το αποτέλεσμα αυτό είναι περιορισμένης χρήσης. Κάποιος που έχει χρησιμοποιήσει αντικατάσταση λέξεων-κλειδιών σε CVS ή Subversion, μπορεί να συμπεριλάβει χρονική σήμανση —ο αριθμός SHA-1 δεν είναι και πολύ χρήσιμος, επειδή είναι αρκετά τυχαίος και δεν μπορούμε να διαπιστώσουμε αν ένας SHA-1 είναι παλαιότερος ή νεότερος απλά κοιτάζοντάς τους.
Αποδεικνύεται ότι μπορούμε να γράψουμε τα δικά μας φίλτρα για να κάνουμε αντικαταστάσεις στα αρχεία κατά την υποβολή ή ενημέρωση.
Αυτά ονομάζονται clean
(“καθαρίσματος”) και smudge
(“μουτζούρωματος”).
Στο αρχείο .gitattributes
, μπορούμε να ορίσουμε ένα φίλτρο για συγκεκριμένες διαδρομές και στη συνέχεια να ορίσουμε script που θα επεξεργάζονται αρχεία λίγο πριν από την ενημέρωσή (checkout) τους (“μουτζούρωμα”, βλ. Τα φίλτρα “μουτζουρώματος” τρέχουν στην ενημέρωση (checkout).) και ακριβώς πριν μπουν στο στάδιο καταχώρισης (βλ. Τα φίλτρα “καθαρίσματος” τρέχουν όταν τα αρχεία μπαίνουν στο στάδιο καταχώρισης.).
Αυτά τα φίλτρα μπορούν να ρυθμιστούν ώστε να κάνουν διάφορα είδη διασκέδασης.


Το αρχικό μήνυμα υποβολής για αυτό το χαρακτηριστικό παρέχει ένα απλό παράδειγμα εκτέλεσης όλου του πηγαίου κώδικα C μας μέσω του προγράμματος indent
πριν από την υποβολή.
Μπορούμε να το ρυθμίσουμε ορίζοντας στο φίλτρο γνωρισμάτων στο αρχείο .gitattributes
να φιλτράρει τα αρχεία *.c
με το φίλτρο ‘indent’:
*.c filter=indent
Στη συνέχεια, λέμε στο Git τι κάνει το φίλτρο indent
κατά το μουτζούρωμα και το καθάρισμα:
$ git config --global filter.indent.clean indent
$ git config --global filter.indent.smudge cat
Σε αυτήν την περίπτωση, όταν υποβάλλουμε αρχεία που ταιριάζουν με το *.c
, το Git θα τα περάσει μέσα από το indent
πριν τα βάλει στο στάδιο καταχώρισης και στη συνέχεια θα τα περάσει μέσα από το πρόγραμμα cat
προτού τα ενημερώσει (checkout) ξανά στον δίσκο.
Το πρόγραμμα cat
ουσιαστικά δεν κάνει τίποτα: βγάζει ως έξοδο τα ίδια δεδομένα που δέχεται ως είσοδο.
Αυτός ο συνδυασμός ουσιαστικά φιλτράρει όλα τα αρχεία πηγαίου κώδικα C μέσω του indent
πριν από την υποβολή.
Ένα άλλο ενδιαφέρον παράδειγμα είναι αυτό που κάνει την επέκταση λέξης-κλειδιού $Date$
, όπως στο RCS.
Για να γίνει αυτό σωστά, χρειαζόμαστε ένα μικρό script που παίρνει ένα όνομα αρχείου, βρίσκει την τελευταία ημερομηνία υποβολής για αυτό το έργο και εισάγει την ημερομηνία στο αρχείο.
Εδώ είναι ένα μικρό script Ruby που το κάνει αυτό:
#! /usr/bin/env ruby
data = STDIN.read
last_date = `git log --pretty=format:"%ad" -1`
puts data.gsub('$Date$', '$Date: ' + last_date.to_s + '$')
Αυτό που κάνει το script είναι να παίρνει την τελευταία ημερομηνία υποβολής από την εντολή git log
, να τη βάζει δίπλα σε όποια συμβολοσειρά $Date$
βλέπει στο stdin και να εκτυπώνει το αποτέλεσμα —θα πρέπει να είναι απλό να κάνουμε σε οποιαδήποτε γλώσσα έχουμε μεγαλύτερη αυτοπεποίθηση.
Μπορούμε να ονομάσουμε αυτό το αρχείο expand_date
και να το βάλουμε στη διαδρομή μας.
Τώρα πρέπει να ρυθμίσουμε ένα φίλτρο στο Git (ας το ονομάσουμε dater
) και να του πούμε να χρησιμοποιηεί το φίλτρο expand_date
για να μουτζουρώσει τα αρχεία κατά την ενημέρωσή τους (checkout).
Θα χρησιμοποιήσουμε μια εντολή Perl για να καθαρίσουμε την υποβολή:
$ git config filter.dater.smudge expand_date
$ git config filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"'
Αυτός ο κώδικας Perl διαγράφει ο,τιδήποτε βλέπει σε μια συμβολοσειρά $Date$
, για να επιστρέψουμε στο σημείο από το οποίο ξεκινήσαμε.
Τώρα που το φίλτρο μας είναι έτοιμο, μπορούμε να το δοκιμάσουμε φτιάχνοντας ένα αρχείο με τη λέξη κλειδί $Date$
και στη συνέχεια να ορίσουμε ένα γνώρισμα του Git για το συγκεκριμένο αρχείο που ενεργοποιεί το νέο φίλτρο:
$ echo '# $Date$' > date_test.txt
$ echo 'date*.txt filter=dater' >> .gitattributes
Εάν υποβάλλουμε αυτές τις αλλαγές και ενημερώσουμε (checkout) ξανά το αρχείο, θα δούμε τη λέξη-κλειδί να έχει αντικατασταθεί σωστά:
$ git add date_test.txt .gitattributes
$ git commit -m "Testing date expansion in Git"
$ rm date_test.txt
$ git checkout date_test.txt
$ cat date_test.txt
# $Date: Tue Apr 21 07:26:52 2009 -0700$
Είναι φανερό το πόσο ισχυρή είναι αυτή η τεχνική για εξατομικευμένες εφαρμογές.
Θα πρέπει όμως να είμαστε προσεκτικοί επειδή το αρχείο .gitattributes
υποβάλλεται και μεταφέρεται με το έργο, αλλά ο οδηγός (σε αυτήν την περίπτωση, το φίλτρο dater
) δεν υποβάλλεται ή μεταφέρεται, οπότε δεν θα λειτουργεί παντού.
Όταν σχεδιάζουμε αυτά τα φίλτρα, θα πρέπει να είναι σε θέση να αποτύχουν με χάρη και το έργο να εξακολουθεί να λειτουργεί σωστά.
Εξαγωγή του αποθετηρίου
Τα δεδομένα γνωρίσματων του Git μάς επιτρέπουν επίσης να κάνουμε μερικά ενδιαφέροντα πράγματα κατά την εξαγωγή μίας αρχειοθήκης (archive) του έργου μας.
export-ignore
Μπορούμε να πούμε στο Git να μην εξάγει συγκεκριμένα αρχεία ή καταλόγους κατά τη δημιουργία μίας αρχειοθήκης.
Αν υπάρχουν υποκατάλογοι ή αρχεία που δεν θέλουμε να συμπεριλάβουμε στην αρχειοθήκη αλλά θέλουμε να ελέγχονται στο έργο μας, μπορούμε να τα προσδιορίσουμε μέσω του γνωρίσματος export-ignore
.
Για παράδειγμα, ας πούμε ότι έχουμε κάποια δοκιμαστικά αρχεία σε έναν υποκατάλογο test/
και δεν έχει νόημα να τα συμπεριλάβουμε στην εξαγωγή ενός αρχείου tarball του έργου μας.
Μπορούμε να προσθέσουμε την ακόλουθη γραμμή στο αρχείο γνωρίσματων Git:
test/ export-ignore
Τώρα, όταν τρέχουμε αρχείο git για να δημιουργήσουμε ένα tarball του έργου μας, αυτός ο κατάλογος δεν θα συμπεριληφθεί στο αρχείο.
export-subst
Κατά την εξαγωγή αρχείων για ανάπτυξη (deployment), μπορούμε να εφαρμόσουμε τη μορφοποίηση της git log
και την επέκταση λέξεων-κλειδιών σε επιλεγμένα τμήματα αρχείων που σημειώνονται με το γνώρισμα export-subst
.
Για παράδειγμα, εάν θέλουμε να συμπεριλάβουμε ένα αρχείο με το όνομα LAST_COMMIT
στο έργο μας και να έχουμε μεταδεδομένα για την τελευταία υποβολή που εισάγεται αυτόματα σε αυτό όταν τρέχει η git archive
, μπορούμε π.χ. να ρυθμίσουμε το αρχείο ως εξής:
$ echo 'Last commit date: $Format:%cd by %aN$' > LAST_COMMIT
$ echo "LAST_COMMIT export-subst" >> .gitattributes
$ git add LAST_COMMIT .gitattributes
$ git commit -am 'adding LAST_COMMIT file for archives'
Όταν τρέχουμε την git archive
, τα περιεχόμενα του αρχειοθετημένου αρχείου θα μοιάζουν με αυτό:
$ git archive HEAD | tar xCf ../deployment-testing -
$ cat ../deployment-testing/LAST_COMMIT
Last commit date: Tue Apr 21 08:38:48 2009 -0700 by Scott Chacon
Οι αντικαταστάσεις είναι δυνατό να περιλαμβάνουν, για παράδειγμα, το μήνυμα υποβολής και οποιεσδήποτε σημειώσεις της git
και της git log
μπορεί να κάνει απλή αναδίπλωση λέξεων:
$ echo '$Format:Last commit: %h by %aN at %cd%n%+w(76,6,9)%B$' > LAST_COMMIT
$ git commit -am 'export-subst uses git log's custom formatter
git archive uses git log's `pretty=format:` processor
directly, and strips the surrounding `$Format:` and `$`
markup from the output.
'
$ git archive @ | tar xfO - LAST_COMMIT
Last commit: 312ccc8 by Jim Hill at Fri May 8 09:14:04 2015 -0700
export-subst uses git log's custom formatter
git archive uses git log's `pretty=format:` processor directly, and
strips the surrounding `$Format:` and `$` markup from the output.
Το αρχείο που προκύπτει είναι κατάλληλο για εργασία ανάπτυξης, αλλά όπως και οποιαδήποτε εξαγόμενη αρχειοθήκη, δεν είναι κατάλληλο για περαιτέρω εργασίες ανάπτυξης.
Στρατηγικές συγχώνευσης
Μπορούμε επίσης να χρησιμοποιήσουμε τα γνωρίσματα του Git για να πούμε στο Git να χρησιμοποιεί διαφορετικές στρατηγικές συγχώνευσης για συγκεκριμένα αρχεία στο έργο μας. Μια πολύ χρήσιμη επιλογή είναι να πούμε στο Git να μην προσπαθήσει να συγχωνεύσει συγκεκριμένα αρχεία όταν έχουν συγκρούσει, αλλά να χρησιμοποιήσει τις δικές μας αλλαγές σε βάρος αυτών κάποιου άλλου.
Αυτό είναι χρήσιμο εάν ένας κλάδος στο έργο μας έχει αποκλίνει ή είναι εξειδικευμένο, αλλά θέλουμε να μπορούμε να συγχωνεύουμε αλλαγές από αυτόν και θέλουμε να αγνοήσουμε ορισμένα αρχεία.
Ας υποθέσουμε ότι έχουμε ένα αρχείο ρυθμίσεων μίας βάσης δεδομένων που ονομάζεται database.xml
που διαφέρει σε δύο κλάδους και θέλουμε να συγχωνεύσουμε τον άλλο κλάδο μας χωρίς να ανακατώσουμε το αρχείο της βάσης δεδομένων.
Μπορούμε να ορίσουμε ένα γνώρισμα όπως αυτό:
database.xml merge=ours
Στη συνέχεια, ορίζουμε μια ψεύτικη στρατηγική συγχώνευσης ours
:
$ git config --global merge.ours.driver true
Εάν συγχωνευτούμε στον άλλο κλάδο, αντί να έχουμε συγκρούσεις συγχώνευσης στο αρχείο database.xml
, θα δούμε κάτι σαν αυτό:
$ git merge topic
Auto-merging database.xml
Merge made by recursive.
Σε αυτήν την περίπτωση, το database.xml
παραμένει σε οποιαδήποτε έκδοση έχουμε αρχικά.