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

Useful options for git log --pretty=format lists some of the more useful options that format takes.

Table 1. Useful options for git log --pretty=format
Option Description of Output

%H

Commit hash

%h

Abbreviated commit hash

%T

Tree hash

%t

Abbreviated tree hash

%P

Parent hashes

%p

Abbreviated parent hashes

%an

Author name

%ae

Author e-mail

%ad

Author date (format respects the --date=option)

%ar

Author date, relative

%cn

Committer name

%ce

Committer email

%cd

Committer date

%cr

Committer date, relative

%s

Subject

Σε αυτό το σημείο, μπορεί να αναρωτιέστε ποια η διαφορά μεταξύ του author (δημιουργού, συγγραφέα) και του committer (αυτός που έκανε την υποβολή). Ο δημιουργός είναι το πρόσωπο που έγραψε αρχικά την δουλειά, ενώ o committer είναι αυτός που την υπέβαλε τελευταίος. Συνεπώς, αν στείλετε μια επιδιόρθωση λογισμικού για ένα έργο και ένα άλλο πρόσωπο το υποβάλλει, θα πρέπει και οι δύο να πιστωθείτε την δουλειά: εσείς ως ο δημιουργός και το άλλο πρόσωπο ως αυτός που το υπέβαλλε. Θα καλύψουμε την διαφορά αυτή σε λίγο, στο κεφάλαιο Distributed 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, υπάρχουν και πολλές άλλες. Ο πίνακας Common options to git log καταγράφει όλες τις επιλογές που καλύψαμε μέχρι στιγμής, καθώς και κάποιες άλλες επιλογές διαμόρφωσης που μπορεί να σας φανούν χρήσιμες μαζί με μια περιγραφή της λειτουργίας τους.

Table 2. Common options to git log
Option Description

-p

Show the patch introduced with each commit.

--stat

Show statistics for files modified in each commit.

--shortstat

Display only the changed/insertions/deletions line from the --stat command.

--name-only

Show the list of files modified after the commit information.

--name-status

Show the list of files affected with added/modified/deleted information as well.

--abbrev-commit

Show only the first few characters of the SHA-1 checksum instead of all 40.

--relative-date

Display the date in a relative format (for example, “2 weeks ago”) instead of using the full date format.

--graph

Display an ASCII graph of the branch and merge history beside the log output.

--pretty

Show commits in an alternate format. Options include oneline, short, full, fuller, and format (where you specify your own 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 -Sfunction_name

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

Στον πίνακα Options to limit the output of git log καταγράφουμε κάποιες από τις επιλογές αυτές ώστε να έχετε μια αναφορά.

Table 3. Options to limit the output of git log
Option Description

-(n)

Show only the last n commits

--since, --after

Limit the commits to those made after the specified date.

--until, --before

Limit the commits to those made before the specified date.

--author

Only show commits in which the author entry matches the specified string.

--committer

Only show commits in which the committer entry matches the specified string.

--grep

Only show commits with a commit message containing the string

-S

Only show commits adding or removing code matching the string

Για παράδειγμα, αν θέλετε να δείτε ποιες υποβολές τροποποίησαν αρχεία τεστ στο ιστορικό του πηγαίου κώδικα του 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, η εντολη΄αυτή θα σας δείξει μόνο έξι που να ταιριάζουν με τα παραπάνω κριτήρια.