Cherry-pick — είναι μια εντολή του Git που εφαρμόζει αλλαγές από ένα συγκεκριμένο commit στο τρέχον branch, χωρίς να μεταφέρει ολόκληρο το ιστορικό του αρχικού branch. Σε αντίθεση με το merge ή το rebase, το cherry-pick λειτουργεί με κάθε commit ξεχωριστά: ο αναπτυκτής επιλέγει ένα συγκεκριμένο commit με βάση το hash και μεταφέρει μόνο τις αλλαγές του. Σύμφωνα με την τεκμηρίωση Git (2026), το cherry-pick είναι ιδιαίτερα χρήσιμο για τη στοχευμένη μεταφορά διορθώσεων μεταξύ branches έκδοσης, όταν ένα πλήρες merge είναι περιττό ή επικίνδυνο. Η εντολή δημιουργεί ένα νέο commit με νέο hash, αλλά διατηρεί το αρχικό μήνυμα και τον συγγραφέα.
Βασικά σημεία
Cherry-pick — είναι η εντολή git cherry-pick που παίρνει αλλαγές από ένα υπάρχον commit και τις εφαρμόζει ως ένα νέο commit στο τρέχον branch. Το αρχικό commit παραμένει στη θέση του στο δικό του branch, ενώ ένα αντίγραφο των αλλαγών δημιουργείται στο branch-στόχο. Η εντολή είναι χρήσιμη όταν πρέπει να μεταφέρετε μια συγκεκριμένη διόρθωση χωρίς να μετακινείτε ολόκληρο το branch.
Σύνταξη: git cherry-pick <commit-hash>. Το Git αναλύει τη διαφορά (diff) του καθορισμένου commit με τον γονέα του και εφαρμόζει αυτή τη διαφορά στο τρέχον branch. Εάν οι αλλαγές αφορούν πολλά αρχεία — όλα μεταφέρονται μαζί. Η εντολή δέχεται επίσης εύρη: git cherry-pick A..B — όλα τα commits από A έως B, χωρίς το A.
Τα flags επεκτείνουν τις δυνατότητες: το -n (--no-commit) εφαρμόζει αλλαγές στον κατάλογο εργασίας και στο index χωρίς δημιουργία commit — χρήσιμο όταν πρέπει να συγχωνεύσετε αλλαγές πολλών commits σε ένα. Το flag -x προσθέτει μια γραμμή (cherry picked from commit ...) στο μήνυμα του commit, απλοποιώντας την ιχνηλάσηση της προέλευσης των αλλαγών στο ιστορικό.
# Cherry-pick ενός commit με βάση το hash
git cherry-pick a1b2c3d
# Cherry-pick πολλαπλών commits (διαδοχικά)
git cherry-pick a1b2c3d e4f5g6h i6j7k8l
# Cherry-pick χωρίς αυτόματη commit
git cherry-pick -n a1b2c3d
# Flag -x προσθέτει αναφορά στο αρχικό commit
git cherry-pick -x a1b2c3d
Κύριο σενάριο — μεταφορά διορθώσεων μεταξύ branches έκδοσης. Φανταστείτε: στο develop βρέθηκε και διορθώθηκε ένα κριτικό σφάλμα. Το release branch release/v2.1 έχει ήδη αποκολλεί και αυτό το σφάλμα υπάρχει επίσης. Ένα merge ολόκληρου του develop στο release θα μεταφέρει πολύ ατελή κώδικα, ενώ ένα cherry-pick ενός commit με τη διόρθωση είναι ασφαλής και ακριβής λύση.
Δεύτερο σενάριο — αναίρεση αλλαγών (revert) με επαναφορά. Εάν ένα commit ανακλήθηκε μέσω git revert, και στη συνέχεια αποδείχθηκε ότι η ανάκληση ήταν λανθασμένη — το cherry-pick του ανακληθέντος commit αποκαθιστά τις αλλαγές. Αυτό είναι πιο σωστό από την ανάκληση του revert, καθώς δεν δημιουργεί επαναλημμένες συγκρούσεις.
Τρίτο σενάριο — συγχώνευση commits από διαφορετικά feature branches σε ένα δοκιμαστικό branch για δοκιμές ολοκλήρωσης. Αντί να συγχωνεύσετε πολλά ημιτελή branches (με ατελή κώδικα), μπορείτε να επιλέξετε μόνο τα έτοιμα commits από κάθε ένα και να δοκιμάσετε τη συνεργασία τους.
Cherry-pick διαφέρει από το rebase και το merge καθώς λειτουργεί σε επίπεδο μεμονωμένων commits, όχι ολόκληρων branches. Ενώ το rebase μεταφέρει όλα τα commits ενός branch και το merge συγχωνεύει δύο branches, το cherry-pick επιλέγει μόνο τα απαραίτητα. Αυτό το καθιστά πιο ακριβές εργαλείο, αλλά και πιο χειροκίνητο.
Ένα ακόμη διαφορά — συγγραφική ιδιότητα. Στο cherry-pick, το Git από προεπιλογή διατηρεί τον συγγραφέα (Author) του αρχικού commit, αλλά ο committer (Committer) γίνεται ο τρέχων χρήστης. Στο μήνυμα του commit, η προέλευση μπορεί να ιχνηλαθηθεί μέσω του flag -x. Στο rebase, και ο συγγραφέας και ο committer είναι ο τρέχων χρήστης με νέο hash.
Απόδοση: το cherry-pick ενός commit εκτελείται πιο γρήγορα από το merge δύο branches με πολλά commits. Αλλά εάν πρέπει να μεταφέρετε δοσεντάδες commits, είναι καλύτερο να δημιουργήσετε ένα προσωρινό branch και να κάνετε rebase — αυτό είναι πιο αποδοτικό και δεν απαιτεί την καθορισμό δοσεντάδων hash.
| Λειτουργία | Πεδίο εφαρμογής | Παρενέργειες |
|---|---|---|
| Cherry-pick | Μεμονωμένα commits | Νέο hash, αντιγραφή κώδικα |
| Rebase | Όλα τα commits ενός branch | Επαναγραφή ιστορικού, νέα hash |
| Merge | Πλήρης συγχώνευση branches | Merge-commit, διατήρηση ιστορικού |
Πολλαπλά commits μπορούν να μεταφερθούν με μία εντολή, απαριθμώντας τα hash τους με κενό: git cherry-pick A B C. Το Git εφαρμόζει τα commits διαδοχικά στην καθορισμένη σειρά. Εάν κάποιο από τα commits προκαλέσει σύγκρουση, το cherry-pick διακόπτεται και ο αναπτυκτής πρέπει να επιλύσει τη σύγκρουση, μετά από την οποία μπορεί να συνεχίσει με την εντολή git cherry-pick --continue.
Περιοχή commits: git cherry-pick A..B (όλα τα commits μετά το A έως το B, χωρίς το A) και git cherry-pick A^..B (όλα τα commits από το A συμπεριλαμβανομένου έως το B). Οι περιοχές είναι βολικές όταν πρέπει να μεταφέρετε όλα τα commits από ένα branch αλλά χωρίς τη σχέση γονέα — για παράδειγμα, κατά τη μεταφορά ετοιμος λειτουργίας από ένα παλιό branch σε ένα νέο.
Το flag --strategy καθορίζει πώς το Git θα εφαρμόσει τις αλλαγές. Από προεπιλογή χρησιμοποιείται recursive στρατηγική, αλλά μπορείτε να καθορίσετε ours ή theirs για αυτόματη επιλογή πλευράς σύγκρουσης. Το flag --mainline χρησιμοποιείται στο cherry-pick merge commit — καθορίζει τον αριθμό γονέα (1 ή 2) ως προς τον οποίο υπολογίζεται το diff.
# Cherry-pick περιοχής commits
git cherry-pick develop~5..develop~2
# Cherry-pick merge commit (καθορίστε γονέα)
git cherry-pick -m 1 m9n0o1p
# Χρήση theirs στρατηγικής
git cherry-pick --strategy=recursive \
--strategy-option=theirs a1b2c3d
# Συνέχεια μετά την επίλυση σύγκρουσης
git cherry-pick --continue
Συγκρούσεις κατά το cherry-pick προκύπτουν όταν οι αλλαγές του μεταφερόμενου commit επηρεάζουν τις ίδιες γραμμές που αλλάχθηκαν στο branch-στόχο. Το Git διακόπτει την εκτέλεση, σημαιώνει τα αρχεία που έχουν σύγκρουση και περιμένει επίλυση. Στην κατάσταση, αυτά τα αρχεία εμφανίζονται ως both modified.
Διαδικασία σε περίπτωση σύγκρουσης: ανοίξτε το αρχείο που έχει σύγκρουση, βρείτε τα σημάδια σύγκρουσης (<<<<<<<, =======, >>>>>>>), επεξεργαστείτε το περιεχόμενο, αφαιρείτε τα σημάδια, εκτελείτε git add για τα επιλυμένα αρχεία και εκτελείτε git cherry-pick --continue. Εάν η σύγκρουση δεν είναι επιλύσιμη — το git cherry-pick --abort ακυρώνει ολόκληρο το cherry-pick, επαναφέροντας το branch στην αρχική κατάσταση.
Συνηθισμένο πρόβλημα: το commit περιέχει ήδη αλλαγές ισοδύναμες με τις υπάρχουσες. Σε αυτή την περίπτωση, το Git αναφέρει «nothing to commit» ή «empty commit» κατά την προσπάθεια cherry-pick. Τα flags --keep-redundant-commits και --empty=keep αναγκάζουν το Git να δημιουργήσει κενό commit για διατήρηση της σειράς, ενώ το --skip επιτρέπει την παράλειψη τέτοιου commit.
# Σύγκρουση κατά το cherry-pick — διακοπή
git cherry-pick a1b2c3d
# error: could not apply a1b2c3d... commit message
# Επίλυση σύγκρουσης → προσθήκη στο index
git add src/conflicted_file.swift
git cherry-pick --continue
# Παράλειψη κενού commit (ήδη εφαρμοσμένο)
git cherry-pick --skip
# Πλήρης ακύρωση
git cherry-pick --abort
Πρώτος κανόνας: ελέγχετε πάντα αν το μεταφερόμενο commit είναι αυτοτελές. Εάν το commit A εξαρτάται από αλλαγές στο commit B που δεν μεταφέρεται, το cherry-pick του A μπορεί να σπάσει το build. Πριν το cherry-pick, είναι χρήσιμο να ελέγξετε ποια αρχεία τροποποίησε το commit μέσω git show --stat <hash>.
Δεύτερος κανόνας: τεκμηριώστε το cherry-pick. Χρησιμοποιείτε το flag -x ώστε το μήνυμα του commit να διατηρήσει την αναφορά στο αρχικό commit. Αυτό βοηθάει στην μετέπειτα ανάλυση του ιστορικού για να καταλάβετε από πού προήλθε η αλλαγή. Χωρίς -x, το cherry-pick μοιάζει με κανονικό commit, και η προέλευσή του μπορεί να εξακριβωθεί μόνο μέσω git log --graph.
Τρίτος κανόνας: αποφύγετε το cherry-pick μεταξύ branches που αποκλίνουν πάρα πολύ. Εάν έχει περάσει πολύς χρόνος από τη δημιουργία του commit και η βάση κώδικα έχει αλλάξει σημαντικά, οι συγκρούσεις θα είναι πολλές και περίπλοκες. Σε τέτοιες περιπτώσεις, είναι καλύτερο να κάνετε τη διόρθωση ξανά στο branch-στόχο — αυτό θα πάρει λιγότερο χρόνο από την επίλυση δοσεντάδων συγκρούσεων.
Συχνές Ερωτήσεις
Cherry-pick — η εφαρμογή των αλλαγών ενός καθορισμένου commit στο τρέχον branch μέσω git cherry-pick. Η εντολή δημιουργεί ένα νέο commit με τις ίδιες αλλαγές αλλά νέο hash. Το αρχικό commit παραμένει αμετάβλητο στο δικό του branch. Αυτό είναι μια εναλλακτική λύση στη συγχώνευση ολόκληρου του branch όταν χρειάζεται μόνο ένα συγκεκριμένο commit.
Cherry-pick επιλέγεται όταν πρέπει να μεταφέρετε ένα ή περισσότερα συγκεκριμένα commits χωρίς τη μεταφορά ολόκληρου του branch. Το merge χρησιμοποιείται για πλήρη συγχώνευση branches. Το τυπικό σενάριο cherry-pick είναι η μεταφορά διόρθωσης σφάλματος από το development branch στο release branch, όπου οι υπόλοιπες αλλαγές δεν είναι ακόμη έτοιμες.
Πριν την ολοκλήρωση — git cherry-pick --abort ακυρώνει την λειτουργία πλήρως. Μετά από επιτυχή ολοκλήρωση — git revert <hash> δημιουργεί ένα commit που ακυρώνει τις αλλαγές του cherry-pick. Διαφορά από το --abort: το revert δεν αφαιρεί το commit από το ιστορικό, αλλά δημιουργεί ένα νέο commit ακύρωσης.
Ένα κενό commit προκύπτει όταν οι αλλαγές είναι ήδη παρούσες στο branch-στόχο. Χρησιμοποιείτε git cherry-pick --skip για να παραλείψετε τέτοιο commit, ή git cherry-pick --keep-redundant-commits για να δημιουργήσετε κενό commit για διατήρηση της σειράς των hash.
Cherry-pick μεταφέρει επιλεγμένα commits (ένα ή λίστα) στο τρέχον branch. Rebase μεταφέρει όλα τα commits ενός branch σε νέα βάση. Το cherry-pick δεν τροποποιεί το αρχικό branch, το rebase επαναγράφει το ιστορικό. Το cherry-pick είναι ακριβές αλλά χειροκίνητο; το rebase είναι αυτόματο αλλά επικίνδυνο για δημόσια branches.
Συμπεράσματα
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης