Git
Chapters ▾ 2nd Edition

2.4 Τα θεμελιώδη στοιχεία του Git - Αναιρώντας κάτι

Αναιρώντας κάτι

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

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

$ git commit --amend

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

Όταν εκτελέσετε την εντολή, θα σας εμφανιστεί το μήνυμα από την προηγούμενή σας υποβολή. Το μήνυμα αυτό μπορείτε να το επεξεργαστείτε, αλλά η τελευταία υποβολή θα αντικατασταθεί.

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

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

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

Unstaging a Staged File

Στις επόμενες δύο ενότητες θα δούμε πως μπορείτε να διαχειριστείτε τις αλλαγές στην περιοχή καταχώρησης και στον κατάλογο εργασίας. Κάτι που θα σας φανεί πολύ χρήσιμο είναι ότι η εντολή που μας προσδιορίζει την κατάσταση αυτών των περιοχών, μας υπενθυμίζει και πως να αναιρέσουμε τις αλλαγές σε αυτές. Για παράδειγμα, έστω ότι έχετε κάνει αλλαγές σε δύο αρχεία και θέλετε να τα υποβάλλετε ως ξεχωριστές αλλαγές, αλλά τα καταχωρήσατε και τα δύο κατά λάθος με την εντολή git add *. Πως μπορούμε να αναιρέσουμε την καταχώρηση του ενός από τα δύο; Η εντολή git status μας υπενθυμίζει:

$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README
    modified:   CONTRIBUTING.md

Όπως βλέπετε, το κείμενο της εντολής μας συμβουλεύει να χρησιμοποιήσουμε την εντολή git reset HEAD <file>... ώστε να αναιρέσουμε μια καταχώρηση. Ας χρησιμοποιήσουμε λοιπόν τη συμβουλή αυτή για το αρχείο CONTRIBUTING.md:

$ git reset HEAD CONTRIBUTING.md
Unstaged changes after reset:
M	CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Η εντολή φαίνεται λίγο περίεργη, αλλά δουλεύει. Το αρχείο CONTRIBUTING.md είναι τροποποιημένο αλλά δεν βρίσκεται στην περιοχή καταχώρησης.

Note

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

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

Αναιρώντας τροποποιήσεις ενός αρχείου

Τι μπορείτε να κάνετε όμως αν διαπιστώσετε ότι δεν θέλετε να κρατήσετε τις αλλαγές που κάνατε στο αρχείο CONTRIBUTING.md; Πως μπορείτε να τις αναιρέσετε εύκολα και να φέρετε το αρχείο στη μορφή που είχε στην τελευταία του υποβολή (ή όπως βρισκόταν αρχικά στον κατάλογο εργασίας σας); Η εντολή git status μας βοηθάει εδώ και πάλι. Στο αποτέλεσμα του προηγούμενου παραδείγματος, η περιογή με τα μη καταχωρημένα αρχεία ήταν κάπως έτσι:

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   CONTRIBUTING.md

Η εντολή μας ενημερώνει αναλυτικά πως να απορρίψετε τις αλλαγές που έχετε κάνει. Ας ακολουθήσουμε τι λέει:

$ git checkout -- CONTRIBUTING.md
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    README.md -> README

Μπορείτε να δείτε πλέον ότι οι αλλαγές σας έχουν απορριφθεί.

Important

Είναι σημαντικό να καταλάβετε ότι η εντολή git checkout -- [file] είναι αρκετά επικίνδυνη. Όλες οι αλλαγές που έχετε κάνει σε αυτό το αρχείο έχουν πλέον χαθεί καθώς έχετε αντιγράψει ένα αρχείο πάνω από αυτό. Μην χρησιμοποιείτε την εντολή αυτή παρά μόνο αν είσαστε σίγουροι ότι δεν θέλετε να κρατήσετε τις αλλαγές σας.

Αν θέλετε να κρατήσετε τις αλλαγές που κάνατε στο αρχείο, αλλά παρόλα αυτά χρειάζεστε να το κάνετε στην άκρη, θα πρέπει να εξετάσουμε την εναπόθεση (stashing) και την διακλάδωση (branching) στο κεφάλαιο Διακλαδώσεις στο Git.

Να θυμάστε ότι οτιδήποτε είναι υποβεβλημένο στο Git μπορεί να ανακτηθεί. Μπορείτε να ανακτήσετε ακόμα και υποβολές σε κλάδους που έχουν διαγραφεί ή υποβολές που επανεγγράφηκαν, με την εντολή git commit --amend (βλ. Data Recovery για περισσότερα πάνω στην ανάκτηση δεδομένων). Ωστόσο, αν κάτι δεν είναι υποβεβλημένο και το χάσετε, είναι πολύ πιθανό να μην μπορέσετε να το ανακτήσετε.