Git
Chapters ▾ 2nd Edition

7.7 Εργαλεία του Git - Απομυθοποίηση της reset

Απομυθοποίηση της reset

Πριν προχωρήσουμε σε πιο εξειδικευμένα εργαλεία, ας μιλήσουμε για τα reset και checkout. Αυτές οι εντολές είναι δύο από τα πιο δυσνόητα σημεία του Git όταν τα συναντά κανείς για πρώτη φορά. Κάνουν τόσο πολλά πράγματα, που φαίνεται να μην υπάρχει καμία ελπίδα πραγματικής κατανόησης σωστής χρήσης τους. Γι' αυτό, θα κάνουμε μία απλή μεταφορά.

Τα τρία δέντρα

Ένας ευκολότερος τρόπος για να σκεφτούμε τα reset και checkout είναι μέσα από ένα νοητική πλαίσιο στο οποίο το Git είναι διαχειριστής του περιεχομένου τριών διαφορετικών δέντρων. Με τον όρο “δέντρο” εδώ εννοούμε ουσιαστικά “συλλογή αρχείων”, όχι ειδικότερα τη δομή δεδομένων. (Υπάρχουν μερικές περιπτώσεις στις οποίες το Ευρετήριο δεν λειτουργεί ακριβώς όπως ένα δέντρο, αλλά για τον σκοπό μας είναι ευκολότερο να το σκεφτούμε με αυτόν τον τρόπο προς το παρόν.)

Το Git, ως σύστημα, διαχειρίζεται και μεταχειρίζεται τρία δέντρα στην κανονική του λειτουργία:

Δέντρο Ρόλος

HEAD

Στιγμιότυπο τελευταίας υποβολής, επόμενος γονέας

Ευρετήριο

Προτεινόμενο στιγμιότυπο για την επόμενη υποβολή

Κατάλογος Εργασίας

Αμμοδοχείο

Το δέντρο HEAD

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

Στην πραγματικότητα, είναι αρκετά εύκολο να δούμε με τι μοιάζει αυτό το στιγμιότυπο. Ακολουθεί ένα παράδειγμα της πραγματικής λίστας καταλόγου και των αθροισμάτων ελέγχου SHA-1 για κάθε αρχείο στο στιγμιότυπο HEAD:

$ git cat-file -p HEAD
tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
author Scott Chacon  1301511835 -0700
committer Scott Chacon  1301511835 -0700

initial commit

$ git ls-tree -r HEAD
100644 blob a906cb2a4a904a152...   README
100644 blob 8f94139338f9404f2...   Rakefile
040000 tree 99f1a6d12cb4b6f19...   lib

Οι εντολές cat-file και ls-tree είναι εντολές “διοχέτευσης” που χρησιμοποιούνται για πράγματα χαμηλότερου επιπέδου και σπάνια χρησιμοποιούνται στην καθημερινή εργασία μας, αλλά μας βοηθούν να δούμε τι συμβαίνει εδώ.

Το Ευρετήριο

Το Ευρετήριο είναι η προτεινόμενη επόμενη υποβολή. Έχουμε επίσης αναφερθεί σε αυτήν την έννοια ως “στάδιο καταχώρισης” του Git, καθώς αυτό εξετάζει το Git όταν τρέχουμε την ‘git commit’.

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

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

$ git ls-files -s
100644 a906cb2a4a904a152e80877d4088654daad0c859 0	README
100644 8f94139338f9404f26296befa88755fc2598c289 0	Rakefile
100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0	lib/simplegit.rb

