Chapters ▾ 2nd Edition

2.5 Τα θεμελιώδη στοιχεία του Git - Δουλεύοντας με απομακρυσμένα αποθετήρια

Δουλεύοντας με απομακρυσμένα αποθετήρια

Για να μπορούμε να συνεργαζόμαστε σε έργα του Git, θα πρέπει να γνωρίζουμε πώς να διαχειριζόμαστε τα απομακρυσμένα αποθετήριά μας. Τα απομακρυσμένα αποθετήρια (remote repositories) είναι εκδόσεις του έργου μας που βρίσκονται στο Διαδίκτυο ή σε κάποιο δίκτυο. Μπορούμε να δημιουργήσουμε όσα θέλουμε και καθένα από αυτά είναι προσβάσιμα από μας είτε ως για ανάγνωση-μόνο είτε για ανάγνωση/εγγραφή. Η συνεργασία με άλλους συμπεριλαμβάνει τη διαχείριση αυτών των απομακρυσμένων αποθετηρίων, ώθηση και ελκυσμό δεδομένων προς και από αυτά όποτε χρειάζεται να κοινοποιήσουμε τη δουλειά μας ή να ενημερωθούμε για τη δουλειά άλλων. Η διαχείριση τέτοιων αποθετηρίων χρειάζεται ικανότητες όπως: πρόσθεση καινούριων απομακρυσμένων αποθετηρίων, διαγραφή αποθετηρίων που δεν έχουν πια κάποια χρησιμότητα, διαχείριση απομακρυσμένων κλάδων και ορισμό τους ως υπο-παρακολούθηση ή τερματισμό της παρακολούθησής τους και άλλα. Σε αυτή την ενότητα, θα ασχοληθούμε με κάποιες από αυτές τις δεξιότητες.

Note
Τα απομακρυσμένα αποθετήρια μπορεί να βρίσκονται στον υπολογιστή μας.

Είναι απολύτως δυνατό να εργάζεστε με ένα “απομακρυσμένο” αποθετήριο, που βρίσκεται στον ίδιο υπολογιστή στον οποίο βρίσκεστε και εσείς. Η λέξη “απομακρυσμένο” δεν υπονοεί απαραίτητα ότι το αποθετήριο βρίσκεται κάπου αλλού στο δίκτυο ή στο Διαδίκτυο, αλλά μόνο ότι βρίσκεται κάπου αλλού. Όταν εργάζεστε με ένα τέτοιο απομακρυσμένο αποθετήριο περιλαμβάνει επίσης τις συνήθεις λειτουργίες ώθησης (push), ελκυσμού (pull) και ανάκτησης (fetch), όπως με κάθε άλλο απομακρυσμένο αποθετήριο.

Εμφάνιση των απομακρυσμένων αποθετηρίων μας

Για να δούμε τους απομακρυσμένους διακομιστές που έχουμε παραμετροποιήσει, εκτελούμε την εντολή git remote. Η εντολή αυτή θα μας επιστρέψει μια λίστα με τα ονόματα των απομακρυσμένων που έχουμε ορίσει. Αν έχουμε κλωνοποιήσει το αποθετήριό μας, θα πρέπει να βλέπουμε τουλάχιστον το origin — που είναι το προεπιλεγμένο όνομα που δίνει το Git στον διακομιστή από τον οποίο μόλις κλωνοποιήσαμε:

$ git clone https://github.com/schacon/ticgit
Cloning into 'ticgit'...
remote: Reusing existing pack: 1857, done.
remote: Total 1857 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (1857/1857), 374.35 KiB | 268.00 KiB/s, done.
Resolving deltas: 100% (772/772), done.
Checking connectivity... done.
$ cd ticgit
$ git remote
origin

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

$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)

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

$ cd grit
$ git remote -v
bakkdoor  https://github.com/bakkdoor/grit (fetch)
bakkdoor  https://github.com/bakkdoor/grit (push)
cho45     https://github.com/cho45/grit (fetch)
cho45     https://github.com/cho45/grit (push)
defunkt   https://github.com/defunkt/grit (fetch)
defunkt   https://github.com/defunkt/grit (push)
koke      git://github.com/koke/grit.git (fetch)
koke      git://github.com/koke/grit.git (push)
origin    git@github.com:mojombo/grit.git (fetch)
origin    git@github.com:mojombo/grit.git (push)

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

Παρατηρούμε ότι τα απομακρυσμένα αποθετήρια χρησιμοποιούν πολλά πρωτόκολλα· θα καλύψουμε αναλυτικά τα πρωτόκολλα αυτά στο Εγκατάσταση του Git σε διακομιστή.

Προσθήκη απομακρυσμένων αποθετηρίων

