Skip to content

Latest commit

 

History

History
807 lines (637 loc) · 66 KB

contributing.asc

File metadata and controls

807 lines (637 loc) · 66 KB

Συνεισφέροντας σε ένα έργο

Η κύρια δυσκολία με την περιγραφή του τρόπου με τον οποίο μπορεί να συνεισφέρει κανείς σε ένα έργο είναι ότι υπάρχει ένας τεράστιος αριθμός παραλλαγών στον τρόπο γίνεται κάτι τέτοιο. Επειδή το Git είναι πολύ ευέλικτο, οι χρήστες του έχουν τη δυνατότητα να συνεργάζονται με πολλούς τρόπους και πράγματι το κάνουν, κάτι που καθιστά δύσκολο να περιγράψει κανείς πώς πρέπει να συνεισφέρετε --κάθε έργο είναι λίγο διαφορετικό από τα άλλα. Ορισμένοι από τους παράγοντες που χρειάζεται να λάβετε υπόψη είναι ο ενεργός αριθμός συνεργατών, η ροή εργασίας που έχει επιλεχθεί, η πρόσβασή σας στις υποβολές και ενδεχομένως η μέθοδος εξωτερικής συνεισφοράς.

Ο πρώτος παράγοντας είναι ο ενεργός αριθμός συνεργατών --πόσοι χρήστες συμβάλλουν ενεργά στον κώδικα αυτού του έργου και πόσο συχνά; Σε πολλές περιπτώσεις, θα έχετε δύο ή τρεις προγραμματιστές με κάποιες υποβολές ανά ημέρα ή και λιγότερες για κάπως αδρανή έργα. Για μεγαλύτερες εταιρείες ή έργα, ο αριθμός των προγραμματιστών μπορεί να φτάσει τις χιλιάδες, με εκατοντάδες ή χιλιάδες υποβολές να καταφτάνουν κάθε μέρα. Αυτός ο παράγοντας είναι σημαντικός επειδή όσο περισσότεροι προγραμματιστές εμπλέκονται, τόσο περισσότερα θέματα έχετε όσον αφορά στην καθαρή εφαρμογή και ευκολία συγχώνευσης του κώδικά σας. Οι αλλαγές που υποβάλετε ενδέχεται να καταστούν παρωχημένες ή να αλλοιωθούν σε σημαντικό βαθμό από εργασίες που συγχωνεύονται ενώ εργάζεστε ή ενώ οι αλλαγές σας αναμένουν έγκριση ή εφαρμογή. Πώς, λοιπόν, μπορείτε να διατηρήσετε τον κώδικά σας συνεχώς ενημερωμένο και τις υποβολές σας έγκυρες;

Ο επόμενος παράγοντας είναι η ροή εργασίας που χρησιμοποιείται στο έργο. Είναι συγκεντρωτική με κάθε προγραμματιστή να έχει ισότιμη πρόσβαση για εγγραφή στην κύρια γραμμή παραγωγής κώδικα; Έχει το πρόγραμμα κάποιον συντηρητή ή διαχειριστή ενσωμάτωσης, ο οποίος ελέγχει όλα τα επιθέματα; Περνούν τα επιθέματα κάποια διαδικασία ελέγχου από συνεργάτες ή έγκρισης; Συμμετέχετε εσείς σε αυτή τη διαδικασία; Υπάρχει σύστημα υπαρχηγού και πρέπει πρώτα να υποβάλλετε την εργασία σας πρώτα σε αυτόν;

Ο επόμενος παράγοντας είναι η το επίπεδο πρόσβασής σας όσον αφορά στις υποβολές. Η ροή εργασίας που απαιτείται για να συνεισφέρετε σε ένα έργο είναι πολύ διαφορετική εάν έχετε πρόσβαση για εγγραφή στο έργο απ' ό,τι αν δεν έχετε. Εάν δεν έχετε πρόσβαση για εγγραφή, πώς προτιμά το έργο να δέχεται συνεισφερόμενη εργασία; Υπάρχει κάποια σχετική πολιτική; Πόση δουλειά υποβάλετε κάθε φορά; Πόσο συχνά συμβάλλετε;

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

Κατευθυντήριες γραμμές για τις υποβολές

Πριν ξεκινήσετε να εξετάζετε τις συγκεκριμένες περιπτώσεις χρήσης, ας δούμε μιλήσουμε λίγο για τα μηνύματα υποβολής. Η ύπαρξη καλών κατευθυντήριων γραμμών σχετικά με τη δημιουργία υποβολών και η τήρησή τους διευκολύνουν την εργασία με το Git και τη συνεργασία με άλλους. Το έργο Git παρέχει ένα έγγραφο που παραθέτει πολλές καλές συμβουλές για τη δημιουργία υποβολών για επιθέματα — μπορείτε να το διαβάσετε στον πηγαίο κώδικα του Git στο αρχείο Documentation/SubmittingPatches.

Καταρχάς δεν θέλετε οι υποβολές σας να έχουν προβλήματα με τους λευκούς χαρακτήρες (whitespace). Το Git παρέχει έναν εύκολο τρόπο για να ελέγξετε τέτοιου είδους σφάλματα — προτού υποβάλλετε, εκτελείτε την εντολή git diff --check, η οποίο προσδιορίζει πιθανά σφάλματα διαστημάτων και σας τα παραθέτει.

Έξοδος μίας `git diff --check`.
Figure 1. Έξοδος μίας git diff --check.

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

Δεύτερον, προσπαθήστε ώστε κάθε υποβολή να έχει ένα λογικά διακριτό σύνολο αλλαγών. Αν είναι δυνατό, προσπαθείτε να κάνετε τις αλλαγές σας εύπεπτες — ας μην γράφετε κώδικα για ένα ολόκληρο Σαββατοκύριακο σε πέντε διαφορετικά θέματα και στη συνέχεια τα υποβάλλετε όλα ως μια τεράστια υποβολή τη Δευτέρα. Ακόμη και αν δεν υποβάλλετε μέσα στο Σαββατοκύριακο, χρησιμοποιήστε τον προθάλαμο τη Δευτέρα για να διαχωρίσετε την εργασία σας σε τουλάχιστον μία υποβολή ανά ζήτημα, με ένα χρήσιμο μήνυμα ανά υποβολή. Εάν ορισμένες από τις αλλαγές τροποποιούν το ίδιο αρχείο, προσπαθείτε να χρησιμοποιήσετε το git add --patch ώστε να τοποθετείτε μερικώς αρχεία στον προθάλαμο (αυτό καλύπτεται σε βάθος στην ενότητα ch07-git-tools.asc). Το στιγμιότυπο του έργου στην άκρη του κλάδου είναι το ίδιο είτε πραγματοποιείτε μία υποβολή είτε πέντε, εφόσον όλες οι αλλαγές προστίθενται σε κάποιο σημείο, οπότε προσπαθήστε να διευκολύνετε τους συνεργάτες σας όταν θα πρέπει να ελέγξουν τις αλλαγές σας.

