-
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 Εντολές διοχέτευσης
7.5 Εργαλεία του Git - Αναζήτηση
Αναζήτηση
Με κώδικα σχεδόν κάθε μεγέθους, θα χρειαστεί συχνά να εντοπίσουμε πού καλείται ή ορίζεται μια συνάρτηση ή να βρούμε το ιστορικό μιας μεθόδου. Το Git παρέχει μερικά χρήσιμα εργαλεία για γρήγορη και εύκολη αναζήτηση στον κώδικα και τις υποβολές που είναι αποθηκευμένα στη βάση δεδομένων του. Θα δούμε κάποια από αυτά.
Η grep
του Git
Το Git συνοδεύεται από μια εντολή που ονομάζεται grep
και μας επιτρέπει να αναζητούμε εύκολα μέσα σε οποιοδήποτε υποβεβλημένο δένδρο ή τον κατάλογο εργασίας μια συμβολοσειρά ή κανονική έκφραση (regular expression).
Για αυτά τα παραδείγματα, θα εξετάσουμε τον ίδιο τον πηγαίο κώδικα του Git.
Εκ προεπιλογής, θα εξετάσει τα αρχεία στον κατάλογο εργασίας μας.
Μπορούμε να περάσουμε την επιλογή -n
για να εκτυπώσουμε τους αριθμούς γραμμών όπου το Git βρήκε αντιστοίχιση.
$ git grep -n gmtime_r
compat/gmtime.c:3:#undef gmtime_r
compat/gmtime.c:8: return git_gmtime_r(timep, &result);
compat/gmtime.c:11:struct tm *git_gmtime_r(const time_t *timep, struct tm *result)
compat/gmtime.c:16: ret = gmtime_r(timep, result);
compat/mingw.c:606:struct tm *gmtime_r(const time_t *timep, struct tm *result)
compat/mingw.h:162:struct tm *gmtime_r(const time_t *timep, struct tm *result);
date.c:429: if (gmtime_r(&now, &now_tm))
date.c:492: if (gmtime_r(&time, tm)) {
git-compat-util.h:721:struct tm *git_gmtime_r(const time_t *, struct tm *);
git-compat-util.h:723:#define gmtime_r git_gmtime_r
Υπάρχουν πολλές ενδιαφέρουσες επιλογές που μπορούμε να δώσουμε στην εντολή grep
.
Για παράδειγμα, αντί για την προηγούμενη κλήση, μπορούμε να βάλουμε το Git να συνοψίζει την έξοδο, δείχνοντας ακριβώς σε ποια αρχεία βρέθηκαν αντιστοιχίσεις και πόσες αντιστοιχίσεις βρέθηκαν σε κάθε αρχείο με την επιλογή --count
:
$ git grep --count gmtime_r
compat/gmtime.c:4
compat/mingw.c:1
compat/mingw.h:1
date.c:2
git-compat-util.h:2
Αν θέλουμε να δούμε σε ποια μέθοδο ή συνάρτηση πιστεύει ότι έχει βρει μία αντιστοίχιση, μπορούμε να περάσουμε την επιλογή -p
:
$ git grep -p gmtime_r *.c
date.c=static int match_multi_number(unsigned long num, char c, const char *date, char *end, struct tm *tm)
date.c: if (gmtime_r(&now, &now_tm))
date.c=static int match_digit(const char *date, struct tm *tm, int *offset, int *tm_gmt)
date.c: if (gmtime_r(&time, tm)) {
Έτσι, εδώ βλέπουμε ότι η gmtime_r
καλείται στις match_multi_number
και match_digit
στο αρχείο date.c
.
Μπορούμε επίσης να αναζητήσουμε σύνθετους συνδυασμούς συμβολοσειρών με την επιλογή --and
, που διασφαλίζει ότι υπάρχουν πολλαπλές αντιστοιχίσεις βρίσκονται στην ίδια γραμμή.
Για παράδειγμα, ας αναζητήσουμε τις γραμμές που ορίζουν μια σταθερά με τις συμβολοσειρές LINK
ή BUF_MAX
σε αυτές στη βάση του κώδικα του Git σε μια παλαιότερη έκδοση, την 1.8.0.
Εδώ θα χρησιμοποιήσουμε επίσης τις επιλογές --break
και --head
που βοηθούν στον διαχωρισμό της εξόδου σε πιο ευανάγνωστη μορφή.
$ git grep --break --heading \
-n -e '#define' --and \( -e LINK -e BUF_MAX \) v1.8.0
v1.8.0:builtin/index-pack.c
62:#define FLAG_LINK (1u<<20)
v1.8.0:cache.h
73:#define S_IFGITLINK 0160000
74:#define S_ISGITLINK(m) (((m) & S_IFMT) == S_IFGITLINK)
v1.8.0:environment.c
54:#define OBJECT_CREATION_MODE OBJECT_CREATION_USES_HARDLINKS
v1.8.0:strbuf.c
326:#define STRBUF_MAXLINK (2*PATH_MAX)
v1.8.0:symlinks.c
53:#define FL_SYMLINK (1 << 2)
v1.8.0:zlib.c
30:/* #define ZLIB_BUF_MAX ((uInt)-1) */
31:#define ZLIB_BUF_MAX ((uInt) 1024 * 1024 * 1024) /* 1GB */
Η εντολή git grep έχει μερικά πλεονεκτήματα έναντι των κανονικών εντολών αναζήτησης όπως grep
και ack
.
Το πρώτο είναι ότι είναι πολύ γρήγορο, το δεύτερο είναι ότι μπορούμε να ψάξουμε μέσα σε οποιοδήποτε δέντρο στο Git, όχι μόνο στον κατάλογο εργασίας.
Όπως είδαμε στο παραπάνω παράδειγμα, αναζητήσαμε όρους σε μια παλαιότερη έκδοση του πηγαίου κώδικα Git, όχι στην έκδοση στην οποία βρισκόμαστε αυτήν τη στιγμή.
Αναζήτηση στο μητρώο του Git
Ίσως ψάχνουμε όιχ για το πού υπάρχει ένας όρος, αλλά πότε υπήρχε ή πότε εισήχθη.
Η εντολή git log
έχει πολλά ισχυρά εργαλεία για την εξεύρεση συγκεκριμένων υποβολών από το περιεχόμενο των μηνυμάτων τους ή ακόμη και από το περιεχόμενο των diff που εισάγουν.
Αν θέλουμε να μάθουμε, για παράδειγμα, πότε η σταθερά ZLIB_BUF_MAX
εισήχθη για πρώτη φορά, μπορούμε να πούμε στο Git να μας δείξει μόνο τις υποβολές που είτε πρόσθεσαν είτε αφαίρεσαν αυτήν τη συμβολοσειρά με την επιλογή -S
.
$ git log -SZLIB_BUF_MAX --oneline
e01503b zlib: allow feeding more than 4GB in one go
ef49a7a zlib: zlib can only process 4GB at a time
Αν κοιτάξουμε το diff αυτών των υποβολών μπορούμε να δούμε ότι η σταθερά εισήχθη στην ef49a7a
και τροποποιήθηκε στην e01503b
.
Αν χρειάζεται να είμαστε πιο συγκεκριμένοι, μπορούμε να παράσχουμε μια κανονική έκφραση για αναζήτηση με την επιλογή -G
.
Γραμμική αναζήτηση στο μητρώο
Μια άλλη αρκετά προηγμένη αναζήτηση στο μητρώο που είναι απίστευτα χρήσιμη είναι η γραμμική αναζήτηση στο ιστορικό.
Αυτή είναι μια αρκετά πρόσφατη προσθήκη και δεν είναι πολύ γνωστή, αλλά μπορεί να είναι πραγματικά χρήσιμη.
Καλείται με την επιλογή -L
στην git log
και θα μας δείξει το ιστορικό μιας συνάρτησης ή μιας γραμμής στον κώδικά μας.
Για παράδειγμα, αν θέλαμε να δούμε κάθε αλλαγή που έγινε στη συνάρτηση git_deflate_bound
στο αρχείο zlib.c
, θα μπορούσαμε να εκτελέσουμε git log -L :git_deflate_bound:zlib.c
.
Αυτήη εντολή θα προσπαθήσει να καταλάβει ποια είναι τα όρια αυτής της συνάρτησης και στη συνέχεια να ψάξει μέσα στο ιστορικό και θα μας δείξει κάθε αλλαγή που έγινε στη συνάρτηση σαν μια σειρά από επιθέματα από όταν η συνάρτηση δημιουργήθηκε για πρώτη φορά.
$ git log -L :git_deflate_bound:zlib.c
commit ef49a7a0126d64359c974b4b3b71d7ad42ee3bca
Author: Junio C Hamano <gitster@pobox.com>
Date: Fri Jun 10 11:52:15 2011 -0700
zlib: zlib can only process 4GB at a time
diff --git a/zlib.c b/zlib.c
--- a/zlib.c
+++ b/zlib.c
@@ -85,5 +130,5 @@
-unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
+unsigned long git_deflate_bound(git_zstream *strm, unsigned long size)
{
- return deflateBound(strm, size);
+ return deflateBound(&strm->z, size);
}
commit 225a6f1068f71723a910e8565db4e252b3ca21fa
Author: Junio C Hamano <gitster@pobox.com>
Date: Fri Jun 10 11:18:17 2011 -0700
zlib: wrap deflateBound() too
diff --git a/zlib.c b/zlib.c
--- a/zlib.c
+++ b/zlib.c
@@ -81,0 +85,5 @@
+unsigned long git_deflate_bound(z_streamp strm, unsigned long size)
+{
+ return deflateBound(strm, size);
+}
+
Αν το Git δεν μπορεί να καταλάβει πώς να αντιστοιχίσει κάποια συνάρτηση ή μέθοδο στη γλώσσα προγραμματισμού μας, μπορούμε επίσης να του δώσουμε μία κανονική έκφραση.
Για παράδειγμα, αυτό θα έκανε το ίδιο πράγμα: git log -L '/unsigned long git_deflate_bound/',/^}/:zlib.c
.
Θα μπορούσαμε επίσης να του δώσουμε ένα εύρος γραμμών ή έναν μοναδικό αριθμό γραμμής και θα είχαμε το ίδιο είδος εξόδου.