Έχουμε ήδη αναφέρει και έχουμε επιδείξει πώς η εντολή git clone έμμεσα προσθέτει το απομακρυσμένο αποθετήριο origin στο αποθετήριό μας. Ας δούμε πως μπορούμε να προσθέσουμε ένα νέο απομακρυσμένο αποθετήριο άμεσα. Για να προσθέσουμε ένα νέο απομακρυσμένο αποθτεήριο Git με ένα σύντομο όνομα, το οποίο μπορούμε να θυμάστε εύκολα, εκτελούμε την εντολή git remote add <shortname> <url>:

$ git remote
origin
$ git remote add pb https://github.com/paulboone/ticgit
$ git remote -v
origin	https://github.com/schacon/ticgit (fetch)
origin	https://github.com/schacon/ticgit (push)
pb	https://github.com/paulboone/ticgit (fetch)
pb	https://github.com/paulboone/ticgit (push)

Τώρα πλέον μπορούμε να χρησιμοποιούμε στη γραμμή εντολών τη συμβολοσειρά pb αντί για ολόκληρη τη διεύθυνση του αποθετηρίου. Για παράδειγμα, αν θέλουμε να ανακτήσουμε (fetch) όλες τις πληροφορίες που έχει ο Paul στο αποθετήριό του, μπορούμε να εκτελέσουμε την εντολή git fetch pb:

$ git fetch pb
remote: Counting objects: 43, done.
remote: Compressing objects: 100% (36/36), done.
remote: Total 43 (delta 10), reused 31 (delta 5)
Unpacking objects: 100% (43/43), done.
From https://github.com/paulboone/ticgit
 * [new branch]      master     -> pb/master
 * [new branch]      ticgit     -> pb/ticgit

Ο κλάδος master του Paul είναι πλέον προσβάσιμος τοπικά σε μας ως pb/master — μπορούμε να τον συγχωνεύσουμε σε κάποιον δικό μας κλάδο, ή να φτιάξουμε (check out) έναν τοπικό κλάδο σε αυτό το σημείο, αν θέλουμε να το επιθεωρήσουμε. Θα δούμε περισσότερα για τους κλάδους και πώς τους χρησιμοποιούμε στην ενότητα Διακλαδώσεις στο Git.

Ανάκτηση δεδομένων από απομακρυσμένα αποθετήρια

Όπως μόλις είδαμε, για να πάρουμε δεδομένα από απομακρυσμένα έργα, μπορούμε να εκτελέσουμε:

$ git fetch <remote>

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

Όταν κλωνοποιήσουμε ένα αποθετήριο, το αποθετήριο αυτό αποθηκεύεται με το όνομα “origin”. Συνεπώς, η εντολή git fetch origin ανακτά όλες τις νέες αλλαγές που έχουν γίνει από τότε που κλωνοποιήσαμε το αποθετήριο ή από τότε που ανακτήσαμε δεδομένα από αυτό για τελευταία φορά. Είναι σημαντικό να τονίσουμε ότι η εντολή git fetch απλά τραβά δεδομένα στο τοπικό μας αποθετήριο· δεν συγχωνεύει τα δεδομένα αυτά με διάφορες αλλαγές που μπορεί να έχουμε κάνει εμείς τοπικά. Θα πρέπει να κάνουμε τη συγχώνευση χειροκίνητα όταν είστε έτοιμοι.

Αν ο κλάδος που παρακολουθεί έναν απομακρυσμένα κλάδο (περισσότερες λεπτομέρειες για αυτό στην επόμενη ενότητα και την ενότητα Διακλαδώσεις στο Git), μπορούμε να χρησιμοποιήσουμε την εντολή git pull για να γίνει αυτόματη ανάκτηση και συγχώνευση του απομακρυσμένου κλάδου στο τρέχοντα δικό μας. Αυτή η ροή εργασιών ενδεχομένως μας φαίνεται πιο εύκολη· επιπλέον, η εντολή git clone θέτει αυτόματα τον τοπικό μας κλάδο master να παρακολουθεί τον απομακρυσμένο κλάδου master (ή όπως ονομάζεται ο προεπιλεγμένος κλάδος) στον διακομιστή από τον οποίο κλωνοποιήσαμε. Η εκτέλεση της εντολής git pull, γενικά ανακτά τα δεδομένα από τον διακομιστή, τον οποίο είχαμε αρχικά κλωνοποιήσει και προσπαθεί να συγχωνεύσει αυτά τα δεδομάνα στον κώδικα πάνω στον οποίο εργαζόμαστε.

Note

Από την έκδοση 2.27 του Git και μετά, η εντολή git pull σας προειδοποιεί αν η μεταβλητή pull.rebase δεν έχει καθοριστεί. Το Git θα συνεχίσει να σας δίνει προειδοποιήσεις μέχρι να καθορίσετε αυτή τη μεταβλητή.

Αν θέλετε την προεπιλεγμένη συμπεριφορά του Git (fast-forward αν είναι δυνατό, αλλιώς δημιούργησε μία υποβολή συγχώνευσης (merge commit)): git config --global pull.rebase "false"

