Git
Chapters ▾ 2nd Edition

10.8 Εσωτερική λειτουργία του Git - Μεταβλητές περιβάλλοντος

Μεταβλητές περιβάλλοντος

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

Καθολική συμπεριφορά

Μέρος της συμπεριφοράς του Git ως πρόγραμμα υπολογιστή εξαρτάται από τις μεταβλητές περιβάλλοντος.

Η GIT_EXEC_PATH καθορίζει πού το Git αναζητά τα υποπρογράμματά του (όπως git-commit, git-diff και άλλα). Μπορούμε να ελέγξουμε την τρέχουσα ρύθμιση εκτελώντας το git --exec-path.

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

Η PREFIX είναι παρόμοια, αλλά για διαμόρφωση σε όλο το σύστημα. Το Git αναζητά αυτό το αρχείο στο $PREFIX/etc/gitconfig.

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

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

Η GIT_EDITOR είναι ο επεξεργαστής τον οποίο θα ξεκινήσει το Git όταν ο χρήστης χρειάζεται να επεξεργαστεί κάποιο κείμενο (για παράδειγμα ένα μήνυμα αποστολής). Εάν είναι απενεργοποιημένη, θα χρησιμοποιηθεί η EDITOR.

Τοποθεσίες αποθετηρίων

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

Η GIT_DIR είναι η θέση του φακέλου .git. Εάν δεν έχει καθοριστεί, το Git προχωράει στο δέντρο του καταλόγου μέχρι να φτάσει στο ~ ή /, αναζητώντας έναν κατάλογο .git σε κάθε βήμα.

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

Η GIT_WORK_TREE είναι η θέση της ρίζας του καταλόγου εργασίας για ένα μη γυμνό αποθετήριο. Εάν δεν έχει καθοριστεί, χρησιμοποιείται ο γονικός κατάλογος του $GIT_DIR.

Η GIT_INDEX_FILE είναι η διαδρομή στο αρχείο του ευρετηρίου (για μη γυμνά αποθετήρια μονον).

Η GIT_OBJECT_DIRECTORY μπορεί να χρησιμοποιηθεί για να καθορίσει τη θέση του καταλόγου που συνήθως βρίσκεται στο ‘.git/objects’.

Η GIT_ALTERNATE_OBJECT_DIRECTORIES είναι μια λίστα με άνω-κάτω τελεία ως διαχωριστικό (μορφοποιημένη όπως /dir/one:/dir/two:…), η οποία λέει στο Git πού να ψάξει για αντικείμενα αν δεν βρίσκονται στο GIT_OBJECT_DIRECTORY. Αν τυχαίνει να έχουμε πολλά έργα με μεγάλα αρχεία που έχουν ακριβώς το ίδιο περιεχόμενο, αυτό μπορεί να χρησιμοποιηθεί για να αποφευχθεί η αποθήκευση πάρα πολλών αντιγράφων τους.

Pathspecs

Ένα “pathspec” αναφέρεται στον τρόπο με τον οποίο καθορίζουμε διαδρομές στο Git, συμπεριλαμβανομένης της χρήσης μπαλαντέρ. Αυτά χρησιμοποιούνται στο αρχείο .gitignore, αλλά και στη γραμμή εντολών (git add *.c).

Οι GIT_GLOB_PATHSPECS και GIT_NOGLOB_PATHSPECS ελέγχουν την προεπιλεγμένη συμπεριφορά των μπαλαντέρ στα pathspecs. Αν η GIT_GLOB_PATHSPECS έχει τιμή 1, οι χαρακτήρες μπαλαντέρ δρουν ως μπαλαντέρ (αυτή είναι και η προεπιλεγμένη συμπεριφορά)· αν η GIT_NOGLOB_PATHSPECS έχει τιμή 1, οι χαρακτήρες μπαλαντέρ αντιμετωπίζονται ως απλοί χαρακτήρες, κάτι που σημαίνει ότι κάτι σαν *.c θα αντιστοιχούσε μόνο σε ένα αρχείο με όνομα *.c, αντί σε οποιοδήποτε αρχείο του οποίου το όνομα τελειώνει σε .c Μπορούμε να παρακάμψουμε αυτήν τη συμπεριφορά σε μεμονωμένες περιπτώσεις ξεκινώντας το pathspec με :(glob) ή :(literal), όπως στο :(glob)*.c.