Αυτή η προσέγγιση διευκολύνει επίσης την απόσυρση ή επαναφορά κάποιου συνόλου αλλαγών, εφόσον χρειαστεί να γίνει κάτι τέτοιο αργότερα. Η ενότητα ch07-git-tools.asc περιγράφει μια σειρά από χρήσιμα κόλπα που παρέχει το Git για την επανεγγραφή του ιστορικού και την αλληλεπιδραστική τοποθέτηση αρχείων στον προθάλαμο· χρησιμοποιήστε αυτά τα εργαλεία για να δημιουργήσετε ένα καθαρό και κατανοητό ιστορικό πριν στείλετε το έργο σε κάποιον άλλο.

Το τελευταίο πράγμα που πρέπει να έχετε υπόψη είναι το μήνυμα υποβολής. Η δημιουργία μηνυμάτων υψηλής ποιότητας διευκολύνει τη χρήση του Git και τη συνεργασία. Έχετε ως γενικό κανόνα τα μηνύματά σας να ξεκινούν με μία μόνο γραμμή που δεν υπερβαίνει τους 50 χαρακτήρες και περιγράφει συνοπτικά το σύνολο αλλαγών, να ακολουθεί μια κενή γραμμή και στη συνέχεια να ακολουθεί μια πιο λεπτομερής εξήγηση. Το έργο Git απαιτεί η λεπτομερέστερη εξήγηση να περιλαμβάνει το κίνητρό σας για την αλλαγή και να αντιπαραβάλλετε την εφαρμογή της με την προηγούμενη συμπεριφορά — αυτή είναι μια καλή κατευθυντήρια γραμμή που πρέπει να ακολουθείτε. Επίσης είναι καλή ιδέα να χρησιμοποιείτε την προστακτική έγκλιση σε αυτά τα μηνύματα: Αντί για “Διόρθωσα ένα bug” ή “Διόρθωση bug”, χρησιμοποιείτε “Διόρθωσε bug”. Ακολουθεί ένα πρότυπο που μπορείτε να ακολουθείτε και το οποίο έχουμε τροποποιήσει ελαφρά από αυτό που γράφτηκε από τον Tim Pope:

Σύντομη (το πολύ 50 χαρακτήρες) περίληψη των αλλαγών

Λεπτομερέστερη περιγραφή, εφόσον είναι απαραίτητη.  Αναδιπλώνετε σε
περίπου 72 χαρακτήρες.  Σε κάποιες περιστάσεις η πρώτη γραμμή
αντιμετωπίζεται ως το θέμα ενός e-mail και οι υπόλοιπες ως το σώμα του.
Η κενή γραμμή που χωρίζει την περίληψη από τη λεπτομερή περιγραφή
είναι σημαντική (εκτός κι αν η λεπτομερής περιγραφή παραλείπεται
τελείως)· εργαλεία όπως η αλλαγή βάσης (rebase) μπορεί να προκαλέσουν
σύγχυση αν εκτελείτε και δύο ταυτόχρονα.

Γράψτε το μήνυμα υποβολής σας στην προστακτική : "Διόρθωσε bug" και
όχι "Διόρθωσα bug" ή "Διορθώνει bug."  Αυτή η σύμβαση ταιριάζει
με τα μηνύματα υποβολής που δημιουργούν εντολές όπως οι git merge
και git revert.

Περαιτέρω παράγραφοι έρχονται μετά από κενές γραμμές.

- Λίστες με κουκκίδες είναι αποδεκτές

- Συνήθως χρησιμοποιείται παύλα ή αστερίσκος αντί για κουκκίδα,
   ακολουθεί ένα κενό και κενές γραμμές ανάμεσα στα σημεία
   αλλά οι συμβάσεις ποικίλλουν σε αυτό το σημείο

- Χρησιμοποιήστε προεξοχή πρώτης γραμμής

Αν όλα τα μηνύματα υποβολών σας έχουν αυτή τη μορφή, θα διευκολύνεστε τόσο εσείς όσο και οι συνεργάτες σας. Tο έργο Git έχει καλά μορφοποιημένα μηνύματα υποβολών. Αν τρέξετε git log --no-merges θα δείτε πώς φαίνεται ένα όμορφα μορφοποιημένο ιστορικό υποβολών ενός έργου.

Note
Κάντε ό,τι λέμε, όχι ό,τι κάνουμε.

Για χάρη συντομίας, For the sake of brevity, many of the examples in this book don’t have nicely-formatted commit messages like this; instead, we simply use the -m option to git commit.

In short, do as we say, not as we do.

πολλά από τα παραδείγματα αυτού του βιβλίου δεν έχουν μηνύματα υποβολών που είναι μορφοποιημένα όμορφα, όπως παραπάνω· αντί γι' αυτό χρησιμοποιούμε την επιλογή -m στην εντολή git commit.

Πιο απλά, κάντε ό,τι λέμε, όχι ό,τι κάνουμε.

Ιδιωτικές μικρές ομάδες

Η απλούστερη ρύθμιση που ενδεχομένως θα συναντήσετε είναι ένα ιδιωτικό έργο με έναν ή δύο ακόμα προγραμματιστές. “Ιδιωτικό” εδώ σημαίνει κλειστού-κώδικα — που δεν είναι προσβάσιμος από τον έξω κόσμο. Εσείς και όλοι οι άλλοι προγραμματιστές έχετε πρόσβαση ώθησης στο αποθετήριο.

Σε αυτό το περιβάλλον, μπορείτε να ακολουθήσετε μια ροή εργασίας παρόμοια με αυτή που θα ακολουθούσαμε αν χρησιμοποιούσαμε το Subversion ή κάποιο άλλο συγκεντρωτικό σύστημα. Συνεχίζετε να έχετε πλεονεκτήματα όπως η υποβολή εκτός σύνδεσης και η απλούστερη διακλάδωση και συγχώνευση, αλλά η ροή εργασίας μπορεί να είναι πολύ παρόμοια· η κύρια διαφορά είναι ότι οι συγχωνεύσεις συμβαίνουν στην πλευρά του πελάτη αντί στον διακομιστή κατά τη διάρκεια της υποβολής. Ας δούμε τι μπορεί να συμβαίνει όταν δύο προγραμματιστές αρχίζουν να συνεργάζονται σε ένα κοινό αποθετήριο. Ο πρώτος προγραμματιστής, ο Τζον, κλωνοποιεί το αποθετήριο, κάνει μια αλλαγή και την υποβάλλει τοπικά. (Τα μηνύματα πρωτοκόλλου έχουν αντικατασταθεί με …​ σε αυτά τα παραδείγματα για να τα συντομεύσουμε κάπως.)

# Μηχάνημα του Τζον
$ git clone john@githost:simplegit.git
Cloning into 'simplegit'...
...
$ cd simplegit/
$ vim lib/simplegit.rb
$ git commit -am 'Remove invalid default value'
[master 738ee87] Remove invalid default value
 1 files changed, 1 insertions(+), 1 deletions(-)

Η δεύτερη προγραμματίστρια, η Τζέσικα, κάνει το ίδιο πράγμα — κλωνοποιεί το αποθετήριο και κάνει μια αλλαγή:

# Μηχάνημα της Τζέσικα
$ git clone jessica@githost:simplegit.git
Cloning into 'simplegit'...
...
$ cd simplegit/
$ vim TODO
$ git commit -am 'Add reset task'
[master fbff5bc] Add reset task
 1 files changed, 1 insertions(+), 0 deletions(-)

Τώρα, η Τζέσικα ωθεί την εργασία της στον διακομιστή:

# Μηχάνημα της Τζέσικα
$ git push origin master
...
To jessica@githost:simplegit.git
   1edee6b..fbff5bc  master -> master

Η τελευταία γραμμή της εξόδου δείχνει ένα χρήσιμο μήνυμα που επέστρεψε η ώθηση. Η βασική μορφή είναι <oldref>..<newref> fromref → toref, όπου oldref σημαίνει την παλιά αναφορά, newref σημαίνει την νέα αναφορά, fromref είναι το όνομα της τοπικής αναφοράς που ωθήθηκε και toref είναι το όνομα της απομακρυσμένης αναφοράς που ενημερώθηκε. Θα βλέπετε παρόμοια με αυτό μηνύματα στις συζητήσεις, οπότε το να έχετε μια ιδέα του τι σημαίνουν θα σας βοηθήσει να καταλαβαίνετε τις διάφορες καταστάσεις των αποθετηρίων. Περισσότερες λεπτομέρειες υπάρχουν στην τεκμηρίωση της εντολής git-push.

Συνεχίζοντας το παράδειγμα, λίγο αργότερα, ο Τζον κάνει κάποιες αλλαγές, τις υποβάλει στο τοπικό του αποθετήριο και προσπαθεί να τις ωθήσει στον ίδιο διακομιστή:

# Μηχάνημα του Τζον
$ git push origin master
To john@githost:simplegit.git
 ! [rejected]        master -> master (non-fast forward)
error: failed to push some refs to 'john@githost:simplegit.git'

Σε αυτήν την περίπτωση, δεν επιτράπηκε στον Τζον να ωθήσει επειδή στο μεταξύ έχει ωθήσει η Τζέσικα. Αυτό είναι κάτι που πρέπει να καταλάβετε καλά, αν είστε συνηθισμένοι στο Subversion, επειδή όπως παρατηρείτε οι δύο προγραμματιστές δεν επεξεργάστηκαν το ίδιο αρχείο. Παρόλο που το Subversion πραγματοποιεί αυτόματα μια τέτοια συγχώνευση στον διακομιστή, αν τα αρχεία που έχουν υποστεί επεξεργασία είναι διαφορετικά, στο Git πρέπει πρώτα να συγχωνεύσετε τις υποβολές τοπικά. Με άλλα λόγια, ο Τζον πρέπει να ανακτήσει (fetch) τις αλλαγές της Τζέσικα και να τις συγχωνεύσει στο τοπικό του αποθετήριο προτού του επιτραπεί να ωθήσει:

Το πρώτο βήμα που κάνει ο Τζον είνα να ανακτήσει τη δουλειά της Τζέσικα (αυτό μόνο ανακτά τη δουλειά που ανέβασε η Τζέσικα, δεν τη συγχωνεύει ακόμα στη δουλειά του Τζον):

$ git fetch origin
...
From john@githost:simplegit
 + 049d078...fbff5bc master     -> origin/master

Σε αυτό το σημείο, το τοπικό αποθετήριο του Τζον μοιάζει με αυτό:

Το αποκλίνον ιστορικό του Τζον
Figure 2. Το αποκλίνον ιστορικό του Τζον.

Τώρα ο Τζον μπορεί να συγχωνεύσει τη δουλειά της Τζέσικα που ανέκτησε με δική του τοπική δουλειά:

$ git merge origin/master
Merge made by the 'recursive' strategy.
 TODO |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

Εφόσον η συγχώνευση ολοκληρωθεί ομαλά, το ιστορικό του Τζον θα μοιάζει με αυτό:

Το αποθετήριο του Τζον μετά τη συγχώνευση του `origin/master`.
Figure 3. Το αποθετήριο του Τζον μετά τη συγχώνευση του origin/master.

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

$ git push origin master
...
To john@githost:simplegit.git
   fbff5bc..72bbc59  master -> master

Τελικά, το ιστορικό υποβολών του Τζον θα μοιάζει με αυτό:

Ιστορικό του Τζον μετά την ώθηση στον διακομιστή `origin`.
Figure 4. Ιστορικό του Τζον μετά την ώθηση στον διακομιστή origin.

Στο μεταξύ, η Τζέσικα εργαζόταν πάνω σε έναν θεματικό κλάδομ που ονόμασε issue54 και έκανε τρεις υποβολές σε αυτόν. Δεν έχει ακόμη ανακτήσει τις αλλαγές του Τζον, επομένως το ιστορικό υποβολών της μοιάζει ως εξής:

Θεματικός κλάδος της Τζέσικα.
Figure 5. Θεματικός κλάδος της Τζέσικα.

Ξαφνικά, η Τζέσικα μαθαίνει ότι ο Τζον ώθησε νέα δουλειά στον διακομιστή και θέλει να της ρίξει μια ματιά, οπότε ανακτά (fetch) όλα τα δεδομένα από τον διακομιστή, που δε έχει:

# Μηχάνημα της Τζέσικα
$ git fetch origin
...
From jessica@githost:simplegit
   fbff5bc..72bbc59  master     -> origin/master

Έτσι, ανακτά τη δουλειά που έχει ωθήσει ο Τζον στο μεταξύ. To ιστορικό της Τζέσικα μοιάζει τώρα με το εξής:

Ιστορικό της Τζέσικα μετά την ανάκτηση των αλλαγών του Τζον.
Figure 6. Ιστορικό της Τζέσικα μετά την ανάκτηση των αλλαγών του Τζον.

Η Τζέσικα θεωρεί ότι ο τοπικός της κλάδος είναι έτοιμος, αλλά θέλει να γνωρίζει ποιο μέρος της δουλειάς του Τζον πρέπει να συγχωνεύσει στη δική της δουλειά, ώστε να ωθήσει. Εκτελεί την εντολή git log για να το μάθει:

$ git log --no-merges issue54..origin/master
commit 738ee872852dfaa9d6634e0dea7a324040193016
Author: John Smith <[email protected]>
Date:   Fri May 29 16:01:27 2009 -0700

   Remove invalid default value

Η σύνταξη issue54..origin/master είναι ένα φίλτρο της εντολής log που ζητά από το Git να εμφανίσει μόνο τον κατάλογο των υποβολών που βρίσκονται στον τελευταίο κλάδο (στη συγκεκριμένη περίπτωση τον origin/master) που δεν βρίσκονται στον πρώτο κλάδο (στη συγκεκριμένη περίπτωση “issue54”). Θα εξετάσουμε λεπτομερώς σε αυτή τη σύνταξη στην ενότητα ch07-git-tools.asc.

