Ξέρω ότι το Git παρακολουθεί τις αλλαγές που κάνω στην εφαρμογή μου και τις κρατάει μέχρι να δεσμεύσω τις αλλαγές, αλλά εδώ είναι που έχω κολλήσει:
Όταν θέλω να επιστρέψω σε ένα προηγούμενο commit χρησιμοποιώ:
git reset --hard HEAD
Και το Git επιστρέφει:
HEAD is now at 820f417 micro
Πώς μπορώ στη συνέχεια να επαναφέρω τα αρχεία στο σκληρό μου δίσκο πίσω σε αυτό το προηγούμενο commit;
Τα επόμενα βήματά μου ήταν τα εξής:
git add .
git commit -m "revert"
Αλλά κανένα από τα αρχεία δεν άλλαξε στον σκληρό μου δίσκο...
Τι κάνω σωστά/λάθος;
Πρώτον, αξίζει πάντα να σημειωθεί ότι η εντολή git reset --hard
είναι μια δυνητικά επικίνδυνη εντολή, καθώς πετάει όλες τις μη δεσμευμένες αλλαγές σας. Για λόγους ασφαλείας, θα πρέπει πάντα να ελέγχετε ότι η έξοδος της git status
είναι καθαρή (δηλαδή κενή) πριν τη χρησιμοποιήσετε.
Αρχικά λέτε τα εξής:
Γνωρίζω λοιπόν ότι το Git παρακολουθεί τις αλλαγές που κάνω στην εφαρμογή μου και τις κρατάει μέχρι να δεσμεύσω τις αλλαγές, αλλά εδώ είναι που έχω κολλήσει:
Αυτό δεν είναι σωστό. Το Git καταγράφει την κατάσταση των αρχείων μόνο όταν τα stage (με το git add
) ή όταν δημιουργείτε ένα commit. Μόλις δημιουργήσετε ένα commit το οποίο έχει τα αρχεία του έργου σας σε μια συγκεκριμένη κατάσταση, είναι πολύ ασφαλή, αλλά μέχρι τότε το Git δεν παρακολουθεί πραγματικά τις αλλαγές στα αρχεία σας. (για παράδειγμα, ακόμα και αν κάνετε git add
για να σταδιοποιήσετε μια νέα έκδοση του αρχείου, αυτό αντικαθιστά την προηγούμενη σταδιοποιημένη έκδοση του αρχείου στην περιοχή σταδιοποίησης).
Στην ερώτησή σας, στη συνέχεια, ρωτάτε τα εξής: "Τι είναι αυτό που θέλετε να κάνετε;":
Όταν θέλω να επιστρέψω σε μια προηγούμενη δέσμευση χρησιμοποιώ: git reset --hard HEAD Και το git επιστρέφει: HEAD είναι τώρα στο 820f417 micro >, Πώς μπορώ στη συνέχεια να επαναφέρω τα αρχεία στο σκληρό μου δίσκο πίσω σε αυτό το προηγούμενο commit;
Αν κάνετε git reset --hard <SOME-COMMIT>
τότε το Git θα:
master
) στο σημείο <SOME-COMMIT>
.<SOME-COMMIT>
.Το HEAD
δείχνει στον τρέχοντα κλάδο σας (ή την τρέχουσα δέσμευση), οπότε το μόνο που θα κάνει το git reset --hard HEAD
είναι να πετάξει όλες τις μη δεσμευμένες αλλαγές που έχετε.
Έτσι, ας υποθέσουμε ότι η καλή δέσμευση στην οποία θέλετε να επιστρέψετε είναι η f414f31
. (Μπορείτε να το βρείτε μέσω του git log
ή οποιουδήποτε προγράμματος περιήγησης ιστορικού.) Έχετε τότε μερικές διαφορετικές επιλογές ανάλογα με το τι ακριβώς θέλετε να κάνετε:
Να αλλάξετε τον τρέχοντα κλάδο σας ώστε να δείχνει στην παλαιότερη δέσμευση. Μπορείτε να το κάνετε αυτό με την εντολή git reset --hard f414f31
. Ωστόσο, αυτό ξαναγράφει το ιστορικό του κλάδου σας, οπότε θα πρέπει να το αποφύγετε αν έχετε μοιραστεί αυτόν τον κλάδο με κάποιον. Επίσης, οι δεσμεύσεις που κάνατε μετά το f414f31
δεν θα βρίσκονται πλέον στο ιστορικό του κλάδου σας master
.
Δημιουργήστε μια νέα δέσμευση που αντιπροσωπεύει ακριβώς την ίδια κατάσταση του έργου με το f414f31
, αλλά απλά προσθέτει αυτό στο ιστορικό, έτσι ώστε να μην χάσετε κανένα ιστορικό. Μπορείτε να το κάνετε αυτό χρησιμοποιώντας τα βήματα που προτείνονται στην αυτή την απάντηση - κάτι σαν:
git reset --hard f414f31
git reset --soft HEAD@{1}
git commit -m "Επαναφορά στην κατάσταση του έργου στο f414f31",
ΠΡΟΕΙΔΟΠΟΙΗΣΗ: Το
git clean -f
θα αφαιρέσει τα αρχεία που δεν έχουν εντοπιστεί, πράγμα που σημαίνει ότι έχουν εξαφανιστεί για πάντα, αφού δεν είναι αποθηκευμένα στο αποθετήριο. Βεβαιωθείτε ότι θέλετε πραγματικά να αφαιρέσετε όλα τα untracked αρχεία πριν το κάνετε αυτό.
Δοκιμάστε αυτό και δείτε το git clean -f
.
Το git reset --hard
δεν θα αφαιρέσει τα μη παρακολουθούμενα αρχεία, ενώ το git-clean
θα αφαιρέσει όλα τα αρχεία από τον παρακολουθούμενο ριζικό κατάλογο που δεν είναι υπό παρακολούθηση από το Git.
Εναλλακτικά, όπως είπε ο @Paul Betts, μπορείτε να κάνετε αυτό (προσέξτε όμως - αυτό αφαιρεί και όλα τα αγνοημένα αρχεία)
git clean -df
git clean -xdf
ΠΡΟΣΟΧΗ! Αυτό θα διαγράψει επίσης τα αγνοημένα αρχεία