Git
Chapters ▾ 2nd Edition

2.3 Τα θεμελιώδη στοιχεία του Git - Χρησιμοποιώντας το ιστορικό υποβολών

Χρησιμοποιώντας το ιστορικό υποβολών

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

Τα παρακάτω παραδείγματα χρησιμοποιούν ένα πολύ απλό έργο που το ονομάζουμε simplegit. Για να αποκτήσουμε το έργο, μπορούμε να εκτελέσουμε:

git clone https://github.com/schacon/simplegit-progit

Έπειτα, εκτελώντας την εντολή git log σε αυτό το έργο, θα λάβουμε ένα αποτέλεσμα που θα μοιάζει κάπως έτσι:

$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

Εκ προεπιλογής, η εντολή git log καταγράφει όλες τις υποβολές που έχουν γίνει στο αποθετήριο σε αντίθετη χρονολογική σειρά (οι πιο πρόσφατες υποβολές εμφανίζονται πρώτες). Όπως μπορούμε να δούμε, η εντολή καταγράφει κάθε υποβολή μαζί με το άθροισμα ελέγχου SHA-1, το όνομα και την ηλεκτρονική διεύθυνση του δημιουργού, την ημερομηνία εγραφής, καθώς και το μήνυμα της υποβολής.

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

Μια από τις πιο χρήσιμες επιλογές είναι η -p, η οποία δείχνει τη διαφορά που εισήχθη σε κάθε υποβολή. Μπορούμε επίσης να χρησιμοποιήσουμε την -2, η οποία θα περιορίσει το αποτέλεσμα στις δύο μόνο τελευταίες εγγραφές (υποβολές):

$ git log -p -2
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

diff --git a/Rakefile b/Rakefile
index a874b73..8f94139 100644
--- a/Rakefile
+++ b/Rakefile
@@ -5,7 +5,7 @@ require 'rake/gempackagetask'
 spec = Gem::Specification.new do |s|
     s.platform  =   Gem::Platform::RUBY
     s.name      =   "simplegit"
-    s.version   =   "0.1.0"
+    s.version   =   "0.1.1"
     s.author    =   "Scott Chacon"
     s.email     =   "schacon@gee-mail.com"
     s.summary   =   "A simple gem for using Git in Ruby code."

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index a0a60ae..47c6340 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -18,8 +18,3 @@ class SimpleGit
     end

 end
-
-if $0 == __FILE__
-  git = SimpleGit.new
-  puts git.show
-end
\ No newline at end of file

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

$ git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

 Rakefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

 lib/simplegit.rb | 5 -----
 1 file changed, 5 deletions(-)

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

 README           |  6 ++++++
 Rakefile         | 23 +++++++++++++++++++++++
 lib/simplegit.rb | 25 +++++++++++++++++++++++++
 3 files changed, 54 insertions(+)

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

Μια ακόμα χρήσιμη επιλογή είναι η --pretty. Η επιλογή αυτή αλλάζει το αποτέλεσμα της εντολής δίνοντάς του διαφορετική μορφή. Υπάρχουν μερικές προυπάρχουσες τιμές για να χρησιμοποιήσουμε για αυτήν την επιλογή. Η τιμή oneline εκτυπώνει κάθε υποβολή σε μία γραμμή, κάτι το οποίο μπορεί να μας φανεί χρήσιμο αν ψάχνουμε σε πολλές υποβολές. Επιπλέον, οι τιμές short, full, και fuller εμφανίζουν το ίδιο αποτέλεσμα σε παρόμοια μορφή αλλά με λιγότερες ή περισσότερες πληροφορίες αντίστοιχα:

$ git log --pretty=oneline
ca82a6dff817ec66f44342007202690a93763949 changed the version number
085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 removed unnecessary test
a11bef06a3f659402fe7563abf99ad00de2209e6 first commit

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

$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 6 years ago : changed the version number
085bb3b - Scott Chacon, 6 years ago : removed unnecessary test
a11bef0 - Scott Chacon, 6 years ago : first commit

Ο πίνακας Χρήσιμες επιλογές για την git log --pretty=format παραθέτει μερικές από τις πιο χρήσιμες επιλογές μορφοποίησης.