Από την έξοδο που επιστρέφεται μπορούμε να δούμε ότι υπάρχει μόνο μία υποβολή που έχει κάνει ο Τζον την οποία δεν έχει συγχωνεύσει η Τζέσικα. Αν συγχωνεύσει τον κλάδο origin/master, αυτή είναι η μόνη υποβολή που θα τροποποιήσει την τοπική εργασία της.

Τώρα, η Τζέσικα μπορεί να συγχωνεύσει τον θεματικό της κλάδο στον δικό της master, να συγχωνεύσει τη δουλειά του Τζον (origin/master) στον δικό της κλάδο master και στη συνέχεια να ωθήσει ξανά στον διακομιστή. Πρώτα (και αφού έχει υποβάλει τη δουλειά της στον θεματικό κλάδο issue54), μεταβαίνει στον κύριο κλάδο της για να ενσωματώσει όλη αυτή τη δουλειά:

$ git checkout master
Switched to branch 'master'
Your branch is behind 'origin/master' by 2 commits, and can be fast-forwarded.

Μπορεί να συγχωνεύσει πρώτα είτε τον κλάδο origin/master είτε τον issue54 — και οι δύο είναι upstream, οπότε η σειρά δεν έχει σημασία. Το τελικό στιγμιότυπο θα είναι πανομοιότυπο ανεξάρτητα από τη σειρά που επιλέγει· μόνο το ιστορικό θα είναι ελαφρά διαφορετικό. Επιλέγει να συγχωνεύσει πρώτα στον issue54:

$ git merge issue54
Updating fbff5bc..4af4298
Fast forward
 README           |    1 +
 lib/simplegit.rb |    6 +++++-
 2 files changed, 6 insertions(+), 1 deletions(-)

Δεν παρουσιάζονται προβλήματα· όπως μπορείτε να δείτε ήταν μια απλή συγχώνευση ταχυπροώθησης. Τώρα η Τζέσικα ολοκληρώνει τη διαδικασία της τοπικής συγχώνευσης, συγχωνεύοντας την δουλειά του Τζον που κάθεται στον κλάδο origin/master:

$ git merge origin/master
Auto-merging lib/simplegit.rb
Merge made by the 'recursive' strategy.
 lib/simplegit.rb |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

Τα πάντα συγχωνεύονται καθαρά και το ιστορικό της Τζέσικα μοιάζει με αυτό:

Το ιστορικό της Τζέσικα μετά τη συγχώνευση των αλλαγών του Τζον.
Figure 7. Το ιστορικό της Τζέσικα μετά τη συγχώνευση των αλλαγών του Τζον.

Τώρα, ο κλάδος origin/master είναι προσβάσιμος από τον κλάδο master της Τζέσικα, οπότε θα πρέπει να είναι σε θέση να ωθήσει με επιτυχία (αν υποτεθεί ότι ο Τζον δεν ώθησε ξανά στο μεταξύ):

$ git push origin master
...
To jessica@githost:simplegit.git
   72bbc59..8059c15  master -> master

Κάθε προγραμματιστής έχει υποβάλλει μερικές φορές και έχει συγχωνεύσει επιτυχώς στο έργο του άλλου.

Το ιστορικό της Τζέσικα μετά την ώθηση όλων των αλλαγών στον διακομιστή.
Figure 8. Το ιστορικό της Τζέσικα μετά την ώθηση όλων των αλλαγών στον διακομιστή.

Αυτή είναι μία από τις πιο απλές ροές εργασίας. Εργάζεστε για κάποιο χρονικό διάστημα (συνήθως σε έναν θεματικό κλάδο) και συγχωνεύετε τον κύριο κλάδο σας όταν είναι έτοιμος να ενσωματωθεί. Όταν θέλετε να κοινοποιήσετε αυτή τη δουλειά, ανακτάτε από τον origin/master αν αυτός έχει αλλάξει και τον συγχωνεύετε στον master σας και τελικά ωθείτε τον κλάδο σας master στον διακομιστή. Η συνήθης ακολουθία γεγονότων είναι κάτι σαν:

Γενική ακολουθία γεγονότων για μια απλή ροή εργασίας με πολλούς προγραμματιστές.
Figure 9. Γενική ακολουθία γεγονότων για μια απλή ροή εργασίας με πολλούς προγραμματιστές.

Ιδιωτική ομάδα με διαχειριστή

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

Ας πούμε ότι ο Τζον και η Τζέσικα δουλεύουν μαζί σε μια λειτουργικότητα ενώ η Τζέσικα και η Τζόσι εργάζονται σε μια άλλη. Σε αυτή την περίπτωση, η εταιρεία χρησιμοποιεί ένα είδος ροής εργασίας με διαχειριστή ενσωμάτωσης, στην οποία η εργασία των μεμονωμένων ομάδων ενσωματώνεται μόνο από ορισμένους μηχανικούς και ο κλάδος master του κύριου αποθετηρίου μπορεί να ενημερωθεί μόνο από αυτούς τους μηχανικούς. Σε αυτό το σενάριο όλη η δουλειά γίνεται σε κλάδους κοινούς σε ομάδες και συγκεντρώνονται αργότερα από τους υπεύθυνους ενσωμάτωσης.

Ας ακολουθήσουμε τη ροή εργασίας της Τζέσικα καθώς εργάζεται στις δύο λειτουργικότητές της, συνεργαζόμενη παράλληλα με δύο διαφορετικούς προγραμματιστές σε αυτό το περιβάλλον. Αν υποθέσουμε ότι η Τζέσικα έχει ήδη κλωνοποιήσει το αποθετήριό της και ότι αποφασίζει να εργαστεί πρώτα στη λειτουργικότητα featureA. Δημιουργεί ένα νέο κλάδο για τη λειτουργικότητα και κάνει κάποια δουλειά σε αυτό:

# Μηχάνημα της Τζέσικα
$ git checkout -b featureA
Switched to a new branch 'featureA'
$ vim lib/simplegit.rb
$ git commit -am 'Add limit to log function'
[featureA 3300904] Add limit to log function
 1 files changed, 1 insertions(+), 1 deletions(-)

Σε αυτό το σημείο, πρέπει να κοινοποιήσει τη δουλειά της με τον Τζον, οπότε ωθεί τις υποβολές του κλάδου της featureA στον διακομιστή. Η Τζέσικα δεν έχει πρόσβαση ώθησης στον κλάδο master — μόνον οι μηχανικοί ενσωμέτωσης έχουν — γι' αυτό πρέπει να ωθήσει σε έναν άλλο κλάδο για να συνεργαστεί με τον Τζον:

$ git push -u origin featureA
...
To jessica@githost:simplegit.git
 * [new branch]      featureA -> featureA

