Merge — είναι η λειτουργία συγχώνευσης κλάδων στο Git, η οποία συνδυάζει αλλαγές από δύο διαφορετικές γραμμές ανάπτυξης σε έναν κλάδο-στόχο. Σε αντίθεση με το rebase, το merge διατηρεί πλήρες ιστορικό διακλάδωσης, δημιουργώντας ένα ειδικό merge-commit με δύο γονείς. Σύμφωνα με την επίσημη τεκμηρίωση Git (2026), το merge είναι ο ασφαλέστερος τρόπος συγχώνευσης κλάδων, καθώς δεν αντικαθιστά το ιστορικό και επιτρέπει την παρακολούθηση του πότε και ποιοι κλάδοι συγχωνεύτηκαν. Είναι η τυπική επιλογή για συγχώνευση σε δημόσιους κλάδους όπως main, develop και release.
Κύρια σημεία
Merge — είναι η εντολή git merge που συνδυάζει αλλαγές από τον καθορισμένο κλάδο στον τρέχοντα κλάδο. Το Git βρίσκει τον κοινό πρόγονο (κοινό base commit), υπολογίζει το diff κάθε κλάδου σε σχέση με τον πρόγονο και δημιουργεί ένα merge-commit που περιέχει το συνδυασμένο σύνολο αλλαγών. Αποτέλεσμα — ο κλάδος-στόχος συμπληρώνεται με όλες τις αλλαγές από τον συγχωνευμένο κλάδο.
Σύνταξη: βρισκόμενοι στον κλάδο-στόχο (π.χ. main), εκτελέστε git merge feature. Το Git δημιουργεί αυτόματα ένα merge-commit, εάν δεν υπάρχουν συγκρούσεις. Στο προεπιλεγμένο μήνυμα του merge-commit αναγράφεται: “Merge branch ’feature’ into main”. Το μήνυμα μπορεί να αλλάξει μέσω του flag -m ή να επεξεργαστεί στον ανοιχτό επεξεργαστή.
Το merge είναι μια μη καταστροφική λειτουργία. Σε αντίθεση με το rebase, το merge δεν αγγίζει υπάρχοντα commits: παραμένουν με τα ίδια hashes, συγγραφείς και ημερομηνίες. Αυτό καθιστά το merge τον μοναδικό ασφαλή τρόπο συγχώνευσης για κλάδους στους οποίους εργάζονται ταυτόχρονα πολλοί προγραμματιστές. Εάν κάτι πάει στραβά, το merge μπορεί να ακυρωθεί με την εντολή git merge --abort.
# Μετάβαση στον κλάδο-στόχο
git checkout main
# Συγχώνευση feature κλάδου
git merge feature
# Αποτέλεσμα — merge-commit με δύο γονείς
git log --oneline --graph
# Συγχώνευση με προσαρμοσμένο μήνυμα
git merge feature -m "feat: integrate authentication module"
Το Git υποστηρίζει τρεις λειτουργίες συγχώνευσης, οι οποίες επιλέγονται ανάλογα με το επιθυμητό αποτέλεσμα. Το regular merge (προεπιλογή) δημιουργεί merge-commit. Το squash merge συνδυάζει όλα τα commits του feature κλάδου σε ένα. Fast-forward — μετακινεί τον δείκτη του κλάδου προς τα εμπρός χωρίς να δημιουργεί commit, εάν είναι δυνατόν. Η επιλογή λειτουργίας εξαρτάται από το workflow της ομάδας και τους κανόνες ιστορικού.
Regular merge (--no-ff) — δημιουργεί merge-commit ακόμα κι αν η συγχώνευση μπορεί να εκτελεστεί ως fast-forward. Συνιστάται για τον κλάδο main: το merge-commit σηματοδοτεί ρητά τη στιγμή ενσωμάτωσης του feature και επιτρέπει την εύκολη επαναφορά όλων των αλλαγών του feature κλάδου με ένα revert του merge-commit. Το GitHub χρησιμοποιεί αυτή τη λειτουργία από προεπιλογή κατά τη συγχώνευση PR μέσω του κουμπιού Merge.
Squash merge (--squash) — συλλέγει όλα τα commits του feature κλάδου σε ένα commit στον κλάδο-στόχο. Χρήσιμο όταν η πρόχειρη ιστορία του feature κλάδου δεν πρέπει να εισέλθει στο main. Μειονέκτημα: χάνεται η σύνδεση με τα αρχικά commits — δεν μπορείτε να δείτε πώς το feature αναπτύχθηκε βήμα προς βήμα. Το GitHub χρησιμοποιεί αυτή τη λειτουργία όταν επιλέγει “Squash and merge” στο PR.
Fast-forward (--ff) — εάν ο κλάδος-στόχος δεν έχει νέα commits μετά τη διακλάδωση του feature, το Git απλώς μετακινεί τον δείκτη προς τα εμπρός, χωρίς να δημιουργεί merge-commit. Το ιστορικό παραμένει γραμμικό. Το flag --no-ff εξαναγκάζει τη δημιουργία merge-commit, το --ff-only θα τερματιστεί με σφάλμα εάν το fast-forward δεν είναι δυνατό.
# Εξαναγκασμός merge-commit (συνιστάται για main)
git merge --no-ff feature
# Squash merge — όλα τα commits σε ένα
git merge --squash feature
git commit -m "feat: add authentication"
# Fast-forward μόνο εάν είναι δυνατό
git merge --ff-only feature
# Ακύρωση συγχώνευσης με σύγκρουση
git merge --abort
Οι στρατηγικές συγχώνευσης καθορίζουν τον αλγόριθμο που χρησιμοποιεί το Git για τον συνδυασμό αλλαγών. Κάθε στρατηγική είναι κατάλληλη για διαφορετικά σενάρια. Το Git επιλέγει αυτόματα την κατάλληλη στρατηγική, αλλά ο προγραμματιστής μπορεί να την υποδείξει ρητά μέσω του flag --strategy. Η κατανόηση των στρατηγικών βοηθά στην πρόβλεψη της συμπεριφοράς του Git σε σύνθετες συγχωνεύσεις.
Recursive — η προεπιλεγμένη στρατηγική για συγχώνευση δύο κλάδων. Το Git βρίσκει τον κοινό πρόγονο, υπολογίζει τις αλλαγές σε κάθε κλάδο και τις συνδυάζει. Εάν βρεθεί ο κοινός πρόγονος, το recursive χειρίζεται σωστά τη μετονομασία αρχείων και την προσθήκη νέων. Σε συγκρούσεις, το recursive μπορεί να χρησιμοποιήσει πρόσθετες επιλογές: ours (αυτόματη επιλογή της δικής μας έκδοσης) και theirs (επιλογή της δικής τους).
Octopus — για ταυτόχρονη συγχώνευση περισσότερων από δύο κλάδων: git merge feature1 feature2 feature3. Το Octopus δεν υποστηρίζει επίλυση συγκρούσεων — όλες οι συγκρούσεις πρέπει να επιλυθούν πριν από την κλήση της εντολής. Χρησιμοποιείται σπάνια, κυρίως για συνδυασμό πολλών ανεξάρτητων κλάδων που είναι εγγυημένο ότι δεν συγκρούονται (π.χ. διαφορετικές μονάδες).
| Στρατηγική | Αριθμός κλάδων | Επίλυση συγκρούσεων |
|---|---|---|
| Recursive | 2 | Αυτόματη + επιλογές ours/theirs |
| Octopus | 3+ | Όχι — όλες οι συγκρούσεις πρέπει να επιλυθούν εκ των προτέρων |
| Ours | Οποιοσδήποτε | Επιλέγει πάντα τη δική μας έκδοση, οι ξένες αλλαγές αγνοούνται |
| Subtree | 2 | Για συγχώνευση υποδέντρων (subtree merge) |
Ours — μια ειδική στρατηγική που αγνοεί πλήρως τις αλλαγές από τον συγχωνευμένο κλάδο και διατηρεί το τρέχον περιεχόμενο του κλάδου-στόχου. Το merge-commit δημιουργείται, αλλά το περιεχόμενο παραμένει αμετάβλητο. Χρήσιμο όταν πρέπει να καταγράψετε στο ιστορικό το γεγονός της συγχώνευσης, αλλά στην πράξη να απορρίψετε όλες τις αλλαγές από τον ξένο κλάδο.
Σύγκρουση merge προκύπτει όταν οι ίδιες γραμμές ενός αρχείου έχουν τροποποιηθεί διαφορετικά και στους δύο κλάδους. Το Git δεν μπορεί να καθορίσει αυτόματα ποια έκδοση είναι σωστή και διακόπτει το merge. Σύγκρουση μπορεί επίσης να προκύψει κατά τη μετονομασία αρχείου σε έναν κλάδο και την τροποποίησή του σε άλλον, ή κατά την ταυτόχρονη διαγραφή και τροποποίηση του ίδιου αρχείου.
Διαδικασία επίλυσης: Το Git επισημαίνει τα αρχεία με σύγκρουση με δείκτες. Στο αρχείο εμφανίζονται τμήματα με <<<<<<< HEAD (δική μας έκδοση), ======= (διαχωριστικό) και >>>>>>> feature (δική τους έκδοση). Ο προγραμματιστής επεξεργάζεται χειροκίνητα το τμήμα σύγκρουσης, επιλέγοντας τις απαραίτητες γραμμές και από τις δύο εκδόσεις, αφαιρεί τους δείκτες, αποθηκεύει το αρχείο και το προσθέτει στο ευρετήριο μέσω git add.
Για οπτική επίλυση συγκρούσεων, το Git υποστηρίζει το mergetool — ένα εξωτερικό εργαλείο σύγκρισης. Δημοφιλή εργαλεία mergetool: Meld, KDiff3, Beyond Compare, VS Code (ενσωματωμένος επεξεργαστής συγκρούσεων). Το Mergetool εμφανίζει τρία πάνελ: τη δική μας έκδοση, τη δική τους έκδοση και το αποτέλεσμα. Ο προγραμματιστής επιλέγει οπτικά τα μπλοκ κώδικα για συμπερίληψη στο τελικό αρχείο.
# Έναρξη συγχώνευσης και ανίχνευση σύγκρουσης
git merge feature
# ΣΥΓΚΡΟΥΣΗ (περιεχόμενο): Σύγκρουση συγχώνευσης στο src/main.swift
# Έλεγχος αρχείων με σύγκρουση
git status
# Άνοιγμα οπτικού mergetool
git mergetool
# Μετά την επίλυση — προσθήκη και commit
git add src/main.swift
git commit
# Ακύρωση συγχώνευσης
git merge --abort
Το merge προτιμάται έναντι του rebase σε αρκετές βασικές καταστάσεις. Πρώτον: όταν εργάζεστε με δημόσιους κλάδους προσβάσιμους σε άλλους προγραμματιστές. Το merge δεν αντικαθιστά το ιστορικό και οι συνάδελφοι μπορούν να συγχρονιστούν με ασφάλεια. Το rebase σε έναν δημόσιο κλάδο θα δημιουργήσει αποκλίνον ιστορικό και συγκρούσεις για όλους όσους έχουν ήδη λάβει τα παλιά commits.
Δεύτερη κατάσταση: κατά την ολοκλήρωση ενός feature κλάδου. Οι περισσότερες ομάδες προτιμούν το merge (με το flag --no-ff) στο main για να καταγράψουν τη στιγμή ενσωμάτωσης του feature. Αυτό απλοποιεί την πλοήγηση στο ιστορικό και επιτρέπει την εύκολη επαναφορά ολόκληρου του feature με ένα git revert του merge-commit. Το GitHub Flow προσφέρει από προεπιλογή τρεις επιλογές merge: απλό merge, squash merge και rebase merge.
Τρίτη κατάσταση: κατά την εργασία με pull request που έχει περάσει από αναθεώρηση. Το GitHub και το GitLab προσφέρουν κουμπί merge με διαφορετικές επιλογές. Merge (Create a merge commit) — πλήρες ιστορικό με merge-commit. Squash and merge — καθαρό ιστορικό χωρίς λεπτομέρειες ανάπτυξης. Rebase and merge — γραμμικό ιστορικό χωρίς merge-commit, αλλά με αντικατάσταση commits. Η επιλογή εξαρτάται από τους κανόνες της ομάδας.
Πρώτος κανόνας: να είστε πάντα στην ενημερωμένη έκδοση του κλάδου-στόχου πριν από το merge. Εκτελέστε git checkout main && git pull πριν συγχωνεύσετε το feature. Αυτό ελαχιστοποιεί τις συγκρούσεις και εγγυάται ότι το merge-commit θα περιέχει όλες τις τρέχουσες αλλαγές. Εάν ο κλάδος-στόχος έχει προχωρήσει πολύ μπροστά, εκτελέστε πρώτα git merge main μέσα στον feature κλάδο για να επιλύσετε συγκρούσεις στο πλαίσιό του.
Δεύτερος κανόνας: δοκιμάστε τον κώδικα μετά το merge. Το merge μπορεί να αλλάξει τη συμπεριφορά, ακόμα κι αν δεν υπήρξαν συγκρούσεις. Ο αγωγός CI/CD πρέπει να εκτελέσει δοκιμές στο merge-commit πριν από την αποστολή στην παραγωγή. Ορισμένες ομάδες χρησιμοποιούν merge gates — υποχρεωτικούς ελέγχους που μπλοκάρουν το merge μέχρι να ολοκληρωθούν.
Τρίτος κανόνας: τεκμηριώστε τα merge-commits. Το τυπικό μήνυμα “Merge branch ’feature’ into main” είναι ελάχιστα χρήσιμο. Συνιστάται η προσθήκη περιγραφής του τι συγχωνεύτηκε: “Merge authentication module: login, registration, password recovery”. Αυτό απλοποιεί την ανάλυση του ιστορικού και την αναζήτηση παλινδρομήσεων. Σε μεγάλα έργα, τα merge-commits δημιουργούνται αυτόματα από το όνομα του PR.
Συχνές ερωτήσεις
Συγχώνευση (merge) — εκτέλεση git merge για συνδυασμό αλλαγών από έναν κλάδο σε άλλον. Το αποτέλεσμα είναι ένα merge-commit που καταγράφει το γεγονός της συγχώνευσης και περιέχει αλλαγές και από τους δύο κλάδους. Αυτός είναι ο κύριος τρόπος ενσωμάτωσης feature κλάδων στο main, develop ή release στο Git Flow.
Squash merge συνδυάζει όλα τα commits του feature κλάδου σε ένα commit στον κλάδο-στόχο, χάνοντας το ενδιάμεσο ιστορικό ανάπτυξης. Κανονικό merge δημιουργεί ένα merge-commit, διατηρώντας όλα τα commits του feature κλάδου. Το squash merge δίνει καθαρό ιστορικό, αλλά δεν επιτρέπει την παρακολούθηση της βήμα-προς-βήμα ανάπτυξης του feature.
Ανοίξτε το αρχείο με σύγκρουση, βρείτε τα τμήματα με δείκτες <<<<<<< HEAD και >>>>>>>. Επεξεργαστείτε το περιεχόμενο, αφήνοντας τις απαραίτητες γραμμές και από τις δύο εκδόσεις, αφαιρέστε τους δείκτες. Αποθηκεύστε το αρχείο, εκτελέστε git add και git commit. Μπορείτε να χρησιμοποιήσετε το git mergetool για οπτική επίλυση.
Merge χρησιμοποιείται πάντα για δημόσιους κλάδους (main, develop, release), καθώς δεν αντικαθιστά το ιστορικό. Rebase εφαρμόζεται σε προσωπικούς feature κλάδους πριν από τη δημοσίευσή τους. Αφού ο κλάδος γίνει μέρος του κοινόχρηστου αποθετηρίου και οι συνάδελφοι αναφερθούν σε αυτόν, επιτρέπεται μόνο το merge.
Πριν από την ολοκλήρωση του merge (κατά τη διάρκεια σύγκρουσης) — git merge --abort ακυρώνει πλήρως τη συγχώνευση. Μετά την ολοκλήρωση — git revert <merge-commit-hash> -m 1 δημιουργεί ένα commit αναίρεσης. Το flag -m 1 υποδεικνύει ποιον γονικό κλάδο να διατηρηθεί (στόχο). Το git revert είναι ασφαλέστερο από το git reset για δημοσιευμένους κλάδους.
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης