Chapters ▾ 2nd Edition

2.6 Τα θεμελιώδη στοιχεία του Git - Ετικέτες

Ετικέτες

Το Git, όπως και τα περισσότερα VCS, δίνει τη δυνατότητα να βάζουμε ετικέτες (tags) σε συγκεκριμένα σημεία του ιστορικού ενός έργου. Η λειτουργικότητα αυτή χρησιμοποείται συνήθως για σημειωθούν συγκεκριμένες εκδόσεις (π.χ. έκδοση 1.0, 2.0 κ.ο.κ.). Σε αυτή την ενότητα θα μάθουμε πώς να βλέπουμε ποιες ετικέτες έχει ένα έργο, πώς να δημιουργούμε ετικέτες και ποια είδη ετικετών υπάρχουν.

Παράθεση ετικετών

Για να δούμε τις ετικέτες ενός έργου, η εντολή στο Git είναι αρκετά απλή. Απλά πληκτρολογούμε git tag (και προαιρετικά -l ή --list):

$ git tag
v1.0
v2.0

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

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

$ git tag -l "v1.8.5*"
v1.8.5
v1.8.5-rc0
v1.8.5-rc1
v1.8.5-rc2
v1.8.5-rc3
v1.8.5.1
v1.8.5.2
v1.8.5.3
v1.8.5.4
v1.8.5.5
Note
Παράθεση ετικετών με χαρακτήρες υποκατάστασης απαιτεί την επιλογή -l ή --list

Αν θέλετε μόνο την πλήρη λίστα των ετικετών, τότε αν εκτελέσετε την εντολή git tag υποθέτει ότι θέλετε μια λίστα και την εμφανίζει· η χρήση του -l ή του --list σε αυτή την περίπτωση είναι προαιρετική.

Αν όμως δώσετε και ένα μοτίβο με χαρακτήρες υποκατάσταση (wildcards), τότε η χρήση ενός από τα -l ή --list είναι υποχρεωτική.

Δημιουργία ετικετών

Το Git χρησιμοποιεί δύο κατηγορίες ετικετών, τις απλές (lightweight) και τις ετικέτες με επισημείωση (annotated).

Μια απλή ετικέτα μοιάζει πολύ με έναν κλάδο που δεν αλλάζει· είναι απλά ένας δείκτης σε μια συγκεκριμένη υποβολή.

Οι ετικέτες με επισημειώσεις από την άλλη, αποθηκεύονται στη βάση δεδομένων του Git ως πλήρη αντικείμενα. Για καθεμία επισημειωμένη ετικέτα: υπολογίζεται το άθροισμα ελέγχου (checksum) της· περιέχει το όνομα, και τη διεύθυνση e-mail αυτού που βάζει την ετικέτα και την ημερομηνία· έχει ένα μήνυμα· μπορεί να υπογραφεί και να επαληθευθεί με τον GNU Privacy Guard (GPG). Γενικά συνιστάται να δημιουργούμε ετικέτες με επισημειώσεις (annotations) έτσι ώστε να έχουμε όλες αυτές τις πληροφορίες, αλλά αν για κάποιο λόγο θέλουμε μία προσωρινή ετικέτα ή μια ετικέτα χωρίς περαιτέρω πληροφορίες, μπορούμε να χρησιμοποιήσουμε τις απλές ετικέτες.

Επισημασμένες ετικέτες

Η δημιουργία επισημασμένων ετικετών είναι απλή. Ο ευκολότερος τρόπος είναι να χρησιμοποιήσουμε την επιλογή -a όταν εκτελούμε την εντολή tag:

$ git tag -a v1.4 -m "my version 1.4"
$ git tag
v0.1
v1.3
v1.4

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

Χρησιμοποιώντας την εντολή git show μπορούμε να δούμε τις πληροφορίες που περιέχει μια ετικέτα:

$ git show v1.4
tag v1.4
Tagger: Ben Straub <ben@straub.cc>
Date:   Sat May 3 20:19:12 2014 -0700

my version 1.4

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

    Change version number

Η εντολή αυτή μας δείχνει πληροφορίες για τον χρήστη που έφτιαξε την ετικέτα, την ημερομηνία που τοποθετήθηκε η ετικέτα στην υποβολή (commit) και το μήνυμά της.

Απλές ετικέτες

Ένας άλλος τρόπος για να βάζουμε ετικέτες στις υποβολές είναι οι απλές (lightweight) ετικέτες. Μία τέτοια ετικέτα δεν είναι τίποτα άλλο από το άθροισμα ελέγχου της υποβολής μας, που αποθηκεύεται σε ένα αρχείο· δεν διατηρείται καμία άλλη πληροφορία. Για να δημιουργήσουμε μια απλή ετικέτα, δεν θα πρέπει να χρησιμοποιήσουμε τις επιλογές -a, -s ή -m:

$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5

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

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

    Change version number

Προσάρτηση ετικέτας εκ των υστέρων

Μπορούμε επίσης να προσαρτήσουμε ετικέτες σε παλαιότερες υποβολές. Ας υποθέσουμε ότι το ιστορικό υποβολών μας είναι κάπως έτσι:

$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 Create write support
0d52aaab4479697da7686c15f77a3d64d9165190 One more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc Add commit function
4682c3261057305bdd616e23b64b0857d832627b Add todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a Create write support
9fceb02d0ae598e95dc970b74767f19372d61af8 Update rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc Commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a Update readme