Η Τζέσικα ειδοποιεί τον Τζον για να του πει ότι έχει ωθήσει μέρος της δουλειάς της σε έναν κλάδο που ονομάζεται featureA και μπορεί τώρα να τον δει. Ενώ περιμένει τα σχόλια του Τζον, η Τζέσικα αποφασίζει να αρχίσει να δουλεύει στη λειτουργικότητα featureB με την Τζόσι. Για να ξεκινήσει, ξεκινά έναν νέο κλάδο, με βάση τον κλάδο master του διακομιστή:

# Μηχάνημα της Τζέσικα
$ git fetch origin
$ git checkout -b featureB origin/master
Switched to a new branch 'featureB'

Τώρα, η Τζέσικα κάνει δύο υποβολές στον κλάδο featureB:

$ vim lib/simplegit.rb
$ git commit -am 'Make ls-tree function recursive'
[featureB e5b0fdc] Make ls-tree function recursive
 1 files changed, 1 insertions(+), 1 deletions(-)
$ vim lib/simplegit.rb
$ git commit -am 'Add ls-files'
[featureB 8512791] Add ls-files
 1 files changed, 5 insertions(+), 0 deletions(-)

Το αποθετήριο της Τζέσικα μοιάζει με αυτό:

Αρχικό ιστορικό υποβολών της Τζέσικα.
Figure 10. Αρχικό ιστορικό υποβολών της Τζέσικα.

Είναι έτοιμη να ωθήσει τη δουλειά της, αλλά λαμβάνει ένα e-mail από την Τζόσι ότι ένας κλάδος με κάποια αρχική εργασία σε αυτήν τη λειτουργικότητα έχει ήδη ωθηθεί στον διακομιστή ως featureBee. Η Τζέσικα πρέπει πρώτα να συγχωνεύσει αυτές τις αλλαγές με τις δικές της, προτού να μπορέσει να ωθήσει στον διακομιστή. Πρώτα ανακτά τις αλλαγές της Τζόσι με git fetch:

$ git fetch origin
...
From jessica@githost:simplegit
 * [new branch]      featureBee -> origin/featureBee

Με την προϋπόθεση ότι η Τζέσικα βρίσκεται ακόμα στον κλάδο της featureB, μπορεί να συγχωνεύσει τη δουλειά της Τζόσι με git merge:

$ git merge origin/featureBee
Auto-merging lib/simplegit.rb
Merge made by the 'recursive' strategy.
 lib/simplegit.rb |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

Σε αυτό το σημείο, η Τζέσικα θέλει να ωθήσει όλο αυτόν τον συγχωνευμένο κλάδο “featureB” στον διακομιστή, αλλά δεν θέλει απλά να ωθήσει τον δικό της κλάδο featureB. Αντίθετα, αφού η Τζόσι έχει ήδη ξεκινήσει έναν upstream κλάδο featureBee, η Τζέσικα θέλει να ωθήσει σε αυτόν τον κλάδο, το οποίο και κάνει με την εντολή:

$ git push -u origin featureB:featureBee
...
To jessica@githost:simplegit.git
   fba9af8..cd685d1  featureB -> featureBee

Αυτό ονομάζεται refspec. Μια πιο λεπτομερής συζήτηση για τα refspec του Git και διάφορα πράγματα που μπορείτε να κάνετε με αυτά υπάρχουν στην ενότητα ch10-git-internals.asc. Παρατηρήστε επίσης τη σημαία -u· είναι συντομογραφία του --set-upstream, που ρυθμίζει τους κλάδους για ευκολότερη ώθηση και ελκυσμό αργότερα.

Ξάφνου, η Τζέσικα παίρνει ένα e-mail από τον Τζον, που της λέει ότι έχει ωθήσει κάποιες αλλαγές στον κλάδο featureA στον οποίο συνεργάζονται και της ζητά να τις ρίξει μια ματιά. Και πάλι, η Τζέσικα εκτελεί ένα git fetch για να ανακτήσει ό,τι νέο υλικό υπάρχει στον διακομιστή, συμπεριλμβανομένων φυσικά των αλλαγών του Τζον:

$ git fetch origin
...
From jessica@githost:simplegit
   3300904..aad881d  featureA   -> origin/featureA