Και πάλι εδώ χρησιμοποιούμε την εντολή `ls-files ', η οποία είναι περισσότερο μια εντολή παρασκηνίου που μας δείχνει με τι μοιάζει το Ευρετήριο μας αυτήν τη στιγμή.

Ο Κατάλογος Εργασίας

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

$ tree
.
├── README
├── Rakefile
└── lib
    └── simplegit.rb

1 directory, 3 files

Η ροή εργασίας

Ο κύριος σκοπός του Git είναι να καταγράφει στιγμιότυπα του έργου μας σε διαδοχικά καλύτερες καταστάσεις, χειριζόμενο αυτά τα τρία δέντρα.

reset workflow

Ας οπτικοποιήσουμε αυτήν τη διαδικασία: ας πούμε ότι πηγαίνουμε σε έναν νέο κατάλογο με μόνον ένα αρχείο σε αυτόν. Θα ονομάσουμε αυτήν την έκδοση του αρχείου v1 και θα το απεικονίζουμε με μπλε χρώμα. Τώρα τρέχουμε την git init, η οποία θα δημιουργήσει ένα αποθετήριο Git με μια αναφορά HEAD που δείχνει σε έναν κλάδο που δεν υπάρχει (ο master δεν υπάρχει ακόμα).

reset ex1

Σε αυτό το σημείο, μόνο το δέντρο του Καταλόγου Εργασίας έχει κάποιο περιεχόμενο.

Τώρα θέλουμε να υποβάλουμε αυτό το αρχείο, οπότε χρησιμοποιούμε την git add για να πάρουμε το περιεχόμενο που βρίσκεται στον Κατάλογο Εργασίας και να το αντιγράψουμε στο Ευρετήριο.

reset ex2

Στη συνέχεια, τρέχουμε την git commit, η οποία παίρνει τα περιεχόμενα του Ευρετηρίου και τα αποθηκεύει ως μόνιμο στιγμιότυπο, δημιουργεί ένα αντικείμενο υποβολής το οποίο δείχνει σε αυτό το στιγμιότυπο και ενημερώνει τον master να δείχνει σε αυτήν την υποβολή.

reset ex3

Αν εκτελέσουμε την git status, δεν θα δούμε αλλαγές, αφού και τα τρία δέντρα είναι τα ίδια.

Τώρα θέλουμε να κάνουμε μια αλλαγή σε αυτό το αρχείο και να την υποβάλλουμε. Θα επαναληφθεί η ίδια διαδικασία· πρώτα αλλάζουμε το αρχείο στον Κατάλογο Εργασίας μας. Ας ονομάσουμε αυτην την έκδοση του αρχείου v2 και θα την απεικονίζουμε με κόκκινο χρώμα.

reset ex4

Αν εκτελέσουμε την εντολή git status τώρα, το αρχείο θα εμφανιστεί με κόκκινο χρώμα με την ένδειξη “Changes not staged for commit”, επειδή αυτή η εγγραφή διαφέρει μεταξύ του Ευρετηρίου και του Καταλόγου Εργασίας. Στη συνέχεια τρέχουμε την git add σε αυτό για να το προσθέσουμε στο Ευρετήριο μας.

reset ex5

Σε αυτό το σημείο, αν εκτελέσουμε την git status θα δούμε το αρχείο πράσινο κάτω από την ένδειξη Changes to be committed επειδή το Ευρετήριο και ο HEAD διαφέρουν —δηλαδή, η προτεινόμενη επόμενη υποβολή μας τώρα είναι διαφορετική από την τελευταία μας υποβολή. Τέλος, τρέχουμε git commit για να οριστικοποιήσουμε την υποβολή.

reset ex6

Τώρα η git status δεν θα μας δώσει καμία έξοδο, αφού και τα τρία δέντρα είναι τα ίδια ξανά.

Όταν μεταβαίνουμε από έναν κλάδο σε άλλον ή κλωνοποιούμε, γίνεται μία παρόμοια διαδικασία. Όταν μεταβαίνουμε σε έναν κλάδο, αλλάζει ο HEAD ώστε να δείχνει στο ref του νέου κλάδου, το Ευρετήριο γεμίζει με το στιγμιότυπο αυτής της υποβολής και στη συνέχεια τα περιεχόμενα του Ευρετηρίου αντιγράφουνται στον Κατάλογο Εργασίας.

Ο ρόλος της reset

Η εντολή reset γίνεται κατανοητή πιο εύκολα στο παρακάτω πλαίσιο. Για τους σκοπούς αυτών των παραδειγμάτων, ας πούμε ότι τροποποιήσαμε ξανά το file.txt και το υποβάλαμε για τρίτη φορά. Έτσι τώρα το ιστορικό μας μοιάζει με αυτό:

reset start

Ας δούμε τώρα τι ακριβώς κάνει η reset όταν την καλούμε. Χειραγωγεί άμεσα αυτά τα τρία δέντρα με έναν απλό και προβλέψιμο τρόπο. Κάνει το πολύ μέχρι τρεις βασικές λειτουργίες.

Βήμα 1: μετακίνηση του HEAD

Το πρώτο πράγμα που κάνει η reset είναι να μετακινήσει το πού δείχνει ο HEAD. Αυτό δεν είναι το ίδιο με το να αλλάζει τον ίδιο τον HEAD (που είναι αυτό που κάνει η checkout). Η reset μετακινεί τον κλάδο στον οποίο δείχνει ο HEAD. Αυτό σημαίνει ότι αν ο HEAD έχει τεθεί στον κλάδο master (δηλ. βρισκόμαστε στον κλάδο master), η git reset 9e5e6a4 θα ξεκινήσει κάνοντας τον master να δείχνει στην 9e5e6a4.

reset soft

Ανεξάρτητα από το με τι διακόπτες καλούμε την reset, αυτό είναι το πρώτο πράγμα που θα προσπαθήσει πάντα να κάνει. Με τον διακόπτη `--soft ', απλά θα σταματήσει εκεί.

