Παράρτημα: Διαφορά μεταξύ git merge και git rebase

4 λεπτά

Πλαίσιο

Σε αυτό το παράδειγμα, έχουμε ένα αποθετήριο με έναν κύριο κλάδο main που περιέχει ένα βασικό αρχείο fichier1.txt και ένα πρώτο αρχικό commit. Από το main, δημιουργούμε δύο κλάδους, branche1 και branche2, ο καθένας προορισμένος να δοκιμάσει αντίστοιχα το rebase και το merge. Έπειτα δημιουργούνται δύο επιπλέον κλάδοι εργασίας, branche-rebase από το branche1 και branche-merge από το branche2, για να προστεθούν τροποποιήσεις.

Αρχικό ιστορικό

Το έργο ξεκινά με ένα αποθετήριο που περιέχει ένα μόνο commit στο main, που αντιστοιχεί στη δημιουργία του αρχείου fichier1.txt:

plaintext
(main)
A               # Αρχικό commit με fichier1.txt

Στο commit A, προσθέσαμε το αρχείο fichier1.txt με αρχικό περιεχόμενο.

Έπειτα δημιουργούνται δύο νέοι κλάδοι από το main:

  1. branche1: προορίζεται να φιλοξενήσει το branche-rebase για δοκιμή του git rebase.
  2. branche2: προορίζεται να φιλοξενήσει το branche-merge για δοκιμή του git merge.

Εργασία σε κάθε κλάδο εργασίας

Σε κάθε κλάδο εργασίας (branche-rebase και branche-merge), κάνουμε τρία διακριτά commits. Ακολουθούν τα commits λεπτομερώς για κάθε κλάδο:

plaintext
(main)
A

(branche-rebase)
       \
        D---E---F   # Commits προστεθειμένα στο branche-rebase

(branche-merge)
       \
        G---H---I   # Commits προστεθειμένα στο branche-merge
  1. Commits στο branche-rebase:

    • Commit D: Δημιουργία του αρχείου fichier-2-rebase.txt με αρχικό περιεχόμενο "Modification 1 dans branche-rebase".
    • Commit E: Προσθήκη του "Modification 2 dans branche-rebase" στο ίδιο αρχείο fichier-2-rebase.txt.
    • Commit F: Προσθήκη του "Modification 3 dans branche-rebase" στο ίδιο αρχείο fichier-2-rebase.txt.
  2. Commits στο branche-merge:

    • Commit G: Δημιουργία του αρχείου fichier-2-merge.txt με αρχικό περιεχόμενο "Modification 1 dans branche-merge".
    • Commit H: Προσθήκη του "Modification 2 dans branche-merge" στο ίδιο αρχείο fichier-2-merge.txt.
    • Commit I: Προσθήκη του "Modification 3 dans branche-merge" στο ίδιο αρχείο fichier-2-merge.txt.

Αυτά τα commits προσθέτουν πανομοιότυπο περιεχόμενο, αλλά σε διαφορετικά αρχεία (fichier-2-rebase.txt και fichier-2-merge.txt), για σαφή σύγκριση μεταξύ merge και rebase.


Βήμα 1: Συγχώνευση του branche-merge στο branche2 με git merge

Για να ενσωματώσουμε τις τροποποιήσεις του branche-merge στο branche2, χρησιμοποιούμε την εντολή git merge στο branche2. Αυτή η λειτουργία δημιουργεί ένα commit συγχώνευσης που διατηρεί πλήρες ιστορικό και περιλαμβάνει τα commits του κλάδου εργασίας χωρίς να τα αναδιοργανώνει.

Το ιστορικό μετά το merge:

plaintext
(branche2)
A-------J        # J είναι το commit συγχώνευσης
 \       |
  \      |
   G---H---I     # το branche-merge διατηρεί το διακριτό ιστορικό του
  • Εξήγηση των commits:
    • Commit J: Commit συγχώνευσης που συνδυάζει το περιεχόμενο του branche2 με τις τροποποιήσεις του branche-merge (G, H, I) χωρίς να τις μετακινεί ούτε να αλλάζει τη σειρά τους.
  • Παρατήρηση: Με το git merge, το ιστορικό δείχνει ένα «σημείο σύνδεσης» που υποδεικνύει οπτικά πού συγχωνεύθηκε το branche-merge στο branche2. Αυτό διατηρεί πλήρες και διακριτό ιστορικό για κάθε κλάδο, κάτι που είναι συχνά χρήσιμο σε συνεργατικά έργα.

Βήμα 2: Ενσωμάτωση του branche-rebase στο branche1 με git rebase

Για να ενσωματώσουμε τις τροποποιήσεις του branche-rebase στο branche1, χρησιμοποιούμε την εντολή git rebase. Σε αντίθεση με το merge, το rebase επανατοποθετεί τα commits (D, E, F) του branche-rebase σαν να είχαν δημιουργηθεί μετά το τελευταίο commit του branche1 (A).

Το ιστορικό μετά το rebase:

plaintext
(branche1)
A---D'---E'---F'   # Commits του branche-rebase ξαναεφαρμοσμένα στο τέλος του branche1
  • Εξήγηση των commits:
    • Commits D', E', F': Ξαναπαιγμένα commits του branche-rebase εφαρμοσμένα γραμμικά μετά το A στο branche1.
  • Παρατήρηση: Με το git rebase, τα commits του branche-rebase αναδιοργανώνονται ώστε να σχηματίσουν γραμμικό ιστορικό χωρίς «σημείο σύνδεσης», σαν να είχαν προστεθεί απευθείας μετά το αρχικό commit A. Αυτό απλοποιεί το ιστορικό κάνοντάς το καθαρότερο, αλλά μπορεί να κρύψει τη διαδρομή των αρχικών κλάδων εργασίας.

Τελική σύγκριση

Οι διαφορές που παρατηρούνται στα logs του Git επιτρέπουν καλύτερη κατανόηση των ειδικών χρήσεων του merge και του rebase.

  • git merge:

    • Αποτέλεσμα: Διατηρεί πλήρες ιστορικό με commit συγχώνευσης που σηματοδοτεί τη σύνδεση των κλάδων.
    • Πλεονέκτημα: Ιδανικό για παρακολούθηση πλήρους ιστορικού σε συνεργατικά έργα, γιατί κάθε σύνδεση είναι ορατή.
    • Μειονέκτημα: Το ιστορικό μπορεί να γίνει σύνθετο με πολλές συνδέσεις, ειδικά σε έργα με πολλούς κλάδους.
  • git rebase:

    • Αποτέλεσμα: Αναδιοργανώνει τα commits ώστε να τοποθετηθούν γραμμικά στο τέλος του κύριου κλάδου, χωρίς να δημιουργεί commit συγχώνευσης.
    • Πλεονέκτημα: Ιδανικό για γραμμικό και καθαρό ιστορικό, ελαχιστοποιώντας τις συνδέσεις. Προτιμάται συχνά σε μικρά έργα ή για καθαρισμό του ιστορικού πριν την κοινοποίηση.
    • Μειονέκτημα: Μπορεί να κρύψει τη διαδρομή των κλάδων εργασίας, κάτι που μπορεί να δημιουργήσει πρόβλημα αν πολλά άτομα εργάζονται στους ίδιους κλάδους.

Σύνοψη

ΕντολήΙστορικόΙδανική περίπτωση χρήσης
git mergeΠλήρες ιστορικό με σημείο σύνδεσηςΣυνεργατικά έργα με πολλούς κλάδους
git rebaseΓραμμικό ιστορικό χωρίς σημεία σύνδεσηςΚαθαρισμός του ιστορικού πριν από κοινόχρηστο merge

Συνοπτικά:

plaintext
git merge   ->  Πλήρες ιστορικό με commit συγχώνευσης
git rebase  ->  Γραμμικό ιστορικό χωρίς commit συγχώνευσης

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