Η Τζέσικα μπορεί να δει το log της δουλειάς του Τζον συγκρίνοντας το περιεχόμενο του άρτι ανακτημένου κλάδου featureA με το τοπικό της αντίγραφο στον ίδιο κλάδο log`:

$ git log featureA..origin/featureA
commit aad881d154acdaeb2b6b18ea0e827ed8a6d671e6
Author: John Smith <[email protected]>
Date:   Fri May 29 19:57:33 2009 -0700

    Increase log output to 30 from 25

Εφόσον της αρέσει αυτό που βλέπει μπορεί να συγχωνεύσει τη δουλειά του Τζον στον δικό της τοπικό κλάδο featureA:

$ git checkout featureA
Switched to branch 'featureA'
$ git merge origin/featureA
Updating 3300904..aad881d
Fast forward
 lib/simplegit.rb |   10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)

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

$ git commit -am 'Add small tweak to merged content'
[featureA 774b3ed] Add small tweak to merged content
 1 files changed, 1 insertions(+), 1 deletions(-)
$ git push
...
To jessica@githost:simplegit.git
   3300904..774b3ed  featureA -> featureA

Το ιστορικό υποβολών της Τζέσικα τώρα μοιάζει κάτι τέτοιο:

Ιστορικό της Τζέσικα μετά την υποβολή σε έναν θεματικό κλάδο.
Figure 11. Ιστορικό της Τζέσικα μετά την υποβολή σε έναν θεματικό κλάδο.

Κάποια στιγμή, οι Τζέσικα, Τζόσι και Τζον ενημερώνουν τους διαχειριστές ενσωμάτωσης ότι οι κλάδοι featureA και featureBee στον διακομιστή είναι έτοιμοι για ενσωμάτωση στον κύριο κλάδο. Αφού οι διαχειριστές ενσωμάτωσης συγχωνεύσουν αυτούς τους κλάδους στον κύριο κλάδο, μία ανάκτηση θα κατεβάσει τη νέα υποβολή συγχώνευσης, κάνοντας το ιστορικό να μοιάζει με αυτό:

Ιστορικό της Τζέσικα μετά τη συγχώνευση και των δύο θεματικών κλάδων της.
Figure 12. Ιστορικό της Τζέσικα μετά τη συγχώνευση και των δύο θεματικών κλάδων της.

Πολλές ομάδες περνούν στο Git εξαιτίας ακριβώς αυτής της δυνατότητας να έχουν πολλές ομάδες που εργάζονται παράλληλα και να συγχωνεύουν τις διαφορετικές γραμμές εργασίας αργότερα. Η ικανότητα μικρότερων υποομάδων μιας ομάδας να συνεργάζονται μέσω απομακρυσμένων κλάδων χωρίς να χρειάζεται απαραίτητα να εμπλέξουν ή να φρενάρουν ολόκληρη την ομάδα είναι ένα τεράστιο όφελος που παρέχει το Git. Η ακολουθία της ροής εργασίας που είδατε εδώ είναι κάτι σαν αυτό:

Βασική ακολουθία αυτής της ροής εργασίας διαχειριζόμενη ομάδα.
Figure 13. Βασική ακολουθία αυτής της ροής εργασίας διαχειριζόμενη ομάδα.

Αποσχισμένα δημόσια έργα

Η συνεργασία στα δημόσια έργα είναι κάπως διαφορετική. Επειδή δεν έχετε δικαιώματα για άμεση ενημέρωση κλάδων στο έργο, θα πρέπει να στέλνετε τη δουλειά σας στους διαχειριστές με κάποιον άλλο τρόπο. Το πρώτο παράδειγμα περιγράφει τη συνεισφορά μέσω απόσχισης (forking) σε διακομιστές Git που υποστηρίζουν την εύκολη απόσχιση, την οποία υποστηρίζουν πολλοί διακομιστές φιλοξενίας (συμπεριλαμβανομένων των GitHub, BitBucket, Google Code, repo.or.cz και άλλων) και πολλοί διαχειριστές έργων αναμένουν αυτό το στυλ συνεισφοράς. Η επόμενη ενότητα ασχολείται με έργα που προτιμούν να δέχονται συνεισφορές/επιθέματα μέσω e-mail.

Αρχικά, ίσως θέλετε να κλωνοποιήσετε το κύριο αποθετήριο, να δημιουργήσετε έναν θεματικό κλάδο για το επίθεμα ή τα επιθέματα που σκοπεύετε να συνεισφέρετε και να δουλεύετε σε αυτόν. Η ακολουθία μοιάζει ως εξής:

$ git clone <url>
$ cd project
$ git checkout -b featureA
  ... work ...
$ git commit
  ... work ...
$ git commit
Note

Ίσως θελήσετε να χρησιμοποιήσετε την εντολή rebase -i για να συνθλίψετε (squash) την εργασία σας σε μία μόνο υποβολή ή να αναδιατάξετε την εργασία σας στις υποβολές για να διευκολύνετε τον διαχειριστή που θα ελέγξει το επίθεμά σας — βλ. ch07-git-tools.asc για περισσότερες πληροφορίες σχετικά με τη διαδραστική αλλαγή βάσης.

Όταν ολοκληρώσετε την εργασία σας στον κλάδο σας και είστε έτοιμοι να τον επιστρέψετε στους διαχειριστές, μεταβείτε στην αρχική σελίδα του έργου και κάνετε κλικ στο κουμπί “Fork”, ώστε να δημιουργήσετε τη δική σας εγγράψιμη διχάλα του έργου. Στη συνέχεια, πρέπει να προσθέσετε το URL αυτού του αποθετηρίου ως απομακρυσμένο αποθετήριο, στη συγκεκριμένη περίπτωση ας το ονομάσουμε myfork:

$ git remote add myfork <url>

Μετά πρέπει να ωθήσετε την εργασία σας σε αυτό το αποθετήριο. Είναι ευκολότερο να ωθήσετε τον θεματικό κλάδο στον οποίο εργάζεστε στο αποσχισμένο σας αποθετήριο παρά να τον συγχωνεύσετε στον κλάδο master και να ωθήσετε αυτόν. Ο λόγος είναι ότι εάν η εργασία δεν γίνει αποδεκτή ή γίνουν αποδεκτά μόνο κάποια τμήματά της (cherry-picked), δεν χρειάζεται να επαναφέρετε τον κύριο κλάδο σας. Αν οι διαχειριστές συγχωνεύσουν (merge), επανατοποθετήσουν (rebase) ή επιλέξουν μόνον τμήματα της δουλειάς σας (cherry-pick), τότε κάποια στιγμή θα την πάρετε πίσω τραβώντας την από το αποθετήριό τους:

$ git push -u myfork featureA

Όταν έχετε ωθήσει τη δουλειά σας στη διχάλα σας, πρέπει να ειδοποιήσετε τους συντηρητές του αρχικού έργου ότι έχετε κάνει κάποια δουειά που θέλετε να συγχωνεύσουν. Αυτό συχνά ονομάζεται αίτημα ελκυσμού (pull request) και μπορείτε είτε να το δημιουργήσετε μέσω της ιστοσελίδας — το GitHub έχει τον δικό του μηχανισμό αιτημάτων ελκυσμού, τον οποίο θα εξετάσουμε στην ενότητα ch06-github.asc — είτε να τρέξετε την εντολή git request-pull και να στείλετε την έξοδό της με e-mail στον διαχειριστή του έργου.

Η εντολή request-pull παίρνει τον βασικό κλάδο στον οποίο θέλετε να ελκυστεί ο θεματικός σας κλάδος και το URL του αποθετηρίου Git από το οποίο θέλετε να τον τραβήξουν και εξάγει μια σύνοψη όλων των αλλαγών που ζητάμε να ελκυστούν. Για παράδειγμα, αν η Τζέσικα θέλει να στείλει ένα αίτημα ελκυσμού στον Τζον και έχει κάνει δύο υποβολές στον θεματικό κλάδο που μόλις ώθησε, μπορεί να τρέξει το εξής:

$ git request-pull origin/master myfork
The following changes since commit 1edee6b1d61823a2de3b09c160d7080b8d1b3a40:
Jessica Smith (1):
        Create new function

are available in the git repository at:

  https://githost/simplegit.git featureA

Jessica Smith (2):
      Add limit to log function
      Increase log output to 30 from 25

 lib/simplegit.rb |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

Η έξοδος μπορεί να αποσταλεί στον συντηρητή του αποθετηρίου — του λέει από πού διακλαδώθηκε η δουλειά, συνοψίζει τις υποβολές και λέει από πού να την τραβήξει.

Σε ένα έργο στο οποίο δεν είστε ο συντηρητής, είναι γενικά ευκολότερο να έχετε έναν κλάδο όπως ο master να παρακολουθεί πάντα τον origin/master και να δουλεύετε σε θεματικούς κλάδους τους οποίους μπορείτε εύκολα να διαγράψετε αν απορριφθούν. Η διατήρηση ξεχωριστών θεματικών κλάδων για διαφορετικά θέματα διευκολύνει επίσης την αλλαγή βάσης της εργασίας σας, αν η άκρη του κύριου αποθετηρίου έχει μετακινηθεί εν τω μεταξύ και οι υποβολές σας δεν εφαρμόζονται πλέον με καθαρό τρόπο. Για παράδειγμα, εάν θέλετε να δημιουργήσετε ένα δεύτερο θέμα εργασίας στο έργο, καλό είναι να μην συνεχίζετε να εργάζεστε στον κλάδο του θέματος το οποίο μόλις ωθήσατε, αλλά να ξεκινήσετε από τον κλάδο master του αποθετηρίου:

$ git checkout -b featureB origin/master
  ... work ...
$ git commit
$ git push myfork featureB
$ git request-pull origin/master myfork
  ... email generated request pull to maintainer ...
$ git fetch origin

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

Αρχικό ιστορικό υποβολών με τη δουλειά από το `featureB`.
Figure 14. Αρχικό ιστορικό υποβολών με τη δουλειά από το featureB.

Ας υποθέσουμε ότι ο συντηρητής του έργου έχει τραβήξει κάμποσα επιθέματα και έχει δοκιμάσει τον πρώτο σας κλάδο, αλλά δεν μπορεί να τον συγχωνεύσει χωρίς συγκρούσεις. Σε αυτή την περίπτωση, μπορείτε να προσπαθήσετε να αλλάξετε τη βάση (rebase) αυτού του κλάδου στην κορυφή του κλάδου origin/master, να επιλύσετε τις συγκρούσεις για τον διαχειριστή και στη συνέχεια να ωθήσετε εκ νέου τις αλλαγές σας:

$ git checkout featureA
$ git rebase origin/master
$ git push -f myfork featureA

Αυτό επανεγγράφει το ιστορικό σας, ώστε τώρα μοιάζει με το Ιστορικό υποβολών μετά από δουλειά στο featureA..

Ιστορικό υποβολών μετά από δουλειά στο `featureA`.
Figure 15. Ιστορικό υποβολών μετά από δουλειά στο featureA.

Επειδή αλλάξατε τη βάση του κλάδου, πρέπει να χρησιμοποιήσετε την επιλογή -f στην εντολή push, ώστε να μπορέσετε να αντικαταστήσετε τον κλάδο featureA στον διακομιστή με μια υποβολή που δεν είναι απόγονός τoυ. Μια εναλλακτική θα ήταν να ωθήσετε αυτή τη νέα δουλειά σε ένα διαφορετικό κλάδο στον διακομιστή (ίσως με όνομα featureAv2).

Ας δούμε ένα ακόμα πιθανό σενάριο: ο διαχειριστής έχει εξετάσει την εργασία στον δεύτερό σας κλάδο και του αρέσει η ιδέα, αλλά θα ήθελε να αλλάξετε μια-δυο λεπτομέρειες στην υλοποίησή της. Θα εκμεταλλευτείτε αυτή την ευκαιρία για να αλλάξετε τη βάση (rebase) τη δουλειά σας ώστε να διακλαδίζεται από τον τρέχοντα κλάδο master του έργου. Ξεκινάτε ένα νέο κλάδο που διακλαδίζεται από τον τρέχοντα κλάδο origin/master, συνθλίβετε τις αλλαγές του featureB σε αυτόν, επιλύετε τυχόν συγκρούσεις, κάνετε τις αλλαγές στην υλοποίηση που σας ζητήθηκαν και στη συνέχεια τα ωθείτε όλα αυτά ως έναν νέο κλάδο:

$ git checkout -b featureBv2 origin/master
$ git merge --squash featureB
  ... change implementation ...
$ git commit
$ git push myfork featureBv2

Η επιλογή --squash παίρνει όλη τη δουλειά που υπάρχει στον συγχωνευμένο κλάδο και τη στριμώχνει σε ένα σύνολο αλλαγών ώστε παράγει μία κατάσταση του αποθετηρίου σαν να συνέβη στην πραγματικότητα μια συγχώνευση χωρίς όμως να πραγματοποιήσει υποβολή συγχώνευσης. Αυτό σημαίνει ότι η μελλοντική σας υποβολή θα έχει μόνο έναν γονέα και σας επιτρέπει να εισάγετε όλες τις αλλαγές από κάποιον άλλο κλάδο και μετά να κάνετε περισσότερες αλλαγές πριν καταγράψετε τη νέα υποβολή. Επίσης, μία άλλη χρήσιμη επιλογή στην περίπτωση της προεπιλεγμένης διαδικασίας συγχώνευσης είναι η --no-commit που αναβάλλει την υποβολής συγχώνευσης.

Τώρα μπορείτε να στείλετε στον διαχειριστή ένα μήνυμα ότι έχετε κάνει τις ζητούμενες αλλαγές και μπορεί να τις βρει στον κλάδο featureBv2.

Ιστορικό υποβολών μετά τη δουλειά στο `featureBv2`.
Figure 16. Ιστορικό υποβολών μετά τη δουλειά στο featureBv2.

Δημόσιο έργο μέσω e-mail

Πολλά έργα έχουν θεσπίσει διαδικασίες για την αποδοχή των επιθεμάτων — θα πρέπει να ελέγξετε τους συγκεκριμένους κανόνες του έργου, επειδή διαφέρουν από έργο σε έργο. Δεδομένου ότι υπάρχουν πολλά παλαιότερα, μεγαλύτερα έργα που αποδέχονται επιθέματα μέσω mailing list προγραμματιστών, θα εξετάσουμε ένα τέτοιο παράδειγμα.

Η ροή εργασίας είναι παρόμοια με την προηγούμενη περίπτωση — δημιουργείτε θεματικούς κλάδους, έναν για κάθε σειρά επιθεμάτων στα οποία εργάζεστε. Η διαφορά είναι στο πώς τους υποβάλλετε στο έργο. Αντί να αποσχίσετε μία διχάλα από το έργο και να την ωθήσετε στη δική σας εγγράψιμη έκδοση, μπορείτε να δημιουργήσετε εκδόσεις e-mail για κάθε σειρά υποβολών και να τις αποστείλετε με e-mail στη mailing list προγραμματιστών:

$ git checkout -b topicA
  ... work ...
$ git commit
  ... work ...
$ git commit

Τώρα έχετε δύο υποβολές που θέλετε να στείλετε στη mailing list. Χρησιμοποιείτε την git format-patch για να δημιουργήσετε τα μορφοποιημένα αρχεία mbox που μπορείτε να στείλετε με e-mail στη λίστα — μετατρέπει κάθε υποβολή σε μήνυμα e-mail με την πρώτη γραμμή του μηνύματος υποβολής ως θέμα και το υπόλοιπο μήνυμα συν το επίθεμα, που εισάγει η υποβολή, ως σώμα του e-mail. Η ομορφιά σε αυτό είναι ότι η εφαρμογή ενός επιθέματος από ένα μήνυμα e-mail που έχει παραχθεί με format-patch διατηρεί όλες τις πληροφορίες υποβολής όπως πρέπει.

$ git format-patch -M origin/master
0001-add-limit-to-log-function.patch
0002-changed-log-output-to-30-from-25.patch

Η εντολή format-patch εκτυπώνει τα ονόματα των αρχείων-επιθεμάτων που δημιουργεί. Ο διακόπτης -M λέει στο Git να αναζητήσει μετονομασίες. Τα αρχεία καταλήγουν να μοιάζουν ως εξής:

$ cat 0001-add-limit-to-log-function.patch
From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001
From: Jessica Smith <[email protected]>
Date: Sun, 6 Apr 2008 10:17:23 -0700
Subject: [PATCH 1/2] add limit to log function

Limit log functionality to the first 20

---
 lib/simplegit.rb |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 76f47bc..f9815f1 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -14,7 +14,7 @@ class SimpleGit
   end

   def log(treeish = 'master')
-    command("git log #{treeish}")
+    command("git log -n 20 #{treeish}")
   end

   def ls_tree(treeish = 'master')
--
2.1.0

Μπορείτε επίσης να επεξεργαστείτε αυτά τα αρχεία/επιθέματα για να προσθέσετε περισσότερες πληροφορίες για τη mailing list που δεν θέλετε να εμφανίζονται στο μήνυμα υποβολής. Αν προσθέσετε κείμενο μεταξύ της γραμμής --- και της αρχής του επιθέματος (τη γραμμή diff --git), τότε ναι μεν οι προγραμματιστές μπορούν να το διαβάσουν, αλλά το κείμενο αυτό αγνοείται κατά τη διαδικασία εφαρμογής του επιθέματος.

Για να στείλετε το παραπάνω ως e-mail σε μια mailing list, μπορείτε είτε να επικολλήσετε το αρχείο στο πρόγραμμα e-mail είτε να το στείλετε μέσω ενός προγράμματος γραμμής εντολών. Η επικόλληση του κειμένου προκαλεί συχνά ζητήματα μορφοποίησης, ειδικά με “ευφυέστερους” πελάτες που δεν διατηρούν κατάλληλα τους χαρακτήρες αλλαγής γραμμής και άλλους λευκούς χαρακτήρες. Ευτυχώς, το Git παρέχει ένα εργαλείο που σας βοηθά να στέλνετε κατάλληλα μορφοποιημένα επιθέματα μέσω IMAP, κάτι που ενδεχομένως σας διευκολύνει. Θα δείξουμε πώς να στείλετε επιθέματα μέσω του Gmail, που τυγχάνει να είναι το πρόγραμμα e-mail που γνωρίζουμε καλύτερα· μπορείτε να διαβάσετε λεπτομερείς οδηγίες για κάποια προγράμματα e-mail στο τέλος του προαναφερθέντος αρχείου Documentation/SubmittingPatches στον πηγαίο κώδικα του Git.

Πρώτα, πρέπει να ρυθμίσετε την ενότητα imap στο αρχείο ~/.gitconfig. Μπορείτε να ορίσετε ξεχωριστά κάθε τιμή με μια ακολουθία εντολών git config ή μπορείτε να τις προσθέσετε χειροκίνητα· όπως και νά 'χει τελικά το αρχείο config θα πρέπει να φαίνεται σαν αυτό:

[imap]
  folder = "[Gmail]/Drafts"
  host = imaps://imap.gmail.com
  user = [email protected]
  pass = p4ssw0rd
  port = 993
  sslverify = false

Αν ο διακομιστής IMAP δεν χρησιμοποιεί SSL, οι δύο τελευταίες γραμμές πιθανώς δεν είναι απαραίτητες και η τιμή host θα είναι imap:// αντί για 'imaps://. Όταν έχει ρυθμιστεί το αρχείο `~/.gitconfig, μπορείτε να εκτελέσετε την εντολή git imap-send για να τοποθετήσετε τη σειρά επιθεμάτων στον φάκελο Drafts του καθορισμένου διακομιστή IMAP:

$ cat *.patch |git imap-send
Resolving imap.gmail.com... ok
Connecting to [74.125.142.109]:993... ok
Logging in...
sending 2 messages
100% (2/2) done

Σε αυτό το σημείο, θα πρέπει να μπορείτε να μεταβείτε στον φάκελο Drafts, να αλλάξετε το πεδίο To στη mailing list στην οποία θα αποστείλετε την ενημερωμένη έκδοση κώδικα, ενδεχομένως να κοινοποιήσετε με cc στον υπεύθυνο συντήρησης ή όποιον είναι υπεύθυνος για αυτή την ενότητα και να το αποστείλετε.

Μπορείτε επίσης να στείλετε τα επιθέματα μέσω ενός διακομιστή SMTP. Όπως και πριν, μπορείτε να ορίσετε ξεχωριστά κάθε τιμή με μια σειρά εντολών git config ή μπορείτε να τις προσθέσετε χειροκίνητα στην ενότητα sendemail στο αρχείο ~/.gitconfig:

[sendemail]
  smtpencryption = tls
  smtpserver = smtp.gmail.com
  smtpuser = [email protected]
  smtpserverport = 587

Μετά από αυτό, μπορείτε να χρησιμοποιήσετε το git send-email για να αποστείλετε τα επιθέματά σας:

$ git send-email *.patch
0001-add-limit-to-log-function.patch
0002-increase-log-output-to-30-from-25.patch
Who should the emails appear to be from? [Jessica Smith <[email protected]>]
Emails will be sent from: Jessica Smith <[email protected]>
Who should the emails be sent to? [email protected]
Message-ID to be used as In-Reply-To for the first email? y

Στη συνέχεια, το Git εκτοξεύει κάμποσες πληροφορίες log που μοιάζουν με κάτι σαν το παρακάτω για κάθε επίθεμα που στέλνετε:

(mbox) Adding cc: Jessica Smith <[email protected]> from
  \line 'From: Jessica Smith <[email protected]>'
OK. Log says:
Sendmail: /usr/sbin/sendmail -i [email protected]
From: Jessica Smith <[email protected]>
To: [email protected]
Subject: [PATCH 1/2] Add limit to log function
Date: Sat, 30 May 2009 13:29:15 -0700
Message-Id: <[email protected]>
X-Mailer: git-send-email 1.6.2.rc1.20.g8c5b.dirty
In-Reply-To: <y>
References: <y>

Result: OK
Tip

Για βοήθεια όσον αφορά στην παραμετροποίηση του συστήματός σας και του e-mail, περισσότερες συμβουλές και κόλπα και ένα χώρο πειραματισμού για δομικές αποστολής επιθεμάτων με e-mail, επισκεφτείτε το git-send-email.io.

Ανακεφαλαίωση

Σε αυτή την ενότητα κάαλύψαμε διάφορες ροές εργασίας και μιλήσαμε για τις διαφορές ανάμεσα στην εργασία ως μέλος κάποιας μικρής ομάδας σε έργα κλειστού κώδικα και την εργασία σε ένα μεγάλο δημόσιο έργο. Γνωρίζετε πώς να ελέγχετε σφάλματα διαστημάτων πριν να υποβάλετε αλλαγές και να γράφετε εξαιρετικά μηνύματα υποβολής. Μάθατε πώς να μορφοποιείτε επιθέματα και να τα στέλνετε με emaiil σε μια mailing list προγραμματιστών. Καλύψαμε επίσης τις συγχωνεύσεις στο πλαίσιο των διαφορετικών ροών εργασίας. Πλέον είστε καλά προετοιμασμένοι να συνεργαστείτε με άλλους σε κάποιο έργο.

Στη συνέχεια, θα δείτε πώς εργάζεστε στην άλλη όψη του νομίσματος: τη συντήρηση ενός έργου Git. Θα μάθετε πώς να είστε καλοπροαίρετοι δικτάτορες ή διαχειριστές ενσωμάτωσης.