Σε αυτό το βιβλίο, χρησιμοποιήσαμε απλές απεικονίσεις από απομακρυσμένους κλάδους σε τοπικές αναφορές, αλλά οι απεικονίσεις είναι δυνατό να είναι πιο σύνθετες. Ας υποθέσουμε ότι προσθέτουμε ένα απομακρυσμένο σύστημα όπως αυτό:
$ git remote add origin https://github.com/schacon/simplegit-progit
Η παραπάνω προσθέτει μια ενότητα στο αρχείο .git/config
, καθορίζοντας το όνομα του απομακρυσμένου αποθετηρίου (origin
), τη διεύθυνση URL του και το refspec για την ανάκτηση:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
Η μορφή του refspec είναι ένα προαιρετικό `, ακολουθούμενο από `<src>:<dst>`, όπου `<src>` είναι το πρότυπο για αναφορές στην απομακρυσμένη πλευρά και `<dst>` είναι πού θα γραφούν οι αναφορές αυτές τοπικά.
Το `
λέει στο Git να ενημερώσει την αναφορά ακόμα κι αν δεν πρόκειται για ταχυπροώθηση.
Στην προεπιλεγμένη περίπτωση που γράφεται αυτόματα από μια εντολή git remote add
, το Git συγκεντρώνει όλες τις αναφορές κάτω από τον refs/heads/
του διακομιστή και τις γράφει στον refs/remotes/origin/
τοπικά.
Επομένως, εάν υπάρχει ένας κλάδος master
στον διακομιστή, μπορούμε να έχουμε πρόσβαση στο μητρώο αυτού του κλάδου τοπικά μέσω
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Όλες είναι ισοδύναμες, διότι το Git επεκτείνει το καθένα σε refs/remotes/origin/master
.
Εάν θέλουμε το Git αντί να έλκει μόνο τον κλάδο master
κάθε φορά και όχι κάθε άλλο κλάδο από τον απομακρυσμένο διακομιστή, μπορούμε να αλλάξουμε τη γραμμή παραλαβής σε
fetch = +refs/heads/master:refs/remotes/origin/master
Αυτό είναι μόνο το προεπιλεγμένο refspec για την git fetch
για αυτό το απομακρυσμένο αποθετήριο.
Αν θέλουμε να κάνουμε κάτι μία φορά, μπορούμε να καθορίσουμε το refspec στη γραμμή εντολών.
Για να έλξουμε τον κλάδο master
του απομακρυσμένου αποθετηρίου στον τοπικό origin/mymaster
, μπορούμε να τρέξουμε
$ git fetch origin master:refs/remotes/origin/mymaster
Μπορούμε επίσης να ορίσουμε πολλά refspecs. Στη γραμμή εντολών, μπορούμε να έλξουμε αρκετούς κλάδους ως εξής:
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
Σε αυτήν την περίπτωση, η έλξη του κλάδου master
απορρίφθηκε επειδή δεν ήταν αναφορά ταχυπροώθησης. Μπορούμε να παρακάμψουμε αυτήν τη συμπεριφορά βάζοντας το +
μπροστά από το refspec.
Μπορούμε επίσης να ορίσουμε πολλά refspec για ανάκτηση στο αρχείο ρυθμίσεων. Αν θέλουμε πάντα να ανακτούμε τους κύριους και πειραματικούς κλάδους προσθέτουμε αυτές τις δύο γραμμές:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
Δεν μπορούμε να χρησιμοποιήσουμε χαρακτήρες μπαλαντές στο μοτίβο, επομένως το παρακάτω δεν είναι έγκυρη έκφραση:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
Πάντως, μπορούμε να χρησιμοποιήσουμε ονοματοχώρους (ή καταλόγους) για να πετύχουμε κάτι τέτοιο. Εάν έχουμε μια ομάδα QA που ωθεί μια σειρά από κλάδους και θέλουμε να πάρουμε το κύριο κλάδο και οποιοδήποτε από τους κλάδους της ομάδας QA αλλά τίποτα άλλο, μπορούμε να χρησιμοποιήσουμε μια ενότητα config όπως αυτή:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
Εάν έχουμε μια πολύπλοκη ροή εργασίας που διαθέτει μια ομάδα QA που ωθεί κλάδους, προγραμματιστές που ωθούν κλάδους και ομάδες ενσωμάτωσης που ωθούν και συνεργάζονται σε απομακρυσμένα κλάδους, μπορούμε να τους χωρίσουμε σε ονοματοχώρους με αυτό τον τρόπο.
Είναι ωραίο ότι μπορούμε να ανακτήσουμε αναφορές εντός ονοματοχώρων με αυτόν τον τρόπο, αλλά πώς μπόρεσε η ομάδα QA να βάλει όλους τους κλάδους της σε έναν ονοματοχώρο qa/
;
Αυτό το πετυχαίνουμε χρησιμοποιώντας refspec για να ωθήσουμε.
Εάν η ομάδα QA θέλει να ωθήσει τον κλάδο master
στον qa/master
στον απομακρυσμένο διακομιστή, μπορεί να τρέξει
$ git push origin master:refs/heads/qa/master
Αν θέλουν να το κάνει το Git αυτόματα κάθε φορά που τρέχουν την git push origin
, μπορούν να προσθέσουν μια τιμή push
στο αρχείο config:
[remote "origin"]
url = https://github.com/schacon/simplegit-progit
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
Και πάλι, αυτό θα προκαλέσει μια git push origin
να ωθήσει τον τοπικό κλάδο master
στον απομακρυσμένο κλάδο qa/master
εκ προεπιλογής.
Μπορούμε επίσης να χρησιμοποιήσουμε το refspec για να διαγράψουμε αναφορές από τον απομακρυσμένο διακομιστή εκτελώντας κάτι σαν αυτό:
$ git push origin :topic
Επειδή το refspec είναι <src>:<dst>
, αν αφήσουμε το τμήμα <src>
, αυτό ουσιαστικά λέει ``κάνε τον θεματικό κλάδο στο απομακρυσμένο αποθετήριο, τίποτα'', οπότε το διαγράφει.