Η GIT_LITERAL_PATHSPECS απενεργοποιεί και τις δύο παραπάνω συμπεριφορές· δεν θα λειτουργούν χαρακτήρες μπαλαντέρ και τα προθέματα παράκαμψης απενεργοποιούνται επίσης.

Η GIT_ICASE_PATHSPECS ορίζει όλα τα pathspecs να λειτουργούν χωρίς διάκριση πεζών/κεφαλαίων.

Υποβολές

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

Η GIT_AUTHOR_NAME είναι το ανθρωπανάγνωστο όνομα στο πεδίο author.

H GIT_AUTHOR_EMAIL είναι η διεύθυνση e-mail για το πεδίο author.

H GIT_AUTHOR_DATE είναι η χρονοσήμανση που χρησιμοποιείται για το πεδίο author.

H GIT_COMMITTER_NAME ορίζει το ανθρώπινο όνομα για το πεδίο committer.

H GIT_COMMITTER_EMAIL είναι η διεύθυνση e-mail για το πεδίο committer.

H GIT_COMMITTER_DATE χρησιμοποιείται για τη χρονοσήμανση στο πεδίο committer.

H EMAIL είναι η εναλλακτική διεύθυνση e-mail για την περίπτωση που δεν έχει οριστεί η τιμή διαμόρφωσης user.email. Εάν το αυτή δεν έχει οριστεί, το Git χρησιμοποιεί το όνομα του χρήστη και του υπολογιστή.

Δικτύωση

Το Git χρησιμοποιεί τη βιβλιοθήκη curl για λειτουργίες δικτύου μέσω HTTP, έτσι η GIT_CURL_VERBOSE λέει στο Git να τυπώνει όλα τα μηνύματα που δημιουργούνται από αυτήν τη βιβλιοθήκη. Αυτό είναι παρόμοιο με το να τρέξουμε curl -v στη γραμμή εντολών.

H GIT_SSL_NO_VERIFY λέει στο Git να μην επαληθεύει τα πιστοποιητικά SSL. Αυτό μπορεί μερικές φορές να είναι απαραίτητο αν χρησιμοποιούμε πιστοποιητικό που έχει αυτο-υπογραφεί για να εξυπηρετούμε αποθετήρια Git μέσω HTTPS ή είμαστε στη μέση της δημιουργίας ενός διακομιστή Git αλλά δεν έχουμε εγκαταστήσει ακόμα ένα πλήρες πιστοποιητικό.

Εάν ο ρυθμός δεδομένων μιας λειτουργίας HTTP είναι μικρότερος από GIT_HTTP_LOW_SPEED_LIMIT bytes ανά δευτερόλεπτο για περισσότερο από GIT_HTTP_LOW_SPEED_TIME δευτερόλεπτα, το Git θα ακυρώσει αυτήν τη λειτουργία. Αυτές οι τιμές υπερισχύουν των τιμών διαμόρφωσης http.lowSpeedLimit και http.lowSpeedTime.

H GIT_HTTP_USER_AGENT ορίζει τη συμβολοσειρά χρήστη-πράκτορα που χρησιμοποιείται από το Git κατά την επικοινωνία μέσω HTTP. Η προεπιλογή είναι μια τιμή όπως η git/2.0.0.

Diff και συγχώνευση

H GIT_DIFF_OPTS έχει λίγο παραπλανητικό όνομα. Οι μόνες έγκυρες τιμές είναι -u <n> ή --unified=<n>, που ελέγχει τον αριθμό των γραμμών που εμφανίζονται σε μια εντολή git diff.

H GIT_EXTERNAL_DIFF χρησιμοποιείται για να παρακάμψει την τιμή διαμόρφωσης diff.external. Εάν έχει οριστεί, το Git θα καλέσει αυτό το πρόγραμμα όταν καλείται η git diff.

Οι GIT_DIFF_PATH_COUNTER και GIT_DIFF_PATH_TOTAL είναι χρήσιμες από μέσα από το πρόγραμμα που καθορίζεται από την GIT_EXTERNAL_DIFF ή την diff.external. Η πρώτη αντιπροσωπεύει ποιο αρχείο είναι η αναφορά σε μια ακολουθία αρχείων diff (ξεκινώντας από το 1), και το τελευταίο είναι ο συνολικός αριθμός αρχείων της παρτίδας.