Table 1. Χρήσιμες επιλογές για την git log --pretty=format
Επιλογή Περιγραφή εξόδου

%H

Αριθμός SHA-1 υποβολής

%h

Συντμημένος αριθμός SHA-1 υποβολής

%T

Αριθμός SHA-1 δέντρου

%t

Συντμημένος αριθμός SHA-1 δέντρου

%P

Αριθμοί SHA-1 γονέων

%p

Συντμημένοι αριθμός SHA-1 γονέων

%an

Όνομα συγγραφέα

%ae

E-mail συγγραφέα

%ad

Ημερομηνία συγγραφέα (σε μορφή που ορίζεται από την επιλογή --date=)

%ar

Ημερομηνία συγγραφέα, σχετική

%cn

Όνομα υποβάλλοντος

%ce

E-mail υποβάλλοντος

%cd

Ημερομηνία υποβολής

%cr

Ημερομηνία υποβολής, σχετική

%s

Θέμα

Σε αυτό το σημείο, θα αναρωτιόταν κανείς ποια η διαφορά μεταξύ του author (δημιουργού, συγγραφέα) και του committer (αυτός που έκανε την υποβολή). Ο δημιουργός είναι το πρόσωπο που έγραψε αρχικά τη δουλειά, ενώ o committer είναι αυτός που την υπέβαλε τελευταίος. Συνεπώς, αν στείλουμε ένα επίθεμα για ένα έργο και ένα άλλο πρόσωπο το υποβάλλει, θα πρέπει και οι δύο να πιστωθούμε τη δουλειά: εμείς ως ο δημιουργός και το άλλο πρόσωπο ως αυτός που την υπέβαλλε. Θα καλύψουμε τη διαφορά αυτή σε λίγο, στο κεφάλαιο Κατανεμημένο Git.

Οι επιλογές oneline και format είναι ιδιαίτερα χρήσιμες με μια άλλη επιλογή (πάντα για την εντολή log) που ονομάζεται --graph. Η επιλογή αυτή προσθέτει ένα μικρό παραστατικό γράφημα με χαρακτήρες ASCII που δείχνει το ιστορικό των κλάδων και των συγχωνεύσεων:

$ git log --pretty=format:"%h %s" --graph
* 2d3acf9 ignore errors from SIGCHLD on trap
*  5e3ee11 Merge branch 'master' of git://github.com/dustin/grit
|\
| * 420eac9 Added a method for getting the current branch.
* | 30e367c timeout code and tests
* | 5a09431 add timeout protection to grit
* | e1193f8 support for heads with slashes in them
|/
* d6016bc require time for xmlschema
*  11d191e Merge branch 'defunkt' into local

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

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

Table 2. Συνήθεςι επιλογές για την git log
Επιλογή Περιγραφή

-p

Δείξε το επίθεμα (patch) που εισήχθε σε κάθε υποβολή.

--stat

Δείξε στατιστικά σχετικά με τα αρχεία που τροποποιήθηκαν σε κάνε υποβολή.

--shortstat

Δείξε μόνον την τελευταία γραμμή από την επιλογή --stat, που δείχνει μόνο τον συνολικό αριθμό αρχείων που τροποποιήθηκαν και αριθμών που προστέθηκαν, αφαιρέθηκαν.

--name-only

Δείξε τη λίστα των αρχείων που τροποποιήθηκαν (μετά τις πληροφορίες για την υποβολή).

--name-status

Δείξε επιπλέον τη λίστα των αρχείων που επηρεάστηκαν με προσθήκη/τροποποίηση/διαγραφή πληροφοριών.

--abbrev-commit

Δείξε μόνο τους πρώτους χαρακτήρες από τους 40 του αθροίσματος ελέγχου SHA-1.

--relative-date

Δείξε τη σχετική ημερομηνία σε σχετική μορφή (π.χ., “2 weeks ago”) αντί για την πλήρη.

--graph

Δείξε ένα γράφημα ASCII του κλάδου και του ιστορικού συγχώνευσης δίπλα στην έξοδο του μητρώου.

--pretty