Αν θέλετε να κάνετε rebase όταν έλκουμε: git config --global pull.rebase "true"

Ώθηση δεδομένων σε απομακρυσμένα αποθετήρια

Όταν έχουμε φέρει κάποιο έργο μας σε σημείο που θέλουμε να το κοινοποιήσουμε, θα πρέπει να το ωθήσουμε. Η εντολή είναι απλή: git push <remote> <branch>. Για παράδειγμα, αν θέλουμε να ωθήσουμε τον τοπικό μας κλάδο master στον απομακρυσμένο διακομιστή origin (επαναλαμβάνουμε ότι η κλωνοποίηση παραμετροποιεί αυτόματα αυτά τα ονόματα), τότε μπορούμε να εκτελέσουμε αυτή την εντολή έτσι ώστε να ωθήσουμε τις υποβολές (commits) που έχουμε κάνει στον διακομιστή:

$ git push origin master

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

Επιθεώρηση απομακρυσμένου αποθετηρίου

Αν θέλουμε να δούμε περισσότερες πληροφορίες σχετικά με ένα απομακρυσμένο αποθετήριο, μπορούμε να χρησιμοποιήσουμε την εντολή git remote show <remote>. Αν εκτελέσουμε αυτή την εντολή με κάποιο σύντομο όνομα, όπως το origin, θα δούμε κάτι σαν:

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

Παρατίθεται το URL του απομακρυσμένου αποθετηρίου καθώς και οι κλάδοι τους οποίους παρακολουθούμε. Επίσης μας ενημερώνει ότι αν βρισκόμαστε στον κλάδο master και εκτελέσουμε git pull, ο κλάδος master του απομακρυσμένου αποθετηρίου θα συγχωνευτεί αυτόματα στον τοπικό κλάδο master αφότου ανακτηθεί. Επίσης παραθέτει τις απομακρυσμένες αναφορές που έχει κατεβάσει.

Το παραπάνω είναι ένα απλό παράδειγμα που ενδεχομένως θα συναντήσουμε. Όταν αρχίσουμε να χρησιμοποιούμε πιο εκτεταμένα το Git, μπορεί να δούμε πολύ περισσότερες πληροφορίες όταν εκτελούμε την εντολή git remote show.

$ git remote show origin
* remote origin
  URL: https://github.com/my-org/complex-project
  Fetch URL: https://github.com/my-org/complex-project
  Push  URL: https://github.com/my-org/complex-project
  HEAD branch: master
  Remote branches:
    master                           tracked
    dev-branch                       tracked
    markdown-strip                   tracked
    issue-43                         new (next fetch will store in remotes/origin)
    issue-45                         new (next fetch will store in remotes/origin)
    refs/remotes/origin/issue-11     stale (use 'git remote prune' to remove)
  Local branches configured for 'git pull':
    dev-branch merges with remote dev-branch
    master     merges with remote master
  Local refs configured for 'git push':
    dev-branch                     pushes to dev-branch                     (up to date)
    markdown-strip                 pushes to markdown-strip                 (up to date)
    master                         pushes to master                         (up to date)

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

Μετονομασία και διαγραφή απομακρυσμένων αποθετηρίων

Αν θέλουμε να μετονομάσουμε το σύντομο όνομα ενός απομακρυσμένου αποθετηρίου, εκτελούμε την εντολή git remote rename. Για παράδειγμα, αν θέλουμε να μετονομάσουμε το pb σε paul, μπορούμε να χρησιμοποιήσουμε την git remote rename:

$ git remote rename pb paul
$ git remote
origin
paul

Αξίζει να σημειωθεί ότι η εντολή αυτή αλλάζει επίσης τα ονόματα των απομακρυσμένων κλάδων που παρακολουθούμε. Στον κλάδο στον οποίο αναφερόμασταν ως pb/master πλέον θα αναφερόμαστε ως paul/master.

Αν θελήσουμε να διαγράψουμε για κάποιο λόγο ένα απομακρυσμένο αποθετήριο· έχουμε μετακίνησει τον διακομιστή σε άλλη διεύθυνση ή δεν χρησιμοποιούμε καθόλου το συγκεκριμένο αποθετήριο, ή απλά κάποιος συνεργάτης έχει εγκαταλείψει — μπορούμε να χρησιμοποιήσουμε είτε την εντολή git remote remove ή την git remote rm:

$ git remote remove paul
$ git remote
origin

Μόλις σβήσουμε την αναφορά σε κάποιο απομακρυσμένο αποθετήριο με αυτό το τρόπο, όλοι οι απομακρυσμένοι κλάδοι και όλες οι ρυθμίσεις που είναι σχετικές με αυτό το απομακρυσμένο αποθετήριο, θα σβηστούν επίσης.