Τώρα ας σταθούμε λίγο σε αυτό το διάγραμμα και για να συνειδητοποιήσουμε τι συνέβη: ουσιαστικά ξέκανε την τελευταία εντολή git commit. Όταν εκτελούμε την git commit, το Git δημιουργεί μια νέα υποβολή και μετακινεί τον κλάδο στον οποίο δείχνει ο HEAD σε αυτήν. Όταν επαναφέρουμε (reset) στον HEAD~ (τον γονέα του HEAD), μετακινούμε τον κλάδο πίσω στο σημείο στο οποίο βρισκόταν, χωρίς να αλλάξουμε τον Ευρετήριο ή τον Κατάλογο Εργασίας. Θα μπορούσαμε τώρα να ενημερώσουμε τον Ευρετήριο και να εκτελέσουμε ξανά την git commit για να ολοκληρώσουμε τι θα έκανε η git commit --amend (βλ. ενότητα Αλλαγή της τελευταίας υποβολής).

Βήμα 2: Ενημέρωση του Ευρετηρίου (--mixed)

Υπόψη ότι αν αν εκτελέσουμε την git status τώρα, θα δούμε με πράσινο τη διαφορά μεταξύ του Ευρετηρίου και του τι είναι ο νέος HEAD.

Το επόμενο πράγμα που θα κάνει η reset είναι να ενημερώσει το Ευρετήριο με τα περιεχόμενα εκείνου του στιγμιότυπου στο οποίο δείχνει τώρα ο HEAD.

reset mixed

Εάν καθορίσουμε την επιλογή --mixed, η reset θα σταματήσει σε αυτό το σημείο. Αυτή είναι και η προεπιλογή, οπότε αν δεν καθορίσουμε καμία επιλογή (μόνο git reset HEAD~ σε αυτήν την περίπτωση), η εντολή θα σταματήσει εδώ.

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

Βήμα 3: Ενημέρωση του Καταλόγου Εργασίας (--hard)

Το τρίτο πράγμα που μπορεί να κάνει η reset είναι να κάνει τον Κατάλογο Εργασίας να είναι ίδιος με το Ευρετήριο. Αν χρησιμοποιήσουμε την επιλογή --hard, θα συνεχίσει να κάνει ακριβώς αυτό.

reset hard