Δείξε τις υποβολές σε εναλλακτική μορφή· οι επιλογές είναι: oneline, short, full, fuller και format (στην οποία ορίζουμε τη δική μας μορφή).

Περιορίζοντας το αποτέλεσμα της log

Επιπλέον, η εντολή git log χρησιμοποιείται με πολλές επιλογές για περιορισμό των αποτελεσμάτων της. Οι επιλογές αυτές θα μας αφήσουν να δούμε μόνο ένα υποσύνολο των συνολικών υποβολών. Έχουμε ήδη δει μια τέτοια επιλογή, την -2, η οποία θα μας εμφανίσει τις δύο τελευταίες υποβολές μόνο. Στην πραγματικότητα, μπορούμε να χρησιμοποιήσουμε -<n>, όπου n είναι ένας ακέραιος που αντιστοιχεί στις τελευταίες n υποβολές. Στην πραγματικότητα, βέβαια, είναι σχετικά απίθανο να χρησιμοποιούμε αυτήν την επιλογή συχνά, καθώς το Git εκ προεπιλογής παροχετεύει την έξοδο σε έναν σελιδοποιητή οπότε βλέπουμε μόνο μια σελίδα με τα στοιχεία του μητρώου κάθε φορά.

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

$ git log --since=2.weeks

Η εντολή αυτή χρησιμοποιείται με πολλές διαφορετικές μορφές. Μπορούμε να προσδιορίσουμε για παράδειγμα μια συγκεκριμένη μέρα, "2008-01-15", ή μια σχετική μέρα όπως "2 years 1 day 3 minutes ago".

Μπορούμε επίσης να φιλτράρουμε τη λίστα με τις υποβολές με βάση κάποια κριτήρια. Η επιλογή --author μάς επιτρέπει να φιλτράρουμε με βάση έναν συγκεκριμένο δημιουργό. Η επιλογή --grep μας επιτρέπει να ψάξουμε για λέξεις-κλειδιά στα μηνύματα των υποβολών. (Ας σημειωθεί ότι αν θέλουμε να χρησιμοποιήσουμε και τις δύο παραπάνω επιλογές ταυτόχρονα, θα πρέπει να προσθέσουμε την επιλογή --all-match`)

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

$ git log -S όνομα_συνάρτησης

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

Στον πίνακα Επιλογές περιορισμού της εξόδου της git log καταγράφουμε κάποιες από τις επιλογές αυτές ώστε να έχουμε μια αναφορά.

Table 3. Επιλογές περιορισμού της εξόδου της git log
Επιλογή Περιγραφή

-(n)

Δείξε μόνον τις τελευταίες n υποβολές.

--since, --after

Περιόρισε τις υποβολές σε αυτές που έγιναν μετά από συγκεκριμένη ημερομηνία.

--until, --before

Περιόρισε τις υποβολές σε αυτές που έγιναν πριν από συγκεκριμένη ημερομηνία.

--author

Δείξε μόνο τις υποβολές στις οποίες το πεδιο author συμφωνεί με συγκεκριμένη συμβολοσειρά.

--committer

Δείξε μόνο τις υποβολές στις οποίες το πεδιο committer συμφωνεί με συγκεκριμένη συμβολοσειρά.

--grep

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

-S

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

Για παράδειγμα, αν θέλουμε να δούμε ποιες υποβολές τροποποίησαν αρχεία τεστ στο ιστορικό του πηγαίου κώδικα του Git από τον Junio Hamano και δεν αποτελούσαν συγχωνεύσεις, στον Οκτώβριο του 2008, μπορούμε να εκτελέσουμε κάτι τέτοιο:

$ git log --pretty="%h - %s" --author=gitster --since="2008-10-01" \
   --before="2008-11-01" --no-merges -- t/
5610e3b - Fix testcase failure when extended attributes are in use
acd3b9e - Enhance hold_lock_file_for_{update,append}() API
f563754 - demonstrate breakage of detached checkout with symbolic link HEAD
d1a43f2 - reset --hard/read-tree --reset -u: remove unmerged new paths
51a94af - Fix "checkout --track -b newbranch" on detached HEAD
b0ad11e - pull: allow "git pull origin $something:$current_branch" into an unborn branch

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