H GIT_MERGE_VERBOSITY ελέγχει την έξοδο για τη στρατηγική αναδρομικής συγχώνευσης. Οι επιτρεπόμενες τιμές είναι οι εξής:

  • 0 δεν εξάγει τίποτα, εκτός πιθανώς από ένα μήνυμα σφάλματος.

  • 1 δείχνει μόνο συγκρούσεις.

  • 2 εμφανίζει επίσης αλλαγές αρχείων.

  • 3 δείχνει πότε παραλείπονται τα αρχεία επειδή δεν έχουν αλλάξει.

  • 4 δείχνει όλες τις διαδρομές κατά την επεξεργασία τους.

  • 5 και πάνω δείχνουν λεπτομερείς πληροφορίες αποσφαλμάτωσης.

Η προεπιλεγμένη τιμή είναι η 2.

Αποσφαλμάτωση

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

*true, 1 ή 2 —η κατηγορία του ίχνους που γράφεται στην stderr. * Μια απόλυτη διαδρομή που αρχίζει με / —η έξοδος του ίχνους θα γραφτεί σε αυτό το αρχείο.

H GIT_TRACE ελέγχει γενικά τα ίχνη, τα οποία δεν ταιριάζουν σε κάποια συγκεκριμένη κατηγορία. Αυτό περιλαμβάνει την επέκταση των ψευδώνυμων (aliases) και την ανάθεση σε άλλα υποπρογράμματα.

$ GIT_TRACE=true git lga
20:12:49.877982 git.c:554               trace: exec: 'git-lga'
20:12:49.878369 run-command.c:341       trace: run_command: 'git-lga'
20:12:49.879529 git.c:282               trace: alias expansion: lga => 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
20:12:49.879885 git.c:349               trace: built-in: git 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
20:12:49.899217 run-command.c:341       trace: run_command: 'less'
20:12:49.899675 run-command.c:192       trace: exec: 'less'

H GIT_TRACE_PACK_ACCESS ελέγχει τον εντοπισμό της πρόσβασης των πακέτων (packfile). Το πρώτο πεδίο είναι το πακέτο που προσπελαύνεται, το δεύτερο είναι η μετατόπιση (offset) μέσα σε αυτό το αρχείο:

$ GIT_TRACE_PACK_ACCESS=true git status
20:10:12.081397 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 12
20:10:12.081886 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 34662
20:10:12.082115 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 35175
# […]
20:10:12.087398 sha1_file.c:2088        .git/objects/pack/pack-e80e...e3d2.pack 56914983
20:10:12.087419 sha1_file.c:2088        .git/objects/pack/pack-e80e...e3d2.pack 14303666
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

H GIT_TRACE_PACKET επιτρέπει την παρακολούθηση σε επίπεδο πακέτου για λειτουργίες δικτύου.

$ GIT_TRACE_PACKET=true git ls-remote origin
20:15:14.867043 pkt-line.c:46           packet:          git< # service=git-upload-pack
20:15:14.867071 pkt-line.c:46           packet:          git< 0000
20:15:14.867079 pkt-line.c:46           packet:          git< 97b8860c071898d9e162678ea1035a8ced2f8b1f HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/2.0.4
20:15:14.867088 pkt-line.c:46           packet:          git< 0f20ae29889d61f2e93ae00fd34f1cdb53285702 refs/heads/ab/add-interactive-show-diff-func-name
20:15:14.867094 pkt-line.c:46           packet:          git< 36dc827bc9d17f80ed4f326de21247a5d1341fbc refs/heads/ah/doc-gitk-config
# […]

H GIT_TRACE_PERFORMANCE ελέγχει την καταγραφή δεδομένων απόδοσης. Η έξοδος δείχνει πόση ώρα παίρνη η κάθε κλήση σε εντολή του git.

$ GIT_TRACE_PERFORMANCE=true git gc
20:18:19.499676 trace.c:414             performance: 0.374835000 s: git command: 'git' 'pack-refs' '--all' '--prune'
20:18:19.845585 trace.c:414             performance: 0.343020000 s: git command: 'git' 'reflog' 'expire' '--all'
Counting objects: 170994, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (43413/43413), done.
Writing objects: 100% (170994/170994), done.
Total 170994 (delta 126176), reused 170524 (delta 125706)
20:18:23.567927 trace.c:414             performance: 3.715349000 s: git command: 'git' 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' '.git/objects/pack/.tmp-49190-pack'
20:18:23.584728 trace.c:414             performance: 0.000910000 s: git command: 'git' 'prune-packed'
20:18:23.605218 trace.c:414             performance: 0.017972000 s: git command: 'git' 'update-server-info'
20:18:23.606342 trace.c:414             performance: 3.756312000 s: git command: 'git' 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago'
Checking connectivity: 170994, done.
20:18:25.225424 trace.c:414             performance: 1.616423000 s: git command: 'git' 'prune' '--expire' '2.weeks.ago'
20:18:25.232403 trace.c:414             performance: 0.001051000 s: git command: 'git' 'rerere' 'gc'
20:18:25.233159 trace.c:414             performance: 6.112217000 s: git command: 'git' 'gc'

H GIT_TRACE_SETUP εμφανίζει πληροφορίες για το τι ανακάλυψε το Git σχετικά με το αποθετήριο και το περιβάλλον με το οποίο αλληλεπιδρά.

$ GIT_TRACE_SETUP=true git status
20:19:47.086765 trace.c:315             setup: git_dir: .git
20:19:47.087184 trace.c:316             setup: worktree: /Users/ben/src/git
20:19:47.087191 trace.c:317             setup: cwd: /Users/ben/src/git
20:19:47.087194 trace.c:318             setup: prefix: (null)
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Διάφορα

H GIT_SSH, εφόσον ορίζεται, είναι ένα πρόγραμμα που καλείται αντί του ssh όταν το Git προσπαθεί να συνδεθεί με έναν κεντρικό υπολογιστή SSH. Καλείται ως $GIT_SSH [username @] host [-p <θύρα>] <εντολή>. Ας σημειωθεί ότι αυτός δεν είναι ο ευκολότερος τρόπος για να εξατομικεύσουμε τον τρόπο με τον οποίο καλείται η ssh· δεν υποστηρίζει επιπλέον παραμέτρους γραμμής εντολών, οπότε θα πρέπει να γράψουμε ένα wrapper script και να ορίσουμε την GIT_SSH να δείχνει σε αυτό. Είναι μάλλον ευκολότερο να χρησιμοποιήσουμε το αρχείο ~/.ssh/config για αυτό.

H GIT_ASKPASS παρακάμπτει την τιμή διαμόρφωσης core.askpass. Αυτό είναι το πρόγραμμα που καλείται κάθε φορά που το Git χρειάζεται να ζητήσει διαπιστευτήρια από τον χρήστη, και παίρνει ένα κείμενο για προτροπή ως όρισμα γραμμής εντολών και επιστρέφει την απάντηση στη stdout. (Περισσότερα σχετικά με αυτό το υποσύστημα στην ενότητα Αποθήκευση διαπιστευτηρίων.)

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

H GIT_FLUSH μπορεί να χρησιμοποιηθεί για να αναγκάσει το Git να χρησιμοποιήσει I/O χωρίς βαθμίδες απομόνωσης (buffers) όταν γράφει σταδιακά στη stdout. Η τιμή 1 προκαλεί την εκκαθάριση του Git συχνότερα, η τιμή 0 προκαλεί την προσωρινή τοποθέτηση όλων των εξόδων στη βαθμίδα απομόνωσης. Η προεπιλεγμένη τιμή (εάν αυτή η μεταβλητή δεν έχει οριστεί) είναι η επιλογή ενός κατάλληλου προγράμματος απομόνωσης βαθμίδων, ανάλογα με τη δραστηριότητα και τη λειτουργία της εξόδου.

H GIT_REFLOG_ACTION μας επιτρέπει να καθορίσουμε το περιγραφικό κείμενο που γράφτηκε στο reflog. Για παράδειγμα:

$ GIT_REFLOG_ACTION="my action" git commit --allow-empty -m 'my message'
[master 9e3d55a] my message
$ git reflog -1
9e3d55a HEAD@{0}: my action: my message