Ας υποθέσουμε τώρα ότι ξεχάσαμε να βάλουμε ετικέτα στο έργο μας στην έκδοση v1.2 που ήταν η υποβολή με το μήνυμα “updated rakefile”. Μπορούμε να προσαρτήσουμε την ετικέτα αργότερα. Για να το κάνουμε αυτό, θα πρέπει να προσδιορίσουμε το άθροισμα ελέγχου της υποβολής μας (ή ένα μέρος του) (commit checksum) στο τέλος της εντολής:

$ git tag -a v1.2 9fceb02

Μπορούμε να δούμε ότι έχουμε προσθέσει την ετικέτα στην υποβολή:

$ git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5

$ git show v1.2
tag v1.2
Tagger: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Feb 9 15:32:16 2009 -0800

version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <mchacon@gee-mail.com>
Date:   Sun Apr 27 20:43:35 2008 -0700

    Update rakefile
...

Κοινοποίηση ετικετών

Εξ ορισμού, η εντολή git push δεν μεταφέρει ετικέτες στους απομακρυσμένους διακομιστές. Θα πρέπει να ορίσουμε ρητά ότι θέλουμε να ωθήσουμε τις ετικέτες στον διακομιστή, αφού προηγουμένως τις έχουμε δημιουργήσει. Η διαδικασία είναι παρόμοια με την κοινοποίηση απομακρυσμένων κλάδων — εκτελούμε την εντολή git push origin <tagname>.

$ git push origin v1.5
Counting objects: 14, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (12/12), done.
Writing objects: 100% (14/14), 2.05 KiB | 0 bytes/s, done.
Total 14 (delta 3), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
 * [new tag]         v1.5 -> v1.5

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

$ git push origin --tags
Counting objects: 1, done.
Writing objects: 100% (1/1), 160 bytes | 0 bytes/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To git@github.com:schacon/simplegit.git
 * [new tag]         v1.4 -> v1.4
 * [new tag]         v1.4-lw -> v1.4-lw

Πλέον, όταν κάποιος κλωνοποιήσει ή ελκύσει (pulls) δεδομένα από το αποθετήριό μας, θα λάβει μαζί και όλες τις ετικέτες μας.

Note
Η εντολή git push ωθεί και τα δύο είδη ετικετών

Η εντολή git push <remote> --tags θα ωθήσει τόσο τις απλές όσο και τις επισημασμένες ετικέτες. Προς το παρόν δεν υπάρχει κάποιος τρόπος να ωθήσετε μόνο τις απλές ετικέτες, αλλά αν εκτελέσετε git push <remote> --follow-tags μόνο οι επισημασμένες ετικέτες θα ωθηθούν στον απομακρυσμένο διακομιστή.

Διαγραφή ετικετών

Για να διαγράψουμε μια ετικέτα στο τοπικό μας αποθετήριο, μπορούμε να εκτελέσουμε git tag -d <tagname>. Για παράδειγμα, μπορούμε να διαγράψουμε την απλή ετικέτα που δημιουργήσαμε παραπάνω ως εξής:

$ git tag -d v1.4-lw
Deleted tag 'v1.4-lw' (was e7d5add)

Σημειώνουμε ότι η εντολή αυτή δεν διαγράφει την ετικέτα από τους απομακρυσμένους διακομιστές. Υπάρχουν δύο παραλλαγές για τη διαγραφή ετικετών από έναν απομακρυσμένο διακομιστή.

Η πρώτη είναι η εντολή git push <remote> :refs/tags/<tagname>:

$ git push origin :refs/tags/v1.4-lw
To /git@github.com:schacon/simplegit.git
 - [deleted]         v1.4-lw

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

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

$ git push origin --delete <tagname>

Ενημέρωση (check out) ετικετών

Για να δούμε τις εκδόσεις των αρχείων μας στα οποία δείχνει μία ετικέτα, μπορούμε να εκτελέσουμε git checkout για αυτή την ετικέτα, αλλά αυτό θέτει το αποθετήριό μας σε κατάσταση “detached HEAD”, κάτι που έχει κάποιες παρενέργειες:

$ git checkout v2.0.0
Note: switching to 'v2.0.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 99ada87... Merge pull request #89 from schacon/appendix-final

$ git checkout v2.0-beta-0.1
Previous HEAD position was 99ada87... Merge pull request #89 from schacon/appendix-final
HEAD is now at df3f601... Add atlas.json and cover image

Στην κατάσταση “detached HEAD”, αν κάνουμε αλλαγές και δημιουργήσουμε μια υποβολή (commit), η ετικέτα θα παραμείνει η ίδια, αλλά η νέα υποβολή δεν θα ανήκει σε κανέναν κλάδο και δεν θα είναι προσβάσιμη με κανέναν τρόπο εκτός κι αν χρησιμοποιήσουμε το ακριβές hash της υποβολής. Επιπλέον, αν χρειάζεται να κάνουμε αλλαγές — ας πούμε ότι διορθώνουμε κάποιο σφάλμα κάποιας παλιότερης έκδοσης, για παράδειγμα — καλό θα είναι να δημιουργήσουμε έναν κλάδο:

$ git checkout -b version2 v2.0.0
Switched to a new branch 'version2'

Αν βέβαια εκτελέσουμε την παραπάνω εντολή και πραγματοποιήσουμε μια υποβολή, ο κλάδος version2 θα είναι λίγο διαφορετικός από την ετικέτα v2.0.0 διότι θα έχει προχωρήσει με τις νέες αλλαγές· συνεπώς προσοχή.