Ας αναλογιστούμε λοιπόν τι συνέβη. Ξεκάναμε την τελευταία υποβολή μας, τις εντολές git add και git commit και όλη την εργασία που κάναμε στον Κατάλογο Εργασίας μας.

Είναι σημαντικό να σημειωθεί ότι αυτή η σημαία (--hard) είναι ο μόνος τρόπος για να γίνει η εντολή reset επικίνδυνη και μια από τις ελάχιστες περιπτώσεις όπου το Git πραγματικά θα καταστρέψει δεδομένα. Οποιαδήποτε άλλη επίκληση της reset μπορεί εύκολα να αναιρεθεί, αλλά η επιλογή --hard δεν μπορεί, αφού αντικαθιστά με το ζόρι τα αρχεία στον Κατάλογο Εργασίας. Στη συγκεκριμένη περίπτωση, εξακολουθούμε να έχουμε την έκδοση v3 του αρχείου μας σε μια υποβολή στη βάση δεδομένων του Git και θα μπορούσαμε να την επαναφέρουμε εξετάζοντας το reflog μας, αλλά αν δεν το είχαμε υποβάλει, το Git θα είχε και πάλι αντικαταστήσει το αρχείο και αυτήν τη φορά δεν θα ήταν ανακτήσιμο.

Ανακεφαλαίωση

Η εντολή reset αντικαθιστά αυτά τα τρία δέντρα με συγκεκριμένη σειρά και σταματά όταν της λέμε:

  1. Μετακινεί τον κλάδο στον οποίο δείχνει ο HEAD (εάν --soft, σταμάτα εδώ)

  2. Κάνει το Ευρετήριο να είναι ιδιο με τον HEAD (εάν όχι --hard, σταμάτα εδώ)

  3. Κάνει τον Κατάλογο Εργασίας να μοιάζει με το Ευρετήριο.

Επαναφορά με διαδρομή

Τα προηγούμενα καλύπτουν τη συμπεριφορά της reset στη βασική της μορφή, αλλά μπορούμε επίσης να της παράσχουμε μία διαδρομή στην οποία να δράσει. Αν καθορίσουμε μια διαδρομή, η reset θα παραλείψει το Βήμα 1 και θα περιορίσει το υπόλοιπο των ενεργειών της σε ένα συγκεκριμένο αρχείο ή σύνολο αρχείων. Αυτό πραγματικά έχει μία λογική —ο HEAD είναι απλώς ένας δείκτης και δεν μπορεί να δείχνει σε ένα τμήμα μίας υποβολής και σε ένα τμήμα μίας άλλης. Αλλά το Ευρετήριο και ο Κατάλογος Εργασίας μπορούν να ενημερώνονται εν μέρει, οπότε η reset συνεχίζει με τα Bήματα 2 και 3.

Ας υποθέσουμε, λοιπόν, ότι τρέχουμε την git reset file.txt. Αυτή η φόρμα (αφού δεν έχουμε καθορίσει τον αριθμό SHA-1 μιας υποβολής ή έναν κλάδο και δεν έχουμε ορίσει --soft ή --hard) είναι συντομογραφία της git reset --mixed HEAD file.txt, η οποίο θα:

  1. Μετακινήσει τον κλάδο στον οποίο δείχνει ο HEAD (παρακάμπτεται)

  2. Κάνει το Ευρετήριο να μοιάζει με τον HEAD (σταμάτα εδώ)

Έτσι, ουσιαστικά απλά αντιγράφει το file.txt από τον HEAD στο Ευρετήριο.

reset path1

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

reset path2

Αυτός είναι ο λόγος για τον οποίο η έξοδος της εντολής git status υπονοεί ότι την εκτελούμε για να αφαιρέσουμε ένα αρχείο από το στάδιο καταχώρισης. (Περισσότερα σχετικά με αυτό υπάρχουν στην ενότητα Αφαίρεση αρχείου από το στάδιο καταχώρισης.)

Θα μπορούσαμε εξίσου εύκολα να μην αφήσουμε τον Git να υποθέσει ότι εννοούσαμε “έλξε τα δεδομένα από τον HEAD”, καθορίζοντας μια συγκεκριμένη υποβολή από την οποία θέλαμε αν έλξουμε αυτήν την έκδοση του αρχείου. Απλά θα έπρεπε να τρέξουμε κάτι σαν την git reset eb43bf file.txt.

reset path3

Αυτό ουσιαστικά κάνει το ίδιο πράγμα με το να είχαμε επαναφέρει το περιεχόμενο του αρχείου στη v1 στον Κατάλογο Εργασίας, να τρέξουμε git add σε αυτό και στη συνέχεια να το επαναφέρουμε ξανά στην v3 (χωρίς στην πραγματικότητα να περάσουμε όλα αυτά τα στάδια). Αν εκτελέσουμε τώρα την git commit, θα καταγράψει μια αλλαγή που θα επαναφέρει αυτό το αρχείο πίσω στην v1, παρόλο που στην πραγματικότητα ποτέ δεν το ξαναείχαμε στον Κατάλογο Εργασίας .

Είναι επίσης ενδιαφέρον να σημειώσουμε ότι όπως και η git add, η εντολή reset θα δέχεται μια επιλογή --patch για την αφαίρεση από το στάδιο καταχώρισης περιεχομένου κομμάτι-κομμάτι. Επομένως, μπορούμε να αφαιρέσουμε από το στάδιο καταχώρισης ή να επαναφέρουμε περιεχόμενο, επιλεκτικά. ert content.

Συναρμογή

Ας δούμε πώς να κάνουμε κάτι ενδιαφέρον με αυτήν τη νέα δύναμη —τη συναρμογή υποβολών.

Ας πούμε ότι έχουμε μια σειρά υποβολών με μηνύματα όπως oops., WIP και forgot this file. Μπορούμε να χρησιμοποιήσουμε την reset για να τα συναρμόσουμε γρήγορα και εύκολα σε μια ενιαία υποβολή που μας κάνει να φανούμε πραγματικά έξυπνοι. (Στην ενότητα Squashing Commits υπάρχει ένας άλλος τρόπος για να το κάνουμε αυτό, αλλά σε αυτό το παράδειγμα θα χρησιμοποιήσουμε τη reset επειδή είναι απλούστερο.)

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

reset squash r1

Μπορούμε να εκτελέσουμε την git reset --soft HEAD~2 για να μετακινήσουμε τον κλάδο HEAD πίσω σε μια παλαιότερη υποβολή (την πρώτη υποβολή που θέλουμε να κρατήσουμε):

reset squash r2

Στη συνέχεια εκτελούμε ξανά την git commit:

reset squash r3

Τώρα μπορούμε να δούμε ότι το προσβάσιμο ιστορικό μας, δηλαδή το ιστορικό που θα ωθήσουμε, τώρα μοιάζει σαν να είχαμε μία υποβολή με το αρχείο file-a.txt (v1), και στη συνέχεια μία δεύτερη που τροποποίησε το file-a.txt στο v3 και πρόσθεσε το file-b.txt. Η υποβολη με την έκδοση v2 του αρχείου δεν βρίσκεται πλέον στο ιστορικό.

Check out

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

Χωρίς διαδρομή

Το τρέξιμο της git checkout [branch] είναι αρκετά παρόμοιο με το τρέξιμο της git reset --hard [branch] επειδή ενημερώνει και τα τρία δέντρα ώστε να μοιάζουν με τον [branch], αλλά υπάρχουν δύο σημαντικές διαφορές.

Καταρχάς, σε αντίθεση με τη reset --hard, η checkout είναι ασφαλής για τον Κατάλογο Εργασίας· θα ελέγξει ώστε να βεβαιωθεί ότι δεν πετάει αρχεία που έχουν αλλαγές. Στην πραγματικότητα, είναι λίγο πιο έξυπνο από αυτό —προσπαθεί να κάνει μια τετριμμένη συγχώνευση στον Κατάλογο Εργασίας, έτσι ώστε όλα τα αρχεία που δεν έχουμε αλλάξει να ενημερωθούν. Αντίθετα η reset --hard απλά θα αντικαταστήσει τα πάντα χωρίς κανέναν έλεγχο.

Η δεύτερη σημαντική διαφορά είναι ο τρόπος ενημέρωσης του HEAD. Ενώ η reset μετακινεί τον κλάδο στον οποίο ο HEAD, η checkout θα μετακινήσει τον ίδιο τον HEAD για να δείξει σε κάποιον άλλο κλάδο.

Για παράδειγμα, ας πούμε ότι έχουμε τους κλάδους master και develop που δείχνουν σε διαφορετικές υποβολές και αυτήν τη στιγμή βρισκόμαστε στον develop (άρα ο HEAD δείχνει σε αυτόν). Εάν εκτελέσουμε την git reset master, ο develop θα δείχνει τώρα στην ίδια υποβολή που δείχνει ο master. Αν αντίθετα τρέξουμε τη git master checkout, δεν θα κινηθεί ο develop αλλά ο HEAD. Ο HEAD θα δείχνει τώρα στον master.

Επομένως και στις δύο περιπτώσεις ο HEAD μετακινείται, ώστε να δείχνει στην υποβολή A, αλλά το πώς γίνεται αυτό είναι πολύ διαφορετικό. Η reset θα μετακινήσει τον κλάδο στον οποίο δείχνει ο HEAD ενώ η checkout μετακινεί τον ίδιο το HEAD.

reset checkout

Με διαδρομή

Ο άλλος τρόπος για να εκτελέσουμε την checkout είναι με διαδρομή αρχείου, η οποία, όπως η reset, δεν μετακινεί τον HEAD. Είναι ακριβώς όπως η git reset [branch] file ως προς το ότι ενημερώνει το Ευρετήριο με αυτό το αρχείο σε αυτήν την υποβολή, αλλά επίσης αντικαθιστά το αρχείο στον Κατάλογο Εργασίας. Θα ήταν ακριβώς όπως η git reset --hard [branch] file (αν η reset μας επέτρεπε να τρέξουμε κάτι τέτοιο) —δεν είναι ασφαλές για τον Κατάλογο Εργασίας και δεν μετακινεί το HEAD.

Επίσης, όπως οι git reset και git add, η checkout δέχεται επιλογή --patch για να μπορούμε να επαναφέρουμε επιλεκτικά τα περιεχόμενα του αρχείου κομμάτι-κομμάτι.

Ανακεφαλαίωση

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

Ακολουθεί ένα σκονάκι σχετικά με το ποιες εντολές επηρεάζουν ποια δέντρα. Η στήλη HEAD γίνεται REF αν αυτή η εντολή μετακινεί την αναφορά (κλάδο) στην οποία δείχνει ο HEAD και HEAD αν μετακινεί τον ίδιο τον HEAD. Ιδιαίτερη προσοχή χρειάζεται η στήλη “Ασφαλής για ΚΕ;” —αν αναφέρει ΟΧΙ, τότε πρέπει να ξανασκεφτούμε αν πραγματικά θέλουμε να εκτελέσουμε αυτήν την εντολή.

HEAD Ευρετήριο Κατάλογος Εργασίας Ασφαλές για ΚΕ;

Επίπεδο υποβολής

reset --soft [commit]

REF

ΟΧΙ

ΟΧΙ

ΝΑΙ

reset [commit]

REF

ΝΑΙ

ΟΧΙ

ΝΑΙ

reset --hard [commit]

REF

ΝΑΙ

ΝΑΙ

ΟΧΙ

checkout [commit]

HEAD

ΝΑΙ

ΝΑΙ

ΝΑΙ

Επίπεδο αρχείου

reset (commit) [file]

ΟΧΙ

ΝΑΙ

ΟΧΙ

ΝΑΙ

checkout (commit) [file]

ΟΧΙ

ΝΑΙ

ΝΑΙ

ΟΧΙ